|
@@ -0,0 +1,601 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <el-dialog
|
|
|
|
|
+ :model-value="visible"
|
|
|
|
|
+ title="填写访厂报告"
|
|
|
|
|
+ width="1000px"
|
|
|
|
|
+ append-to-body
|
|
|
|
|
+ :close-on-click-modal="false"
|
|
|
|
|
+ :before-close="handleClose"
|
|
|
|
|
+ top="3vh"
|
|
|
|
|
+ class="factory-report-dialog"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template v-if="visit">
|
|
|
|
|
+ <!-- 顶部基础信息 -->
|
|
|
|
|
+ <el-descriptions :column="3" border size="small" class="mb-3">
|
|
|
|
|
+ <el-descriptions-item label="访厂ID">{{ visit.visitCode }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="公司名称">{{ visit.companyName }}</el-descriptions-item>
|
|
|
|
|
+ <el-descriptions-item label="审核部门">{{ visit.auditDept || '-' }}</el-descriptions-item>
|
|
|
|
|
+ </el-descriptions>
|
|
|
|
|
+
|
|
|
|
|
+ <el-tabs v-model="activeTab" type="border-card">
|
|
|
|
|
+ <!-- 模块 1:基础信息核查 -->
|
|
|
|
|
+ <el-tab-pane label="1.基础信息核查" name="basic">
|
|
|
|
|
+ <el-form label-width="280px">
|
|
|
|
|
+ <h4 class="section-title">1.1 资质合法</h4>
|
|
|
|
|
+ <el-form-item label="营业执照齐全有效">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.businessLicense" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="食品经营许可证/生产许可证齐全">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.foodLicense" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="检验检疫证明齐全(生鲜肉/畜/禽)">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.inspectionCert" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="进口食品许可及检验检疫证明">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.importCert" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <h4 class="section-title">1.2 经营合法</h4>
|
|
|
|
|
+ <el-form-item label="生产经营活动及员工合法合规">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.operationLegal" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="产品无虚假标注(批号/日期)">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.productLabel" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="存储/运输/分包活动合法合规">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.logisticsLegal" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <h4 class="section-title">1.5 GMP 标准</h4>
|
|
|
|
|
+ <el-form-item label="GMP 认证齐全有效,覆盖生产范围">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.gmpCert" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <h4 class="section-title">1.6 三大 ISO 标准</h4>
|
|
|
|
|
+ <el-form-item label="ISO9001/14001/45001 证书齐全有效">
|
|
|
|
|
+ <el-select v-model="form.basicEvaluate.isoCert" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="是" value="是" />
|
|
|
|
|
+ <el-option label="否" value="否" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 2:ESG 审查(总分 30:E12+S12+G6) -->
|
|
|
|
|
+ <el-tab-pane label="2.ESG 审查" name="esg">
|
|
|
|
|
+ <el-form label-width="380px">
|
|
|
|
|
+ <h4 class="section-title">环境 E(12 分)</h4>
|
|
|
|
|
+ <el-form-item :label="`碳排放管理(0~${SCORE.esg.carbon})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.carbon" :min="0" :max="SCORE.esg.carbon" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`废弃物管理(0~${SCORE.esg.waste})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.waste" :min="0" :max="SCORE.esg.waste" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`三废排放(0~${SCORE.esg.emission})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.emission" :min="0" :max="SCORE.esg.emission" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`节能降耗(0~${SCORE.esg.energy})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.energy" :min="0" :max="SCORE.esg.energy" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <h4 class="section-title">社会 S(12 分)</h4>
|
|
|
|
|
+ <el-form-item :label="`员工权益(0~${SCORE.esg.labor})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.labor" :min="0" :max="SCORE.esg.labor" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`职业健康(0~${SCORE.esg.health})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.health" :min="0" :max="SCORE.esg.health" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`供应链责任(0~${SCORE.esg.supply})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.supply" :min="0" :max="SCORE.esg.supply" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`社区责任(0~${SCORE.esg.community})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.community" :min="0" :max="SCORE.esg.community" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <h4 class="section-title">治理 G(6 分)</h4>
|
|
|
|
|
+ <el-form-item :label="`ESG管理制度(0~${SCORE.esg.management})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.management" :min="0" :max="SCORE.esg.management" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`反腐败/反商业贿赂(0~${SCORE.esg.antibribery})`">
|
|
|
|
|
+ <el-input-number v-model="form.esgScore.antibribery" :min="0" :max="SCORE.esg.antibribery" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="score-summary">当前 ESG 小计: {{ esgTotal }} / 30</div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 3:GMP 审查(总分 20) -->
|
|
|
|
|
+ <el-tab-pane label="3.GMP 审查" name="gmp">
|
|
|
|
|
+ <el-form label-width="380px">
|
|
|
|
|
+ <el-form-item :label="`车间布局/洁净区(0~${SCORE.gmp.layout})`">
|
|
|
|
|
+ <el-input-number v-model="form.gmpScore.layout" :min="0" :max="SCORE.gmp.layout" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`生产工艺/批记录(0~${SCORE.gmp.process})`">
|
|
|
|
|
+ <el-input-number v-model="form.gmpScore.process" :min="0" :max="SCORE.gmp.process" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`成品检验/召回机制(0~${SCORE.gmp.release})`">
|
|
|
|
|
+ <el-input-number v-model="form.gmpScore.release" :min="0" :max="SCORE.gmp.release" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`原材料供应商管控(0~${SCORE.gmp.material})`">
|
|
|
|
|
+ <el-input-number v-model="form.gmpScore.material" :min="0" :max="SCORE.gmp.material" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`设备清洁/校准/验证(0~${SCORE.gmp.equipment})`">
|
|
|
|
|
+ <el-input-number v-model="form.gmpScore.equipment" :min="0" :max="SCORE.gmp.equipment" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="score-summary">当前 GMP 小计: {{ gmpTotal }} / 20</div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 4:ISO14001(总分 15) -->
|
|
|
|
|
+ <el-tab-pane label="4.ISO14001" name="iso14001">
|
|
|
|
|
+ <el-form label-width="380px">
|
|
|
|
|
+ <el-form-item :label="`环境管理手册/程序文件(0~${SCORE.iso14001.manual})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso14001Score.manual" :min="0" :max="SCORE.iso14001.manual" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`环保设施/监测记录(0~${SCORE.iso14001.facility})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso14001Score.facility" :min="0" :max="SCORE.iso14001.facility" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`环境因素识别/风险管控(0~${SCORE.iso14001.factor})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso14001Score.factor" :min="0" :max="SCORE.iso14001.factor" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`内审/管理评审/持续改进(0~${SCORE.iso14001.review})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso14001Score.review" :min="0" :max="SCORE.iso14001.review" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="score-summary">当前 ISO14001 小计: {{ iso14001Total }} / 15</div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 5:ISO45001(总分 15) -->
|
|
|
|
|
+ <el-tab-pane label="5.ISO45001" name="iso45001">
|
|
|
|
|
+ <el-form label-width="380px">
|
|
|
|
|
+ <el-form-item :label="`职业健康手册/程序文件(0~${SCORE.iso45001.manual})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso45001Score.manual" :min="0" :max="SCORE.iso45001.manual" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`安全培训/应急演练(0~${SCORE.iso45001.training})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso45001Score.training" :min="0" :max="SCORE.iso45001.training" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`职业危害/防控措施(0~${SCORE.iso45001.hazard})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso45001Score.hazard" :min="0" :max="SCORE.iso45001.hazard" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`工伤/职业病记录与整改(0~${SCORE.iso45001.incident})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso45001Score.incident" :min="0" :max="SCORE.iso45001.incident" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="score-summary">当前 ISO45001 小计: {{ iso45001Total }} / 15</div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 6:ISO9001(总分 20) -->
|
|
|
|
|
+ <el-tab-pane label="6.ISO9001" name="iso9001">
|
|
|
|
|
+ <el-form label-width="380px">
|
|
|
|
|
+ <el-form-item :label="`质量管理手册/目标(0~${SCORE.iso9001.manual})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso9001Score.manual" :min="0" :max="SCORE.iso9001.manual" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`过程质量管控/记录(0~${SCORE.iso9001.process})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso9001Score.process" :min="0" :max="SCORE.iso9001.process" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`内审/客户投诉/改进(0~${SCORE.iso9001.review})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso9001Score.review" :min="0" :max="SCORE.iso9001.review" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`供应商评价/采购追溯(0~${SCORE.iso9001.supplier})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso9001Score.supplier" :min="0" :max="SCORE.iso9001.supplier" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item :label="`设备校准/检测仪器(0~${SCORE.iso9001.equipment})`">
|
|
|
|
|
+ <el-input-number v-model="form.iso9001Score.equipment" :min="0" :max="SCORE.iso9001.equipment" :step="1" controls-position="right" />
|
|
|
|
|
+ <span class="score-tip">分</span>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <div class="score-summary">当前 ISO9001 小计: {{ iso9001Total }} / 20</div>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 模块 7:致敏原管控 -->
|
|
|
|
|
+ <el-tab-pane label="7.致敏原管控" name="allergen">
|
|
|
|
|
+ <el-form label-width="320px">
|
|
|
|
|
+ <h4 class="section-title">7.1 访问前准备核查</h4>
|
|
|
|
|
+ <el-form-item label="提前获取工厂致敏原清单">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.prep1.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.prep1.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="访问人员已完成致敏原认知培训">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.prep2.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.prep2.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="按特性准备防护装备(N95/防护服)">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.prep3.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.prep3.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="访问人员无急性过敏症状">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.prep4.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.prep4.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <h4 class="section-title">7.2 现场区域管控核查</h4>
|
|
|
|
|
+ <el-form-item label="致敏原区物理隔离到位">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.area1.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.area1.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="致敏原区域有醒目标识">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.area2.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.area2.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="区域入口有准入要求提示">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.area3.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.area3.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="致敏原仓储区分区存放">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.area4.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.area4.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <h4 class="section-title">7.3 人员行为与防护管控核查</h4>
|
|
|
|
|
+ <el-form-item label="穿戴/脱卸防护装备合规">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.person1.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.person1.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="禁止跨致敏原/非致敏原区流动">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.person2.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.person2.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="防护装备按规定集中处理">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.person3.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.person3.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="员工已接受致敏原专项培训">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.person4.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.person4.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <h4 class="section-title">7.4 设备与清洁管控核查</h4>
|
|
|
|
|
+ <el-form-item label="致敏原专用设备无混用">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.equip1.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.equip1.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="设备清洁流程规范">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.equip2.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.equip2.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="清洁验证记录完整可追溯">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.equip3.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.equip3.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="清洁工具分区专用">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.equip4.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.equip4.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <h4 class="section-title">7.5 台账与追溯管控核查</h4>
|
|
|
|
|
+ <el-form-item label="致敏原台账完整可追溯">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.log1.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.log1.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="定期巡检与整改闭环">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.log2.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.log2.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item label="变更(原料/工序)有评估记录">
|
|
|
|
|
+ <el-select v-model="form.allergenEvaluate.log3.result" placeholder="请选择" style="width: 160px">
|
|
|
|
|
+ <el-option label="合格" value="合格" />
|
|
|
|
|
+ <el-option label="不合格" value="不合格" />
|
|
|
|
|
+ <el-option label="不适用" value="不适用" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-input v-model="form.allergenEvaluate.log3.remark" placeholder="问题描述/说明" style="width: 320px; margin-left: 8px" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 7.6 问题汇总 -->
|
|
|
|
|
+ <el-tab-pane label="7.6 问题汇总" name="summary">
|
|
|
|
|
+ <el-form label-width="auto">
|
|
|
|
|
+ <el-form-item label="问题描述及整改措施">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ v-model="form.summary"
|
|
|
|
|
+ type="textarea"
|
|
|
|
|
+ :rows="12"
|
|
|
|
|
+ placeholder="请填写整体问题描述及整改要求(无预设选项)"
|
|
|
|
|
+ maxlength="2000"
|
|
|
|
|
+ show-word-limit
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
|
+ </el-tabs>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 总分显示 -->
|
|
|
|
|
+ <el-alert
|
|
|
|
|
+ class="mt-3"
|
|
|
|
|
+ :title="`访查实际得分: ${totalScore} / 100`"
|
|
|
|
|
+ type="info"
|
|
|
|
|
+ show-icon
|
|
|
|
|
+ :closable="false"
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <el-button @click="handleClose">取 消</el-button>
|
|
|
|
|
+ <el-button type="primary" :loading="submitLoading" @click="onSubmit">提 交</el-button>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import { ref, reactive, computed, watch } from 'vue';
|
|
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
|
+import { submitFactoryVisitReport } from '@/api/risk/factoryVisit';
|
|
|
|
|
+
|
|
|
|
|
+const props = defineProps<{
|
|
|
|
|
+ visible: boolean;
|
|
|
|
|
+ visit: any;
|
|
|
|
|
+}>();
|
|
|
|
|
+const emit = defineEmits<{
|
|
|
|
|
+ 'update:visible': [v: boolean];
|
|
|
|
|
+ success: [];
|
|
|
|
|
+}>();
|
|
|
|
|
+
|
|
|
|
|
+const activeTab = ref('basic');
|
|
|
|
|
+const submitLoading = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+// 评分上限常量(参考需求文档)
|
|
|
|
|
+const SCORE = {
|
|
|
|
|
+ esg: { carbon: 3, waste: 3, emission: 3, energy: 3, labor: 3, health: 3, supply: 3, community: 3, management: 3, antibribery: 3 },
|
|
|
|
|
+ gmp: { layout: 4, process: 4, release: 4, material: 4, equipment: 4 },
|
|
|
|
|
+ iso14001: { manual: 3, facility: 4, factor: 4, review: 4 },
|
|
|
|
|
+ iso45001: { manual: 3, training: 4, hazard: 4, incident: 4 },
|
|
|
|
|
+ iso9001: { manual: 4, process: 4, review: 4, supplier: 4, equipment: 4 }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 初始化表单默认值
|
|
|
|
|
+const makeEmptyBasic = () => ({
|
|
|
|
|
+ businessLicense: '',
|
|
|
|
|
+ foodLicense: '',
|
|
|
|
|
+ inspectionCert: '',
|
|
|
|
|
+ importCert: '',
|
|
|
|
|
+ operationLegal: '',
|
|
|
|
|
+ productLabel: '',
|
|
|
|
|
+ logisticsLegal: '',
|
|
|
|
|
+ gmpCert: '',
|
|
|
|
|
+ isoCert: ''
|
|
|
|
|
+});
|
|
|
|
|
+const makeEmptyEsg = () => ({
|
|
|
|
|
+ carbon: 0, waste: 0, emission: 0, energy: 0,
|
|
|
|
|
+ labor: 0, health: 0, supply: 0, community: 0,
|
|
|
|
|
+ management: 0, antibribery: 0
|
|
|
|
|
+});
|
|
|
|
|
+const makeEmptyGmp = () => ({ layout: 0, process: 0, release: 0, material: 0, equipment: 0 });
|
|
|
|
|
+const makeEmptyIso = () => ({ manual: 0, facility: 0, factor: 0, review: 0 });
|
|
|
|
|
+const makeEmptyIso2 = () => ({ manual: 0, training: 0, hazard: 0, incident: 0 });
|
|
|
|
|
+const makeEmptyIso3 = () => ({ manual: 0, process: 0, review: 0, supplier: 0, equipment: 0 });
|
|
|
|
|
+const makeEmptyAllergen = () => ({
|
|
|
|
|
+ prep1: { result: '', remark: '' }, prep2: { result: '', remark: '' }, prep3: { result: '', remark: '' }, prep4: { result: '', remark: '' },
|
|
|
|
|
+ area1: { result: '', remark: '' }, area2: { result: '', remark: '' }, area3: { result: '', remark: '' }, area4: { result: '', remark: '' },
|
|
|
|
|
+ person1: { result: '', remark: '' }, person2: { result: '', remark: '' }, person3: { result: '', remark: '' }, person4: { result: '', remark: '' },
|
|
|
|
|
+ equip1: { result: '', remark: '' }, equip2: { result: '', remark: '' }, equip3: { result: '', remark: '' }, equip4: { result: '', remark: '' },
|
|
|
|
|
+ log1: { result: '', remark: '' }, log2: { result: '', remark: '' }, log3: { result: '', remark: '' }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const form = reactive({
|
|
|
|
|
+ basicEvaluate: makeEmptyBasic(),
|
|
|
|
|
+ esgScore: makeEmptyEsg(),
|
|
|
|
|
+ gmpScore: makeEmptyGmp(),
|
|
|
|
|
+ iso14001Score: makeEmptyIso(),
|
|
|
|
|
+ iso45001Score: makeEmptyIso2(),
|
|
|
|
|
+ iso9001Score: makeEmptyIso3(),
|
|
|
|
|
+ allergenEvaluate: makeEmptyAllergen(),
|
|
|
|
|
+ summary: ''
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 监听 visit 变化:加载已有报告数据(仅在有 report 时)
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => props.visit,
|
|
|
|
|
+ (v) => {
|
|
|
|
|
+ if (!v) return;
|
|
|
|
|
+ const r = v.report;
|
|
|
|
|
+ if (r) {
|
|
|
|
|
+ // 已有报告数据,合并
|
|
|
|
|
+ Object.assign(form.basicEvaluate, r.basicEvaluate || {});
|
|
|
|
|
+ Object.assign(form.esgScore, r.esgScore || {});
|
|
|
|
|
+ Object.assign(form.gmpScore, r.gmpScore || {});
|
|
|
|
|
+ Object.assign(form.iso14001Score, r.iso14001Score || {});
|
|
|
|
|
+ Object.assign(form.iso45001Score, r.iso45001Score || {});
|
|
|
|
|
+ Object.assign(form.iso9001Score, r.iso9001Score || {});
|
|
|
|
|
+ if (r.allergenEvaluate) {
|
|
|
|
|
+ for (const k of Object.keys(r.allergenEvaluate)) {
|
|
|
|
|
+ if (form.allergenEvaluate[k]) {
|
|
|
|
|
+ form.allergenEvaluate[k] = { ...form.allergenEvaluate[k], ...(r.allergenEvaluate[k] || {}) };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ form.summary = r.summary || '';
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { immediate: true }
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+// 计算各模块小计
|
|
|
|
|
+const sumObj = (o: Record<string, number>) => Object.values(o).reduce((a, b) => a + (Number(b) || 0), 0);
|
|
|
|
|
+const esgTotal = computed(() => sumObj(form.esgScore));
|
|
|
|
|
+const gmpTotal = computed(() => sumObj(form.gmpScore));
|
|
|
|
|
+const iso14001Total = computed(() => sumObj(form.iso14001Score));
|
|
|
|
|
+const iso45001Total = computed(() => sumObj(form.iso45001Score));
|
|
|
|
|
+const iso9001Total = computed(() => sumObj(form.iso9001Score));
|
|
|
|
|
+const totalScore = computed(
|
|
|
|
|
+ () => esgTotal.value + gmpTotal.value + iso14001Total.value + iso45001Total.value + iso9001Total.value
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
|
|
+const handleClose = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await ElMessageBox.confirm('报告尚未提交,确认关闭?', '提示', { type: 'warning' });
|
|
|
|
|
+ emit('update:visible', false);
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ // 用户取消
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const onSubmit = async () => {
|
|
|
|
|
+ submitLoading.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const payload = {
|
|
|
|
|
+ visitId: props.visit.id,
|
|
|
|
|
+ basicEvaluate: form.basicEvaluate,
|
|
|
|
|
+ esgScore: form.esgScore,
|
|
|
|
|
+ gmpScore: form.gmpScore,
|
|
|
|
|
+ iso14001Score: form.iso14001Score,
|
|
|
|
|
+ iso45001Score: form.iso45001Score,
|
|
|
|
|
+ iso9001Score: form.iso9001Score,
|
|
|
|
|
+ allergenEvaluate: form.allergenEvaluate,
|
|
|
|
|
+ summary: form.summary,
|
|
|
|
|
+ totalScore: totalScore.value,
|
|
|
|
|
+ visitDate: props.visit.visitDate
|
|
|
|
|
+ };
|
|
|
|
|
+ const res: any = await submitFactoryVisitReport(payload);
|
|
|
|
|
+ ElMessage.success(`报告提交成功,得分 ${totalScore.value} 分,已转待审核`);
|
|
|
|
|
+ emit('update:visible', false);
|
|
|
|
|
+ emit('success');
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ submitLoading.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss">
|
|
|
|
|
+.factory-report-dialog :deep(.el-dialog__body) {
|
|
|
|
|
+ max-height: 75vh;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+}
|
|
|
|
|
+.section-title {
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ font-size: 14px;
|
|
|
|
|
+ color: #303133;
|
|
|
|
|
+ border-left: 3px solid #409eff;
|
|
|
|
|
+ padding-left: 10px;
|
|
|
|
|
+ margin: 16px 0 12px 0;
|
|
|
|
|
+}
|
|
|
|
|
+.score-tip {
|
|
|
|
|
+ margin-left: 8px;
|
|
|
|
|
+ color: #909399;
|
|
|
|
|
+}
|
|
|
|
|
+.score-summary {
|
|
|
|
|
+ margin-top: 16px;
|
|
|
|
|
+ padding: 8px 16px;
|
|
|
|
|
+ background: #ecf5ff;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ color: #409eff;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ text-align: right;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|