diff --git a/src/views/finance/purchasingrequisition/add.vue b/src/views/finance/purchasingrequisition/add.vue
index c11e65c..31d6c3f 100644
--- a/src/views/finance/purchasingrequisition/add.vue
+++ b/src/views/finance/purchasingrequisition/add.vue
@@ -21,12 +21,13 @@
ref="formRef"
:model="dataForm"
:rules="dataRules"
- label-width="140px">
+ label-width="120px"
+ class="compact-form">
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
+
+
-
-
部门自行采购
-
+
+
部门自行采购
+
-
+
+ class="mb16">
+ class="mb16">
+ class="mb16">
+ class="mb16">
-
+
服务类网上商城
@@ -245,7 +258,7 @@
-
+
有
无
@@ -256,11 +269,11 @@
+ class="mb16">
@@ -271,7 +284,7 @@
+ class="mb16">
+ class="mb16">
+ class="mb16">
-
+
- 有
- 无
+ 有
+ 无
-
+
+ class="mb16">
+ class="mb16">
+ class="mb16">
-
+
-
-
学校统一采购
-
-
-
-
-
-
-
-
-
-
+
+
学校统一采购
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
- 下载《项目可行性论证报告模板.doc》
-
-
-
-
-
-
+
+
+
+
+ 下载《项目可行性论证报告模板.doc》
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
-
-
- 下载《单一来源论专家证附件.docx》
-
-
-
-
-
-
+
+
+
+
+ 下载《单一来源论专家证附件.docx》
+
+
+
+
+
+
+
+
+
+
-
-
- 下载《进口产品申请及专家论证意见表.doc》
-
-
-
-
-
-
+
+
+
+
+ 下载《进口产品申请及专家论证意见表.doc》
+
+
+
+
+
+
+
+
+
+
-
-
- 有
- 无
-
-
-
-
-
-
- 请输入三家供应商名称,用逗号或分号分隔
-
-
+
+
+
+
+ 有
+ 无
+
+
+
+
+
+
+
+
+ 请输入三家供应商名称,用逗号或分号分隔
+
+
+
+
-
+
@@ -691,38 +745,45 @@
-
-
-
-
+
+
+
+
+
+
+
-
-
-
- 支持上传zip格式的压缩包文件
-
+
+
+
+
+ 支持上传zip格式的压缩包文件
+
+
+
-
+
@@ -846,6 +907,10 @@ const businessDeptList = ref([]);
const schoolLeaderList = ref([]);
const loading = ref(false);
+// 预算金额输入相关
+const budgetUnit = ref<'yuan' | 'thousand' | 'wan'>('yuan');
+const budgetInputValue = ref(null);
+
// 采购方式ID常量
const PURCHASE_TYPE_IDS = {
BUSINESS_NEGOTIATION: '77b429c146fc9e12ba4c5573da19ad70', // 商务洽谈
@@ -1635,7 +1700,11 @@ const handleSubmit = async () => {
router.push('/finance/purchasingrequisition');
}
} catch (err: any) {
- useMessage().error(err.msg || '提交失败');
+ // 全局拦截器已经显示了错误提示,这里不需要再次显示
+ // 只有当错误没有 msg 时才显示默认错误提示
+ if (!err?.msg) {
+ useMessage().error('提交失败');
+ }
} finally {
loading.value = false;
}
@@ -1698,7 +1767,11 @@ const handleTempStore = async () => {
router.push('/finance/purchasingrequisition');
}
} catch (err: any) {
- useMessage().error(err.msg || '暂存失败');
+ // 全局拦截器已经显示了错误提示,这里不需要再次显示
+ // 只有当错误没有 msg 时才显示默认错误提示
+ if (!err?.msg) {
+ useMessage().error('暂存失败');
+ }
} finally {
loading.value = false;
}
@@ -1718,6 +1791,83 @@ const setCategoryCodePath = () => {
}
};
+// 预算金额单位转换
+const handleBudgetChange = (value: number | null) => {
+ if (value === null || value === undefined) {
+ dataForm.budget = null;
+ return;
+ }
+
+ // 根据单位转换为元
+ switch (budgetUnit.value) {
+ case 'yuan':
+ dataForm.budget = value;
+ break;
+ case 'thousand':
+ dataForm.budget = value * 1000;
+ break;
+ case 'wan':
+ dataForm.budget = value * 10000;
+ break;
+ }
+};
+
+// 预算金额单位变化处理
+const handleBudgetUnitChange = (unit: 'yuan' | 'thousand' | 'wan') => {
+ if (!dataForm.budget) {
+ budgetInputValue.value = null;
+ return;
+ }
+
+ // 根据新单位转换显示值
+ switch (unit) {
+ case 'yuan':
+ budgetInputValue.value = dataForm.budget;
+ break;
+ case 'thousand':
+ budgetInputValue.value = dataForm.budget / 1000;
+ break;
+ case 'wan':
+ budgetInputValue.value = dataForm.budget / 10000;
+ break;
+ }
+};
+
+// 获取预算金额输入框的 placeholder
+const getBudgetPlaceholder = (): string => {
+ switch (budgetUnit.value) {
+ case 'yuan':
+ return '请输入金额';
+ case 'thousand':
+ return '请输入金额(千元)';
+ case 'wan':
+ return '请输入金额(万元)';
+ default:
+ return '请输入金额';
+ }
+};
+
+// 监听 dataForm.budget 变化,同步到 budgetInputValue
+watch(() => dataForm.budget, (newVal) => {
+ if (newVal === null || newVal === undefined) {
+ budgetInputValue.value = null;
+ return;
+ }
+
+ // 根据当前单位转换显示值
+ switch (budgetUnit.value) {
+ case 'yuan':
+ budgetInputValue.value = newVal;
+ break;
+ case 'thousand':
+ budgetInputValue.value = newVal / 1000;
+ break;
+ case 'wan':
+ budgetInputValue.value = newVal / 10000;
+ break;
+ }
+}, { immediate: true });
+
// 监听 categoryTreeData 变化,设置回显路径
watch(() => categoryTreeData.value, () => {
if (dataForm.categoryCode) {
@@ -1780,6 +1930,11 @@ onMounted(async () => {
dataForm.isSpecial = '0';
}
+ // 初始化预算金额显示值
+ if (dataForm.budget) {
+ budgetInputValue.value = dataForm.budget;
+ }
+
// 如果有 categoryCode,设置回显路径
if (dataForm.categoryCode) {
setCategoryCodePath();
@@ -1793,6 +1948,9 @@ onMounted(async () => {
.mb20 {
margin-bottom: 20px;
}
+.mb16 {
+ margin-bottom: 16px;
+}
.mb10 {
margin-bottom: 10px;
}
@@ -1805,18 +1963,94 @@ onMounted(async () => {
color: var(--el-text-color-primary);
padding-bottom: 10px;
border-bottom: 1px solid var(--el-border-color-light);
- margin-bottom: 20px;
+ margin-bottom: 16px;
}
+
+/* 紧凑表单样式 */
+.compact-form {
+ :deep(.el-form-item) {
+ margin-bottom: 16px;
+ }
+
+ :deep(.el-form-item__label) {
+ padding-right: 12px;
+ font-size: 14px;
+ }
+
+ :deep(.el-input__inner),
+ :deep(.el-textarea__inner) {
+ font-size: 14px;
+ }
+}
+
.template-note {
margin-top: 5px;
color: var(--el-text-color-secondary);
+ font-size: 12px;
}
+
+/* 预算金额输入组样式 - 并排显示,无缝连接 */
+.budget-input-group {
+ display: flex;
+ align-items: stretch;
+ width: 100%;
+ transition: all 0.2s ease;
+
+ .budget-input {
+ flex: 1;
+
+ :deep(.el-input__wrapper) {
+ border-radius: 4px 0 0 4px;
+ border-right: none;
+ transition: all 0.2s ease;
+ }
+
+ :deep(.el-input__wrapper:hover) {
+ z-index: 1;
+ border-color: var(--el-color-primary);
+ box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
+ }
+
+ :deep(.el-input__wrapper.is-focus) {
+ z-index: 1;
+ border-color: var(--el-color-primary);
+ box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
+ }
+ }
+
+ .budget-unit-select {
+ width: 100px;
+ flex-shrink: 0;
+ cursor: pointer;
+
+ :deep(.el-input__wrapper) {
+ border-radius: 0 4px 4px 0;
+ border-left: 1px solid var(--el-border-color);
+ margin-left: -1px;
+ transition: all 0.2s ease;
+ }
+
+ :deep(.el-input__wrapper:hover) {
+ z-index: 1;
+ border-color: var(--el-color-primary);
+ box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
+ }
+
+ :deep(.el-input__wrapper.is-focus) {
+ z-index: 1;
+ border-color: var(--el-color-primary);
+ box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
+ }
+ }
+}
+
.form-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
- padding-top: 20px;
+ padding-top: 16px;
border-top: 1px solid var(--el-border-color-light);
+ margin-top: 16px;
}
diff --git a/src/views/finance/purchasingrequisition/form.vue b/src/views/finance/purchasingrequisition/form.vue
index c9937a6..c1fa2b6 100644
--- a/src/views/finance/purchasingrequisition/form.vue
+++ b/src/views/finance/purchasingrequisition/form.vue
@@ -2,12 +2,17 @@
-
-
-
+ draggable
+ :class="{ 'view-dialog': isView }">
+
+
+
@@ -16,41 +21,49 @@
ref="formRef"
:model="dataForm"
:rules="dataRules"
- label-width="140px">
+ :label-width="isView ? '120px' : '140px'"
+ :class="{ 'view-form': isView }">
-
-
-
+
+
+
+
+ {{ dataForm.projectName || '-' }}
+
+ clearable />
-
+
+
+ {{ dataForm.applyDate || '-' }}
+
-
-
-
+
+
+ {{ getDictLabel(fundSourceList, dataForm.fundSource) || '-' }}
+
-
+
+
+
+
+ {{ dataForm.budget ? Number(dataForm.budget).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '-' }}
+
-
-
-
+
+
+ 是
+ 否
+ -
+
-
+
+
+ {{ getDictLabel(isSpecialList, dataForm.isSpecial) || '-' }}
+
-
-
+
+
+
+ {{ getCategoryDisplayText() }}
+
@@ -126,27 +153,34 @@
-
+
-
部门自行采购
-
+ 部门自行采购
+
+
+ {{ dataForm.projectContent || '-' }}
+
+ clearable />
-
+
+
+ {{ getDictLabel(purchaseTypeDeptList, dataForm.purchaseType) || '-' }}
+
-
- 下载商务洽谈表模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载商务洽谈表模版
+
+
-
- 下载市场采购纪要模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载市场采购纪要模版
+
+
+ :class="isView ? 'mb16' : 'mb20'">
-
+
请上传zip格式的压缩包
-
-
+
+
+ {{ dataForm.entrustCenterType === 'service_online' ? '服务类网上商城' : dataForm.entrustCenterType === 'other' ? '其他方式' : '-' }}
+
+
服务类网上商城
其他方式
@@ -281,16 +320,17 @@
v-if="dataForm.entrustCenterType === 'other' && isGoodsCategory"
label="采购需求填报模板"
prop="purchaseRequirementTemplate"
- class="mb20">
-
- 下载《表1:采购需求填报模板》模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《表1:采购需求填报模板》模版
+
+
-
-
+
+
+ {{ dataForm.hasRecommendedSupplier === 'yes' ? '有' : dataForm.hasRecommendedSupplier === 'no' ? '无' : '-' }}
+
+
有
无
@@ -311,29 +354,34 @@
v-if="dataForm.hasRecommendedSupplier === 'yes'"
label="推荐供应商"
prop="recommendedSuppliers"
- class="mb20">
-
-
- 请输入三家供应商名称,用逗号分隔
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+ {{ dataForm.recommendedSuppliers || '-' }}
+
+
+
+
+ 请输入三家供应商名称,用逗号分隔
+
+
-
- 下载《服务商城项目需求模板(邀请比选)》模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《服务商城项目需求模板(邀请比选)》模版
+
+
-
- 下载《服务商城项目需求模板(公开比选)》模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《服务商城项目需求模板(公开比选)》模版
+
+
-
学校统一采购
-
-
-
-
-
-
-
-
-
-
+
学校统一采购
+
+
+
+
+ {{ getDictLabel(purchaseModeSchoolList, dataForm.purchaseMode) || '-' }}
+
+
+
+
+
+
+
+
+
+ {{ getDictLabel(purchaseTypeUnionList, dataForm.purchaseTypeUnion) || '-' }}
+
+
+
+
+
+
+
-
- 下载《项目可行性论证报告模板.doc》
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《项目可行性论证报告模板.doc》
+
+
-
+
-
- 下载《单一来源论专家证附件.docx》
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《单一来源论专家证附件.docx》
+
+
-
+
-
- 下载《进口产品申请及专家论证意见表.doc》
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《进口产品申请及专家论证意见表.doc》
+
+
-
+
-
-
- 下载《采购需求填报模板》模版
-
+
+
+
+ 下载《采购需求填报模板》模版
+
+
-
- 下载《服务商城项目需求模板(公开比选)》模版
-
+ :class="isView ? 'mb16' : 'mb20'">
+
+
+ 下载《服务商城项目需求模板(公开比选)》模版
+
+
+ :class="isView ? 'mb16' : 'mb20'">
-
+
@@ -638,6 +704,19 @@ const dataForm = reactive({
governmentPurchaseIntent: '',
servicePublicSelectSchool: '',
});
+// 定义 props
+const props = defineProps<{
+ dictData?: {
+ fundSourceList?: any[];
+ isCentralizedList?: any[];
+ isSpecialList?: any[];
+ purchaseTypeDeptList?: any[];
+ purchaseModeSchoolList?: any[];
+ purchaseTypeUnionList?: any[];
+ categoryTreeData?: any[];
+ };
+}>();
+
const categoryTreeData = ref([]);
const categoryCodePath = ref([]); // 级联选择器的路径数组
const selectedCategory = ref(null);
@@ -669,6 +748,77 @@ const stepTwoTitle = computed(() => {
return isDeptPurchase.value ? '部门自行采购' : '学校统一采购';
});
+// 获取字典项的label
+const getDictLabel = (list: any[], value: string | number | null | undefined): string => {
+ if (!value || !list || list.length === 0) return '';
+ const item = list.find(item => item.value === value || item.id === value);
+ return item ? (item.label || item.dictLabel || item.name || '') : '';
+};
+
+// 获取品目编码的显示文本(用于查看模式)
+const getCategoryDisplayText = (): string => {
+ if (!dataForm.categoryCode) return '-';
+
+ // 如果 categoryCodePath 已经有值,根据路径查找名称
+ if (categoryCodePath.value && categoryCodePath.value.length > 0) {
+ const names: string[] = [];
+ let currentData = categoryTreeData.value;
+
+ for (const code of categoryCodePath.value) {
+ const found = findCategoryByCode(currentData, code);
+ if (found) {
+ names.push(found.name || found.label || code);
+ currentData = found.children || [];
+ } else {
+ names.push(code);
+ }
+ }
+
+ return names.length > 0 ? names.join(' / ') : dataForm.categoryCode;
+ }
+
+ // 如果 categoryCodePath 没有值,尝试查找路径
+ if (categoryTreeData.value && categoryTreeData.value.length > 0) {
+ const path = findCategoryPath(categoryTreeData.value, dataForm.categoryCode);
+ if (path && path.length > 0) {
+ // 根据路径查找名称
+ const names: string[] = [];
+ let currentData = categoryTreeData.value;
+
+ for (const code of path) {
+ const found = findCategoryByCode(currentData, code);
+ if (found) {
+ names.push(found.name || found.label || code);
+ currentData = found.children || [];
+ } else {
+ names.push(code);
+ }
+ }
+
+ return names.length > 0 ? names.join(' / ') : dataForm.categoryCode;
+ }
+ }
+
+ return dataForm.categoryCode || '-';
+};
+
+// 根据 code 查找分类项
+const findCategoryByCode = (data: any[], code: string): any => {
+ if (!data || !Array.isArray(data) || !code) {
+ return null;
+ }
+ for (const item of data) {
+ if (item && item.code === code) {
+ return item;
+ }
+ if (item && item.children && Array.isArray(item.children) && item.children.length > 0) {
+ const found = findCategoryByCode(item.children, code);
+ if (found) return found;
+ }
+ }
+ return null;
+};
+
// 根据 code 查找完整路径(用于回显)
const findCategoryPath = (data: any[], targetCode: string, path: string[] = []): string[] | null => {
for (const item of data) {
@@ -929,15 +1079,27 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
servicePublicSelectSchool: '',
});
- await Promise.all([
- getCategoryTreeData(),
- getFundSourceDict(),
- getIsCentralizedDict(),
- getIsSpecialDict(),
- getPurchaseTypeDeptDict(),
- getPurchaseModeSchoolDict(),
- getPurchaseTypeUnionDict(),
- ]);
+ // 如果通过 props 传递了字典数据,直接使用;否则调用接口获取
+ if (props.dictData) {
+ fundSourceList.value = props.dictData.fundSourceList || [];
+ isCentralizedList.value = props.dictData.isCentralizedList || [];
+ isSpecialList.value = props.dictData.isSpecialList || [];
+ purchaseTypeDeptList.value = props.dictData.purchaseTypeDeptList || [];
+ purchaseModeSchoolList.value = props.dictData.purchaseModeSchoolList || [];
+ purchaseTypeUnionList.value = props.dictData.purchaseTypeUnionList || [];
+ categoryTreeData.value = props.dictData.categoryTreeData || [];
+ } else {
+ // 如果没有传递字典数据,则调用接口获取(兼容性处理)
+ await Promise.all([
+ getCategoryTreeData(),
+ getFundSourceDict(),
+ getIsCentralizedDict(),
+ getIsSpecialDict(),
+ getPurchaseTypeDeptDict(),
+ getPurchaseModeSchoolDict(),
+ getPurchaseTypeUnionDict(),
+ ]);
+ }
nextTick(() => {
formRef.value?.resetFields();
@@ -946,11 +1108,16 @@ const openDialog = async (type: 'add' | 'edit' | 'view', rowData?: any) => {
getObj(rowData.id)
.then((res) => {
Object.assign(dataForm, res.data || {});
- // 设置品目编码回显路径
+ // 设置品目编码回显路径 - 使用 nextTick 确保 categoryTreeData 已经设置
if (dataForm.categoryCode) {
- setCategoryCodePath();
+ nextTick(() => {
+ setCategoryCodePath();
+ });
}
- if (type === 'edit' || type === 'view') {
+ if (type === 'edit') {
+ currentStep.value = 1;
+ } else if (type === 'view') {
+ // 查看模式下直接显示所有内容,不需要步骤
currentStep.value = 1;
}
})
@@ -1252,11 +1419,20 @@ const handleTempStore = async () => {
};
// 监听 categoryTreeData 变化,设置回显路径
-watch(() => categoryTreeData.value, () => {
- if (dataForm.categoryCode) {
+watch(() => categoryTreeData.value, (newVal) => {
+ if (newVal && newVal.length > 0 && dataForm.categoryCode) {
setCategoryCodePath();
}
-}, { deep: true });
+}, { deep: true, immediate: false });
+
+// 监听 dataForm.categoryCode 变化,设置回显路径(用于查看模式)
+watch(() => dataForm.categoryCode, (newVal) => {
+ if (newVal && categoryTreeData.value && categoryTreeData.value.length > 0) {
+ nextTick(() => {
+ setCategoryCodePath();
+ });
+ }
+});
// 暴露变量
defineExpose({
@@ -1268,6 +1444,9 @@ defineExpose({
.mb20 {
margin-bottom: 20px;
}
+.mb16 {
+ margin-bottom: 16px;
+}
.mb10 {
margin-bottom: 10px;
}
@@ -1285,4 +1464,57 @@ defineExpose({
margin-top: 5px;
color: var(--el-text-color-secondary);
}
+
+/* 查看模式优化样式 */
+:deep(.view-dialog) {
+ .el-dialog__body {
+ max-height: calc(100vh - 150px);
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 20px;
+ }
+}
+
+.view-content {
+ max-height: calc(100vh - 200px);
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+.view-form {
+ /* 查看模式下使用更紧凑的布局 */
+}
+
+.view-form :deep(.el-form-item) {
+ margin-bottom: 16px;
+}
+
+.view-form :deep(.el-form-item__label) {
+ font-weight: 500;
+ color: #606266;
+}
+
+/* 查看模式文本样式 */
+.view-text {
+ color: #303133;
+ font-size: 14px;
+ line-height: 1.5;
+ word-break: break-word;
+}
+
+.view-textarea {
+ white-space: pre-wrap;
+ min-height: 40px;
+ padding: 8px 0;
+}
+
+/* 查看模式下两列布局优化 */
+.view-form :deep(.el-row) {
+ margin-bottom: 0;
+}
+
+.view-form :deep(.el-col) {
+ margin-bottom: 16px;
+}
+
diff --git a/src/views/finance/purchasingrequisition/index.vue b/src/views/finance/purchasingrequisition/index.vue
index cb35355..d67529e 100644
--- a/src/views/finance/purchasingrequisition/index.vue
+++ b/src/views/finance/purchasingrequisition/index.vue
@@ -102,16 +102,10 @@
-
+
- 编号
-
-
-
-
-
- 采购编号
+ 申请单编号
@@ -120,27 +114,57 @@
采购项目名称
-
+
+
+
+ 填报日期
+
+
+
+
+
+ 需求部门
+
+
+
项目类别
- 货物
- 工程
- 服务
- -
+
+ 货物
+ 工程
+ 服务
+
+ {{ scope.row.categoryName }}
+
+
+ {{ scope.row.categoryCode }}
+
+
-
+
- 预算金额
+ 项目预算
{{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }}
+
+
+
+ 是否特殊
+
+
+ 是
+ 否
+ -
+
+
@@ -152,10 +176,10 @@
-
-
+
- 状态
+ 审核状态
撤回
@@ -167,13 +191,7 @@
-
-
-
-
- 创建时间
-
-
-
+
@@ -217,7 +235,8 @@
+ />
-
+