让步接收审批前端代码
This commit is contained in:
parent
57c7eb92eb
commit
34df51c8ce
@ -402,8 +402,31 @@ export const fileApi = {
|
||||
return request({
|
||||
url: '/sys/file/upload',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
data: formData
|
||||
// headers: { 'Content-Type': 'multipart/form-data' }
|
||||
})
|
||||
},
|
||||
|
||||
uploadAndDingding(file: File, path?: string, groupId?: number | null): Promise<SysFile>{
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
if (path) {
|
||||
formData.append('path', path)
|
||||
}
|
||||
if (groupId !== undefined && groupId !== null && groupId > 0) {
|
||||
formData.append('groupId', groupId.toString())
|
||||
}
|
||||
return request({
|
||||
url: '/sys/file/uploadAndDingding',
|
||||
method: 'post',
|
||||
data: formData
|
||||
})
|
||||
},
|
||||
|
||||
getApprovalSpaceId() {
|
||||
return request({
|
||||
url:'sys/file/getApprovalSpaceId',
|
||||
method:'get',
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@ -125,6 +125,12 @@ service.interceptors.request.use(
|
||||
if (userStore.token) {
|
||||
config.headers['Authorization'] = userStore.token
|
||||
}
|
||||
|
||||
if (config.data instanceof FormData) {
|
||||
// 文件上传:不设置 JSON 请求头、不序列化,交给浏览器自动处理 multipart
|
||||
return config
|
||||
}
|
||||
|
||||
config.headers["Content-Type"] = 'application/json;charset=utf-8'
|
||||
config.data = config.data instanceof Object ? JSON.stringify(config.data) : config.data
|
||||
return config
|
||||
|
||||
@ -49,13 +49,28 @@
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
:row-key="(row) => row.id"
|
||||
:scroll-x="1200"
|
||||
@update:page="handlePageChange"
|
||||
@update:page-size="handlePageSizeChange"
|
||||
@update:checked-row-keys="handleCheck"
|
||||
size="small"
|
||||
remote
|
||||
:border="false"
|
||||
:single-line="false"
|
||||
striped
|
||||
/>
|
||||
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
|
||||
<n-pagination
|
||||
v-model:page="pagination.page"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:item-count="pagination.itemCount"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
show-size-picker
|
||||
show-quick-jumper
|
||||
@update:page="handlePageChange"
|
||||
@update:page-size="handlePageSizeChange"
|
||||
>
|
||||
<template #prefix>
|
||||
共 {{ pagination.itemCount }} 条
|
||||
</template>
|
||||
</n-pagination>
|
||||
</div>
|
||||
</n-card>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
@ -125,13 +140,13 @@
|
||||
</template>
|
||||
</n-modal>
|
||||
|
||||
<!-- 审批纪律弹窗 -->
|
||||
<n-modal v-model:show="recordModalVisible" preset="card" title="审批记录" style="width: 800px">
|
||||
<!-- 审批记录弹窗 -->
|
||||
<n-modal v-model:show="recordModalVisible" ref="exportWrapRef" preset="card" title="审批记录" style="width: 800px">
|
||||
<n-card bordered style="width:100%;max-width:800px;padding:24px;position:relative;">
|
||||
<div class="header-bar" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;">
|
||||
<span style="font-size:20sp;color:#666">审批编号: {{ detailModel?.businessId }}</span>
|
||||
<div>
|
||||
<n-icon style="font-size:22px;margin:0 6px;cursor:pointer" ><DownloadOutline /></n-icon>
|
||||
<n-icon style="font-size:22px;margin:0 6px;cursor:pointer" @click="downloadOutline()" ><DownloadOutline /></n-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div style="padding:10px 0;">
|
||||
@ -214,6 +229,12 @@ import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline,
|
||||
import { concessionApplyApi, DetailModel, type ConcessionApply } from '@/api/concessionApply'
|
||||
import { dictDataApi } from '@/api/org'
|
||||
|
||||
import html2canvas from 'html2canvas'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import * as dd from 'dingtalk-jsapi';
|
||||
|
||||
|
||||
|
||||
|
||||
const message = useMessage()
|
||||
const dialog = useDialog()
|
||||
@ -551,6 +572,149 @@ const getRemark=(item) =>{
|
||||
|
||||
}
|
||||
|
||||
async function downloadOutline() {
|
||||
const model = detailModel.value
|
||||
if (!model) {
|
||||
alert("暂无审批数据")
|
||||
return
|
||||
}
|
||||
|
||||
// 1. 动态拼接审批记录行 HTML(彻底修复表格结构)
|
||||
let recordHtml = ""
|
||||
const recordList = model.approveRecord || []
|
||||
recordList.forEach((item, index) => {
|
||||
const remark = item.remark ?? ""
|
||||
// 第一条记录需要带左侧的「审批人」单元格,后续记录只显示右侧内容
|
||||
if (index === 0) {
|
||||
recordHtml += `
|
||||
<tr>
|
||||
<td style="background: #f5f5f5;" rowspan="${recordList.length}">审批人</td>
|
||||
<td colspan="3">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
|
||||
<div>
|
||||
${remark ? remark + "<br>" : ""}
|
||||
${item.username ?? "未知人员"} ${item.operationResult ?? ""}
|
||||
</div>
|
||||
<span style="color: #888; white-space: nowrap;">${item.date ?? ""}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
`
|
||||
} else {
|
||||
// 后续记录只需要右侧的内容单元格,左侧被 rowspan 合并
|
||||
recordHtml += `
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-start;">
|
||||
<div>
|
||||
${remark ? remark + "<br>" : ""}
|
||||
${item.username ?? "未知人员"} ${item.operationResult ?? ""}
|
||||
</div>
|
||||
<span style="color: #888; white-space: nowrap;">${item.date ?? ""}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
`
|
||||
}
|
||||
})
|
||||
|
||||
// 2. 动态印章
|
||||
let sealText = ""
|
||||
let sealBorder = "#00b42a"
|
||||
let sealColor = "#00b42a"
|
||||
if (model.approveResult === "已通过") {
|
||||
sealText = "已通过"
|
||||
} else if (model.approveResult === "已驳回") {
|
||||
sealText = "已驳回"
|
||||
sealBorder = "#f53f3f"
|
||||
sealColor = "#f53f3f"
|
||||
} else if (model.approveResult === "已撤销") {
|
||||
sealText = "已撤销"
|
||||
sealBorder = "#ff7d00"
|
||||
sealColor = "#ff7d00"
|
||||
}
|
||||
|
||||
const createUser = recordList[0]?.username ?? ""
|
||||
const nowTime = new Date().toLocaleString()
|
||||
|
||||
// 3. 完整 HTML(修复了表格结构)
|
||||
const html = `
|
||||
<div style="width: 750px; margin: 0 auto; font-family: SimSun, serif; position: relative; background: #fff;">
|
||||
<div style="text-align: center; font-size: 22px; font-weight: bold; margin-bottom: 20px;">通用审批</div>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 14px; margin-bottom: 20px; align-items: center;">
|
||||
<span>${model.title ?? ""}</span>
|
||||
<span>创建时间:${model.createTime ?? ""}</span>
|
||||
</div>
|
||||
<table border="1" cellpadding="8" cellspacing="0" style="width: 100%; border-collapse: collapse; font-size: 14px;">
|
||||
<tr>
|
||||
<td style="width: 120px; background: #f5f5f5;">审批编号</td>
|
||||
<td colspan="3">${model.businessId ?? ""}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: #f5f5f5;">创建人</td>
|
||||
<td>${createUser}</td>
|
||||
<td style="width: 120px; background: #f5f5f5;">创建人部门</td>
|
||||
<td>${model.deptName ?? ""}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: #f5f5f5;">申请内容</td>
|
||||
<td colspan="3">${model.content ?? ""}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: #f5f5f5;">审批详情</td>
|
||||
<td colspan="3">${model.approveResult ?? ""}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background: #f5f5f5;">附件</td>
|
||||
<td colspan="3"></td>
|
||||
</tr>
|
||||
${recordHtml}
|
||||
</table>
|
||||
<div style="display: flex; justify-content: space-between; font-size: 12px; margin-top: 20px;">
|
||||
<span>打印时间:${nowTime}</span>
|
||||
<span>打印人:${createUser}</span>
|
||||
</div>
|
||||
${sealText ? `
|
||||
<div style="position: absolute; top: 100px; right: 20px; width: 100px; height: 100px; border: 3px solid ${sealBorder}; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: ${sealColor}; font-size: 20px; font-weight: bold; transform: rotate(15deg);">
|
||||
${sealText}
|
||||
</div>
|
||||
` : ""}
|
||||
</div>
|
||||
`
|
||||
|
||||
// ========== 导出PDF逻辑 ==========
|
||||
const tempDiv = document.createElement('div')
|
||||
tempDiv.innerHTML = html
|
||||
tempDiv.style.position = 'absolute'
|
||||
tempDiv.style.left = '-9999px'
|
||||
tempDiv.style.top = '0'
|
||||
document.body.appendChild(tempDiv)
|
||||
|
||||
try {
|
||||
const canvas = await html2canvas(tempDiv, {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
logging: false,
|
||||
backgroundColor: '#ffffff',
|
||||
allowTaint: true
|
||||
})
|
||||
|
||||
const imgData = canvas.toDataURL('image/jpeg', 1.0)
|
||||
const pdf = new jsPDF('p', 'mm', 'a4')
|
||||
const a4W = 210
|
||||
const imgH = (canvas.height * a4W) / canvas.width
|
||||
|
||||
pdf.addImage(imgData, 'JPEG', 0, 0, a4W, imgH)
|
||||
pdf.save(`通用审批_${model.businessId || "审批记录"}.pdf`)
|
||||
} catch (err) {
|
||||
console.error("导出失败:", err)
|
||||
alert("导出PDF失败")
|
||||
} finally {
|
||||
document.body.removeChild(tempDiv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
loadDictOptions()
|
||||
|
||||
@ -384,6 +384,7 @@ import {fileApi} from '@/api/system1'
|
||||
import value = Language.value;
|
||||
import {QcResultDetail} from "@/api/qcResultDetail.ts";
|
||||
import router from "@/router";
|
||||
import dd from 'dingtalk-jsapi'
|
||||
|
||||
const message = useMessage()
|
||||
const dialog = useDialog()
|
||||
@ -1014,20 +1015,25 @@ async function handleSubmitResultDetail() {
|
||||
|
||||
//提交部分判定明细
|
||||
function submitBFResultDetail(row) {
|
||||
Object.assign(formDetailOKData, reactive<QcResultDetail>({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 }))
|
||||
Object.assign(formDetailScrapData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 }))
|
||||
Object.assign(formDetailReworkData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 }))
|
||||
Object.assign(formDetailConcessionData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 4,handleAction:'让步接收',actionStatus:1 }))
|
||||
// Object.assign(formDetailOKData, reactive<QcResultDetail>({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 }))
|
||||
// Object.assign(formDetailScrapData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 }))
|
||||
// Object.assign(formDetailReworkData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 }))
|
||||
// Object.assign(formDetailConcessionData, reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 4,handleAction:'让步接收',actionStatus:1 }))
|
||||
|
||||
if (row.traceType != 1) {
|
||||
traceCodeShow.value = true
|
||||
}
|
||||
submitFlag.value = false
|
||||
submitDetailModalVisible.value = true
|
||||
formDetailOKData.qcId = row.id
|
||||
formDetailScrapData.qcId = row.id
|
||||
formDetailReworkData.qcId = row.id
|
||||
formDetailConcessionData.qcId = row.id
|
||||
// submitDetailModalVisible.value = true
|
||||
// formDetailOKData.qcId = row.id
|
||||
// formDetailScrapData.qcId = row.id
|
||||
// formDetailReworkData.qcId = row.id
|
||||
// formDetailConcessionData.qcId = row.id
|
||||
|
||||
|
||||
//version-2
|
||||
let path = `/qc/submitDetail/${row.qcNo}/${row.id}/${submitFlag.value}/${traceCodeShow.value}`
|
||||
router.push(path)
|
||||
|
||||
}
|
||||
|
||||
@ -1058,8 +1064,14 @@ function handleCancelQuality(row) {
|
||||
}
|
||||
|
||||
|
||||
const isDingTalkEnv = () => {
|
||||
// 确保 dd 对象存在,并且其 platform 属性不是 'notInDingTalk'
|
||||
return typeof dd !== 'undefined' && dd.env && dd.env.platform !== 'notInDingTalk';
|
||||
};
|
||||
|
||||
//上传附件
|
||||
async function handleUploadChange ({ file, fileList: list }: any) {
|
||||
|
||||
// 允许的后缀白名单
|
||||
const allowExt = ['pdf','doc','docx','xls','xlsx','jpg','jpeg','png','gif','bmp']
|
||||
const invalidFiles:any[] = []
|
||||
@ -1081,7 +1093,7 @@ async function handleUploadChange ({ file, fileList: list }: any) {
|
||||
fileList.value = list
|
||||
console.log('选中的文件列表', fileList.value)
|
||||
|
||||
// ✅关键:只筛选【pending等待上传】的文件,success/error/removed全部跳过,不再重复上传
|
||||
|
||||
const validList = list.filter(item =>
|
||||
item.status === 'pending' && item.file && item.status !== 'error'
|
||||
)
|
||||
@ -1096,19 +1108,20 @@ async function handleUploadChange ({ file, fileList: list }: any) {
|
||||
|
||||
const uploadPromises = validList.map(async (item: any) => {
|
||||
try {
|
||||
const res = await fileApi.upload(item.file, null, null)
|
||||
const res = await fileApi.uploadAndDingding(item.file, null, null)
|
||||
uploadFiles.value.push(res)
|
||||
const targetFile = fileList.value.find(f => f.id === item.id)
|
||||
if (targetFile) {
|
||||
targetFile.status = 'success'
|
||||
targetFile.percentage = 100
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('文件上传失败', error)
|
||||
const targetFile = fileList.value.find(f => f.id === item.id)
|
||||
if (targetFile) targetFile.status = 'error'
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(uploadPromises)
|
||||
}
|
||||
|
||||
|
||||
281
src/views/biz/qualityTesting/submitDetail.vue
Normal file
281
src/views/biz/qualityTesting/submitDetail.vue
Normal file
@ -0,0 +1,281 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<n-card :title="title" style="margin-bottom: 16px">
|
||||
<n-tabs type="card" animated>
|
||||
<n-tab-pane name="合格" tab="合格">
|
||||
<n-form ref="formRef" :model="formDetailOKData" label-placement="left" label-width="100px">
|
||||
<n-grid x-gap="12" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="判定数量" path="qty">
|
||||
<n-input-number v-model:value="formDetailOKData.qty" placeholder="请输入判定数量" :min="0" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="批次号或SN码" path="traceCode" v-show="traceCodeShow">
|
||||
<n-input v-model:value="formDetailOKData.traceCode" placeholder="请输入批次号或SN码(启用追溯时必填)" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid x-gap="8" :cols="3">
|
||||
<n-gi>
|
||||
<n-form-item label="备注" >
|
||||
<n-input
|
||||
v-model:value="formDetailOKData.remark"
|
||||
type="textarea"
|
||||
placeholder="输入备注原因"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
</n-form>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="报废" tab="报废">
|
||||
<n-form ref="formRef" :model="formDetailScrapData" label-placement="left" label-width="100px">
|
||||
<n-grid x-gap="12" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="判定数量" path="qty">
|
||||
<n-input-number v-model:value="formDetailScrapData.qty" placeholder="请输入判定数量" :min="0" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="批次号或SN码" path="traceCode" v-show="traceCodeShow">
|
||||
<n-input v-model:value="formDetailScrapData.traceCode" placeholder="请输入批次号或SN码(启用追溯时必填)" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid x-gap="8" :cols="3">
|
||||
<n-gi>
|
||||
<n-form-item label="备注" >
|
||||
<n-input
|
||||
v-model:value="formDetailScrapData.remark"
|
||||
type="textarea"
|
||||
placeholder="输入备注原因"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
</n-form>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="返工" tab="返工">
|
||||
<n-form ref="formRef" :model="formDetailReworkData" label-placement="left" label-width="100px">
|
||||
<n-grid x-gap="12" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="判定数量" path="qty">
|
||||
<n-input-number v-model:value="formDetailReworkData.qty" placeholder="请输入判定数量" :min="0" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="批次号或SN码" path="traceCode" v-show="traceCodeShow">
|
||||
<n-input v-model:value="formDetailReworkData.traceCode" placeholder="请输入批次号或SN码(启用追溯时必填)" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid x-gap="8" :cols="3">
|
||||
<n-gi>
|
||||
<n-form-item label="备注" >
|
||||
<n-input
|
||||
v-model:value="formDetailReworkData.remark"
|
||||
type="textarea"
|
||||
placeholder="输入备注原因"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</n-form>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="让步接收" tab="让步接收">
|
||||
<n-form ref="formRef" :model="formDetailConcessionData" label-placement="left" label-width="100px">
|
||||
<n-grid x-gap="12" :cols="2">
|
||||
<n-gi>
|
||||
<n-form-item label="判定数量" path="qty">
|
||||
<n-input-number v-model:value="formDetailConcessionData.qty" placeholder="请输入判定数量" :min="0" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="批次号或SN码" path="traceCode" v-show="traceCodeShow">
|
||||
<n-input v-model:value="formDetailConcessionData.traceCode" placeholder="请输入批次号或SN码(启用追溯时必填)" />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid x-gap="8" :cols="3">
|
||||
<n-gi>
|
||||
<n-form-item label="备注" >
|
||||
<n-input
|
||||
v-model:value="formDetailConcessionData.remark"
|
||||
type="textarea"
|
||||
placeholder="输入备注原因"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid x-gap="8" :cols="3">
|
||||
<n-gi>
|
||||
<n-form-item label="附件">
|
||||
<n-upload
|
||||
multiple
|
||||
directory-dnd
|
||||
:max="5"
|
||||
:action="null"
|
||||
:custom-request="()=>{}"
|
||||
@change="handleUploadChange"
|
||||
:file-list="fileList"
|
||||
accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png,.gif,.bmp"
|
||||
:max-size="10*1024*1024"
|
||||
>
|
||||
<n-upload-dragger>
|
||||
<div style="margin-bottom: 12px">
|
||||
<n-icon size="48" :depth="3">
|
||||
<ArchiveIcon />
|
||||
</n-icon>
|
||||
</div>
|
||||
<n-text style="font-size: 16px">
|
||||
点击或者拖动文件到该区域来上传
|
||||
</n-text>
|
||||
<n-p depth="3" style="margin: 8px 0 0 0">
|
||||
仅支持 PDF、DOC、DOCX、XLS、XLSX、JPG、PNG、GIF,单文件最大10MB
|
||||
</n-p>
|
||||
</n-upload-dragger>
|
||||
</n-upload>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
</n-form>
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
|
||||
|
||||
<n-space justify="center" style="width: 100%; margin-top: 16px;">
|
||||
<n-button size="small" @click="handleReset">重置</n-button>
|
||||
<n-button type="primary" size="small" @click="handleSubmitResultDetail">提交</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, h, onMounted } from 'vue'
|
||||
import {
|
||||
NButton, NSpace, NIcon, NUpload,NTag, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions,
|
||||
NDropdown
|
||||
} from 'naive-ui'
|
||||
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
import {QcResultDetail} from "@/api/qcResultDetail.ts";
|
||||
import {fileApi} from '@/api/system1'
|
||||
import { qualityTestingApi, type QualityTesting } from '@/api/qualityTesting'
|
||||
|
||||
const message = useMessage()
|
||||
const route = useRoute()
|
||||
const qcId =ref( Number(route.params.id))
|
||||
|
||||
const traceCodeShow = ref(route.params.traceCodeShow === 'true')
|
||||
const submitFlag = ref(route.params.submitFlag === 'true')
|
||||
|
||||
//提交附件
|
||||
const fileList = ref<any[]>([])
|
||||
const uploadFiles = ref<File[]>([])
|
||||
|
||||
const title = ref(`质检编号: ${route.params.qcNo}`)
|
||||
|
||||
|
||||
const defaultFormDetailData:QcResultDetail = {
|
||||
qcId: undefined,
|
||||
resultType: undefined,
|
||||
qty: 0,
|
||||
traceCode: undefined,
|
||||
defectCode: undefined,
|
||||
handleAction: undefined,
|
||||
actionStatus: undefined
|
||||
}
|
||||
|
||||
const formDetailOKData = reactive<QcResultDetail>({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 })
|
||||
const formDetailScrapData = reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 })
|
||||
const formDetailReworkData = reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 })
|
||||
const formDetailConcessionData = reactive<QcResultDetail>({ ...defaultFormDetailData,resultType: 4,handleAction:'让步接收',actionStatus:1 })
|
||||
|
||||
|
||||
async function handleSubmitResultDetail() {
|
||||
|
||||
formDetailConcessionData.files = uploadFiles.value
|
||||
|
||||
const submitParam = [
|
||||
formDetailOKData,
|
||||
formDetailScrapData,
|
||||
formDetailReworkData,
|
||||
formDetailConcessionData]
|
||||
|
||||
|
||||
submitFlag.value? await qualityTestingApi.submit(submitParam) : await qualityTestingApi.submitBF(submitParam)
|
||||
|
||||
message.success('提交成功')
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handleUploadChange ({ file, fileList: list }: any) {
|
||||
|
||||
// 允许的后缀白名单
|
||||
const allowExt = ['pdf','doc','docx','xls','xlsx','jpg','jpeg','png','gif','bmp']
|
||||
const invalidFiles:any[] = []
|
||||
|
||||
list.forEach(item=>{
|
||||
const name = item.file.name.toLowerCase()
|
||||
const ext = name.split('.').pop()
|
||||
if(!allowExt.includes(ext)){
|
||||
invalidFiles.push(item.file.name)
|
||||
item.status = 'error'
|
||||
}
|
||||
})
|
||||
if(invalidFiles.length){
|
||||
window.$message.error(`【${invalidFiles.join('、')}】文件格式不支持`)
|
||||
}
|
||||
|
||||
|
||||
|
||||
fileList.value = list
|
||||
console.log('选中的文件列表', fileList.value)
|
||||
|
||||
|
||||
const validList = list.filter(item =>
|
||||
item.status === 'pending' && item.file && item.status !== 'error'
|
||||
)
|
||||
|
||||
const successIds = list.filter(x=>x.status==='success' && x.file).map(x=>x.id)
|
||||
// 只保留页面还存在的附件信息
|
||||
uploadFiles.value = uploadFiles.value.filter(item=> successIds.includes(item.uid))
|
||||
|
||||
// 只上传pending新文件
|
||||
const pendingList = list.filter(item => item.status === 'pending' && item.file && item.status !== 'error')
|
||||
if(pendingList.length === 0) return
|
||||
|
||||
const uploadPromises = validList.map(async (item: any) => {
|
||||
try {
|
||||
const res = await fileApi.uploadAndDingding(item.file, null, null)
|
||||
uploadFiles.value.push(res)
|
||||
const targetFile = fileList.value.find(f => f.id === item.id)
|
||||
if (targetFile) {
|
||||
targetFile.status = 'success'
|
||||
targetFile.percentage = 100
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('文件上传失败', error)
|
||||
const targetFile = fileList.value.find(f => f.id === item.id)
|
||||
if (targetFile) targetFile.status = 'error'
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(uploadPromises)
|
||||
}
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user