更新采购申请前端给审核时用

This commit is contained in:
吴红兵
2026-02-08 21:12:20 +08:00
parent 496116d7f8
commit f209700fa9
2 changed files with 307 additions and 129 deletions

View File

@@ -16,11 +16,11 @@
:model="dataForm" :model="dataForm"
:rules="dataRules" :rules="dataRules"
label-width="150px" label-width="150px"
:disabled="isViewMode" :disabled="isViewMode || flowFormDisabled"
class="compact-form"> class="compact-form">
<!-- 第一步基本信息查看模式下一并展示新增/编辑按步骤切换 --> <!-- 第一步基本信息查看/流程嵌入时单页展示否则按步骤切换 -->
<div v-show="isViewMode || currentStep === 0"> <div v-show="isViewMode || isFlowEmbed || currentStep === 0">
<el-row :gutter="24"> <el-row :gutter="24">
<el-col :span="12" class="mb16"> <el-col :span="12" class="mb16">
<el-form-item label="采购项目名称" prop="projectName"> <el-form-item label="采购项目名称" prop="projectName">
@@ -131,8 +131,8 @@
</el-row> </el-row>
</div> </div>
<!-- 第二步采购详情查看模式下一并展示新增/编辑按步骤切换 --> <!-- 第二步采购详情查看/流程嵌入时单页展示否则按步骤切换 -->
<div v-show="isViewMode || currentStep === 1"> <div v-show="isViewMode || isFlowEmbed || currentStep === 1">
<!-- 分支一部门自行采购单行两列流式布局条件显示的项自动填满两列 --> <!-- 分支一部门自行采购单行两列流式布局条件显示的项自动填满两列 -->
<div class="mb20" v-if="isDeptPurchase"> <div class="mb20" v-if="isDeptPurchase">
<div class="step-title mb16">部门自行采购</div> <div class="step-title mb16">部门自行采购</div>
@@ -384,7 +384,7 @@
</div> </div>
</div> </div>
<el-row :gutter="24" v-if="currentStep === 1"> <el-row :gutter="24" v-if="currentStep === 1 || isFlowEmbed">
<el-col :span="12" class="mb16"> <el-col :span="12" class="mb16">
<el-form-item label="备注" prop="remark" class="mb16"> <el-form-item label="备注" prop="remark" class="mb16">
<el-input <el-input
@@ -398,24 +398,24 @@
</el-row> </el-row>
</el-form> </el-form>
<!-- 操作按钮 --> <!-- 操作按钮流程嵌入时隐藏取消/返回由流程页处理 -->
<div class="form-footer"> <div class="form-footer">
<template v-if="isViewMode"> <template v-if="isViewMode">
<el-button @click="handleCancel">返回</el-button> <el-button v-if="!isFlowEmbed" @click="handleCancel">返回</el-button>
</template> </template>
<template v-else> <template v-else>
<el-button @click="handleCancel">取消</el-button> <el-button v-if="!isFlowEmbed" @click="handleCancel">取消</el-button>
<el-button v-if="currentStep > 0" @click="prevStep">上一步</el-button> <el-button v-if="!isFlowEmbed && currentStep > 0" @click="prevStep">上一步</el-button>
<el-button <el-button
v-if="currentStep < 1" v-if="!isFlowEmbed && currentStep < 1"
type="primary" type="primary"
@click="nextStep" @click="nextStep"
:disabled="loading"> :disabled="loading">
下一步 下一步
</el-button> </el-button>
<template v-if="currentStep === 1"> <template v-if="currentStep === 1 || isFlowEmbed">
<el-button <el-button
v-if="!isEditMode" v-if="!isEditMode && !flowSubmitDisabled"
type="warning" type="warning"
@click="handleTempStore" @click="handleTempStore"
:disabled="loading"> :disabled="loading">
@@ -449,20 +449,56 @@ import other from '/@/utils/other';
import { Document, Download } from '@element-plus/icons-vue'; import { Document, Download } from '@element-plus/icons-vue';
import { fetchList as getBusinessDeptList } from '/@/api/purchase/purchasingBusinessDept'; import { fetchList as getBusinessDeptList } from '/@/api/purchase/purchasingBusinessDept';
import { getPage as getSchoolLeaderPage } from '/@/api/finance/purchasingschoolleader'; import { getPage as getSchoolLeaderPage } from '/@/api/finance/purchasingschoolleader';
import * as orderVue from '/@/api/order/order-key-vue';
// 兼容流程 dynamic-link 引用:接收 currJob / currElTab并支持 handleJob 事件
const props = defineProps({
currJob: { type: Object, default: null },
currElTab: { type: Object, default: null }
});
const emit = defineEmits(['handleJob']);
// 路由 // 路由
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
// 模式add | edit | view来自 URL 参数,用于 form 弹窗内 iframe 打开) /** 是否被流程 handle 页通过 dynamic-link 嵌入 */
const isEditMode = computed(() => String(route.query.mode) === 'edit'); const isFlowEmbed = computed(() => !!props.currJob);
const isViewMode = computed(() => String(route.query.mode) === 'view');
/** 当前使用的申请单 ID优先来自流程 currJob.orderId否则来自 route.query.id */
const effectiveQueryId = computed(() => {
if (props.currJob?.orderId != null && props.currJob?.orderId !== '') {
return String(props.currJob.orderId);
}
const q = route.query.id;
return q ? String(q) : '';
});
// 模式add | edit | viewURL 参数 或 流程嵌入时的 currJob/currElTab
const isEditMode = computed(() => {
if (isFlowEmbed.value && props.currElTab) {
return !!effectiveQueryId.value && props.currElTab.isFormEdit !== '0' && !props.currJob?.hiJob;
}
return String(route.query.mode) === 'edit';
});
const isViewMode = computed(() => {
if (isFlowEmbed.value && props.currJob) {
if (props.currJob.hiJob) return true;
if (props.currElTab?.isFormEdit === '0') return true;
return false;
}
return String(route.query.mode) === 'view';
});
const pageTitle = computed(() => { const pageTitle = computed(() => {
if (isViewMode.value) return '查看采购申请'; if (isViewMode.value) return '查看采购申请';
if (isEditMode.value) return '编辑采购申请'; if (isEditMode.value) return '编辑采购申请';
return '新增采购申请'; return '新增采购申请';
}); });
/** 流程嵌入时,由 currElTabIsView 控制的只读/禁用提交 */
const flowFormDisabled = ref(false);
const flowSubmitDisabled = ref(false);
// 定义变量内容 // 定义变量内容
const formRef = ref(); const formRef = ref();
const currentStep = ref(0); const currentStep = ref(0);
@@ -999,7 +1035,10 @@ const prevStep = () => {
// 取消 // 取消
const handleCancel = () => { const handleCancel = () => {
// 如果是在 iframe 中,向父窗口发送关闭消息 // 流程嵌入时由流程页处理返回,不 postMessage
if (isFlowEmbed.value) {
return;
}
if (window.parent !== window) { if (window.parent !== window) {
window.parent.postMessage({ window.parent.postMessage({
type: 'purchasingrequisition:close' type: 'purchasingrequisition:close'
@@ -1009,6 +1048,151 @@ const handleCancel = () => {
} }
}; };
/** 根据申请单 ID 加载详情并回填表单(供 URL 与流程嵌入共用) */
async function loadDetail(applyId: string | number) {
if (!applyId) return;
try {
const res = await getObj(Number(applyId));
const detail = res?.data;
if (detail && typeof detail === 'object') {
Object.assign(dataForm, {
id: detail.id ?? dataForm.id,
projectName: detail.projectName ?? '',
projectType: detail.projectType ?? '',
projectContent: detail.projectContent ?? '',
applyDate: detail.applyDate ?? '',
fundSource: detail.fundSource ?? '',
budget: detail.budget != null ? Number(detail.budget) : null,
isCentralized: detail.isCentralized != null ? String(detail.isCentralized) : '',
isSpecial: detail.isSpecial != null ? String(detail.isSpecial) : '',
purchaseMode: detail.purchaseMode ?? '',
purchaseType: detail.purchaseType ?? '',
purchaseTypeUnion: detail.purchaseTypeUnion ?? '',
categoryCode: detail.categoryCode ?? '',
remark: detail.remark ?? '',
status: detail.status ?? '',
businessNegotiationTable: detail.businessNegotiationTable ?? '',
marketPurchaseMinutes: detail.marketPurchaseMinutes ?? '',
onlineMallMaterials: detail.onlineMallMaterials ?? '',
inquiryTemplate: detail.inquiryTemplate ?? '',
entrustCenterType: detail.entrustCenterType ?? '',
hasSupplier: detail.hasSupplier != null && detail.hasSupplier !== '' ? detail.hasSupplier : '0',
suppliers: detail.suppliers ?? '',
serviceDirectSelect: detail.serviceDirectSelect ?? '',
servicePublicSelect: detail.servicePublicSelect ?? '',
purchaseRequirementTemplate: detail.purchaseRequirementTemplate ?? '',
serviceInviteSelect: detail.serviceInviteSelect ?? '',
servicePublicSelectAuto: detail.servicePublicSelectAuto ?? '',
purchaseRequirement: detail.purchaseRequirement ?? '',
meetingMinutes: detail.meetingMinutes ?? '',
feasibilityReport: detail.feasibilityReport ?? '',
meetingMinutesUrgent: detail.meetingMinutesUrgent ?? '',
meetingMinutesSingle: detail.meetingMinutesSingle ?? '',
meetingMinutesImport: detail.meetingMinutesImport ?? '',
singleSourceProof: detail.singleSourceProof ?? '',
importApplication: detail.importApplication ?? '',
governmentPurchaseIntent: detail.governmentPurchaseIntent ?? '',
servicePublicSelectSchool: detail.servicePublicSelectSchool ?? '',
serviceInviteSelectSchool: detail.serviceInviteSelectSchool ?? '',
servicePublicSelectSchoolAuto: detail.servicePublicSelectSchoolAuto ?? '',
deptClassifyUserId: detail.deptClassifyUserId ?? '',
deptClassifyName: detail.deptClassifyName ?? '',
schoolLeaderUserId: detail.schoolLeaderUserId ?? '',
schoolLeaderName: detail.schoolLeaderName ?? '',
otherMaterials: detail.otherMaterials ?? '',
});
setCategoryCodePath();
if (dataForm.budget != null) {
budgetInputValue.value = dataForm.budget;
budgetUnit.value = 'yuan';
}
currentStep.value = 0;
try {
const fileRes = await getApplyFiles(String(applyId));
const fileList: { id: string; fileType: string; fileTitle?: string }[] = fileRes?.data ?? [];
if (Array.isArray(fileList) && fileList.length > 0) {
const byType: Record<string, { id: string; fileTitle?: string }[]> = {};
fileList.forEach((f: any) => {
const t = String(f.fileType || '');
if (!byType[t]) byType[t] = [];
byType[t].push({ id: f.id, fileTitle: f.fileTitle });
});
Object.entries(byType).forEach(([fileType, files]) => {
const fields = FILE_TYPE_TO_FIELDS[fileType];
if (!fields || fields.length === 0) return;
const fileItems = files.map((f) => ({ id: f.id, name: f.fileTitle || '附件' }));
if (fields.length === 1) {
(dataForm as any)[fields[0]] = fileItems;
} else {
fields.forEach((field) => {
(dataForm as any)[field] = fileItems.length ? [...fileItems] : '';
});
}
});
}
} catch (err) {
console.error('加载采购申请附件失败', err);
}
}
} catch (e) {
console.error('加载采购申请详情失败', e);
useMessage().error('加载详情失败');
}
}
/** 流程嵌入时提供给 orderVue.currElTabIsView 的 methods只读/禁用提交) */
const flowMethods = {
disableForm(disabled?: boolean) {
flowFormDisabled.value = !!disabled;
},
disableSubmit() {
flowSubmitDisabled.value = true;
},
enableSubmit() {
flowSubmitDisabled.value = false;
},
};
/** 流程嵌入时的“保存”回调:校验后调用 editObj并通知流程已保存 */
async function flowSubmitForm() {
if (loading.value) return;
loading.value = true;
try {
const valid = await formRef.value?.validate().catch(() => false);
if (!valid) {
loading.value = false;
return;
}
const submitData: any = { ...dataForm };
const fileFields = [
'businessNegotiationTable', 'marketPurchaseMinutes', 'onlineMallMaterials', 'inquiryTemplate',
'serviceDirectSelect', 'servicePublicSelect', 'purchaseRequirementTemplate',
'serviceInviteSelect', 'servicePublicSelectAuto', 'purchaseRequirement',
'meetingMinutes', 'feasibilityReport', 'meetingMinutesUrgent',
'meetingMinutesSingle', 'meetingMinutesImport', 'singleSourceProof', 'importApplication',
'governmentPurchaseIntent', 'servicePublicSelectSchool', 'serviceInviteSelectSchool',
'servicePublicSelectSchoolAuto', 'otherMaterials'
];
const allFileIds: string[] = [];
fileFields.forEach(field => {
if (submitData[field]) {
allFileIds.push(...getFileIdsArray(submitData[field]));
delete submitData[field];
}
});
if (allFileIds.length > 0) submitData.fileIds = allFileIds;
await editObj(submitData);
useMessage().success('保存成功');
if (props.currJob && props.currElTab?.id) {
orderVue.currElTabIsSave(props.currJob, props.currElTab.id, true, emit);
}
} catch (err: any) {
if (!err?.msg) useMessage().error('保存失败');
} finally {
loading.value = false;
}
}
// 获取品目树形数据 // 获取品目树形数据
const getCategoryTreeData = async () => { const getCategoryTreeData = async () => {
try { try {
@@ -1427,18 +1611,17 @@ const handleTempStore = async () => {
await tempStore(submitData); await tempStore(submitData);
useMessage().success('暂存成功'); useMessage().success('暂存成功');
// 流程嵌入时不关闭、不跳转
// 如果是在 iframe 中,向父窗口发送消息 if (!isFlowEmbed.value) {
if (window.parent !== window) { if (window.parent !== window) {
window.parent.postMessage({ window.parent.postMessage({
type: 'purchasingrequisition:submitSuccess' type: 'purchasingrequisition:submitSuccess'
}, '*'); }, '*');
} else { } else {
router.push('/finance/purchasingrequisition'); router.push('/finance/purchasingrequisition');
}
} }
} catch (err: any) { } catch (err: any) {
// 全局拦截器已经显示了错误提示,这里不需要再次显示
// 只有当错误没有 msg 时才显示默认错误提示
if (!err?.msg) { if (!err?.msg) {
useMessage().error('暂存失败'); useMessage().error('暂存失败');
} }
@@ -1545,6 +1728,17 @@ watch(() => categoryTreeData.value, () => {
} }
}, { deep: true }); }, { deep: true });
// 流程嵌入:切换工单时重新加载该 tab 对应的申请单
watch(
() => props.currJob?.id,
async (newVal, oldVal) => {
if (!isFlowEmbed.value || !props.currJob?.orderId) return;
if (newVal !== oldVal) {
await loadDetail(props.currJob.orderId);
}
}
);
// 初始化 // 初始化
onMounted(async () => { onMounted(async () => {
// 检测是否在 iframe 中,如果是,则修改相关元素的 overflow 样式以支持滚动 // 检测是否在 iframe 中,如果是,则修改相关元素的 overflow 样式以支持滚动
@@ -1584,101 +1778,16 @@ onMounted(async () => {
getSchoolLeaderListData(), getSchoolLeaderListData(),
]); ]);
// 编辑/查看:从 URL 参数 id 加载详情 // 编辑/查看:从 URL 或流程 currJob.orderId 加载详情
const queryId = route.query.id; const queryId = effectiveQueryId.value;
if (queryId) { if (queryId) {
try { await loadDetail(queryId);
const res = await getObj(Number(queryId)); }
const detail = res?.data;
if (detail && typeof detail === 'object') { // 流程嵌入:注册 tab 显隐与保存回调,供审批页调用
Object.assign(dataForm, { if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
id: detail.id ?? dataForm.id, orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
projectName: detail.projectName ?? '', await orderVue.currElTabIsView(flowMethods, props.currJob, props.currElTab.id, flowSubmitForm);
projectType: detail.projectType ?? '',
projectContent: detail.projectContent ?? '',
applyDate: detail.applyDate ?? '',
fundSource: detail.fundSource ?? '',
budget: detail.budget != null ? Number(detail.budget) : null,
isCentralized: detail.isCentralized != null ? String(detail.isCentralized) : '',
isSpecial: detail.isSpecial != null ? String(detail.isSpecial) : '',
purchaseMode: detail.purchaseMode ?? '',
purchaseType: detail.purchaseType ?? '',
purchaseTypeUnion: detail.purchaseTypeUnion ?? '',
categoryCode: detail.categoryCode ?? '',
remark: detail.remark ?? '',
status: detail.status ?? '',
businessNegotiationTable: detail.businessNegotiationTable ?? '',
marketPurchaseMinutes: detail.marketPurchaseMinutes ?? '',
onlineMallMaterials: detail.onlineMallMaterials ?? '',
inquiryTemplate: detail.inquiryTemplate ?? '',
entrustCenterType: detail.entrustCenterType ?? '',
hasSupplier: detail.hasSupplier != null && detail.hasSupplier !== '' ? detail.hasSupplier : '0',
suppliers: detail.suppliers ?? '',
serviceDirectSelect: detail.serviceDirectSelect ?? '',
servicePublicSelect: detail.servicePublicSelect ?? '',
purchaseRequirementTemplate: detail.purchaseRequirementTemplate ?? '',
suppliers: detail.suppliers ?? '',
serviceInviteSelect: detail.serviceInviteSelect ?? '',
servicePublicSelectAuto: detail.servicePublicSelectAuto ?? '',
purchaseRequirement: detail.purchaseRequirement ?? '',
meetingMinutes: detail.meetingMinutes ?? '',
feasibilityReport: detail.feasibilityReport ?? '',
meetingMinutesUrgent: detail.meetingMinutesUrgent ?? '',
meetingMinutesSingle: detail.meetingMinutesSingle ?? '',
meetingMinutesImport: detail.meetingMinutesImport ?? '',
singleSourceProof: detail.singleSourceProof ?? '',
importApplication: detail.importApplication ?? '',
governmentPurchaseIntent: detail.governmentPurchaseIntent ?? '',
servicePublicSelectSchool: detail.servicePublicSelectSchool ?? '',
suppliers: detail.suppliers ?? '',
serviceInviteSelectSchool: detail.serviceInviteSelectSchool ?? '',
servicePublicSelectSchoolAuto: detail.servicePublicSelectSchoolAuto ?? '',
deptClassifyUserId: detail.deptClassifyUserId ?? '',
deptClassifyName: detail.deptClassifyName ?? '',
schoolLeaderUserId: detail.schoolLeaderUserId ?? '',
schoolLeaderName: detail.schoolLeaderName ?? '',
otherMaterials: detail.otherMaterials ?? '',
});
setCategoryCodePath();
if (dataForm.budget != null) {
budgetInputValue.value = dataForm.budget;
budgetUnit.value = 'yuan';
}
// 编辑时默认显示第一步,用户可自行切换到第二步查看
currentStep.value = 0;
// 加载已上传附件并按 fileType 回填到对应表单项
try {
const fileRes = await getApplyFiles(String(queryId));
const fileList: { id: string; fileType: string; fileTitle?: string }[] = fileRes?.data ?? [];
if (Array.isArray(fileList) && fileList.length > 0) {
const byType: Record<string, { id: string; fileTitle?: string }[]> = {};
fileList.forEach((f: any) => {
const t = String(f.fileType || '');
if (!byType[t]) byType[t] = [];
byType[t].push({ id: f.id, fileTitle: f.fileTitle });
});
Object.entries(byType).forEach(([fileType, files]) => {
const fields = FILE_TYPE_TO_FIELDS[fileType];
if (!fields || fields.length === 0) return;
const fileItems = files.map((f) => ({ id: f.id, name: f.fileTitle || '附件' }));
if (fields.length === 1) {
(dataForm as any)[fields[0]] = fileItems;
} else {
// 同类型多字段(如 120 采购需求表):后端不区分具体子项,将同一批文件回填到所有对应字段,当前展示的“需求文件”才能正确显示
fields.forEach((field) => {
(dataForm as any)[field] = fileItems.length ? [...fileItems] : '';
});
}
});
}
} catch (err) {
console.error('加载采购申请附件失败', err);
}
}
} catch (e) {
console.error('加载采购申请详情失败', e);
useMessage().error('加载详情失败');
}
} }
// 新增模式下设置默认值(只有在没有 id 的情况下才设置) // 新增模式下设置默认值(只有在没有 id 的情况下才设置)

View File

@@ -184,13 +184,48 @@
<span style="margin-left: 4px">审核状态</span> <span style="margin-left: 4px">审核状态</span>
</template> </template>
<template #default="scope"> <template #default="scope">
<el-tag v-if="scope.row.status === '-2'" type="info">撤回</el-tag> <el-tooltip v-if="scope.row.flowInstId" content="点击查看审批过程" placement="top">
<el-tag v-else-if="scope.row.status === '-1'" type="warning">暂存</el-tag> <el-tag
<el-tag v-else-if="scope.row.status === '0'" type="primary">运行中</el-tag> v-if="scope.row.status === '-2'"
<el-tag v-else-if="scope.row.status === '1'" type="success">完成</el-tag> type="info"
<el-tag v-else-if="scope.row.status === '2'" type="danger">作废</el-tag> class="status-tag-clickable"
<el-tag v-else-if="scope.row.status === '3'" type="info">终止</el-tag> @click="handleShowFlowComment(scope.row)">撤回</el-tag>
<span v-else>-</span> <el-tag
v-else-if="scope.row.status === '-1'"
type="warning"
class="status-tag-clickable"
@click="handleShowFlowComment(scope.row)">暂存</el-tag>
<el-tag
v-else-if="scope.row.status === '0'"
type="primary"
class="status-tag-clickable"
@click="handleShowFlowComment(scope.row)">运行中</el-tag>
<el-tag
v-else-if="scope.row.status === '1'"
type="success"
class="status-tag-clickable"
@click="handleShowFlowComment(scope.row)">完成</el-tag>
<el-tag
v-else-if="scope.row.status === '2'"
type="danger"
class="status-tag-clickable"
@click="handleShowFlowComment(scope.row)">作废</el-tag>
<el-tag
v-else-if="scope.row.status === '3'"
type="info"
class="status-tag-clickable"
@click="handleShowFlowComment(scope.row)">终止</el-tag>
<span v-else>-</span>
</el-tooltip>
<template v-else>
<el-tag v-if="scope.row.status === '-2'" type="info">撤回</el-tag>
<el-tag v-else-if="scope.row.status === '-1'" type="warning">暂存</el-tag>
<el-tag v-else-if="scope.row.status === '0'" type="primary">运行中</el-tag>
<el-tag v-else-if="scope.row.status === '1'" type="success">完成</el-tag>
<el-tag v-else-if="scope.row.status === '2'" type="danger">作废</el-tag>
<el-tag v-else-if="scope.row.status === '3'" type="info">终止</el-tag>
<span v-else>-</span>
</template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="150"> <el-table-column label="操作" align="center" fixed="right" width="150">
@@ -232,6 +267,19 @@
<!-- 履约验收弹窗 --> <!-- 履约验收弹窗 -->
<PurchasingAcceptModal ref="acceptModalRef" @refresh="getDataList" /> <PurchasingAcceptModal ref="acceptModalRef" @refresh="getDataList" />
<!-- 查看审批过程参考 hi-job 流程弹窗 -->
<el-dialog
v-model="showFlowComment"
v-if="showFlowComment"
title="查看审批过程"
top="20px"
width="90%"
append-to-body
destroy-on-close
@close="currFlowJob = null">
<FlowCommentTimeline v-if="currFlowJob" :key="currFlowJob.flowInstId" :curr-job="currFlowJob" />
</el-dialog>
</div> </div>
</template> </template>
@@ -249,6 +297,7 @@ import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, I
const FormDialog = defineAsyncComponent(() => import('./form.vue')); const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue')); const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'));
const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue')); const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue'));
const FlowCommentTimeline = defineAsyncComponent(() => import('/@/views/jsonflow/comment/timeline.vue'));
// 字典数据和品目树数据 // 字典数据和品目树数据
const dictData = ref({ const dictData = ref({
@@ -268,6 +317,9 @@ const formDialogRef = ref()
const acceptModalRef = ref() const acceptModalRef = ref()
const searchFormRef = ref() const searchFormRef = ref()
const showSearch = ref(true) const showSearch = ref(true)
/** 审批过程弹窗:是否显示、当前行对应的流程 job供 Comment 组件用) */
const showFlowComment = ref(false)
const currFlowJob = ref<{ id?: number; flowInstId?: number } | null>(null)
/** /**
* 定义响应式表格数据 * 定义响应式表格数据
@@ -305,6 +357,19 @@ const handleAdd = () => {
}; };
/** /**
/**
* 点击审核状态:若有流程实例则打开「查看审批过程」弹窗(参考 hi-job.vue
* @param row - 当前行数据(需含 flowInstId
*/
const handleShowFlowComment = (row: any) => {
if (!row?.flowInstId) {
useMessage().info('暂存状态无审批过程');
return;
}
currFlowJob.value = { id: row.id, flowInstId: row.flowInstId };
showFlowComment.value = true;
};
/** /**
* 打开查看对话框 * 打开查看对话框
* @param row - 当前行数据 * @param row - 当前行数据
@@ -569,5 +634,9 @@ onMounted(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.status-tag-clickable {
cursor: pointer;
}
</style> </style>