refactor: 重命名 CRUD 组件为 Crud 并简化字典标签类型

- CURD 组件 PageModal、PageSearch、PageContent、usePage 重命名为 CrudModal、CrudSearch、CrudTable、useCrudPage
- 字典项标签类型改用 primary/success/warning/danger/info,保留历史单字母值兼容读取
- 字典项页面拆分为独立子组件,移除 GithubCorner 组件
- 新增 icon 工具与 screen 样式
- 新增路由缓存、路由跳转、大屏与表格 CRUD 示例页
This commit is contained in:
Ray.Hao committed 2026-09-25 21:10:54 +08:00
1 parent 3ccbdb7c06
commit 89d45da839
224 files changed
+7926 -3052

No files matched your search

@@ -112,7 +112,7 @@ const { toggle: toggleFullscreen } = useFullscreen(tableWrapperRef);
const queryFormRef = ref<FormInstance>();
/** 分页表格数据管理 */
// 分页表格数据管理
const { loading, list, total, params, fetchData, handleQuery, handleResetQuery } = usePageTable<
DoneTaskItem,
WorkflowTaskQueryParams
@@ -126,10 +126,12 @@ const { loading, list, total, params, fetchData, handleQuery, handleResetQuery }
onBeforeReset: () => queryFormRef.value?.resetFields(),
});
/** 暴露刷新能力:审批中心页签切换时父组件调用 */
/**
* 暴露刷新能力:审批中心页签切换时父组件调用
*/
defineExpose({ fetchData });
/** 实例详情抽屉 */
// 实例详情抽屉
const detailDrawerRef = ref<InstanceType<typeof InstanceDetailDrawer>>();
/**
@@ -146,7 +146,7 @@ const { toggle: toggleFullscreen } = useFullscreen(tableWrapperRef);
const queryFormRef = ref<FormInstance>();
/** 实例状态展示映射(标签文案 + 标签色) */
// 实例状态展示映射(标签文案 + 标签色)
const statusOptions: Record<
InstanceStatus,
{ label: string; tag: "primary" | "success" | "danger" }
@@ -156,7 +156,7 @@ const statusOptions: Record<
terminated: { label: "已终止", tag: "danger" },
};
/** 分页表格数据管理 */
// 分页表格数据管理
const { loading, list, total, params, fetchData, handleQuery, handleResetQuery } = usePageTable<
WorkflowInstanceItem,
WorkflowInstanceQueryParams
@@ -170,10 +170,12 @@ const { loading, list, total, params, fetchData, handleQuery, handleResetQuery }
onBeforeReset: () => queryFormRef.value?.resetFields(),
});
/** 暴露刷新能力:审批中心页签切换时父组件调用 */
/**
* 暴露刷新能力:审批中心页签切换时父组件调用
*/
defineExpose({ fetchData });
/** 实例详情抽屉 */
// 实例详情抽屉
const detailDrawerRef = ref<InstanceType<typeof InstanceDetailDrawer>>();
/**
+16 -11
View File
@@ -92,8 +92,8 @@
<el-descriptions-item label="当前任务">{{ detail.taskName }}</el-descriptions-item>
</el-descriptions>
<!-- AI 摘要:按需生成,未开启 AI 时接口不存在,失败不影响审批 -->
<div class="todo-approve__ai">
<!-- AI 摘要:按需生成,未开启 AI 时入口不显示;生成失败不影响审批 -->
<div v-if="appConfig.aiEnabled" class="todo-approve__ai">
<div class="todo-approve__ai-header">
<span>AI 摘要</span>
<el-button link type="primary" :loading="aiLoading" @click="handleAiSummary">
@@ -187,6 +187,7 @@ import type {
WorkflowTaskQueryParams,
} from "@/api/workflow";
import { usePageTable } from "@/composables";
import { appConfig } from "@/settings";
import ApprovalTimeline from "../../components/ApprovalTimeline.vue";
import FormDetail from "../../components/FormDetail.vue";
import ProcessStages from "../../components/ProcessStages.vue";
@@ -195,7 +196,9 @@ defineOptions({
name: "WorkflowTodoTab",
});
/** 待办数量回传(驱动审批中心页签角标) */
/**
* 待办数量回传(驱动审批中心页签角标)
*/
const emit = defineEmits<{
totalChange: [total: number];
}>();
@@ -205,7 +208,7 @@ const { toggle: toggleFullscreen } = useFullscreen(tableWrapperRef);
const queryFormRef = ref<FormInstance>();
/** 分页表格数据管理 */
// 分页表格数据管理
const { loading, list, total, params, fetchData, handleQuery, handleResetQuery } = usePageTable<
TodoTaskItem,
WorkflowTaskQueryParams
@@ -221,27 +224,29 @@ const { loading, list, total, params, fetchData, handleQuery, handleResetQuery }
watch(total, (value) => emit("totalChange", value), { immediate: true });
/** 暴露刷新能力:审批中心页签切换时父组件调用 */
/**
* 暴露刷新能力:审批中心页签切换时父组件调用
*/
defineExpose({ fetchData });
/** 办理弹窗状态 */
// 办理弹窗状态
const approveState = reactive({
visible: false,
loading: false,
title: "审批办理",
});
/** 当前任务详情 */
// 当前任务详情
const detail = ref<TaskDetailData>();
/** 审批意见(通过/驳回共用) */
// 审批意见(通过/驳回共用)
const comment = ref("");
/** AI 摘要与生成状态 */
// AI 摘要与生成状态
const aiSummary = ref("");
const aiLoading = ref(false);
/** 当前任务在流程走向中的位置(节点ID精确匹配,当前环节高亮进行中,之前为已完成;未匹配时不高亮) */
// 当前任务在流程走向中的位置(节点 ID 精确匹配,当前环节高亮进行中,之前为已完成;未匹配时不高亮)
const currentStageIndex = computed(() => {
const stages = detail.value?.stages;
if (!stages?.length || !detail.value?.taskDefinitionKey) {
@@ -250,7 +255,7 @@ const currentStageIndex = computed(() => {
return stages.findIndex((stage) => stage.nodeId === detail.value?.taskDefinitionKey);
});
/** 驳回模式状态 */
// 驳回模式状态
const rejectMode = ref(false);
const rejectTargets = ref<RejectTargetItem[]>([]);
const rejectTargetId = ref("");
+4 -5
View File
@@ -37,21 +37,20 @@ defineOptions({
const route = useRoute();
/** 当前页签;发起成功跳转携带 ?tab=mine 直达「我发起的」查看进度 */
// 当前页签;发起成功跳转携带 ?tab=mine 直达「我发起的」查看进度
const activeTab = ref((route.query.tab as string) || "todo");
/** 待办数量(TodoTab 查询后回传,驱动页签角标) */
// 待办数量(TodoTab 查询后回传,驱动页签角标)
const todoTotal = ref(0);
/** 各页签组件引用(调用其暴露的刷新能力) */
// 各页签组件引用(调用其暴露的刷新能力)
const todoTabRef = ref<InstanceType<typeof TodoTab>>();
const doneTabRef = ref<InstanceType<typeof DoneTab>>();
const mineTabRef = ref<InstanceType<typeof MineTab>>();
/**
* 页签切换刷新对应列表
*
* @description lazy 页签首次激活时 ref 尚未就绪,由子组件 onMounted 自行首查,此处跳过不重复请求;
* lazy 页签首次激活时 ref 尚未就绪,由子组件 onMounted 自行首查,此处跳过不重复请求;
* 再次切换时调用子组件刷新,保证办理/发起后切回页签即见最新数据
*/
function handleTabChange(name: string | number): void {