更新采购申请前端给审核时用
This commit is contained in:
@@ -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 | view(URL 参数 或 流程嵌入时的 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,103 +1778,18 @@ 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') {
|
|
||||||
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 ?? '',
|
|
||||||
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('加载详情失败');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 流程嵌入:注册 tab 显隐与保存回调,供审批页调用
|
||||||
|
if (isFlowEmbed.value && props.currJob && props.currElTab?.id) {
|
||||||
|
orderVue.currElTabIsExist(props.currJob, props.currElTab.id);
|
||||||
|
await orderVue.currElTabIsView(flowMethods, props.currJob, props.currElTab.id, flowSubmitForm);
|
||||||
|
}
|
||||||
|
|
||||||
// 新增模式下设置默认值(只有在没有 id 的情况下才设置)
|
// 新增模式下设置默认值(只有在没有 id 的情况下才设置)
|
||||||
if (!dataForm.id) {
|
if (!dataForm.id) {
|
||||||
// 填报日期默认为当天
|
// 填报日期默认为当天
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user