|
|
@@ -1,10 +1,5 @@
|
|
|
<template>
|
|
|
- <div class="safety-platform-container">
|
|
|
- <header class="safety-platform-container__header">
|
|
|
- <BreadcrumbBack />
|
|
|
- <span class="breadcrumb-title">{{ headerTitle }}</span>
|
|
|
- </header>
|
|
|
- <main class="safety-platform-container__main">
|
|
|
+ <main class="safety-platform-container__main">
|
|
|
<el-form
|
|
|
ref="formRef"
|
|
|
:model="form"
|
|
|
@@ -30,7 +25,7 @@
|
|
|
<el-table-column type="index" label="编号" width="100" align="center" />
|
|
|
<el-table-column label="劳防用品名称" min-width="140">
|
|
|
<template #default="{ row }">
|
|
|
- <span v-if="isViewMode || isAuditMode">{{ row.ppeName || '-' }}</span>
|
|
|
+ <span v-if="isViewMode || isAuditMode">{{ row.ppeName || row.equipmentName || '-' }}</span>
|
|
|
<el-select
|
|
|
v-else
|
|
|
v-model="row.ppeName"
|
|
|
@@ -63,7 +58,7 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="物品尺寸/鞋码" min-width="150">
|
|
|
<template #default="{ row }">
|
|
|
- <span v-if="isViewMode || isAuditMode">{{ row.sizeOrShoeSize || '-' }}</span>
|
|
|
+ <span v-if="isViewMode || isAuditMode">{{ row.sizeOrShoeSize || row.specSize || '-' }}</span>
|
|
|
<el-input
|
|
|
v-else
|
|
|
v-model="row.sizeOrShoeSize"
|
|
|
@@ -74,7 +69,7 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="需求数量" min-width="150">
|
|
|
<template #default="{ row }">
|
|
|
- <span v-if="isViewMode || isAuditMode">{{ row.requiredQty ?? '-' }}</span>
|
|
|
+ <span v-if="isViewMode || isAuditMode">{{ row.requiredQty ?? row.applyNum ?? '-' }}</span>
|
|
|
<el-input-number
|
|
|
v-else
|
|
|
v-model="row.requiredQty"
|
|
|
@@ -88,7 +83,7 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="规格、型号、类型" min-width="200">
|
|
|
<template #default="{ row }">
|
|
|
- <span v-if="isViewMode || isAuditMode">{{ row.specModelType || '-' }}</span>
|
|
|
+ <span v-if="isViewMode || isAuditMode">{{ row.specModelType || row.model || '-' }}</span>
|
|
|
<el-input
|
|
|
v-else
|
|
|
v-model="row.specModelType"
|
|
|
@@ -170,24 +165,23 @@
|
|
|
</el-button>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
- </main>
|
|
|
- <footer class="safety-platform-container__footer">
|
|
|
- <el-button @click="router.back()">返回</el-button>
|
|
|
- <template v-if="isCreateMode || isEditMode">
|
|
|
- <el-button type="primary" :loading="submitting" @click="handleSubmit">
|
|
|
- {{ isCreateMode ? '提交' : '保存' }}
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- <template v-if="isAuditMode">
|
|
|
- <el-button type="success" :loading="auditSubmitting" @click="handleAuditPass">
|
|
|
- 审核通过
|
|
|
- </el-button>
|
|
|
- <el-button type="danger" :loading="auditSubmitting" @click="showRejectDialog = true">
|
|
|
- 审核不通过
|
|
|
- </el-button>
|
|
|
- </template>
|
|
|
- </footer>
|
|
|
- </div>
|
|
|
+ </main>
|
|
|
+ <footer class="safety-platform-container__footer">
|
|
|
+ <el-button @click="router.back()">返回</el-button>
|
|
|
+ <template v-if="isCreateMode || isEditMode">
|
|
|
+ <el-button type="primary" :loading="submitting" @click="handleSubmit">
|
|
|
+ {{ isCreateMode ? '提交' : '保存' }}
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ <template v-if="isAuditMode">
|
|
|
+ <el-button type="success" :loading="auditSubmitting" @click="handleAuditPass">
|
|
|
+ 审核通过
|
|
|
+ </el-button>
|
|
|
+ <el-button type="danger" :loading="auditSubmitting" @click="showRejectDialog = true">
|
|
|
+ 审核不通过
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </footer>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
@@ -196,7 +190,6 @@
|
|
|
import { ElMessage } from 'element-plus';
|
|
|
import type { FormInstance, FormRules } from 'element-plus';
|
|
|
import { Plus, Minus } from '@element-plus/icons-vue';
|
|
|
- import BreadcrumbBack from '@/components/BreadcrumbBack.vue';
|
|
|
import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
|
|
|
import type { FileItem } from '@/components/UploadFiles/types';
|
|
|
import { queryPersonalProtectiveEquipmentList } from '@/api/production-safety/personal-protective-equipment';
|
|
|
@@ -208,6 +201,8 @@
|
|
|
auditPurchaseApply,
|
|
|
type PersonalProtectiveEquipmentPurchaseApply,
|
|
|
type PurchaseApplyItem,
|
|
|
+ type PpePurchaseApplyDetail,
|
|
|
+ type SavePpePurchaseApplyReq,
|
|
|
} from '@/api/production-safety/personal-protective-equipment-purchase-apply';
|
|
|
import type { QueryPageRequest } from '@/types/basic-query';
|
|
|
|
|
|
@@ -221,21 +216,12 @@
|
|
|
|
|
|
const operate = computed(() => (route.query.operate as string) || 'inventory-create');
|
|
|
const currentId = computed(() => Number(route.query.id));
|
|
|
-
|
|
|
- const headerTitle = computed(() => {
|
|
|
- switch (operate.value) {
|
|
|
- case 'inventory-create':
|
|
|
- return '新增劳防用品采购申请';
|
|
|
- case 'inventory-edit':
|
|
|
- return '编辑劳防用品采购申请';
|
|
|
- case 'inventory-view':
|
|
|
- return '查看劳防用品采购申请';
|
|
|
- case 'audit':
|
|
|
- return '审核劳防用品采购申请';
|
|
|
- default:
|
|
|
- return '劳防用品采购申请详情';
|
|
|
- }
|
|
|
- });
|
|
|
+ /** 从列表带入的申请单号/申请人/部门(无主表查询接口时用于展示) */
|
|
|
+ const mainFromQuery = computed(() => ({
|
|
|
+ applyCode: route.query.applyCode as string | undefined,
|
|
|
+ applicantName: route.query.applicantName as string | undefined,
|
|
|
+ deptName: route.query.deptName as string | undefined,
|
|
|
+ }));
|
|
|
|
|
|
const isCreateMode = computed(() => operate.value === 'inventory-create');
|
|
|
const isEditMode = computed(() => operate.value === 'inventory-edit');
|
|
|
@@ -266,14 +252,17 @@
|
|
|
};
|
|
|
|
|
|
function getRowFileList(row: PurchaseApplyItem): FileItem[] {
|
|
|
+ if (row.pictureUrl && typeof row.pictureUrl === 'string') {
|
|
|
+ return [{ fileId: 0, fileName: '样式图', fileType: 'image', fileSize: '', fileUrl: row.pictureUrl }];
|
|
|
+ }
|
|
|
if (!row.stylePhoto) return [];
|
|
|
try {
|
|
|
const parsed = typeof row.stylePhoto === 'string' ? JSON.parse(row.stylePhoto) : row.stylePhoto;
|
|
|
const arr = Array.isArray(parsed) ? parsed : [parsed];
|
|
|
return arr.map((f: any) => ({
|
|
|
fileId: f.fileId ?? 0,
|
|
|
- fileName: f.fileName ?? '',
|
|
|
- fileType: f.fileType ?? 'pdf',
|
|
|
+ fileName: f.fileName ?? '样式图',
|
|
|
+ fileType: f.fileType ?? 'image',
|
|
|
fileSize: f.fileSize ?? '',
|
|
|
fileUrl: f.fileUrl,
|
|
|
}));
|
|
|
@@ -282,8 +271,9 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /** 查看/审核时样式照片列仅显示文件名文本 */
|
|
|
+ /** 查看/审核时样式照片列仅显示文件名或链接文本 */
|
|
|
function getStylePhotoDisplay(row: PurchaseApplyItem): string {
|
|
|
+ if (row.pictureUrl) return row.pictureUrl;
|
|
|
const list = getRowFileList(row);
|
|
|
if (!list.length) return '-';
|
|
|
return list.map((f) => f.fileName).filter(Boolean).join('、') || '-';
|
|
|
@@ -295,9 +285,51 @@
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ /** 后端明细行 → 表单行 */
|
|
|
+ function detailToItem(d: PpePurchaseApplyDetail): PurchaseApplyItem {
|
|
|
+ return {
|
|
|
+ ...defaultItem(),
|
|
|
+ id: d.id,
|
|
|
+ ppeApplyId: d.ppeApplyId,
|
|
|
+ equipmentId: d.equipmentId,
|
|
|
+ equipmentName: d.equipmentName,
|
|
|
+ ppeName: d.equipmentName,
|
|
|
+ ppeId: d.equipmentId,
|
|
|
+ specSize: d.specSize,
|
|
|
+ sizeOrShoeSize: d.specSize,
|
|
|
+ applyNum: d.applyNum,
|
|
|
+ requiredQty: d.applyNum,
|
|
|
+ model: d.model,
|
|
|
+ specModelType: d.model,
|
|
|
+ unitPrice: d.unitPrice,
|
|
|
+ pictureUrl: d.pictureUrl,
|
|
|
+ stylePhoto: d.pictureUrl ?? '',
|
|
|
+ remark: d.remark,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 表单行 → 后端明细行 */
|
|
|
+ function itemToDetail(it: PurchaseApplyItem): PpePurchaseApplyDetail {
|
|
|
+ return {
|
|
|
+ id: it.id,
|
|
|
+ ppeApplyId: it.ppeApplyId ?? currentId.value,
|
|
|
+ equipmentId: it.equipmentId ?? it.ppeId,
|
|
|
+ equipmentName: it.equipmentName ?? it.ppeName,
|
|
|
+ specSize: it.specSize ?? it.sizeOrShoeSize,
|
|
|
+ applyNum: it.applyNum ?? it.requiredQty,
|
|
|
+ model: it.model ?? it.specModelType,
|
|
|
+ unitPrice: it.unitPrice,
|
|
|
+ pictureUrl: it.pictureUrl ?? (typeof it.stylePhoto === 'string' ? it.stylePhoto : undefined),
|
|
|
+ remark: it.remark,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
function onPpeSelect(row: PurchaseApplyItem, ppeName: string) {
|
|
|
const found = ppeOptions.value.find((p) => p.ppeName === ppeName);
|
|
|
- if (found?.id) row.ppeId = found.id;
|
|
|
+ if (found?.id) {
|
|
|
+ row.ppeId = found.id;
|
|
|
+ row.equipmentId = found.id;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function addRow() {
|
|
|
@@ -326,10 +358,12 @@
|
|
|
async function getDetail() {
|
|
|
if (!currentId.value) return;
|
|
|
try {
|
|
|
+ form.applyNo = mainFromQuery.value.applyCode ?? '';
|
|
|
const res = await queryPurchaseApplyDetail(currentId.value);
|
|
|
- if (res) {
|
|
|
- form.applyNo = res.applyNo ?? '';
|
|
|
- form.itemList = (res.itemList && res.itemList.length) ? res.itemList.map((it) => ({ ...defaultItem(), ...it })) : [defaultItem()];
|
|
|
+ if (res && Array.isArray(res) && res.length) {
|
|
|
+ form.itemList = res.map((d) => detailToItem(d));
|
|
|
+ } else if (res && Array.isArray(res)) {
|
|
|
+ form.itemList = [defaultItem()];
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.error('获取采购申请详情失败:', e);
|
|
|
@@ -337,29 +371,24 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function buildSubmitPayload() {
|
|
|
- const itemList = form.itemList.map((it) => ({
|
|
|
- ppeName: it.ppeName,
|
|
|
- ppeId: it.ppeId,
|
|
|
- stylePhoto: it.stylePhoto,
|
|
|
- sizeOrShoeSize: it.sizeOrShoeSize,
|
|
|
- requiredQty: it.requiredQty,
|
|
|
- specModelType: it.specModelType,
|
|
|
- unitPrice: it.unitPrice,
|
|
|
- productNo: it.productNo,
|
|
|
- remark: it.remark,
|
|
|
- }));
|
|
|
+ function buildSubmitPayload(): SavePpePurchaseApplyReq {
|
|
|
+ const ppePurchaseApplyDetails = form.itemList
|
|
|
+ .filter((it) => it.ppeName || it.equipmentName)
|
|
|
+ .map((it) => itemToDetail(it));
|
|
|
return {
|
|
|
id: currentId.value || undefined,
|
|
|
- applyNo: form.applyNo || undefined,
|
|
|
- itemList,
|
|
|
+ applyCode: form.applyNo ? Number(form.applyNo) : undefined,
|
|
|
+ applicantName: mainFromQuery.value.applicantName,
|
|
|
+ deptName: mainFromQuery.value.deptName,
|
|
|
+ saveOrSubmit: isCreateMode.value ? 1 : 0,
|
|
|
+ ppePurchaseApplyDetails,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
async function handleSubmit() {
|
|
|
const valid = await formRef.value?.validate().catch(() => false);
|
|
|
if (!valid) return;
|
|
|
- if (!form.itemList.length || form.itemList.every((it) => !it.ppeName)) {
|
|
|
+ if (!form.itemList.length || form.itemList.every((it) => !it.ppeName && !it.equipmentName)) {
|
|
|
ElMessage.warning('请至少填写一条劳防用品明细');
|
|
|
return;
|
|
|
}
|
|
|
@@ -367,10 +396,10 @@
|
|
|
try {
|
|
|
const payload = buildSubmitPayload();
|
|
|
if (isCreateMode.value) {
|
|
|
- await savePurchaseApply(payload as PersonalProtectiveEquipmentPurchaseApply);
|
|
|
+ await savePurchaseApply(payload);
|
|
|
ElMessage.success('提交成功');
|
|
|
} else {
|
|
|
- await updatePurchaseApply(payload as PersonalProtectiveEquipmentPurchaseApply);
|
|
|
+ await updatePurchaseApply(payload);
|
|
|
ElMessage.success('保存成功');
|
|
|
}
|
|
|
router.back();
|