feat(M5-P4): mock V2 化 + 伪接口清理 + vite 代理 + 走查修复
- mock 整体重写为「V2 单一存储 + V1 适配层」:教师 19 / 学生 6 / 通知 3 全端点,
V1 冻结 7 端点由同一存储派生(与后端同一张 homework 表一致);
提交内核对齐后端 doSubmit(版本翻转/逾期分流/附件 dataURL 拒绝/
仅查阅拒绝),submit/action 返回 {submissionId} 契约对齐
- 删除伪接口 mock 与客户端方法:Submissions/SubmissionDetail/Grade/Remind/
MyHomeworks/MySubmission/Submit/Create/Edit/InitializeRed/UserPull/
SetTopmost/Expedite/ReceiveUsers/List/GetClassTree(真实环境必 404)
- types/homework.ts 收敛为 V1 冻结契约(删 11 个孤儿类型)
- 删除被切换孤儿化的组件:HomeworkUpload/ClassCheckInput/UserCheckModal
- vite 代理指向本地 8102(M5 联调目标,远程测试环境保留注释)
- 走查修复:TeacherHomeworks 操作列改模板插槽(render 函数 Dropdown 插槽
在 view-ui-plus 下失效导致菜单内联);ReviewModal :value/@input 改
modelValue(Vue2 API 残留导致弹窗打不开);StudentHomeworks 重新提交
按钮补 canSubmit 门控(已截止且不允许补交时后端必拒)
- 验收:dev:mock 冒烟 58/58 PASS;构建 EXIT=0;tsc 47 条均为存量(基线 65)
且无引用已删符号;浏览器走查 9 页面 + 批阅保存闭环 + 3 秒阅读上报通过
This commit is contained in:
@@ -252,11 +252,6 @@ function del(row: HomeworkV2Vo) {
|
||||
});
|
||||
}
|
||||
|
||||
/* 文本按钮 */
|
||||
function btn(text: string, onClick: () => void) {
|
||||
return h("Button", { type: "text", size: "small", onClick }, () => text);
|
||||
}
|
||||
|
||||
/* ============ 已发布列表列 ============ */
|
||||
const pubColumns = computed(() => [
|
||||
{ title: "序号", type: "index", width: 60, align: "center" },
|
||||
@@ -335,44 +330,21 @@ const pubColumns = computed(() => [
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 250,
|
||||
slot: "action",
|
||||
width: 230,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h: any, p: any) => {
|
||||
const row = p.row as HomeworkV2Vo;
|
||||
const nodes: any[] = [];
|
||||
nodes.push(btn("提交情况", () => viewSubmissions(row)));
|
||||
if ((row.progress?.pendingGrade ?? 0) > 0) nodes.push(btn("批阅", () => toGrade(row)));
|
||||
const more: any[] = [];
|
||||
if (row.hwStatus === "PUBLISHED") {
|
||||
if ((row.progress?.unread ?? 0) > 0) more.push(mItem("提醒未读", () => remind(row, "NOT_READ")));
|
||||
if ((row.progress?.unsubmitted ?? 0) > 0) more.push(mItem("催交", () => remind(row, "NOT_SUBMITTED")));
|
||||
more.push(mItem("延长截止", () => openExtend(row)));
|
||||
}
|
||||
more.push(mItem("复制", () => copyRow(row)));
|
||||
if (row.hwStatus === "PUBLISHED" || row.hwStatus === "CLOSED") more.push(mItem("归档", () => archive(row)));
|
||||
more.push(mItem("导出报表", () => doExport(row)));
|
||||
nodes.push(
|
||||
h("Dropdown", { transfer: true, onOnClick: (name: string) => onMore(name) }, () => [
|
||||
h("Button", { type: "text", size: "small" }, () => "更多∨"),
|
||||
h("DropdownMenu", { slot: "list" }, () => more),
|
||||
])
|
||||
);
|
||||
return h("div", {}, nodes);
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
/* 更多菜单回调(闭包 name→action) */
|
||||
const moreActions = new Map<string, () => void>();
|
||||
let moreSeq = 0;
|
||||
function mItem(text: string, action: () => void) {
|
||||
const key = `m${++moreSeq}`;
|
||||
moreActions.set(key, action);
|
||||
return h("DropdownItem", { name: key }, () => text);
|
||||
}
|
||||
function onMore(name: string) {
|
||||
moreActions.get(name)?.();
|
||||
/* 更多菜单分发 */
|
||||
function onPubMore(name: string, row: HomeworkV2Vo) {
|
||||
if (name === "notRead") remind(row, "NOT_READ");
|
||||
else if (name === "notSubmitted") remind(row, "NOT_SUBMITTED");
|
||||
else if (name === "extend") openExtend(row);
|
||||
else if (name === "copy") copyRow(row);
|
||||
else if (name === "archive") archive(row);
|
||||
else if (name === "export") doExport(row);
|
||||
}
|
||||
|
||||
/* ============ 草稿箱列 ============ */
|
||||
@@ -401,18 +373,10 @@ const draftColumns = computed(() => [
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
slot: "draftAction",
|
||||
width: 250,
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
render: (h: any, p: any) => {
|
||||
const row = p.row as HomeworkV2Vo;
|
||||
const nodes: any[] = [];
|
||||
nodes.push(btn("编辑", () => edit(row)));
|
||||
nodes.push(btn("发布", () => publishDraft(row)));
|
||||
if (row.hwStatus === "DRAFT_SCHEDULED") nodes.push(btn("取消定时", () => cancelSchedule(row)));
|
||||
nodes.push(btn("删除", () => del(row)));
|
||||
return nodes;
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -462,7 +426,33 @@ const tableHeight = computed(() => Utils.useTableHeight({ isSearch: true, isOper
|
||||
:height="tableHeight"
|
||||
:loading="loading"
|
||||
no-data-text="暂无数据"
|
||||
></Table>
|
||||
>
|
||||
<!-- 已发布行操作 -->
|
||||
<template #action="{ row }">
|
||||
<Button type="text" size="small" @click="viewSubmissions(row)">提交情况</Button>
|
||||
<Button v-if="(row.progress?.pendingGrade ?? 0) > 0" type="text" size="small" @click="toGrade(row)">批阅</Button>
|
||||
<Dropdown transfer @on-click="(name: string) => onPubMore(name, row)">
|
||||
<Button type="text" size="small">更多∨</Button>
|
||||
<template #list>
|
||||
<DropdownMenu>
|
||||
<DropdownItem v-if="row.hwStatus === 'PUBLISHED' && (row.progress?.unread ?? 0) > 0" name="notRead">提醒未读</DropdownItem>
|
||||
<DropdownItem v-if="row.hwStatus === 'PUBLISHED' && (row.progress?.unsubmitted ?? 0) > 0" name="notSubmitted">催交</DropdownItem>
|
||||
<DropdownItem v-if="row.hwStatus === 'PUBLISHED'" name="extend">延长截止</DropdownItem>
|
||||
<DropdownItem name="copy">复制</DropdownItem>
|
||||
<DropdownItem v-if="row.hwStatus === 'PUBLISHED' || row.hwStatus === 'CLOSED'" name="archive">归档</DropdownItem>
|
||||
<DropdownItem name="export">导出报表</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</template>
|
||||
<!-- 草稿箱行操作 -->
|
||||
<template #draftAction="{ row }">
|
||||
<Button type="text" size="small" @click="edit(row)">编辑</Button>
|
||||
<Button type="text" size="small" @click="publishDraft(row)">发布</Button>
|
||||
<Button v-if="row.hwStatus === 'DRAFT_SCHEDULED'" type="text" size="small" @click="cancelSchedule(row)">取消定时</Button>
|
||||
<Button type="text" size="small" @click="del(row)">删除</Button>
|
||||
</template>
|
||||
</Table>
|
||||
<div class="page-panel">
|
||||
<div class="fl ml-15 align-middle"></div>
|
||||
<Page
|
||||
|
||||
Reference in New Issue
Block a user