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:
1 parent
3ccbdb7c06
commit
89d45da839
224 files changed
+7926
-3052
No files matched your search
@@ -58,10 +58,8 @@ defineOptions({
|
||||
|
||||
/**
|
||||
* 审批流程时间线(流程走向 + 审批记录融合)
|
||||
*
|
||||
* @description 以设计环节为骨架按编排顺序展示,实际办理记录按 activityId 归位到环节:
|
||||
* 已办(办理人/意见/时间)、进行中(待认领或等待办理)、未到(运行中位于当前环节之后)、
|
||||
* 未经过(网关分支跳过或流程结束仍未到达),驳回重办的多轮记录全部保留
|
||||
* 以设计环节为骨架按编排顺序展示,实际办理记录按 activityId 归位到环节:
|
||||
* 已办(办理人/意见/时间)、进行中(待认领或等待办理)、未到(运行中位于当前环节之后)、 未经过(网关分支跳过或流程结束仍未到达),驳回重办的多轮记录全部保留
|
||||
*/
|
||||
const props = defineProps<{
|
||||
/** 审批环节(按 BPMN 编排顺序,含分支未走节点) */
|
||||
@@ -74,7 +72,7 @@ const props = defineProps<{
|
||||
status: InstanceStatus;
|
||||
}>();
|
||||
|
||||
/** 节点ID -> 办理记录(驳回重办为多条) */
|
||||
// 节点 ID -> 办理记录(驳回重办为多条)
|
||||
const recordMap = computed(() => {
|
||||
const map = new Map<string, ApprovalHistoryItem[]>();
|
||||
props.history.forEach((item) => {
|
||||
@@ -86,25 +84,37 @@ const recordMap = computed(() => {
|
||||
return map;
|
||||
});
|
||||
|
||||
/**
|
||||
* 取节点对应的审批记录
|
||||
*/
|
||||
function recordsOf(nodeId: string): ApprovalHistoryItem[] {
|
||||
return recordMap.value.get(nodeId) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断节点是否已有审批记录
|
||||
*/
|
||||
function hasRecord(nodeId: string): boolean {
|
||||
return recordsOf(nodeId).length > 0;
|
||||
}
|
||||
|
||||
/** 是否"未到":流程运行中且位于当前环节之后 */
|
||||
/**
|
||||
* 是否"未到":流程运行中且位于当前环节之后
|
||||
*/
|
||||
function isUpcoming(index: number): boolean {
|
||||
return props.status === "running" && index >= props.active;
|
||||
}
|
||||
|
||||
/** 无记录环节状态标签:未到(后续环节)/ 未经过(分支跳过或已结束) */
|
||||
/**
|
||||
* 无记录环节状态标签:未到(后续环节)/ 未经过(分支跳过或已结束)
|
||||
*/
|
||||
function pendingLabel(index: number): string {
|
||||
return isUpcoming(index) ? "未到" : "未经过";
|
||||
}
|
||||
|
||||
/** 环节办理人描述:角色(成员账号);发起人办理环节标注"发起人" */
|
||||
/**
|
||||
* 环节办理人描述:角色(成员账号);发起人办理环节标注"发起人"
|
||||
*/
|
||||
function describe(stage: ProcessStageItem): string {
|
||||
if (stage.initiator) {
|
||||
return "发起人";
|
||||
|
||||
@@ -186,8 +186,7 @@ defineOptions({
|
||||
|
||||
/**
|
||||
* BPMN 流程设计器
|
||||
*
|
||||
* @description bpmn-js 建模器 + 轻量属性面板(名称/表单标识/办理人/候选组/条件表达式),
|
||||
* bpmn-js 建模器 + 轻量属性面板(名称/表单标识/办理人/候选组/条件表达式),
|
||||
* 扩展 flowable 命名空间属性,保存时产出引擎可直接部署的 BPMN 2.0 XML
|
||||
*/
|
||||
const props = defineProps<{
|
||||
@@ -205,10 +204,10 @@ const emit = defineEmits<{
|
||||
const canvasRef = ref<HTMLElement | null>(null);
|
||||
const modeler = shallowRef<Modeler>();
|
||||
|
||||
/** 脏标记:画布有未保存的修改(承载页据此拦截离开) */
|
||||
// 脏标记:画布有未保存的修改(承载页据此拦截离开)
|
||||
const dirty = ref(false);
|
||||
|
||||
/** 当前选中元素(Shape/Connection 统称) */
|
||||
// 当前选中元素(Shape/Connection 统称)
|
||||
const selectedElement = shallowRef<Shape | null>(null);
|
||||
|
||||
const isUserTask = computed(
|
||||
@@ -217,7 +216,7 @@ const isUserTask = computed(
|
||||
const isSequenceFlow = computed(
|
||||
() => !!selectedElement.value && is(selectedElement.value, "bpmn:SequenceFlow")
|
||||
);
|
||||
/** 仅开始节点可绑定表单(后端只读开始节点 formKey 渲染发起表单,审批展示复用同一份数据) */
|
||||
// 仅开始节点可绑定表单(后端只读开始节点 formKey 渲染发起表单,审批展示复用同一份数据)
|
||||
const isFormBindable = computed(
|
||||
() => !!selectedElement.value && is(selectedElement.value, "bpmn:StartEvent")
|
||||
);
|
||||
@@ -227,20 +226,20 @@ const selectedFormKey = computed(() => selectedElement.value?.businessObject?.ge
|
||||
const selectedAssignee = computed(
|
||||
() => selectedElement.value?.businessObject?.get("assignee") ?? ""
|
||||
);
|
||||
/** 候选组(角色编码,逗号分隔)与办理人二选一配置,均空发布时会被后端拦截 */
|
||||
// 候选组(角色编码,逗号分隔)与办理人二选一配置,均空发布时会被后端拦截
|
||||
const selectedCandidateGroups = computed(
|
||||
() => selectedElement.value?.businessObject?.get("candidateGroups") ?? ""
|
||||
);
|
||||
/** 候选组多选值:XML 逗号串 ↔ 选项数组互转,数据结构保持引擎兼容 */
|
||||
// 候选组多选值:XML 逗号串 ↔ 选项数组互转,数据结构保持引擎兼容
|
||||
const candidateGroupCodes = computed(() =>
|
||||
String(selectedCandidateGroups.value)
|
||||
.split(",")
|
||||
.map((code) => code.trim())
|
||||
.filter(Boolean)
|
||||
);
|
||||
/** 角色编码选项(label 角色名 / value 角色编码) */
|
||||
// 角色编码选项(label 角色名 / value 角色编码)
|
||||
const roleCodeOptions = ref<OptionItem[]>([]);
|
||||
/** 发起表单选项(label 表单名 / value formKey,仅已发布 workflow 类型) */
|
||||
// 发起表单选项(label 表单名 / value formKey,仅已发布 workflow 类型)
|
||||
const workflowFormOptions = ref<OptionItem[]>([]);
|
||||
const selectedCondition = computed(
|
||||
() => selectedElement.value?.businessObject?.conditionExpression?.body ?? ""
|
||||
@@ -250,7 +249,7 @@ const selectedCondition = computed(
|
||||
* 更新元素普通属性(名称/formKey/assignee/candidateGroups)
|
||||
*
|
||||
* @param property 属性名
|
||||
* @param value 属性值(空值传 undefined 移除属性,避免序列化出空串属性干扰引擎解析)
|
||||
* @param value 属性值(空值传 undefined 移除属性,避免序列化出空串属性干扰引擎解析)
|
||||
*/
|
||||
function updateProperty(property: string, value: string): void {
|
||||
const element = selectedElement.value;
|
||||
@@ -273,12 +272,16 @@ function updateCandidateGroups(codes: string[]): void {
|
||||
updateProperty("candidateGroups", codes.join(","));
|
||||
}
|
||||
|
||||
/** 加载角色编码选项(候选组下拉数据源) */
|
||||
/**
|
||||
* 加载角色编码选项(候选组下拉数据源)
|
||||
*/
|
||||
async function loadRoleCodeOptions(): Promise<void> {
|
||||
roleCodeOptions.value = await RoleAPI.getCodeOptions();
|
||||
}
|
||||
|
||||
/** 加载发起表单选项(formKey 下拉数据源) */
|
||||
/**
|
||||
* 加载发起表单选项(formKey 下拉数据源)
|
||||
*/
|
||||
async function loadWorkflowFormOptions(): Promise<void> {
|
||||
workflowFormOptions.value = await FormAPI.getWorkflowOptions();
|
||||
}
|
||||
@@ -319,12 +322,16 @@ function handleZoom(delta: number): void {
|
||||
canvas.zoom(canvas.zoom() + delta);
|
||||
}
|
||||
|
||||
/** 适应画布(完整展示流程图) */
|
||||
/**
|
||||
* 适应画布(完整展示流程图)
|
||||
*/
|
||||
function handleFitViewport(): void {
|
||||
(modeler.value!.get("canvas") as CanvasLike).zoom("fit-viewport");
|
||||
}
|
||||
|
||||
/** 导入 XML 并选中态复位 */
|
||||
/**
|
||||
* 导入 XML 并选中态复位
|
||||
*/
|
||||
async function importXml(xml: string): Promise<void> {
|
||||
if (!xml || !modeler.value) return;
|
||||
try {
|
||||
|
||||
@@ -18,16 +18,15 @@ defineOptions({
|
||||
|
||||
/**
|
||||
* BPMN 流程图查看器
|
||||
*
|
||||
* @description 渲染 BPMN XML 并按节点状态高亮:已办节点标记走过路径、
|
||||
* 渲染 BPMN XML 并按节点状态高亮:已办节点标记走过路径、
|
||||
* 进行中节点标记当前待办;缩放平移由 NavigatedViewer 自带滚轮/空格拖拽支持
|
||||
*/
|
||||
const props = defineProps<{
|
||||
/** BPMN 2.0 XML */
|
||||
xml: string;
|
||||
/** 已办节点ID列表(走过路径高亮) */
|
||||
/** 已办节点 ID 列表(走过路径高亮) */
|
||||
executedActivityIds?: string[];
|
||||
/** 进行中节点ID列表(当前待办高亮) */
|
||||
/** 进行中节点 ID 列表(当前待办高亮) */
|
||||
activeActivityIds?: string[];
|
||||
}>();
|
||||
|
||||
@@ -38,8 +37,8 @@ const viewer = shallowRef<Viewer>();
|
||||
* 导入 XML 并叠加高亮标记
|
||||
*
|
||||
* @param xml BPMN XML
|
||||
* @param executedIds 已办节点ID列表
|
||||
* @param activeIds 进行中节点ID列表
|
||||
* @param executedIds 已办节点 ID 列表
|
||||
* @param activeIds 进行中节点 ID 列表
|
||||
*/
|
||||
async function renderDiagram(
|
||||
xml: string,
|
||||
|
||||
@@ -12,8 +12,7 @@ defineOptions({
|
||||
|
||||
/**
|
||||
* 表单只读回显
|
||||
*
|
||||
* @description 按提交时快照规则渲染表单并禁用全部控件,
|
||||
* 按提交时快照规则渲染表单并禁用全部控件,
|
||||
* 供审批办理、实例详情等场景回看发起数据
|
||||
*/
|
||||
const props = defineProps<{
|
||||
@@ -45,7 +44,6 @@ watch(
|
||||
|
||||
/**
|
||||
* 递归禁用规则中的全部控件
|
||||
*
|
||||
* 同时移除校验规则,只读态不展示必填星号
|
||||
*
|
||||
* @param rules form-create 规则(JSON 解析值)
|
||||
|
||||
@@ -69,7 +69,7 @@ defineOptions({
|
||||
name: "InstanceDetailDrawer",
|
||||
});
|
||||
|
||||
/** 实例状态展示映射(标签文案 + 标签色) */
|
||||
// 实例状态展示映射(标签文案 + 标签色)
|
||||
const statusOptions: Record<
|
||||
InstanceStatus,
|
||||
{ label: string; tag: "primary" | "success" | "danger" }
|
||||
@@ -84,7 +84,7 @@ const loading = ref(false);
|
||||
|
||||
const detail = ref<InstanceDetailData>();
|
||||
|
||||
/** 流程图数据(详情抽屉"流程图"页签) */
|
||||
// 流程图数据(详情抽屉"流程图"页签)
|
||||
const diagram = ref<ProcessDiagramData>({
|
||||
bpmnXml: "",
|
||||
executedActivityIds: [],
|
||||
|
||||
@@ -33,15 +33,15 @@ defineOptions({
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
/** 模型 ID(设计器始终由列表页"设计"按钮带参进入) */
|
||||
// 模型 ID(设计器始终由列表页"设计"按钮带参进入)
|
||||
const modelId = computed(() => String(route.query.modelId ?? ""));
|
||||
|
||||
/** 页面标题(列表页携带,如【请假审批】流程设计) */
|
||||
// 页面标题(列表页携带,如【请假审批】流程设计)
|
||||
const title = computed(() => String(route.query.title ?? "流程设计"));
|
||||
|
||||
const designerRef = ref<InstanceType<typeof BpmnDesigner>>();
|
||||
|
||||
/** 回显的 BPMN XML(新模型为空串,画布空白可自由拖拽) */
|
||||
// 回显的 BPMN XML(新模型为空串,画布空白可自由拖拽)
|
||||
const xml = ref("");
|
||||
|
||||
const loading = ref(false);
|
||||
@@ -58,7 +58,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
// 菜单 keep_alive=1 缓存页面,换模型再次进入需按 modelId 重载画布;
|
||||
// 离开页面时 query 置空,跳过重载避免缓存页误报"缺少模型ID参数"
|
||||
// 离开页面时 query 置空,跳过重载避免缓存页误报"缺少模型 ID 参数"
|
||||
watch(modelId, (val) => {
|
||||
if (val) loadXml();
|
||||
});
|
||||
@@ -101,7 +101,7 @@ async function handleSave(xml: string): Promise<void> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回流程设计列表(有未保存修改时二次确认)
|
||||
* @returns 流程设计列表(有未保存修改时二次确认)
|
||||
*/
|
||||
async function handleBack(): Promise<void> {
|
||||
if (designerRef.value?.isDirty()) {
|
||||
|
||||
@@ -104,10 +104,10 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
/** 演示引导提示条可见状态(关闭后本次会话不再显示) */
|
||||
// 演示引导提示条可见状态(关闭后本次会话不再显示)
|
||||
const demoTipVisible = ref(true);
|
||||
|
||||
/** 可发起流程列表 */
|
||||
// 可发起流程列表
|
||||
const processList = ref<StartableProcessItem[]>([]);
|
||||
|
||||
const selectedId = ref("");
|
||||
@@ -116,28 +116,25 @@ const selectedProcess = computed(() =>
|
||||
processList.value.find((process) => process.id === selectedId.value)
|
||||
);
|
||||
|
||||
/** 审批流程走向预览 */
|
||||
// 审批流程走向预览
|
||||
const stages = ref<ProcessStageItem[]>([]);
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
/**
|
||||
* 流程实例名称:默认按"流程-姓名-时间"自动拼接,切换流程或手动修改后重置,
|
||||
* 用户可编辑以获得可读标题(同一流程多次发起也能从列表一眼区分)
|
||||
*/
|
||||
// 流程实例名称:默认按"流程-姓名-时间"自动拼接,切换流程或手动修改后重置, 用户可编辑以获得可读标题(同一流程多次发起也能从列表一眼区分)
|
||||
const processName = ref("");
|
||||
const autoNameValue = ref("");
|
||||
/** 名称被手动修改过:区别于自动值,展示"恢复自动命名"入口 */
|
||||
// 名称被手动修改过:区别于自动值,展示"恢复自动命名"入口
|
||||
const autoNameDirty = ref(false);
|
||||
|
||||
/**
|
||||
* 生成默认流程名称:流程名-昵称-MM月DD日
|
||||
*
|
||||
* <p>精确到日即可:同日多次发起由列表的"发起时间"列区分,名称保持简洁;特殊情况可手动编辑</p>
|
||||
* 生成默认流程名称:流程名-昵称-MM 月 DD 日
|
||||
* 精确到日即可:同日多次发起由列表的"发起时间"列区分,名称保持简洁;特殊情况可手动编辑
|
||||
*/
|
||||
function buildAutoName(): string {
|
||||
const nickname = userStore.userInfo?.nickname || userStore.userInfo?.username || "";
|
||||
const now = new Date();
|
||||
// 数值补零为两位
|
||||
const pad = (num: number) => String(num).padStart(2, "0");
|
||||
return selectedProcess.value
|
||||
? `${selectedProcess.value.name}-${nickname}-${pad(now.getMonth() + 1)}月${pad(now.getDate())}日`
|
||||
@@ -168,7 +165,9 @@ function resetAutoName(): void {
|
||||
autoNameDirty.value = false;
|
||||
}
|
||||
|
||||
/** 发起表单渲染状态(复用动态表单渲染管线,保证与填写页一致) */
|
||||
/**
|
||||
* 发起表单渲染状态(复用动态表单渲染管线,保证与填写页一致)
|
||||
*/
|
||||
const { rule, option, loading, submitted, load, refill } = useFormRenderer(() =>
|
||||
FormAPI.getRender(selectedProcess.value?.formKey ?? "")
|
||||
);
|
||||
@@ -181,7 +180,6 @@ onMounted(async () => {
|
||||
|
||||
/**
|
||||
* 切换流程时按 formKey 加载发起表单规则与审批走向
|
||||
*
|
||||
* 未绑定表单的流程走确认直发,不加载规则
|
||||
*/
|
||||
async function handleProcessChange(): Promise<void> {
|
||||
|
||||
@@ -257,10 +257,12 @@ const { toggle: toggleFullscreen } = useFullscreen(tableWrapperRef);
|
||||
const queryFormRef = ref<FormInstance>();
|
||||
const modelFormRef = ref<FormInstance>();
|
||||
|
||||
/** 启用开关权限(el-switch 不支持 v-hasPerm 指令移除,改 v-if 控制) */
|
||||
/**
|
||||
* 启用开关权限(el-switch 不支持 v-hasPerm 指令移除,改 v-if 控制)
|
||||
*/
|
||||
const hasStatePerm = hasPerm("workflow:definition:update");
|
||||
|
||||
/** 分页表格数据管理 */
|
||||
// 分页表格数据管理
|
||||
const { loading, list, total, params, fetchData, handleQuery, handleResetQuery } = usePageTable<
|
||||
WorkflowModelItem,
|
||||
WorkflowModelQueryParams
|
||||
@@ -297,7 +299,7 @@ const rules: FormRules<WorkflowModelFormData> = {
|
||||
],
|
||||
};
|
||||
|
||||
/** 流程图弹窗状态 */
|
||||
// 流程图弹窗状态
|
||||
const diagramState = reactive({
|
||||
title: "",
|
||||
visible: false,
|
||||
@@ -305,7 +307,7 @@ const diagramState = reactive({
|
||||
xml: "",
|
||||
});
|
||||
|
||||
/** 正在切换启用状态的流程 ID(该行开关转圈,其余行禁用防并发) */
|
||||
// 正在切换启用状态的流程 ID(该行开关转圈,其余行禁用防并发)
|
||||
const switchingId = ref<string | null>(null);
|
||||
|
||||
/**
|
||||
@@ -465,7 +467,7 @@ async function handleResetDemo(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否正在重置演示流程(重置请求期间按钮转圈并防重复点击) */
|
||||
// 是否正在重置演示流程(重置请求期间按钮转圈并防重复点击)
|
||||
const resetting = ref(false);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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>>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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("");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user