fix(front): 打卡/计划提交不再强制课程含图片;选课不限媒体;曲谱文案改为图片

- daka/jihua prepare 去掉仅 Picture+CourseSection 的前端校验
- pick 列表始终可选课,去掉仅按图片判断的警告
- 课程与练习相关界面 ref_name 与提示由「曲谱」改为「图片」等

Made-with: Cursor
This commit is contained in:
2026-04-26 21:38:34 +08:00
parent be211a2638
commit 19fbb53060
15 changed files with 21 additions and 50 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
:backgroundUrl="qupu.resource_url" :marks="marks" @pause="mark($event)" @update="update($event)" />
</div>
<div class="piyue-btn" v-if="!info.has_piyue && is_teacher && info.id && piyueable">
<van-button block size="mini" :disabled="!marks.length" @click="piyue" :type="marks.length > 0 ? 'success' : 'danger'">{{marks.length > 0 ? '提交批阅' : '点击曲谱进行批阅'}}</van-button>
<van-button block size="mini" :disabled="!marks.length" @click="piyue" :type="marks.length > 0 ? 'success' : 'danger'">{{marks.length > 0 ? '提交批阅' : '点击图片进行批阅'}}</van-button>
</div>
</template>
</template>
+2 -2
View File
@@ -5,8 +5,8 @@
</template>
<template v-else>
<van-image @click="preview(signed_url)" :radius="radius" v-if="signed_url" width="100%" height="auto" fit="contain" :src="signed_url" />
<van-empty v-else-if="valid(task)" description="曲谱图片处理中..."></van-empty>
<van-empty image="error" v-else description="曲谱图片处理失败" />
<van-empty v-else-if="valid(task)" description="图片处理中..."></van-empty>
<van-empty image="error" v-else description="图片处理失败" />
</template>
</template>
<script lang="ts">
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<qupu-map v-if="qupu?.resource_url" :video_id="video_id" :background-url="qupu?.resource_url" :marks="marks" :readonly="disabled || readonly"
@pause="pause" @update="$emit('update', $event)"/>
<van-empty v-else description="曲谱图片加载中..."></van-empty>
<van-empty v-else description="图片加载中..."></van-empty>
<van-action-sheet :lock-scroll="false" v-model:show="state.replying" :title="'批注 ' + state.pausing"
@close="close" :close-on-click-overlay="false">
<comments-sheet :disabled="disabled" :readonly="!replyable" :ref_id="mark_id" v-model:comment="state.comment" :qupu="qupu"
+1 -1
View File
@@ -23,7 +23,7 @@
</van-tag>
</div>
</van-cell>
<van-field label="曲谱" readonly colon/>
<van-field label="图片" readonly colon/>
<div class="uploader">
<photo-uploader native v-model="store.qupuList" multiple :max-count="9" :do-upload="false"/>
</div>
+2 -2
View File
@@ -20,7 +20,7 @@
</div>
<div class="qupu">
<h2>
<span>曲谱</span>
<span>图片</span>
<div class="toolbar">
<div class="toolbar-btn" v-if="state.allowMark">
<van-button size="mini" :disabled="state.drawing || saving || !changed" type="primary" @click="piyue">保存标注</van-button>
@@ -36,7 +36,7 @@
@pause="pause" @draw="state.drawing = $event" @update="update($event)" />
</div>
<hty-image v-else-if="qupu_resource?.tasks" :task="qupu_resource?.tasks?.vals[0]" />
<van-empty v-else description="暂无曲谱" />
<van-empty v-else description="暂无图片" />
</div>
<div class="example">
<h2>视频<small>(标星的为示范曲)</small></h2>
+1 -1
View File
@@ -31,7 +31,7 @@
</van-tag>
</div>
</van-cell>
<van-field label="曲谱" readonly colon></van-field>
<van-field label="图片" readonly colon></van-field>
<div class="uploader">
<photo-uploader native :show-upload="!store.qupuList.some(x => x.hty_resource_id)" v-model="store.qupuList" multiple
:max-count="9" :do-upload="false"/>
+1 -1
View File
@@ -23,7 +23,7 @@
</van-tag>
</div>
</van-cell>
<van-field label="曲谱" readonly colon></van-field>
<van-field label="图片" readonly colon></van-field>
<qupu-map-editor :qupu="state.qupu" :ref_id="state.entity.id" @submit="save_notes"
:resource_note_group="state.entity.resource_note_group">
</qupu-map-editor>
+2 -23
View File
@@ -20,18 +20,8 @@
<van-icon color="#c8c9cc" class="course-toggle" size="0.5rem" name="arrow-up" v-else @click="() => onToggle(item)" />
</template>
<template #right-icon>
<template v-if="item.has_qupu">
<van-icon color="#07c160" size="0.5rem" name="checked" v-if="item.checked" @click="() => onClick(item)" />
<van-icon color="#07c160" size="0.5rem" name="circle" v-else @click="() => onClick(item)" />
</template>
<template v-else>
<van-popover placement="left">
<div class="warning-tip">该课程尚未添加曲谱</div>
<template #reference>
<van-icon name="warning" color="red" size="0.5rem"></van-icon>
</template>
</van-popover>
</template>
<van-icon color="#07c160" size="0.5rem" name="checked" v-if="item.checked" @click="() => onClick(item)" />
<van-icon color="#07c160" size="0.5rem" name="circle" v-else @click="() => onClick(item)" />
</template>
</van-cell>
<div class="course-resource" v-if="!item.closed">
@@ -76,7 +66,6 @@ import {
Icon,
Tag,
ActionSheet,
Popover,
Tabs,
Tab,
showFailToast
@@ -128,7 +117,6 @@ export default defineComponent({
[HtyImage.name]: HtyImage,
[UploadProgress.name]: UploadProgress,
[MultiVideoUploader.name]: MultiVideoUploader,
[Popover.name]: Popover,
[Tabs.name]: Tabs,
[Tab.name]: Tab
},
@@ -218,8 +206,6 @@ export default defineComponent({
let item = {
...x,
checked: false,
has_qupu: !!x.resources?.some(r => r.resource_type == RefResourceTypes.Picture),
has_video: !!x.resources?.some(r => r.resource_type == RefResourceTypes.Video)
}
item.checked = state.checked.some(c => c.id === x.id);
item.closed = !state.opening.includes(x.id as string)
@@ -380,11 +366,4 @@ export default defineComponent({
}
}
.warning-tip {
font-size: 0.24rem;
padding: 0.24rem;
color: var(--van-gray-6);
}
</style>
+2 -2
View File
@@ -23,7 +23,7 @@
</van-collapse>
<van-field label="练习录音"></van-field>
<audio-record :label="'点击录音'" v-model="state.question"></audio-record>
<van-field label="练习曲谱" readonly colon/>
<van-field label="练习图片" readonly colon/>
<div class="uploader">
<photo-uploader native v-model="state.qupus" multiple :do-upload="false" :max-count="5"
:max-size="5 * 1024 * 1024"/>
@@ -215,7 +215,7 @@ export default defineComponent({
let qupu_resource: RefResource = {
resource_type: RefResourceTypes.Picture,
ref_type: "Lianxi",
ref_name: "练习曲谱",
ref_name: "练习图片",
tasks: {vals: [{task_id, task_type: TaskTypes.UPLOAD_PICTURE}]}
}
data.ref_resources.push(qupu_resource)
+1 -1
View File
@@ -12,7 +12,7 @@ import {Grid, GridItem} from "vant";
const pages = [
{name: "功能测试", url: "/tester/function", icon: "shield-o"},
{name: "AI测试", url: "/tester/ai", icon: "bulb-o"},
{name: "曲谱测试", url: "/tester/xml", icon: "music-o"},
{name: "图片/XML 测试", url: "/tester/xml", icon: "music-o"},
{name: "日历测试", url: "/tester/calendar", icon: "calendar-o"},
{name: "标注测试", url: "/tester/map", icon: "flower-o"},
{name: "头像测试", url: "/tester/avatar", icon: "user-circle-o"},
+1 -1
View File
@@ -39,7 +39,7 @@ import useUser from '~/store/user'
const TESTER_PAGES = [
{ name: '功能测试', url: '/tester/function', icon: 'shield-o' },
{ name: 'AI测试', url: '/tester/ai', icon: 'bulb-o' },
{ name: '曲谱测试', url: '/tester/xml', icon: 'music-o' },
{ name: '图片/XML 测试', url: '/tester/xml', icon: 'music-o' },
{ name: '日历测试', url: '/tester/calendar', icon: 'calendar-o' },
{ name: '标注测试', url: '/tester/map', icon: 'flower-o' },
{ name: '头像测试', url: '/tester/avatar', icon: 'user-circle-o' },
+1 -1
View File
@@ -147,7 +147,7 @@ export default [
{path: '/tester/function', component: TesterFunction, meta: {title: "功能测试"}},
{path: '/tester/ai', component: TesterAI, meta: {title: "AI测试"}},
{path: '/tester/calendar', component: TesterCalendar, meta: {title: "日历测试"}},
{path: '/tester/xml', component: TesterXml, meta: {title: "曲谱测试"}},
{path: '/tester/xml', component: TesterXml, meta: {title: "图片/XML 测试"}},
{path: '/tester/map', component: TesterMap, meta: {title: "标注测试"}},
{path: '/tester/profile', component: TesterProfile, meta: {title: "我的"}},
{path: '/tester/avatar', component: TesterAvatar, meta: {title: "头像测试"}},
+1 -5
View File
@@ -15,7 +15,7 @@ import {
NotifyParam,
NotifyTypes,
Piyue,
CourseSection, RefResourceTypes, RefTypes, TeacherSummary
CourseSection, TeacherSummary
} from '~/types'
import useUser from "~/store/user";
import useRefResource from "~/store/ref-resource";
@@ -217,10 +217,6 @@ export default function useDaka() {
}
let { resources, ref_resources, id, resource_note_group, ...rest } = course_sections[i];
ref_resources = ref_resources || resources;
if (!ref_resources?.some(r => r.ref_type === RefTypes.CourseSection && r.resource_type === RefResourceTypes.Picture)) {
showFailToast("课程【" + rest.course_name + "(" + rest.section_name + ")" + "】没有曲谱!")
return false;
}
if (!resource_note_group) {
resource_note_group = await get_resource_note_group_by_ref_id(id as string)
}
+1 -5
View File
@@ -14,7 +14,7 @@ import {
NotifyTypes,
PickTargets,
Piyue,
CourseSection, RefResourceTypes, RefTypes,
CourseSection,
VersionedData, VersionedDataTypes
} from '~/types'
import useUser from "~/store/user";
@@ -237,10 +237,6 @@ export default function useJihua() {
}
let { resources, ref_resources, id, resource_note_group, ...rest } = course_sections[i];
ref_resources = ref_resources || resources;
if (!ref_resources?.some(r => r.ref_type === RefTypes.CourseSection && r.resource_type === RefResourceTypes.Picture)) {
showFailToast("课程【" + rest.course_name + "(" + rest.section_name + ")" + "】没有曲谱!")
return false;
}
if (!resource_note_group) {
resource_note_group = await get_resource_note_group_by_ref_id(id)
}
+3 -3
View File
@@ -186,7 +186,7 @@ export default function useCourseSection(router?: Router) {
return false
}
// if (!qupuList.length && !videoList.length) {
// showFailToast('请添加曲谱或视频!')
// showFailToast('请添加图片或视频!')
// return false
// }
return true
@@ -210,7 +210,7 @@ export default function useCourseSection(router?: Router) {
let resources = [...videoList]
if (task_id) {
resources.push({
ref_type: RefTypes.CourseSection, ref_name: "曲谱", resource_type: RefResourceTypes.Picture,
ref_type: RefTypes.CourseSection, ref_name: "图片", resource_type: RefResourceTypes.Picture,
tasks: {vals: [{task_id, task_type: TaskTypes.UPLOAD_PICTURE}]}
} as RefResource)
}
@@ -293,7 +293,7 @@ export default function useCourseSection(router?: Router) {
return Promise.reject();
}
resources.push({
ref_type: "CourseSection", ref_name: "曲谱", resource_type: RefResourceTypes.Picture,
ref_type: "CourseSection", ref_name: "图片", resource_type: RefResourceTypes.Picture,
tasks: {vals: [{task_id, task_type: TaskTypes.UPLOAD_PICTURE}]}
} as RefResource);
} else {