feat: migrate app routes and business modules

This commit is contained in:
2026-08-12 18:22:59 +08:00
parent 555aa00043
commit cc706378c2
247 changed files with 28623 additions and 14988 deletions
+144
View File
@@ -0,0 +1,144 @@
import { isWriteOutcomeUnknown } from '@/utils/request-outcome.js'
const messages = {
submitted:
"反馈已提交。以下内容为本次提交记录;修改任一项后可提交新反馈。",
submittedWithEdits: "上一份反馈已提交,当前修改尚未提交。",
uncertain:
"暂时无法确认是否提交成功,请不要重复提交相同内容。你可以修改内容后再提交一份反馈。",
uncertainWithEdits: "上一份反馈暂未确认,当前修改尚未提交。",
};
const normalizeFeedback = (form) => ({
feedbackType: String(form?.feedbackType || "").trim(),
feedbackContent: String(form?.feedbackContent || "").trim(),
contactInfo: String(form?.contactInfo || "").trim(),
});
// 字段顺序固定的快照既用于脏数据判断,也用于阻止非幂等 POST 重复提交。
// 不能改成对象引用比较,否则 Vue 表单原地修改时无法识别同一份内容。
const snapshotOf = (form) => JSON.stringify(normalizeFeedback(form));
const errorMessage = (error) => {
if (error?.code === "WRITE_UNAVAILABLE") {
return "当前为本地预览,反馈没有发出。";
}
if (error?.httpStatus === 401) {
return "登录状态已失效,请重新登录后再提交。";
}
return "提交未完成,请稍后再试。";
};
const submitLabelFor = (phase) => {
if (phase === "submitting") return "正在提交";
if (phase === "success") return "反馈已提交";
if (phase === "uncertain") return "暂未确认";
if (phase === "error") return "重新提交";
return "提交反馈";
};
export const createFeedbackSubmissionSession = (initialForm) => {
let baselineSnapshot = snapshotOf(initialForm);
let lastSubmittedSnapshot = "";
let lastUncertainSnapshot = "";
let phase = "ready";
let message = "";
let tone = "";
const view = (currentForm) => {
const currentSnapshot = snapshotOf(currentForm);
const isRepeatedSubmission =
currentSnapshot === lastSubmittedSnapshot ||
currentSnapshot === lastUncertainSnapshot;
return {
phase,
message,
tone,
isDirty: currentSnapshot !== baselineSnapshot,
isSubmitDisabled: phase === "submitting" || isRepeatedSubmission,
submitLabel: submitLabelFor(phase),
};
};
const begin = (currentForm) => {
const currentSnapshot = snapshotOf(currentForm);
if (
phase === "submitting" ||
currentSnapshot === lastSubmittedSnapshot ||
currentSnapshot === lastUncertainSnapshot
) {
return null;
}
phase = "submitting";
message = "";
tone = "";
return {
snapshot: currentSnapshot,
payload: normalizeFeedback(currentForm),
};
};
const succeed = (submission, currentForm) => {
baselineSnapshot = submission.snapshot;
lastSubmittedSnapshot = submission.snapshot;
tone = "success";
if (snapshotOf(currentForm) === submission.snapshot) {
phase = "success";
message = messages.submitted;
} else {
phase = "ready";
message = messages.submittedWithEdits;
}
};
const fail = (submission, error, currentForm) => {
if (!isWriteOutcomeUnknown(error)) {
phase = "error";
message = errorMessage(error);
tone = "error";
return;
}
// 超时或异常 2xx 可能已经被后端写入。记录原快照并禁用原样重试,
// 避免用户在网络恢复后生成两条内容完全相同的反馈。
lastUncertainSnapshot = submission.snapshot;
tone = "uncertain";
if (snapshotOf(currentForm) === submission.snapshot) {
phase = "uncertain";
message = messages.uncertain;
} else {
phase = "ready";
message = messages.uncertainWithEdits;
}
};
const reconcile = (currentForm) => {
if (phase === "submitting") return;
const currentSnapshot = snapshotOf(currentForm);
if (lastSubmittedSnapshot && currentSnapshot === lastSubmittedSnapshot) {
phase = "success";
message = messages.submitted;
tone = "success";
return;
}
if (lastUncertainSnapshot && currentSnapshot === lastUncertainSnapshot) {
phase = "uncertain";
message = messages.uncertain;
tone = "uncertain";
return;
}
phase = "ready";
if (lastUncertainSnapshot) {
message = messages.uncertainWithEdits;
tone = "uncertain";
} else if (lastSubmittedSnapshot) {
message = messages.submittedWithEdits;
tone = "success";
} else {
message = "";
tone = "";
}
};
return { begin, succeed, fail, reconcile, view };
};