feat: 优化工作进度管理页面的样式

- 优化工作进度管理页面的样式,使其更加美观和易读
- 更新了 StatusBlock 组件,使其支持动态传入标题和副标题
- 更新了 Lesson 类型定义,将脚本文件、拍摄文件和素材文件的类型改为字符串
- 添加了 wd-drop-menu 和 wd-drop-menu-item 组件,用于下拉菜单的展示和选择
- 更新了首页列表请求参数,添加了加载指示器
- 在 Lesson 页面增加了单位、角色和权限的展示
- 修复了一些接口请求的问题,提升了用户资料更新的效率
This commit is contained in:
2024-09-23 23:41:37 +08:00
parent 66289511dd
commit fe36c1a72b
7 changed files with 130 additions and 20 deletions

View File

@ -1,13 +1,16 @@
<script lang="ts" setup>
import BussApi from '@/api/BussApi';
import { useDayjs } from '@/composables/useDayjs';
import { useTabbar } from '@/stores/useTabbar';
import type { Lesson } from '@/types/api/lesson';
import { calcLessonProgress, extractLessonStage, getLessonSteps } from '@/utils/lesson';
import { useRoute } from 'uni-mini-router';
import { useRoute, useRouter } from 'uni-mini-router';
import { computed, onMounted, ref } from 'vue';
import { useToast } from 'wot-design-uni';
const route = useRoute()
const router = useRouter()
const tabbar = useTabbar()
const toast = useToast()
const dayjs = useDayjs()
@ -16,6 +19,17 @@ 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)
const goProgress = (lessonId: number) => {
router.replaceAll({
name: 'progress',
params: {
courseName: `${lesson.value?.course_name}`,
lessonId: `${lessonId}`
}
})
tabbar.activeTab = 'progress'
}
onMounted(() => {
if (!route.params?.courseId) {
toast.error({
@ -37,7 +51,8 @@ onMounted(() => {
<template>
<div>
<div :class="`pattern p-4 flex flex-col gap-6 relative ${lessonProgress === 100 ? 'bg-emerald' : (lessonProgress === 0 ? 'bg-neutral' : 'bg-blue')}`">
<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>
@ -57,6 +72,9 @@ onMounted(() => {
:description="step.description" />
</wd-steps>
</div>
<div class="px-4 pt-2">
<wd-button type="primary" :round="false" plain block @click="goProgress(lesson?.id!)">进度处理</wd-button>
</div>
</div>
</template>

View File

@ -0,0 +1,18 @@
<script lang="ts" setup>
const props = defineProps({
title: String,
subtitle: String
})
</script>
<template>
<div class="rounded-lg mx-4 p-4 py-12 bg-neutral-100 flex items-center flex-col gap-4">
<slot name="icon"></slot>
<div class="text-center">
<p class="text-base">{{ title }}</p>
<p class="text-xs text-neutral-500">{{ subtitle }}</p>
</div>
</div>
</template>
<style scoped></style>

View File

@ -1,11 +1,14 @@
<script lang="ts" setup>
import BussApi from '@/api/BussApi';
import { useDayjs } from '@/composables/useDayjs';
import type { Lesson, ScriptFileDestination } from '@/types/api/lesson';
import { extractLessonStage, getLessonSteps } from '@/utils/lesson';
import { computed, onMounted, ref } from 'vue';
import type { Lesson, 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';
const route = useRoute()
const message = useMessage()
const toast = useToast()
const dayjs = useDayjs()
@ -39,7 +42,7 @@ const selectedLessonStage = computed(() => {
const onCoursePick = ({ value }: { value: string }) => {
pickerCourseValue.value = value
pickerLessonValue.value = void 0
pickerLessonValue.value = undefined
}
const onLessonPick = ({ value }: { value: number }) => {
@ -50,7 +53,7 @@ const onLessonPick = ({ value }: { value: number }) => {
* lesson progress modifition steps
*/
const script_file_destination = ref<ScriptFileDestination>('wechat')
const script_file_destination = ref<FileUploadDestination>('wechat')
const onStep0 = () => {
message.confirm({
@ -67,7 +70,10 @@ const onStep0 = () => {
msg: '正在提交...'
})
BussApi.editCourse(selectedLesson.value.id, {
script_file: script_file_destination.value,
script_file: JSON.stringify({
method: script_file_destination.value,
uploaded: false
}),
script_upload_time: dayjs().unix()
}).then(res => {
toast.success({
@ -101,6 +107,13 @@ const updateLessons = () => {
pickerCourseColumns.value = [
...Object.keys(groupData)
]
if (route.params?.courseName) {
onCoursePick({ value: decodeURI(route.params.courseName) })
if (route.params?.lessonId) {
onLessonPick({ value: parseInt(route.params.lessonId) })
}
}
}).catch(err => {
toast.error({ msg: err.message })
})
@ -141,7 +154,25 @@ onMounted(() => {
<wd-button type="primary" block @click="onStep0" custom-class="w-full">提交脚本</wd-button>
</div>
<div v-if="selectedLessonStage?.step === 1"></div>
<div v-if="selectedLessonStage?.step === 1">
<StatusBlock v-if="!parseCombinedFileString(selectedLesson!, 'script_file')?.uploaded" title="脚本已提交"
subtitle="请耐心等待审核">
<template #icon>
<div class="i-tabler-progress-bolt text-7xl text-neutral-400"></div>
</template>
</StatusBlock>
<div v-else>
<StatusBlock title="脚本处理已完成" subtitle="请核对并审核">
<template #icon>
<div class="i-tabler-progress-check text-7xl text-neutral-400"></div>
</template>
</StatusBlock>
<div class="mt-4 px-4 space-y-2">
<wd-button type="primary" :round="false" block>通过</wd-button>
<wd-button type="error" :round="false" block>驳回</wd-button>
</div>
</div>
</div>
<div v-if="selectedLessonStage?.step === 2"></div>
<div v-if="selectedLessonStage?.step === 3"></div>
<div v-else-if="selectedLessonStage?.step === 4">