|
|
@@ -48,22 +48,11 @@ import type { ListColumn } from '@/components/list-column';
|
|
|
import { useListPage } from '@/composables/use-list-page';
|
|
|
import { useScope } from '@/store/scope';
|
|
|
import { formatDateTime, formatMoney, moneyPlain } from '@/utils/format';
|
|
|
+import { epMessage, epConfirm } from '@/utils/ep-message';
|
|
|
|
|
|
const scope = useScope();
|
|
|
|
|
|
-/** 命令式 EP(UMD 全局,http.ts 同款读法) */
|
|
|
-function ElMessage_(type: 'success' | 'warning' | 'error', text: string): void {
|
|
|
- const M = (globalThis.ElementPlus ?? {}).ElMessage;
|
|
|
- if (M) M({ type, message: text });
|
|
|
- else console.warn(`[${type}]`, text);
|
|
|
-}
|
|
|
-function ElConfirm(text: string): Promise<void> {
|
|
|
- const B = (globalThis.ElementPlus ?? {}).ElMessageBox;
|
|
|
- if (!B) return Promise.resolve();
|
|
|
- return B.confirm(text, '操作确认', { confirmButtonText: '执行', cancelButtonText: '取消', type: 'warning' })
|
|
|
- .then(() => undefined)
|
|
|
- .catch(() => Promise.reject(new Error('cancel')));
|
|
|
-}
|
|
|
+/* 命令式 EP(epMessage/epConfirm)已收口到 @/utils/ep-message(UMD 全局单点读取) */
|
|
|
|
|
|
/* ================= 选项数据(老师/学生/校区;机构级全量) ================= */
|
|
|
const staffOpts = ref<MemberDTO[]>([]);
|
|
|
@@ -140,9 +129,9 @@ async function loadClasses(): Promise<void> {
|
|
|
try {
|
|
|
const r = await listClasses(selectedCourseId.value, { ...scope.toQuery(), pageSize: 200 });
|
|
|
if (r.code === 200) classRows.value = r.data?.list ?? [];
|
|
|
- else ElMessage_('error', r.message || '排班规则加载失败');
|
|
|
+ else epMessage('error', r.message || '排班规则加载失败');
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
classLoading.value = false;
|
|
|
}
|
|
|
@@ -199,11 +188,11 @@ function toggleWeek(v: number): void {
|
|
|
async function doCreateClass(): Promise<void> {
|
|
|
if (!selectedCourseId.value) return;
|
|
|
if (!classForm.teacherId || !weeksToString() || !classForm.start || !classForm.end) {
|
|
|
- ElMessage_('warning', '请填全老师/周/上课起止时间');
|
|
|
+ epMessage('warning', '请填全老师/周/上课起止时间');
|
|
|
return;
|
|
|
}
|
|
|
if (Number(classForm.end) < Number(classForm.start)) {
|
|
|
- ElMessage_('warning', '下课时间需晚于上课时间');
|
|
|
+ epMessage('warning', '下课时间需晚于上课时间');
|
|
|
return;
|
|
|
}
|
|
|
classBusy.value = true;
|
|
|
@@ -217,15 +206,15 @@ async function doCreateClass(): Promise<void> {
|
|
|
campusId: classForm.campusId,
|
|
|
});
|
|
|
if (r.code === 200) {
|
|
|
- ElMessage_('success', '排班规则已创建');
|
|
|
+ epMessage('success', '排班规则已创建');
|
|
|
classVisible.value = false;
|
|
|
void loadClasses();
|
|
|
} else {
|
|
|
// 3122 排班冲突 / 2001 参数缺失:读 code 直显
|
|
|
- ElMessage_('warning', r.message || `创建失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `创建失败(code ${r.code})`);
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
classBusy.value = false;
|
|
|
}
|
|
|
@@ -276,16 +265,16 @@ async function doGenerate(): Promise<void> {
|
|
|
try {
|
|
|
const r = await generateRecords(selectedCourseId.value, { days: genDays.value });
|
|
|
if (r.code === 200 && r.data) {
|
|
|
- if (r.data.changed) ElMessage_('success', `课表已更新:当前 ${r.data.generated} 节未开始课表(本次有新增)`);
|
|
|
- else ElMessage_('warning', `无新增(幂等命中):当前 ${r.data.generated} 节未开始课表,请求 ${r.data.days} 天已覆盖`);
|
|
|
+ if (r.data.changed) epMessage('success', `课表已更新:当前 ${r.data.generated} 节未开始课表(本次有新增)`);
|
|
|
+ else epMessage('warning', `无新增(幂等命中):当前 ${r.data.generated} 节未开始课表,请求 ${r.data.days} 天已覆盖`);
|
|
|
genVisible.value = false;
|
|
|
recPage.value = 1;
|
|
|
void fetchRecords();
|
|
|
} else {
|
|
|
- ElMessage_('warning', r.message || `生成失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `生成失败(code ${r.code})`);
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
genBusy.value = false;
|
|
|
}
|
|
|
@@ -298,15 +287,15 @@ async function doStart(rec: CourseRecordDTO): Promise<void> {
|
|
|
try {
|
|
|
const r = await startRecord(rec.recordId);
|
|
|
if (r.code === 200) {
|
|
|
- ElMessage_('success', '已开始上课');
|
|
|
+ epMessage('success', '已开始上课');
|
|
|
void fetchRecords();
|
|
|
} else {
|
|
|
// 3121 状态非法:读 code 直显 + 刷新课表(状态可能已被他人变更)
|
|
|
- ElMessage_('warning', r.message || `开始失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `开始失败(code ${r.code})`);
|
|
|
void fetchRecords();
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
startBusy.value = false;
|
|
|
}
|
|
|
@@ -317,7 +306,7 @@ const finishBusy = ref(false);
|
|
|
async function doFinish(rec: CourseRecordDTO): Promise<void> {
|
|
|
if (finishBusy.value) return;
|
|
|
try {
|
|
|
- await ElConfirm(
|
|
|
+ await epConfirm(
|
|
|
`确认结束课表 ${rec.recordId}(${formatDateTime(rec.startTime)})?\n本操作为单事务重操作:将同时产生 扣课时 + 余额变动 + 分账明细 + 课酬记录,不可撤销。`,
|
|
|
);
|
|
|
} catch {
|
|
|
@@ -327,10 +316,10 @@ async function doFinish(rec: CourseRecordDTO): Promise<void> {
|
|
|
try {
|
|
|
const r = await finishRecord(rec.recordId);
|
|
|
if (r.code === 200 && r.data) {
|
|
|
- ElMessage_('success', `下课结算完成:消耗 ${r.data.totalSpend},分账 ${r.data.divide.length} 条,课酬 ${r.data.payroll.reward}`);
|
|
|
+ epMessage('success', `下课结算完成:消耗 ${r.data.totalSpend},分账 ${r.data.divide.length} 条,课酬 ${r.data.payroll.reward}`);
|
|
|
} else {
|
|
|
// 3121 状态非法 / 其它:读 code 直显
|
|
|
- ElMessage_('warning', r.message || `结束失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `结束失败(code ${r.code})`);
|
|
|
}
|
|
|
// 契约明令:失败/成功后均刷新整页(课表 + 报课学生 + 欠费),不局部推断
|
|
|
recPage.value = 1;
|
|
|
@@ -338,7 +327,7 @@ async function doFinish(rec: CourseRecordDTO): Promise<void> {
|
|
|
void loadStudents();
|
|
|
void fetchArrears();
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
recPage.value = 1;
|
|
|
void fetchRecords();
|
|
|
} finally {
|
|
|
@@ -375,7 +364,7 @@ async function openAttendance(rec: CourseRecordDTO): Promise<void> {
|
|
|
// 初值 = 端点 53 课程级报课学生(risk-1 免后端方案:52 提交时后端按该课实际学生匹配,不在课内的 userId 不生效)
|
|
|
const r = await listCourseStudents(selectedCourseId.value, { ...scope.toQuery(), pageSize: 200 });
|
|
|
if (r.code !== 200) {
|
|
|
- ElMessage_('error', r.message || '学生初值加载失败');
|
|
|
+ epMessage('error', r.message || '学生初值加载失败');
|
|
|
return;
|
|
|
}
|
|
|
attRows.value = (r.data?.list ?? []).map((s) => ({
|
|
|
@@ -405,16 +394,16 @@ async function doAttendance(): Promise<void> {
|
|
|
try {
|
|
|
const r = await checkAttendance(rec.recordId, { list });
|
|
|
if (r.code === 200 && r.data) {
|
|
|
- ElMessage_('success', `打卡完成:${r.data.checked} 人`);
|
|
|
+ epMessage('success', `打卡完成:${r.data.checked} 人`);
|
|
|
attVisible.value = false;
|
|
|
void fetchRecords();
|
|
|
} else {
|
|
|
// 3121 已结束不可再打卡:读 code 直显 + 刷新课表
|
|
|
- ElMessage_('warning', r.message || `打卡失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `打卡失败(code ${r.code})`);
|
|
|
void fetchRecords();
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
attBusy.value = false;
|
|
|
}
|
|
|
@@ -432,9 +421,9 @@ async function loadStudents(): Promise<void> {
|
|
|
try {
|
|
|
const r = await listCourseStudents(selectedCourseId.value, { ...scope.toQuery(), pageSize: 200 });
|
|
|
if (r.code === 200) stuRows.value = r.data?.list ?? [];
|
|
|
- else ElMessage_('error', r.message || '报课学生加载失败');
|
|
|
+ else epMessage('error', r.message || '报课学生加载失败');
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
stuLoading.value = false;
|
|
|
}
|
|
|
@@ -475,7 +464,7 @@ const recommenderOpts = computed(() => studentOpts.value.filter((m) => m.userId
|
|
|
async function doEnroll(): Promise<void> {
|
|
|
if (!selectedCourseId.value) return;
|
|
|
if (!enrollForm.userId || !enrollForm.pay || !enrollForm.lessonCost || enrollForm.number <= 0) {
|
|
|
- ElMessage_('warning', '请填全学生/课程费用/单节课时费用/课次');
|
|
|
+ epMessage('warning', '请填全学生/课程费用/单节课时费用/课次');
|
|
|
return;
|
|
|
}
|
|
|
enrollBusy.value = true;
|
|
|
@@ -493,16 +482,16 @@ async function doEnroll(): Promise<void> {
|
|
|
...(enrollForm.remark ? { remark: enrollForm.remark } : {}),
|
|
|
});
|
|
|
if (r.code === 200) {
|
|
|
- ElMessage_('success', '报名成功(仅记应收/实收快照,不写资金流水、不动余额;真实收款走财务域)');
|
|
|
+ epMessage('success', '报名成功(仅记应收/实收快照,不写资金流水、不动余额;真实收款走财务域)');
|
|
|
enrollVisible.value = false;
|
|
|
void loadStudents();
|
|
|
void fetchRecords(); // 学生数变化
|
|
|
} else {
|
|
|
// 3143 重复报名(专用码)/ 2001 参数缺失:读 code 直显
|
|
|
- ElMessage_('warning', r.message || `报名失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `报名失败(code ${r.code})`);
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
enrollBusy.value = false;
|
|
|
}
|
|
|
@@ -541,7 +530,7 @@ function openCounteract(row: ArrearsDTO): void {
|
|
|
async function doCounteract(): Promise<void> {
|
|
|
const t = actTarget.value;
|
|
|
if (!t || !actMoney.value || actMoney.value <= 0) {
|
|
|
- ElMessage_('warning', '请输入有效核销金额(>0)');
|
|
|
+ epMessage('warning', '请输入有效核销金额(>0)');
|
|
|
return;
|
|
|
}
|
|
|
actBusy.value = true;
|
|
|
@@ -553,15 +542,15 @@ async function doCounteract(): Promise<void> {
|
|
|
money: moneyPlain(actMoney.value),
|
|
|
});
|
|
|
if (r.code === 200 && r.data) {
|
|
|
- ElMessage_('success', `核销完成:${studentName(t.studentId)} 核销 ${r.data.amount}`);
|
|
|
+ epMessage('success', `核销完成:${studentName(t.studentId)} 核销 ${r.data.amount}`);
|
|
|
actVisible.value = false;
|
|
|
arrPage.value = 1;
|
|
|
void fetchArrears();
|
|
|
} else {
|
|
|
- ElMessage_('warning', r.message || `核销失败(code ${r.code})`);
|
|
|
+ epMessage('warning', r.message || `核销失败(code ${r.code})`);
|
|
|
}
|
|
|
} catch {
|
|
|
- ElMessage_('error', '网络连接异常');
|
|
|
+ epMessage('error', '网络连接异常');
|
|
|
} finally {
|
|
|
actBusy.value = false;
|
|
|
}
|
|
|
@@ -922,7 +911,7 @@ async function doCounteract(): Promise<void> {
|
|
|
.schedule-page__section {
|
|
|
margin-top: 16px;
|
|
|
padding-top: 12px;
|
|
|
- border-top: 1px solid var(--app-color-border, #e3e7ea);
|
|
|
+ border-top: 1px solid var(--app-color-border);
|
|
|
}
|
|
|
.schedule-page__head {
|
|
|
display: flex;
|
|
|
@@ -948,7 +937,7 @@ async function doCounteract(): Promise<void> {
|
|
|
}
|
|
|
.schedule-page__hint {
|
|
|
font-size: var(--app-font-sm);
|
|
|
- color: var(--app-color-text-2, #5d6672);
|
|
|
+ color: var(--app-color-text-2);
|
|
|
}
|
|
|
.schedule-page__rec-actions {
|
|
|
margin-top: 12px;
|
|
|
@@ -969,12 +958,12 @@ async function doCounteract(): Promise<void> {
|
|
|
}
|
|
|
.schedule-page__rec-label {
|
|
|
font-size: var(--app-font-md);
|
|
|
- color: var(--app-color-text-2, #5d6672);
|
|
|
+ color: var(--app-color-text-2);
|
|
|
min-width: 280px;
|
|
|
}
|
|
|
.schedule-page__rec-done {
|
|
|
font-size: var(--app-font-sm);
|
|
|
- color: var(--app-color-text-2, #5d6672);
|
|
|
+ color: var(--app-color-text-2);
|
|
|
}
|
|
|
.att-loading {
|
|
|
margin-top: 12px;
|