统一状态流转为前端状态机

This commit is contained in:
Cheng Zhou
2025-12-17 20:52:55 +08:00
parent c074c2b5bc
commit c2328594b0
15 changed files with 361 additions and 188 deletions
+9 -26
View File
@@ -4,7 +4,7 @@
<div class="header">
<div>
<h3>{{ item?.title }}</h3>
<el-tag :type="statusTag(item?.status)">{{ statusLabel(item?.status) }}</el-tag>
<el-tag :type="stateColor(item?.status)">{{ stateLabel(item?.status) }}</el-tag>
</div>
<div class="header-actions" v-if="item">
<PermissionAction action="finance.create">
@@ -53,6 +53,7 @@ import { fetchFinanceItem } from "../api/finance";
import { useStudyStore } from "../store/study";
import { useAuthStore } from "../store/auth";
import { usePermission } from "../utils/permission";
import { financeMachine, getAvailableActions, getStateColor, getStateLabel } from "../state-machine";
const study = useStudyStore();
const auth = useAuthStore();
@@ -62,7 +63,11 @@ const item = ref<any>(null);
const loading = ref(false);
const showEdit = ref(false);
const { can } = usePermission();
const canEditDraft = computed(() => item.value?.status === "DRAFT" && can("finance.create"));
const canEditDraft = computed(() => {
const actions = getAvailableActions(financeMachine, item.value?.status);
const submitAllowed = actions.some((a) => a.key === "submit");
return submitAllowed && can("finance.create");
});
const loadItem = async () => {
if (!study.currentStudy) return;
@@ -78,30 +83,8 @@ const loadItem = async () => {
}
};
const statusTag = (status?: string) => {
switch (status) {
case "DRAFT":
return "info";
case "SUBMITTED":
return "warning";
case "APPROVED":
return "success";
case "REJECTED":
return "danger";
case "PAID":
return "success";
default:
return "info";
}
};
const statusLabel = (status?: string) =>
({
DRAFT: "草稿",
SUBMITTED: "已提交",
APPROVED: "已审批",
REJECTED: "已驳回",
PAID: "已支付",
}[status || ""] || status || "");
const stateLabel = (v?: string | null) => getStateLabel(financeMachine, v);
const stateColor = (v?: string | null) => getStateColor(financeMachine, v) || "info";
const formatAmount = (num?: number | string) => {
const n = Number(num);