feat: 添加角色权限控制和教师筛选功能
This commit is contained in:
@ -2,11 +2,11 @@
|
||||
import BussApi from '@/api/BussApi';
|
||||
import pageWrapper from '@/components/page-wrapper.vue';
|
||||
import { useUser } from '@/stores/useUser';
|
||||
import type { Lesson } from '@/types/api/lesson';
|
||||
import type { LessonTask } from '@/types/api/lesson';
|
||||
import { calcLessonProgress } from '@/utils/lesson';
|
||||
import { onPageShow } from '@dcloudio/uni-app';
|
||||
import { useRouter } from 'uni-mini-router';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useToast } from 'wot-design-uni';
|
||||
import type { DropMenuItemBeforeToggle } from 'wot-design-uni/components/wd-drop-menu-item/types';
|
||||
import WdTag from 'wot-design-uni/components/wd-tag/wd-tag.vue';
|
||||
@ -17,19 +17,43 @@ const router = useRouter()
|
||||
const user = useUser()
|
||||
|
||||
const teacherFilterValue = ref<number>(0)
|
||||
|
||||
const teacherFilterOptions = ref<Record<string, any>[]>([
|
||||
{ label: '老师1', value: 0 },
|
||||
{ label: '老师2', value: 1 },
|
||||
{ label: '老师3', value: 2 }
|
||||
{ label: '全部', value: 0 }
|
||||
])
|
||||
|
||||
const loadTeacherOptions = async () => {
|
||||
if (!user.userinfo?.departmentId) return
|
||||
|
||||
try {
|
||||
const res = await BussApi.getDepartmentTeachers(user.userinfo.departmentId)
|
||||
if (res.code === 10000 && Array.isArray(res.data)) {
|
||||
teacherFilterOptions.value = [
|
||||
{ label: '全部', value: 0 },
|
||||
...res.data.map(teacher => ({
|
||||
label: teacher.username,
|
||||
value: teacher.id
|
||||
}))
|
||||
]
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error) {
|
||||
toast.error({ msg: err.message })
|
||||
} else {
|
||||
toast.error({ msg: '获取教师列表失败' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadTeacherOptions()
|
||||
})
|
||||
|
||||
const handleBeforeToggle: DropMenuItemBeforeToggle = ({ status, resolve }) => {
|
||||
resolve(true)
|
||||
}
|
||||
|
||||
const expandedCourse = ref(['lesson'])
|
||||
const groupedLessons = ref<{ [key: string]: Lesson[] }>({})
|
||||
const groupedLessons = ref<{ [key: string]: LessonTask[] }>({})
|
||||
|
||||
const openLessonDetail = (courseId: number) => {
|
||||
router.push({
|
||||
@ -40,37 +64,73 @@ const openLessonDetail = (courseId: number) => {
|
||||
})
|
||||
}
|
||||
|
||||
onPageShow(() => {
|
||||
toast.loading({
|
||||
msg: '加载中...'
|
||||
})
|
||||
BussApi.lessons(1, 512).then(res => {
|
||||
toast.close()
|
||||
const groupData = res.data.sort((a: Lesson, b: Lesson) => {
|
||||
return a.id - b.id
|
||||
}).reduce((acc: any, cur: any) => {
|
||||
if (!acc[cur.course_name]) {
|
||||
acc[cur.course_name] = []
|
||||
}
|
||||
acc[cur.course_name].push(cur)
|
||||
return acc
|
||||
}, {})
|
||||
const loadLessons = async () => {
|
||||
if (!user.userinfo) {
|
||||
toast.error({ msg: '请先登录' })
|
||||
return
|
||||
}
|
||||
|
||||
toast.loading({ msg: '加载中...' })
|
||||
|
||||
try {
|
||||
const userId = teacherFilterValue.value === 0 ? undefined : teacherFilterValue.value
|
||||
const res = await BussApi.getLessonTasks(1, 512, userId)
|
||||
|
||||
if (res.code !== 10000 || !res.data?.content || !Array.isArray(res.data.content)) {
|
||||
toast.error({ msg: res.message || '获取数据失败' })
|
||||
return
|
||||
}
|
||||
|
||||
const groupData = res.data.content
|
||||
.sort((a: LessonTask, b: LessonTask) => a.id - b.id)
|
||||
.reduce((acc: { [key: string]: LessonTask[] }, cur: LessonTask) => {
|
||||
if (!acc[cur.courseName]) {
|
||||
acc[cur.courseName] = []
|
||||
}
|
||||
acc[cur.courseName].push(cur)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
groupedLessons.value = groupData
|
||||
// expand courses with lessons in progress
|
||||
expandedCourse.value = Object.keys(groupData).filter(courseName => {
|
||||
return groupData[courseName].filter((lesson: Lesson) => calcLessonProgress(lesson) !== 0 && calcLessonProgress(lesson) !== 100).length > 0
|
||||
return groupData[courseName].filter((lesson: LessonTask) =>
|
||||
calcLessonProgress(lesson) !== 0 && calcLessonProgress(lesson) !== 100
|
||||
).length > 0
|
||||
})
|
||||
}).catch(err => {
|
||||
toast.error({ msg: err.message })
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error) {
|
||||
toast.error({ msg: err.message })
|
||||
} else {
|
||||
toast.error({ msg: '获取课程列表失败' })
|
||||
}
|
||||
} finally {
|
||||
toast.close()
|
||||
}
|
||||
}
|
||||
|
||||
// 监听教师筛选值的变化
|
||||
watch(teacherFilterValue, () => {
|
||||
loadLessons()
|
||||
})
|
||||
|
||||
onPageShow(() => {
|
||||
loadLessons()
|
||||
})
|
||||
|
||||
const getUsernameById = (userId: number) => {
|
||||
if (teacherFilterValue.value === 0) {
|
||||
const teacher = teacherFilterOptions.value.find(t => t.value === userId)
|
||||
return teacher?.label || '未知老师'
|
||||
} else
|
||||
return ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-wrapper>
|
||||
<div>
|
||||
<!-- todo teacher filter [for role B] -->
|
||||
<wd-drop-menu v-if="user.hasJobTag('B')">
|
||||
<wd-drop-menu v-if="!user.hasRole('teacher')">
|
||||
<wd-drop-menu-item v-model="teacherFilterValue" :options="teacherFilterOptions"
|
||||
:before-toggle="handleBeforeToggle" />
|
||||
</wd-drop-menu>
|
||||
@ -81,15 +141,33 @@ onPageShow(() => {
|
||||
<template #title="{ expanded, disabled, isFirst }">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="pt-1">{{ courseName || '无标题课程' }}</p>
|
||||
<p class="pt-1">
|
||||
{{ courseName || '无标题课程' }}
|
||||
<span v-if="getUsernameById(courses[0]?.userId)" class=" text-xs text-gray-400 ml-2">
|
||||
{{ getUsernameById(courses[0]?.userId) }}
|
||||
</span>
|
||||
</p>
|
||||
<div class="flex items-center gap-1">
|
||||
<wd-tag v-if="courses.filter(lesson => calcLessonProgress(lesson) !== 0 && calcLessonProgress(lesson) !==
|
||||
100).length > 0" custom-class="w-fit" type="primary">进行中</wd-tag>
|
||||
<wd-tag v-if="courses.filter(lesson => calcLessonProgress(lesson) === 100).length === courses.length"
|
||||
custom-class="w-fit" type="success">已完成</wd-tag>
|
||||
<wd-tag v-if="(() => {
|
||||
const hasInProgress = courses.some(lesson => {
|
||||
const progress = calcLessonProgress(lesson);
|
||||
return progress > 0 && progress < 100;
|
||||
});
|
||||
return hasInProgress;
|
||||
})()" custom-class="w-fit" type="primary">进行中</wd-tag>
|
||||
<wd-tag v-if="(() => {
|
||||
const allCompleted = courses.every(lesson => {
|
||||
const progress = calcLessonProgress(lesson);
|
||||
return progress === 100;
|
||||
});
|
||||
return allCompleted;
|
||||
})()" custom-class="w-fit" type="success">已完成</wd-tag>
|
||||
<wd-tag custom-class="op-60" plain>
|
||||
共{{ courses.length }}课时
|
||||
共{{ courses.length }}节微课
|
||||
</wd-tag>
|
||||
<!-- <wd-tag v-if="teacherFilterValue === 0" custom-class="w-fit" plain>
|
||||
{{ getUsernameById(courses[0]?.userId) }}
|
||||
</wd-tag> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
@ -127,7 +205,7 @@ onPageShow(() => {
|
||||
<div v-if="calcLessonProgress(lesson) === 100" class="i-tabler-circle-check"></div>
|
||||
<div v-else-if="calcLessonProgress(lesson) === 0" class="i-tabler-circle-dashed"></div>
|
||||
<div v-else class="i-tabler-hourglass-empty"></div>
|
||||
<span>{{ lesson.m_lesson_name || '无标题视频' }}</span>
|
||||
<span>{{ lesson.microLessonName || '无标题视频' }}</span>
|
||||
</div>
|
||||
<div class="w-24 flex items-center gap-3">
|
||||
<wd-progress :percentage="calcLessonProgress(lesson)"
|
||||
|
@ -2,7 +2,8 @@
|
||||
import BussApi from '@/api/BussApi';
|
||||
import { useDayjs } from '@/composables/useDayjs';
|
||||
import { useTabbar } from '@/stores/useTabbar';
|
||||
import type { Lesson } from '@/types/api/lesson';
|
||||
import { useUser } from '@/stores/useUser'
|
||||
import type { LessonTask } from '@/types/api/lesson';
|
||||
import { calcLessonProgress, extractLessonStage, getLessonSteps } from '@/utils/lesson';
|
||||
import { useRoute, useRouter } from 'uni-mini-router';
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
@ -13,8 +14,9 @@ const router = useRouter()
|
||||
const tabbar = useTabbar()
|
||||
const toast = useToast()
|
||||
const dayjs = useDayjs()
|
||||
const user = useUser()
|
||||
|
||||
const lesson = ref<Lesson | null>(null)
|
||||
const lesson = ref<LessonTask | null>(null)
|
||||
const lessonSteps = computed(() => lesson.value ? getLessonSteps(lesson.value) : [])
|
||||
const lessonStages = computed(() => lesson.value ? extractLessonStage(lesson.value) : null)
|
||||
const lessonProgress = computed(() => lesson.value ? calcLessonProgress(lesson.value) : 0)
|
||||
@ -23,7 +25,7 @@ const goProgress = (lessonId: number) => {
|
||||
router.replaceAll({
|
||||
name: 'progress',
|
||||
params: {
|
||||
courseName: `${lesson.value?.course_name}`,
|
||||
courseName: `${lesson.value?.courseName}`,
|
||||
lessonId: `${lessonId}`
|
||||
}
|
||||
})
|
||||
@ -40,7 +42,7 @@ onMounted(() => {
|
||||
toast.loading({
|
||||
msg: '加载中...'
|
||||
})
|
||||
BussApi.course(route.params.courseId).then(courseData => {
|
||||
BussApi.getLessonTask(route.params.courseId).then(courseData => {
|
||||
toast.close()
|
||||
lesson.value = courseData
|
||||
}).catch(err => {
|
||||
@ -54,11 +56,14 @@ onMounted(() => {
|
||||
<div
|
||||
:class="`pattern p-4 flex flex-col gap-6 relative ${lessonProgress === 100 ? 'bg-emerald' : (lessonProgress === 0 ? 'bg-neutral' : 'bg-blue')}`">
|
||||
<div class="flex flex-col gap-0">
|
||||
<h2 class="text-sm text-white font-black op-50">{{ lesson?.course_name }}</h2>
|
||||
<h1 class="text-lg text-white font-bold">{{ lesson?.m_lesson_name }}</h1>
|
||||
<h2 class="text-sm text-white font-black op-50">{{ lesson?.courseName }}</h2>
|
||||
<h1 class="text-lg text-white font-bold">{{ lesson?.microLessonName }}</h1>
|
||||
</div>
|
||||
<p class="text-xs text-white font-bold op-50" style="line-height: 1;">
|
||||
创建于 {{ dayjs(lesson?.created_at).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
创建于 {{ lesson?.createdAt ? dayjs(lesson.createdAt * 1000).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
</p>
|
||||
<p v-if="lessonProgress === 100" class="text-xs text-white font-bold op-50" style="line-height: 1;">
|
||||
完成于 {{ lesson?.finishTime ? dayjs(lesson.finishTime * 1000).format('YYYY-MM-DD HH:mm:ss') : '-' }}
|
||||
</p>
|
||||
<div class="absolute text-white top-2 right-2 op-35 text-18">
|
||||
<div v-if="lessonProgress === 100" class="i-tabler-circle-check"></div>
|
||||
@ -73,7 +78,8 @@ onMounted(() => {
|
||||
</wd-steps>
|
||||
</div>
|
||||
<div class="px-4 pt-2">
|
||||
<wd-button type="primary" :round="false" plain block @click="goProgress(lesson?.id!)">进度处理</wd-button>
|
||||
<wd-button v-if="!user.hasRole('liaison')" type="primary" :round="false" plain block
|
||||
@click="goProgress(lesson?.id!)">进度处理</wd-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -33,7 +33,7 @@ const handleSubmit = () => {
|
||||
BussApi.login({
|
||||
email: model.email,
|
||||
password: model.password,
|
||||
remember: model.remember + '',
|
||||
remember: model.remember
|
||||
}).then(res => {
|
||||
user.token = res.token
|
||||
toast.loading({
|
||||
@ -55,7 +55,7 @@ const handleSubmit = () => {
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(error, 'error')
|
||||
// console.log(error, 'error')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -68,6 +68,13 @@ const handleSubmit = () => {
|
||||
:rules="[{ required: true, message: '请填写邮箱' }]" />
|
||||
<wd-input label="密码" label-width="100px" prop="password" show-password clearable v-model="model.password"
|
||||
placeholder="请输入密码" :rules="[{ required: true, message: '请填写密码' }]" />
|
||||
<wd-cell>
|
||||
<template #title>
|
||||
<div class="pl-[5px]">
|
||||
<wd-checkbox v-model="model.remember">记住登录</wd-checkbox>
|
||||
</div>
|
||||
</template>
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
<view class="p-4">
|
||||
<wd-button type="primary" size="large" @click="handleSubmit" block>登录</wd-button>
|
||||
|
@ -1,24 +1,17 @@
|
||||
<script lang="ts" setup>
|
||||
<script setup lang="ts">
|
||||
import BussApi from '@/api/BussApi';
|
||||
import pageWrapper from '@/components/page-wrapper.vue';
|
||||
import { useUser } from '@/stores/useUser';
|
||||
import type { User } from '@/types/api/user';
|
||||
import { Jobs, Roles } from '@/types/api/user';
|
||||
import { useRouter } from 'uni-mini-router';
|
||||
import { onMounted } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useToast } from 'wot-design-uni';
|
||||
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const user = useUser()
|
||||
|
||||
const logout = () => {
|
||||
user.logout()
|
||||
router.replaceAll('/pages/login/index')
|
||||
}
|
||||
|
||||
const departmentMap = {
|
||||
4: '重庆眩生花科技有限公司',
|
||||
5: '重庆电子科技职业大学',
|
||||
}
|
||||
const userInfo = ref<User | null>(null)
|
||||
|
||||
onMounted(() => {
|
||||
toast.loading({
|
||||
@ -29,17 +22,75 @@ onMounted(() => {
|
||||
user.userinfo = res
|
||||
})
|
||||
})
|
||||
|
||||
const logout = async () => {
|
||||
try {
|
||||
toast.loading({ msg: '退出中...' })
|
||||
await BussApi.logout()
|
||||
toast.success('退出成功')
|
||||
user.logout()
|
||||
router.replaceAll('/pages/login/index')
|
||||
} catch (error: any) {
|
||||
toast.error(error.message || '退出失败')
|
||||
} finally {
|
||||
toast.close()
|
||||
}
|
||||
}
|
||||
|
||||
// 部门ID映射
|
||||
enum DepartmentId {
|
||||
XSH = 1, // 重庆眩生花科技有限公司
|
||||
CQEPU = 2 // 重庆电子科技职业大学
|
||||
}
|
||||
|
||||
const departmentMap: Record<DepartmentId, string> = {
|
||||
[DepartmentId.XSH]: '重庆眩生花科技有限公司',
|
||||
[DepartmentId.CQEPU]: '重庆电子科技职业大学',
|
||||
}
|
||||
|
||||
// 角色映射
|
||||
const roleMap: Record<number, string> = {
|
||||
[Roles.TEACHER]: '教师',
|
||||
[Roles.GENERAL_ADMIN]: '普通管理员',
|
||||
[Roles.CONTACTOR]: '沟通联络人',
|
||||
[Roles.SYSTEM_ADMIN]: '系统管理员',
|
||||
}
|
||||
|
||||
// 岗位映射
|
||||
const jobMap: Record<number, string> = {
|
||||
[Jobs.COURSE_TEACHER]: '课程制作教师',
|
||||
[Jobs.PROJECT_MANAGER]: '课程购买方项目负责人',
|
||||
[Jobs.COURSE_CONTACTOR]: '课程制作方沟通联络人',
|
||||
[Jobs.SYSTEM_MANAGER]: '系统制作方项目负责人',
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
toast.loading({
|
||||
msg: '加载中...'
|
||||
})
|
||||
BussApi.profile(user.token!).then(res => {
|
||||
toast.close()
|
||||
userInfo.value = res
|
||||
}).catch(error => {
|
||||
toast.close()
|
||||
toast.error(error.message || '获取用户信息失败')
|
||||
if (error.response?.data?.code === 10001) {
|
||||
router.replace('/pages/login/index')
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<page-wrapper>
|
||||
<div class="p-4 flex flex-col gap-4">
|
||||
<WdCellGroup :border="true">
|
||||
<WdCell title="用户名" :value="user.userinfo?.username || '-'" />
|
||||
<WdCell title="邮箱" :value="user.userinfo?.email || '-'" />
|
||||
<WdCell title="单位" :value="user.userinfo?.department_id ? departmentMap[user.userinfo.department_id] : '-'" />
|
||||
<WdCell title="角色" :value="user.userinfo?.roles.map(i => i.role_name).join(', ') || '-'" />
|
||||
<WdCell title="权限" :value="user.userinfo?.jobs.map(i => i.job_name).join(', ') || '-'" />
|
||||
<WdCell title="用户名" :value="userInfo?.username || '-'" />
|
||||
<WdCell title="邮箱" :value="userInfo?.email || '-'" />
|
||||
<WdCell title="单位"
|
||||
:value="userInfo?.departmentId ? departmentMap[userInfo.departmentId as DepartmentId] : '-'" />
|
||||
<WdCell title="角色" :value="userInfo?.roles ? roleMap[userInfo.roles] : '-'" />
|
||||
<WdCell title="权限" :value="userInfo?.jobs ? jobMap[userInfo.jobs] : '-'" />
|
||||
</WdCellGroup>
|
||||
<div class="px-4">
|
||||
<wd-button plain hairline block type="error" @click="logout">退出账号</wd-button>
|
||||
|
@ -1,19 +1,21 @@
|
||||
<script lang="ts" setup>
|
||||
import BussApi from '@/api/BussApi';
|
||||
import { useDayjs } from '@/composables/useDayjs';
|
||||
import type { Lesson, FileUploadDestination } from '@/types/api/lesson';
|
||||
import type { LessonTask, FileUploadDestination } from '@/types/api/lesson';
|
||||
import { extractLessonStage, getLessonSteps, getScriptFile, parseCombinedFileString } from '@/utils/lesson';
|
||||
import { computed, nextTick, onMounted, ref } from 'vue';
|
||||
import { useMessage, useToast } from 'wot-design-uni';
|
||||
import StatusBlock from './StatusBlock.vue';
|
||||
import { useRoute } from 'uni-mini-router';
|
||||
import { useUser } from '@/stores/useUser';
|
||||
|
||||
const route = useRoute()
|
||||
const message = useMessage()
|
||||
const toast = useToast()
|
||||
const dayjs = useDayjs()
|
||||
const user = useUser()
|
||||
|
||||
type GroupedLessons = { [key: string]: Lesson[] }
|
||||
type GroupedLessons = { [key: string]: LessonTask[] }
|
||||
|
||||
const groupedLessons = ref<GroupedLessons>({})
|
||||
|
||||
@ -21,10 +23,10 @@ const pickerCourseColumns = ref<string[]>([])
|
||||
const pickerCourseValue = ref()
|
||||
|
||||
const pickerLessonColumns = computed(() => {
|
||||
return pickerCourseValue.value ? groupedLessons.value[pickerCourseValue.value].map((lesson: Lesson) => {
|
||||
return pickerCourseValue.value ? groupedLessons.value[pickerCourseValue.value].map((lesson: LessonTask) => {
|
||||
return {
|
||||
label: (extractLessonStage(lesson).step === 4 ? '✅ ' : '') + lesson.m_lesson_name,
|
||||
value: lesson.id
|
||||
label: (extractLessonStage(lesson).step === 4 ? '✅ ' : '') + lesson.microLessonName,
|
||||
value: lesson.id,
|
||||
}
|
||||
}) : []
|
||||
})
|
||||
@ -32,7 +34,7 @@ const pickerLessonValue = ref()
|
||||
|
||||
const selectedLesson = computed(() => {
|
||||
if (!pickerLessonValue.value) return null
|
||||
return groupedLessons.value[pickerCourseValue.value].find((lesson: Lesson) => lesson.id === pickerLessonValue.value)
|
||||
return groupedLessons.value[pickerCourseValue.value].find((lesson: LessonTask) => lesson.id === pickerLessonValue.value)
|
||||
})
|
||||
|
||||
const selectedLessonStage = computed(() => {
|
||||
@ -55,7 +57,7 @@ const onLessonPick = ({ value }: { value: number }) => {
|
||||
|
||||
const script_file_destination = ref<FileUploadDestination>('wechat')
|
||||
|
||||
const onStep0 = () => {
|
||||
const onStep1 = () => {
|
||||
message.confirm({
|
||||
title: '提交脚本',
|
||||
msg: '请确认已经通过微信或平台上传了脚本文件,再确认提交'
|
||||
@ -69,13 +71,19 @@ const onStep0 = () => {
|
||||
toast.loading({
|
||||
msg: '正在提交...'
|
||||
})
|
||||
BussApi.editCourse(selectedLesson.value.id, {
|
||||
script_file: JSON.stringify({
|
||||
const params = {
|
||||
advise: JSON.stringify({
|
||||
method: script_file_destination.value,
|
||||
uploaded: false
|
||||
}),
|
||||
script_upload_time: dayjs().unix()
|
||||
}).then(res => {
|
||||
scriptUploadTime: dayjs().unix(),
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 1
|
||||
|
||||
}
|
||||
BussApi.updateLessonTask(selectedLesson.value.id, params).then(res => {
|
||||
toast.success({
|
||||
msg: '提交成功'
|
||||
})
|
||||
@ -102,16 +110,24 @@ const onStep2 = (rejected: boolean = false) => {
|
||||
toast.loading({
|
||||
msg: '正在处理...'
|
||||
})
|
||||
BussApi.editCourse(
|
||||
BussApi.updateLessonTask(
|
||||
selectedLesson.value.id,
|
||||
rejected ? {
|
||||
script_file: JSON.stringify({
|
||||
...parseCombinedFileString(selectedLesson.value, 'script_file'),
|
||||
advise: JSON.stringify({
|
||||
...parseCombinedFileString(selectedLesson.value, 'advise'),
|
||||
uploaded: false
|
||||
}),
|
||||
script_upload_time: 0
|
||||
scriptUploadTime: 0,
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 0
|
||||
} : {
|
||||
script_confirm_time: dayjs().unix()
|
||||
scriptConfirmTime: dayjs().unix(),
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 2
|
||||
}).then(res => {
|
||||
toast.success({
|
||||
msg: rejected ? '驳回成功' : '审核通过'
|
||||
@ -139,16 +155,24 @@ const onStep3 = (rejected: boolean = false) => {
|
||||
toast.loading({
|
||||
msg: '正在处理...'
|
||||
})
|
||||
BussApi.editCourse(
|
||||
BussApi.updateLessonTask(
|
||||
selectedLesson.value.id,
|
||||
rejected ? {
|
||||
capture_file: JSON.stringify({
|
||||
...parseCombinedFileString(selectedLesson.value, 'capture_file'),
|
||||
advise: JSON.stringify({
|
||||
...parseCombinedFileString(selectedLesson.value, 'advise'),
|
||||
uploaded: false
|
||||
}),
|
||||
video_capture_time: 0
|
||||
videoCaptureTime: 0,
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 1
|
||||
} : {
|
||||
video_capture_time: dayjs().unix()
|
||||
videoConfirmTime: dayjs().unix(),
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 3
|
||||
}).then(res => {
|
||||
toast.success({
|
||||
msg: rejected ? '驳回成功' : '审核通过'
|
||||
@ -162,19 +186,79 @@ const onStep3 = (rejected: boolean = false) => {
|
||||
})
|
||||
}
|
||||
|
||||
const updateLessons = () => {
|
||||
const onPostProduction = (rejected: boolean = false) => {
|
||||
message.confirm({
|
||||
title: rejected ? '驳回后期制作' : '通过后期制作',
|
||||
msg: rejected ? '后期制作不符合要求,驳回制作方重做' : '请确认后期制作合格无误后,再确认审核通过'
|
||||
}).then(() => {
|
||||
if (!selectedLesson.value?.id) {
|
||||
toast.error({
|
||||
msg: '参数错误'
|
||||
})
|
||||
return
|
||||
}
|
||||
toast.loading({
|
||||
msg: '正在处理...'
|
||||
})
|
||||
BussApi.updateLessonTask(
|
||||
selectedLesson.value.id,
|
||||
rejected ? {
|
||||
advise: JSON.stringify({
|
||||
...parseCombinedFileString(selectedLesson.value, 'advise'),
|
||||
uploaded: false
|
||||
}),
|
||||
videoCaptureTime: 0,
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 2
|
||||
} : {
|
||||
videoConfirmTime: dayjs().unix(),
|
||||
courseName: selectedLesson.value.courseName,
|
||||
microLessonName: selectedLesson.value.microLessonName,
|
||||
userId: selectedLesson.value.userId,
|
||||
progressStatus: 4
|
||||
}).then(res => {
|
||||
toast.success({
|
||||
msg: rejected ? '驳回成功' : '审核通过'
|
||||
})
|
||||
setTimeout(() => {
|
||||
updateLessons()
|
||||
}, 1500);
|
||||
}).catch(err => {
|
||||
toast.error({ msg: err.message })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const updateLessons = async () => {
|
||||
if (!user.userinfo) {
|
||||
toast.error({ msg: '请先登录' })
|
||||
return
|
||||
}
|
||||
|
||||
toast.loading({
|
||||
msg: '加载中...'
|
||||
})
|
||||
BussApi.lessons(1, 512).then(res => {
|
||||
toast.close()
|
||||
const groupData = res.data.sort((a: Lesson, b: Lesson) => {
|
||||
|
||||
try {
|
||||
let res
|
||||
// 如果有查看所有课程的权限
|
||||
if (user.canViewAllCourses()) {
|
||||
res = await BussApi.getLessonTasks(1, 512)
|
||||
} else {
|
||||
// 否则只获取自己的课程
|
||||
res = await BussApi.getLessonTasks(1, 512, user.userinfo.id)
|
||||
}
|
||||
|
||||
// 排序并分组课程
|
||||
const groupData = res.data.content.sort((a: LessonTask, b: LessonTask) => {
|
||||
return a.id - b.id
|
||||
}).reduce((acc: any, cur: any) => {
|
||||
if (!acc[cur.course_name]) {
|
||||
acc[cur.course_name] = []
|
||||
if (!acc[cur.courseName]) {
|
||||
acc[cur.courseName] = []
|
||||
}
|
||||
acc[cur.course_name].push(cur)
|
||||
acc[cur.courseName].push(cur)
|
||||
return acc
|
||||
}, {})
|
||||
groupedLessons.value = groupData
|
||||
@ -185,14 +269,23 @@ const updateLessons = () => {
|
||||
if (route.params?.courseName) {
|
||||
onCoursePick({ value: decodeURI(route.params.courseName) })
|
||||
if (route.params?.lessonId) {
|
||||
onLessonPick({ value: parseInt(route.params.lessonId) })
|
||||
if (typeof route.params.lessonId === 'string') {
|
||||
onLessonPick({ value: parseInt(route.params.lessonId) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
toast.error({ msg: err.message })
|
||||
})
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error) {
|
||||
toast.error({ msg: err.message })
|
||||
} else {
|
||||
toast.error({ msg: '发生未知错误' })
|
||||
}
|
||||
} finally {
|
||||
toast.close()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
updateLessons()
|
||||
})
|
||||
@ -215,6 +308,7 @@ onMounted(() => {
|
||||
:description="(selectedLessonStage?.step || 0 <= index) ? step.description : undefined" />
|
||||
</wd-steps>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedLessonStage?.step === 0" class="px-2">
|
||||
<wd-cell-group>
|
||||
<wd-cell title="脚本提交途径" :title-width="'100px'" center custom-class="mb-4">
|
||||
@ -226,10 +320,10 @@ onMounted(() => {
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
|
||||
<wd-button type="primary" block @click="onStep0" custom-class="w-full">提交脚本</wd-button>
|
||||
<wd-button type="primary" block @click="onStep1" custom-class="w-full">提交脚本</wd-button>
|
||||
</div>
|
||||
<div v-if="selectedLessonStage?.step === 1">
|
||||
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'script_file')?.uploaded" title="脚本已提交"
|
||||
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'advise')?.uploaded" title="脚本已提交"
|
||||
subtitle="请耐心等待审核">
|
||||
<template #icon>
|
||||
<div class="i-tabler-progress-bolt text-7xl text-neutral-400"></div>
|
||||
@ -248,7 +342,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedLessonStage?.step === 2">
|
||||
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'capture_file')?.uploaded" title="视频拍摄进行中"
|
||||
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'advise')?.uploaded" title="视频拍摄进行中"
|
||||
subtitle="请等待线下视频拍摄">
|
||||
<template #icon>
|
||||
<div class="i-tabler-capture text-7xl text-neutral-400"></div>
|
||||
@ -267,6 +361,23 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="selectedLessonStage?.step === 3">
|
||||
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'advise')?.uploaded" title="后期制作进行中"
|
||||
subtitle="请等待视频后期制作">
|
||||
<template #icon>
|
||||
<div class="i-tabler-video text-7xl text-neutral-400"></div>
|
||||
</template>
|
||||
</StatusBlock>
|
||||
<div v-else>
|
||||
<StatusBlock title="后期制作已完成" subtitle="请核对后审核">
|
||||
<template #icon>
|
||||
<div class="i-tabler-video-filled text-7xl text-neutral-400"></div>
|
||||
</template>
|
||||
</StatusBlock>
|
||||
<div class="mt-4 px-4 space-y-2">
|
||||
<wd-button type="primary" :round="false" block @click="onPostProduction()">通过</wd-button>
|
||||
<wd-button type="error" :round="false" block @click="onPostProduction(true)">驳回</wd-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="selectedLessonStage?.step === 4">
|
||||
<wd-status-tip image="comment" tip="该微课已完成" />
|
||||
|
Reference in New Issue
Block a user