From fe6509e66e6852f6b5d740385bdae4fd0a11da77 Mon Sep 17 00:00:00 2001 From: 董国庆 <364620639@qq.com> Date: 星期二, 21 十月 2025 14:55:05 +0800 Subject: [PATCH] 修改问题 --- laboratory/src/views/deliveryAssessment/testingAndEvaluation/components/approval/index.vue | 913 ++++++++++++++++++++++++++++++--------------------------- 1 files changed, 480 insertions(+), 433 deletions(-) diff --git a/laboratory/src/views/deliveryAssessment/testingAndEvaluation/components/approval/index.vue b/laboratory/src/views/deliveryAssessment/testingAndEvaluation/components/approval/index.vue index 2d7b534..ba8c88c 100644 --- a/laboratory/src/views/deliveryAssessment/testingAndEvaluation/components/approval/index.vue +++ b/laboratory/src/views/deliveryAssessment/testingAndEvaluation/components/approval/index.vue @@ -1,499 +1,546 @@ <template> - <el-dialog :title="dialogTitle" :visible.sync="visible" width="80%" po :close-on-click-modal="false" - @close="handleClose"> - <div class="approval-dialog"> - <!-- 左侧审批内容 --> - <div class="approval-content"> - <Card class="approval-content-card"> - <template style="position: relative"> - <div class="header-title" style="width: 100%;"> - <div class="header-title-left"> - <img src="@/assets/public/headercard.png" /> - <div>所属检测项</div> - </div> - </div> - <Table :height="null" :total="0" :data="tableData"> - <template> - <el-table-column prop="teamName" label="所属项目组" /> - <el-table-column prop="itemName" label="检测项名称" /> - <el-table-column prop="itemCode" label="检测项编号" /> - <el-table-column prop="remark" label="备注" /> - <el-table-column prop="createBy" label="创建人" /> - <el-table-column prop="createTime" label="创建时间" /> - </template> - </Table> - - - <el-form ref="form" :model="form" :rules="rules" inline label-position="top" - style="margin-top: 18px"> - <el-form-item prop="name" label="报告内容"> - <el-select v-model="form.reportContent" style="width: 100%;" disabled - placeholder="请选择报告内容"> - <el-option label="国家标准" :value="1" /> - <el-option label="分析方法开发" :value="2" /> - <el-option label="方法验证报告" :value="3" /> - <el-option label="方法确认" :value="4" /> - <el-option label="操作规程" :value="5" /> - <el-option label="方法转移记录清单" :value="6" /> - </el-select> - </el-form-item> - - <div class="header-title" style="width: 100%;"> - <div class="header-title-left"> - <img src="@/assets/public/headercard.png" /> - <div>报告正文</div> - </div> - </div> - <el-form-item prop="name" style="margin-top: 18px"> - <ai-editor :value="form.reportText" :readOnly="true" style="width: 100%;" - placeholder="请输入报告编号" /> - </el-form-item> - <div class="header-title" style="width: 100%;"> - <div class="header-title-left"> - <img src="@/assets/public/headercard.png" /> - <span>附件</span> - </div> - </div> - <el-form-item prop="name" style="margin-top: 18px"> - <el-upload :on-preview="handlePreview" - action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList"> - <!-- <el-button size="small" type="primary">点击上传</el-button> --> - </el-upload> - </el-form-item> - - </el-form> - </template> - <!-- <SelectMember ref="selectMember" /> --> - </Card> + <el-dialog + :title="dialogTitle" + :visible.sync="visible" + width="80%" + po + :close-on-click-modal="false" + @close="handleClose" + > + <div class="approval-dialog"> + <!-- 左侧审批内容 --> + <div class="approval-content"> + <Card class="approval-content-card"> + <template style="position: relative"> + <div class="header-title" style="width: 100%"> + <div class="header-title-left"> + <img src="@/assets/public/headercard.png" /> + <div>所属检测项</div> + </div> </div> - <!-- 右侧审批流程 --> - <div class="approval-flow"> - <div class="flow-content"> - <approval-process :processData="form.processData" /> + <Table :height="null" :total="0" :data="tableData"> + <template> + <el-table-column prop="teamName" label="所属项目组" /> + <el-table-column prop="itemName" label="检测项名称" /> + <el-table-column prop="itemCode" label="检测项编号" /> + <el-table-column prop="remark" label="备注" /> + <el-table-column prop="createBy" label="创建人" /> + <el-table-column prop="createTime" label="创建时间" /> + </template> + </Table> + + <el-form + ref="form" + :model="form" + :rules="rules" + inline + label-position="top" + style="margin-top: 18px" + > + <el-form-item prop="name" label="报告内容"> + <el-select + v-model="form.reportContent" + style="width: 100%" + disabled + placeholder="请选择报告内容" + > + <el-option label="国家标准" :value="1" /> + <el-option label="分析方法开发" :value="2" /> + <el-option label="方法验证报告" :value="3" /> + <el-option label="方法确认" :value="4" /> + <el-option label="操作规程" :value="5" /> + <el-option label="方法转移记录清单" :value="6" /> + </el-select> + </el-form-item> + + <div class="header-title" style="width: 100%"> + <div class="header-title-left"> + <img src="@/assets/public/headercard.png" /> + <div>报告正文</div> </div> + </div> + <el-form-item prop="name" style="margin-top: 18px"> + <ai-editor + :value="form.reportText" + :readOnly="true" + style="width: 100%" + placeholder="请输入报告编号" + /> + </el-form-item> + <div class="header-title" style="width: 100%"> + <div class="header-title-left"> + <img src="@/assets/public/headercard.png" /> + <span>附件</span> + </div> + </div> + <el-form-item prop="name" style="margin-top: 18px"> + <el-upload + :on-preview="handlePreview" + action="https://jsonplaceholder.typicode.com/posts/" + :file-list="fileList" + > + <!-- <el-button size="small" type="primary">点击上传</el-button> --> + </el-upload> + </el-form-item> + </el-form> + </template> + <!-- <SelectMember ref="selectMember" /> --> + </Card> + </div> + <!-- 右侧审批流程 --> + <div class="approval-flow"> + <div class="flow-content"> + <approval-process :processData="form.processData" /> + </div> + </div> + </div> + <div class="approval-dialog-approve" v-if="type === 'approve'"> + <el-row :span="24"> + <el-col :span="12"> + <div class="status"> + <div class="status-title">审批结果</div> + <div class="status-content"> + <div + class="resolve" + :class="status == '1' && 'activeStatus'" + @click.stop="status = 1" + > + 通过 + </div> + <div + class="reject" + :class="status == '2' && 'activeStatus'" + @click.stop="status = 2" + > + 驳回 + </div> </div> - </div> - <div class="approval-dialog-approve" v-if="type === 'approve'"> - <el-row :span="24"> - <el-col :span="12"> - <div class="status"> - <div class="status-title">审批结果</div> - <div class="status-content"> - <div class="resolve" :class="status == '1' && 'activeStatus'" @click.stop="status = 1"> - 通过 - </div> - <div class="reject" :class="status == '2' && 'activeStatus'" @click.stop="status = 2"> - 驳回 - </div> - </div> - </div> - </el-col> - <el-col :span="12"> - <div class="remark"> - <div class="remark-title">审批意见</div> - <el-input type="textarea" v-model="remark" placeholder="请输入审批意见" /> - </div> - </el-col> - </el-row> - - - </div> - <div slot="footer" class="dialog-footer"> - <el-button @click="handleClose">取 消</el-button> - <el-button type="primary" @click="handleApprove" v-if="type === 'approve'">确认</el-button> - </div> - </el-dialog> + </div> + </el-col> + <el-col :span="12"> + <div class="remark"> + <div class="remark-title">审批意见</div> + <el-input + type="textarea" + v-model="remark" + placeholder="请输入审批意见" + /> + </div> + </el-col> + </el-row> + </div> + <div slot="footer" class="dialog-footer"> + <el-button @click="handleClose">取 消</el-button> + <el-button type="primary" @click="handleApprove" v-if="type === 'approve'" + >确认</el-button + > + </div> + </el-dialog> </template> <script> -import ApprovalProcess from '@/components/approvalProcess' -import AiEditor from '@/components/AiEditor' -import { getDetailInfo, getDetail, detailAuditReport } from '../../service' -import apiConfig from '@/utils/baseurl'; -import { getAllocateIp } from '@/utils/utils' +import ApprovalProcess from "@/components/approvalProcess"; +import AiEditor from "@/components/AiEditor"; +import { getDetailInfo, getDetail, detailAuditReport } from "../../service"; +import apiConfig from "@/utils/baseurl"; +import { getAllocateIp, downloadFileByUrl, isImageFile } from "@/utils/utils"; export default { - name: "ApprovalDialog", - components: { - ApprovalProcess, - AiEditor + name: "ApprovalDialog", + components: { + ApprovalProcess, + AiEditor, + }, + props: { + visible: { + type: Boolean, + default: false, }, - props: { - visible: { - type: Boolean, - default: false, - }, - type: { - type: String, - default: "approve", // approve-审批,view-查看 - }, - data: { - type: Object, - default: () => ({}), - }, - id: { - type: String, - default: "", - }, + type: { + type: String, + default: "approve", // approve-审批,view-查看 }, - data() { - return { - form: { - reportText: "", - reportContent: "", - qaReportFiles: [], - processData: [], - }, - tableData: [], - fileList: [], - radio1: 1, - rules: {}, - status: "1", - remark: "", - }; + data: { + type: Object, + default: () => ({}), }, - computed: { - dialogTitle() { - return this.type === "approve" ? "方法验证报告审批" : "方法验证报告详情"; - }, + id: { + type: String, + default: "", }, - watch: { - visible: { - handler(val) { - if (val && this.data.id) { - this.getDetailInfo() - } - if (val && this.data.itemId) { - this.getDetail() - } - }, - immediate: true, - }, + }, + data() { + return { + form: { + reportText: "", + reportContent: "", + qaReportFiles: [], + processData: [], + }, + tableData: [], + fileList: [], + radio1: 1, + rules: {}, + status: "1", + remark: "", + }; + }, + computed: { + dialogTitle() { + return this.type === "approve" ? "方法验证报告审批" : "方法验证报告详情"; }, - methods: { - handlePreview(file) { - console.log('url', file) - if (file && file.url) { - if (file.url && file.url.startsWith(getAllocateIp())) { - window.open(file.url, '_blank'); - } else { - let newUrl = getAllocateIp() + file.url; - window.open(newUrl, '_blank'); - } - } - }, - getDetailInfo() { - getDetailInfo({ id: this.data.id }).then(res => { - if (res) { - this.form = { ...res, reportContent: Number(res.reportContent), processData: [] } - if (res.qaReportFileList && res.qaReportFileList.length > 0) { - this.fileList = res.qaReportFileList.map(file => ({ - name: file.fileName, - url: getFullUrl(file.fileUrl), - uid: file.id - })) - this.form.qaReportFileList = res.fileList - } else { - this.fileList = [] - this.form.qaReportFileList = [] - } - // 组装流程数据 - let processData = []; - // 提交节点 - processData.push({ - type: "primary", - mode: "list", - fields: [ - { label: "提交人:", value: res.updateBy || "" }, - { label: "提交时间:", value: res.createTime || "" }, - ], - }); - if (res.status == 2 || res.status == 3) { - processData.push({ - type: - res.status === 2 - ? "primary" - : res.status === 3 - ? "danger" - : "warning", - mode: "list", - fields: [ - { - label: "审核结果:", - value: - res.status === 2 - ? "通过" - : res.status === 3 - ? "驳回" - : "待审批", - }, - { label: "审批意见:", value: res.auditRemark || "" }, - { label: "审核人:", value: res.auditPersonName || "" }, - { label: "审核时间:", value: res.auditTime || "" }, - ], - }); - } else { - processData.push({ - type: "warning", - mode: "list", - fields: [ - { label: "等待审核" }, - ], - }); - } - // 如有卡片模式,按前述结构 push + }, + watch: { + visible: { + handler(val) { + if (val && this.data.id) { + this.getDetailInfo(); + } + if (val && this.data.itemId) { + this.getDetail(); + } + }, + immediate: true, + }, + }, + methods: { + handlePreview(file) { + if (file && file.url) { + // 判断是否为图片文件 + const isImage = isImageFile(file.url); - this.$nextTick(() => { - this.form.processData = processData; - }) - } - }) - }, - getDetail() { - getDetail(this.data.itemId).then(res => { - if (res) { - this.tableData = [{ ...res, teamName: res.projectTeamVO.teamName }] - } - }) - }, - handleClose() { + if (isImage) { + // 图片文件:使用 window.open 预览 + if (file.url && file.url.startsWith(getAllocateIp())) { + console.log("图片链接", file.url); + window.open(file.url, "_blank"); + } else { + let newUrl = getAllocateIp() + file.url; + console.log("图片链接", newUrl); + window.open(newUrl, "_blank"); + } + } else { + // 非图片文件:使用下载方式 + downloadFileByUrl(file.url, file.name); + } + } + }, + getDetailInfo() { + getDetailInfo({ id: this.data.id }).then((res) => { + if (res) { + this.form = { + ...res, + reportContent: Number(res.reportContent), + processData: [], + }; + if (res.qaReportFileList && res.qaReportFileList.length > 0) { + this.fileList = res.qaReportFileList.map((file) => ({ + name: file.fileName, + url: getFullUrl(file.fileUrl), + uid: file.id, + })); + this.form.qaReportFileList = res.fileList; + } else { + this.fileList = []; + this.form.qaReportFileList = []; + } + // 组装流程数据 + let processData = []; + // 提交节点 + processData.push({ + type: "primary", + mode: "list", + fields: [ + { label: "提交人:", value: res.updateBy || "" }, + { label: "提交时间:", value: res.createTime || "" }, + ], + }); + if (res.status == 2 || res.status == 3) { + processData.push({ + type: + res.status === 2 + ? "primary" + : res.status === 3 + ? "danger" + : "warning", + mode: "list", + fields: [ + { + label: "审核结果:", + value: + res.status === 2 + ? "通过" + : res.status === 3 + ? "驳回" + : "待审批", + }, + { label: "审批意见:", value: res.auditRemark || "" }, + { label: "审核人:", value: res.auditPersonName || "" }, + { label: "审核时间:", value: res.auditTime || "" }, + ], + }); + } else { + processData.push({ + type: "warning", + mode: "list", + fields: [{ label: "等待审核" }], + }); + } + // 如有卡片模式,按前述结构 push + + this.$nextTick(() => { + this.form.processData = processData; + }); + } + }); + }, + getDetail() { + getDetail(this.data.itemId).then((res) => { + if (res) { + this.tableData = [{ ...res, teamName: res.projectTeamVO.teamName }]; + } + }); + }, + handleClose() { + this.$emit("close"); + + this.form.approvalComment = ""; + }, + handleApprove() { + if (!this.remark) { + this.$message.warning("请输入审批意见"); + return; + } + const params = { + id: this.data.id, + auditRemark: this.remark, + auditStatus: this.status === "1" ? 2 : 3, + }; + detailAuditReport(params) + .then((res) => { + if (res) { + this.$message.success("审核成功"); this.$emit("close"); - - this.form.approvalComment = ""; - }, - handleApprove() { - if (!this.remark) { - this.$message.warning("请输入审批意见"); - return; - } - const params = { - id: this.data.id, - auditRemark: this.remark, - auditStatus: this.status === '1' ? 2 : 3 - }; - detailAuditReport(params).then(res => { - if (res) { - this.$message.success('审核成功'); - this.$emit("close"); - } - }).catch(err => { - this.$message.error(err.message || '审核失败'); - }); - }, - handleReject() { - if (!this.form.approvalComment) { - this.$message.warning("请输入审批意见"); - return; - } - this.$emit("reject", { - ...this.form, - status: "rejected", - }); - }, + } + }) + .catch((err) => { + this.$message.error(err.message || "审核失败"); + }); }, + handleReject() { + if (!this.form.approvalComment) { + this.$message.warning("请输入审批意见"); + return; + } + this.$emit("reject", { + ...this.form, + status: "rejected", + }); + }, + }, }; </script> <style scoped lang="less"> ::v-deep .el-dialog__header { - border-bottom: 1px solid #e4e7ed; + border-bottom: 1px solid #e4e7ed; } .approval-dialog { - display: flex; - height: 40vh; + display: flex; + height: 40vh; - .approval-content { - flex: 3; - margin-right: 20px; - background: #ffffff; - box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); - border-radius: 10px; + .approval-content { + flex: 3; + margin-right: 20px; + background: #ffffff; + box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); + border-radius: 10px; + } + + .approval-flow { + padding: 40px 20px; + // width: 405px; + flex: 2; + background: #ffffff; + box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); + border-radius: 10px; + + .flow-title { + font-size: 16px; + font-weight: bold; + margin-bottom: 20px; + color: #303133; } - .approval-flow { - padding: 40px 20px; - // width: 405px; - flex: 2; - background: #ffffff; - box-shadow: 0px 4px 12px 4px rgba(0, 0, 0, 0.08); - border-radius: 10px; + .flow-content { + height: calc(100% - 40px); + overflow-y: auto; - .flow-title { - font-size: 16px; - font-weight: bold; - margin-bottom: 20px; - color: #303133; - } - - .flow-content { - height: calc(100% - 40px); - overflow-y: auto; - - .el-form--inline .el-form-item { - margin-right: 83px; - } - } + .el-form--inline .el-form-item { + margin-right: 83px; + } } + } } .approval-content-card { - height: calc(100% - 100px) !important; - box-shadow: none !important; + height: calc(100% - 100px) !important; + box-shadow: none !important; } .header-title { - // display: flex; + // display: flex; + align-items: center; + flex-wrap: wrap; + margin-bottom: 20px; + gap: 13px; + + .header-title-left { + display: flex; align-items: center; - flex-wrap: wrap; - margin-bottom: 20px; gap: 13px; + margin-top: 18px; - .header-title-left { - display: flex; - align-items: center; - gap: 13px; - margin-top: 18px; - - img { - width: 12px; - height: 19px; - } - - div { - flex-shrink: 0; - font-weight: bold; - font-size: 18px; - color: #222222; - line-height: 27px; - font-family: "Source Han Sans CN Bold Bold"; - - &:before { - content: "*"; - color: #f56c6c; - margin-right: 4px; - } - } - - span { - flex-shrink: 0; - font-weight: bold; - font-size: 18px; - color: #222222; - line-height: 27px; - font-family: "Source Han Sans CN Bold Bold"; - } + img { + width: 12px; + height: 19px; } - .header-title-left :first-child { - margin-top: 0; + div { + flex-shrink: 0; + font-weight: bold; + font-size: 18px; + color: #222222; + line-height: 27px; + font-family: "Source Han Sans CN Bold Bold"; + + &:before { + content: "*"; + color: #f56c6c; + margin-right: 4px; + } } + + span { + flex-shrink: 0; + font-weight: bold; + font-size: 18px; + color: #222222; + line-height: 27px; + font-family: "Source Han Sans CN Bold Bold"; + } + } + + .header-title-left :first-child { + margin-top: 0; + } } .header-title:first-child { - .header-title-left { - margin-top: 0; - } + .header-title-left { + margin-top: 0; + } } .item-title { - padding-left: 25px; + padding-left: 25px; - span { - flex-shrink: 0; - font-weight: bold; - font-size: 14px; - color: #222222; - line-height: 27px; - font-family: "Source Han Sans CN Bold Bold"; - margin: 18px 0; + span { + flex-shrink: 0; + font-weight: bold; + font-size: 14px; + color: #222222; + line-height: 27px; + font-family: "Source Han Sans CN Bold Bold"; + margin: 18px 0; - &:before { - content: "*"; - color: #f56c6c; - margin-right: 4px; - } + &:before { + content: "*"; + color: #f56c6c; + margin-right: 4px; } + } } .approval-dialog-approve { - padding: 18px 20px; - // display: flex; - align-content: center; + padding: 18px 20px; + // display: flex; + align-content: center; - .status { - margin-right: 40px; - max-width: 60%; + .status { + margin-right: 40px; + max-width: 60%; + } + + // align-items: center; + .status-title { + color: #222222; + font-family: "SourceHanSansCN-Medium"; + line-height: 14px; + margin-bottom: 16px; + } + + .status-content { + display: flex; + align-items: center; + width: 100%; + gap: 16px; + background: #ffffff; + border-radius: 10px; + border: 1px solid rgba(4, 156, 154, 0.5); + + .resolve { + border-radius: 10px; + flex: 1; + font-size: 16px; + // padding: 5px 55px; + font-weight: 400; + color: #333333; + cursor: pointer; + line-height: 32px; + display: flex; + align-items: center; + justify-content: center; } - // align-items: center; - .status-title { - color: #222222; - font-family: "SourceHanSansCN-Medium"; - line-height: 14px; - margin-bottom: 16px; + .reject { + flex: 1; + border-radius: 10px; + font-size: 16px; + line-height: 32px; + // padding: 5px 55px; + font-weight: 400; + color: #333333; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; } - .status-content { - display: flex; - align-items: center; - width: 100%; - gap: 16px; - background: #ffffff; - border-radius: 10px; - border: 1px solid rgba(4, 156, 154, 0.5); - - .resolve { - border-radius: 10px; - flex: 1; - font-size: 16px; - // padding: 5px 55px; - font-weight: 400; - color: #333333; - cursor: pointer; - line-height: 32px; - display: flex; - align-items: center; - justify-content: center - } - - .reject { - flex: 1; - border-radius: 10px; - font-size: 16px; - line-height: 32px; - // padding: 5px 55px; - font-weight: 400; - color: #333333; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center - } - - .activeStatus { - background: #ebfefd; - color: #049c9a; - box-shadow: 0px 0px 6px 0px rgba(10, 109, 108, 0.25); - border-radius: 10px; - } + .activeStatus { + background: #ebfefd; + color: #049c9a; + box-shadow: 0px 0px 6px 0px rgba(10, 109, 108, 0.25); + border-radius: 10px; } + } - .remark-title { - color: #222222; - font-family: "SourceHanSansCN-Medium"; - line-height: 14px; - margin-bottom: 16px; - } + .remark-title { + color: #222222; + font-family: "SourceHanSansCN-Medium"; + line-height: 14px; + margin-bottom: 16px; + } } .dialog-footer { - align-items: center; - display: flex; - justify-content: center; - gap: 20px; + align-items: center; + display: flex; + justify-content: center; + gap: 20px; - button { - width: 150px; - } + button { + width: 150px; + } } </style> \ No newline at end of file -- Gitblit v1.7.1