spring
2025-03-04 7b6cad3a3fc3a4dcfc7944be62220e931491c268
监控计划搬迁80%
已添加21个文件
已修改4个文件
5101 ■■■■■ 文件已修改
public/index.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/complaint.js 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/ensureResults/ensureResultsValidity.js 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/ensureResults/qualityControlPlan.js 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/nonconformingWork.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/reportResults.js 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/sampleDisposal.js 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/uncertainty.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/user.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Table/lims-table.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/complaint/index.vue 629 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/ViewRecord.vue 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/carryOutDialog.vue 324 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/detailFormDialog.vue 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/evaluateDialog.vue 334 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/ensureResultsValidity/index.vue 670 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/nonconformingWork/nonconformingDistribution/components/formDia.vue 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/nonconformingWork/nonconformingDistribution/index.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/nonconformingWork/nonconformingItem/components/qualityInfo.vue 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/nonconformingWork/nonconformingItem/index.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/reportResults/index.vue 409 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/sampleDisposal/index.vue 609 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/uncertainty/index.vue 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html
@@ -227,4 +227,5 @@
  </body>
  <script src="<%= BASE_URL %>luckysheet/plugins/js/plugin.js"></script>
  <script src="<%= BASE_URL %>luckysheet/luckysheet.umd.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
</html>
src/api/cnas/process/complaint.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,57 @@
// æŠ•诉汇总表相关接口
import request from "@/utils/request";
// æŠ•诉处理新增
export function addProcessComplain(data) {
  return request({
    url: "/processComplain/addProcessComplain",
    method: "post",
    data: data,
  });
}
//投诉处理详情
export function getProcessComplain(query) {
  return request({
    url: "/processComplain/getProcessComplain",
    method: "get",
    params: query,
  });
}
// æŠ•诉处理修改
export function doProcessComplain(data) {
  return request({
    url: "/processComplain/doProcessComplain",
    method: "post",
    data: data,
  });
}
//投诉处理导出
export function exportProcessComplain(query) {
  return request({
    url: "/processComplain/exportProcessComplain",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//投诉处理分页
export function pageProcessComplain(query) {
  return request({
    url: "/processComplain/pageProcessComplain",
    method: "get",
    params: query,
  });
}
//投诉处理删除
export function delProcessComplain(query) {
  return request({
    url: "/processComplain/delProcessComplain",
    method: "delete",
    params: query,
  });
}
src/api/cnas/process/ensureResults/ensureResultsValidity.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
// è´¨é‡ç›‘控计划页面相关接口
import request from "@/utils/request";
//监控年度计划列表
export function pageQualityMonitor(query) {
  return request({
    url: "/qualityMonitor/pageQualityMonitor",
    method: "get",
    params: query,
  });
}
// ç›‘控计划审核
export function examineQualityMonitor(data) {
  return request({
    url: "/qualityMonitor/examineQualityMonitor",
    method: "post",
    data: data,
  });
}
// ç›‘控计划批准
export function ratifyQualityMonitor(data) {
  return request({
    url: "/qualityMonitor/ratifyQualityMonitor",
    method: "post",
    data: data,
  });
}
//导出监控计划
export function exportQualityMonitorDetail(query) {
  return request({
    url: "/qualityMonitor/exportQualityMonitorDetail",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//监控计划删除
export function delQualitySupervise(query) {
  return request({
    url: "/qualityMonitor/delQualitySupervise",
    method: "delete",
    params: query,
  });
}
//监控计划详情列表
export function pageQualityMonitorDetail(query) {
  return request({
    url: "/qualityMonitor/pageQualityMonitorDetail",
    method: "get",
    params: query,
  });
}
//质量监控实施计划导出
export function exportQualityMonitorRatify(query) {
  return request({
    url: "/qualityMonitor/exportQualityMonitorRatify",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//质量监控评价导出
export function exportQualityMonitorEvaluate(query) {
  return request({
    url: "/qualityMonitor/exportQualityMonitorEvaluate",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//删除监控计划详情
export function delQualityMonitorDetail(query) {
  return request({
    url: "/qualityMonitor/delQualityMonitorDetail",
    method: "delete",
    params: query,
  });
}
//查询监控计划详情实施信息
export function getQualityMonitorRatify(query) {
  return request({
    url: "/qualityMonitor/getQualityMonitorRatify",
    method: "get",
    params: query,
  });
}
// æ–°å¢žç›‘控计划详情实施信息
export function addQualityMonitorRatify(data) {
  return request({
    url: "/qualityMonitor/addQualityMonitorRatify",
    method: "post",
    data: data,
  });
}
// æäº¤ç›‘控计划详情批准意见
export function addQualityMonitorRatifyOpinion(data) {
  return request({
    url: "/qualityMonitor/addQualityMonitorRatifyOpinion",
    method: "post",
    data: data,
  });
}
// æ–°å¢žç›‘控计划详情
export function addQualityMonitorDetail(data) {
  return request({
    url: "/qualityMonitor/addQualityMonitorDetail",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹ç›‘控计划详情
export function updateQualityMonitorDetail(data) {
  return request({
    url: "/qualityMonitor/updateQualityMonitorDetail",
    method: "post",
    data: data,
  });
}
//查询监控评价
export function getQualityMonitorEvaluate(query) {
  return request({
    url: "/qualityMonitor/getQualityMonitorEvaluate",
    method: "get",
    params: query,
  });
}
// æ–°å¢žç›‘控评价批准
export function addMonitorEvaluateOpinion(data) {
  return request({
    url: "/qualityMonitor/addMonitorEvaluateOpinion",
    method: "post",
    data: data,
  });
}
// æ–°å¢žç›‘控评价
export function addQualityMonitorEvaluate(data) {
  return request({
    url: "/qualityMonitor/addQualityMonitorEvaluate",
    method: "post",
    data: data,
  });
}
//删除监控评价附件列表
export function delVerifyEvaluateFileList(query) {
  return request({
    url: "/qualityMonitor/delVerifyEvaluateFileList",
    method: "delete",
    params: query,
  });
}
//查询监控评价附件列表
export function getEvaluateFileList(query) {
  return request({
    url: "/qualityMonitor/getEvaluateFileList",
    method: "get",
    params: query,
  });
}
src/api/cnas/process/ensureResults/qualityControlPlan.js
src/api/cnas/process/nonconformingWork.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
// ä¸ç¬¦åˆå·¥ä½œç›¸å…³æŽ¥å£
import request from "@/utils/request";
//查询监督记录不符合控制信息列表
export function pageSuperviseDetailAccording(query) {
  return request({
    url: "/qualitySupervise/pageSuperviseDetailAccording",
    method: "get",
    params: query,
  });
}
//导出不符合项
export function superviseDetailAccordingExport(query) {
  return request({
    url: "/qualitySupervise/superviseDetailAccordingExport",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//查询监督记录不符合控制信息
export function getSuperviseDetailAccording(query) {
  return request({
    url: "/qualitySupervise/getSuperviseDetailAccording",
    method: "get",
    params: query,
  });
}
//不符合项的分布分页查询
export function pageInconsistentDistribution(query) {
  return request({
    url: "/inconsistentDistribution/pageInconsistentDistribution",
    method: "get",
    params: query,
  });
}
//不符合项的分布删除
export function delInconsistentDistribution(query) {
  return request({
    url: "/inconsistentDistribution/delInconsistentDistribution",
    method: "delete",
    params: query,
  });
}
//导出不符合项的分布
export function exportInconsistentDistribution(query) {
  return request({
    url: "/inconsistentDistribution/exportInconsistentDistribution",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
//不符合项的分布详情
export function getInconsistentDistributionOne(query) {
  return request({
    url: "/inconsistentDistribution/getInconsistentDistributionOne",
    method: "get",
    params: query,
  });
}
// ä¸ç¬¦åˆé¡¹çš„分布新增
export function addInconsistentDistribution(data) {
  return request({
    url: "/inconsistentDistribution/addInconsistentDistribution",
    method: "post",
    data: data,
  });
}
// ä¸ç¬¦åˆé¡¹çš„分布修改
export function updateInconsistentDistribution(data) {
  return request({
    url: "/inconsistentDistribution/updateInconsistentDistribution",
    method: "post",
    data: data,
  });
}
src/api/cnas/process/reportResults.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
// æŠ¥å‘Šç»“果相关接口
import request from "@/utils/request";
//8报告结果-导出
export function exportProcessReport(data) {
  return request({
    url: "/processReport/exportProcessReport",
    method: "post",
    data: data,
  });
}
// 8报告结果-新增
export function addProcessReport(data) {
  return request({
    url: "/processReport/addProcessReport",
    method: "post",
    data: data,
  });
}
// 8报告结果-修改
export function doProcessReport(data) {
  return request({
    url: "/processReport/doProcessReport",
    method: "post",
    data: data,
  });
}
//8报告结果-删除
export function delProcessReport(query) {
  return request({
    url: "/processReport/delProcessReport",
    method: "delete",
    params: query,
  });
}
//8报告结果-列表
export function pageProcessReport(query) {
  return request({
    url: "/processReport/pageProcessReport",
    method: "get",
    params: query,
  });
}
src/api/cnas/process/sampleDisposal.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
// æ£€æµ‹æˆ–校准物品的处置
import request from "@/utils/request";
// ä¿®æ”¹
export function doProcessDeal(data) {
  return request({
    url: "/processDeal/doProcessDeal",
    method: "post",
    data: data,
  });
}
// æ–°å¢ž
export function addProcessDeal(data) {
  return request({
    url: "/processDeal/addProcessDeal",
    method: "post",
    data: data,
  });
}
// æäº¤åŽ†å²  ä¼ å‚id
export function submitProcessTotaldeal(data) {
  return request({
    url: "/processTotaldeal/submitProcessTotaldeal",
    method: "post",
    data: data,
  });
}
//查询详情  åˆ†é¡µæŸ¥è¯¢é‡Œé¢totaldealId  ä¼ å‚历史的id
export function pageProcessDeal(query) {
  return request({
    url: "/processDeal/pageProcessDeal",
    method: "get",
    params: query,
  });
}
// å®¡æ ¸  ä¼ å‚id和通过不通过state(中文)
export function checkProcessTotaldeal(data) {
  return request({
    url: "/processTotaldeal/checkProcessTotaldeal",
    method: "post",
    data: data,
  });
}
// æ‰¹å‡†  ä¼ å‚id和通过不通过state(中文)
export function ratifyProcessTotaldeal(data) {
  return request({
    url: "/processTotaldeal/ratifyProcessTotaldeal",
    method: "post",
    data: data,
  });
}
//删除
export function delProcessDeal(query) {
  return request({
    url: "/processDeal/delProcessDeal",
    method: "delete",
    params: query,
  });
}
//查看历史
export function pageProcessTotaldeal(query) {
  return request({
    url: "/processTotaldeal/pageProcessTotaldeal",
    method: "get",
    params: query,
  });
}
src/api/cnas/process/uncertainty.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
// ä¸ç¡®å®šåº¦è¯„定相关接口
import request from "@/utils/request";
//导出
export function exportProcessEvaluate(query) {
  return request({
    url: "/processEvaluate/exportProcessEvaluate",
    method: "get",
    responseType: "blob",
    params: query,
  });
}
// å¡«å†™ (主要上传id和备注note就好了)
export function doProcessEvaluate(data) {
  return request({
    url: "/processEvaluate/doProcessEvaluate",
    method: "post",
    data: data,
  });
}
//删除
export function delProcessEvaluate(query) {
  return request({
    url: "/processEvaluate/delProcessEvaluate",
    method: "delete",
    params: query,
  });
}
//分页
export function pageProcessEvaluate(query) {
  return request({
    url: "/processEvaluate/pageProcessEvaluate",
    method: "get",
    params: query,
  });
}
src/api/system/user.js
@@ -189,3 +189,11 @@
    params: query,
  });
}
// èŽ·å–å½“å‰ç™»å½•äººå‘˜éƒ¨é—¨
export function selectUserDepartmentLimsName(query) {
  return request({
    url: "/system/newUser/selectUserDepartmentLimsName",
    method: "get",
  });
}
src/components/Table/lims-table.vue
@@ -110,7 +110,7 @@
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="page.total > 0" :total="page.total" :layout="page.layout" :page.sync="page.current"
    <pagination v-if="page" v-show="page.total > 0" :total="page.total" :layout="page.layout" :page.sync="page.current"
      :limit.sync="page.size" @pagination="pagination" />
  </div>
</template>
src/main.js
@@ -71,6 +71,7 @@
Vue.prototype.uploadHeader = {
  Authorization: "Bearer " + getToken(),
};
// è§£å†³el-radio-group单选框自身的bug
Vue.directive("removeAriaHidden", {
  bind(el, binding) {
src/views/CNAS/process/complaint/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,629 @@
<template>
  <div class="Complaint">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">样品编号:</div>
        <div class="search_input"><el-input v-model="queryParams.sampleCode" clearable placeholder="请输入" size="small"
            @keyup.enter.native="refreshTable()"></el-input></div>
      </div>
      <div class="search_thing">
        <div class="search_label">投诉名称:</div>
        <div class="search_input">
          <el-input v-model="queryParams.complainName" clearable placeholder="请输入" size="small"
            @keyup.enter.native="refreshTable()"></el-input>
        </div>
      </div>
      <div class="search_thing" style="padding-left: 30px;">
        <el-button size="small" @click="refresh()">重 ç½®</el-button>
        <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
      </div>
      <div class="btn">
        <el-button :loading="outLoading" size="small" type="primary" @click="handleDown">导出</el-button>
        <el-button size="small" type="primary" @click="openAdd">新增</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading" :height="'calc(100vh - 290px)'"
        :page="page" @pagination="pagination"></lims-table>
    </div>
    <el-dialog :visible.sync="addDialogVisible" title="新增" width="400px">
      <el-row>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">投诉方名称:</div>
            <div class="search_input"><el-input v-model="addInfo.complainName" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">检验报告编号:</div>
            <div class="search_input">
              <el-input v-model="addInfo.code" clearable placeholder="请输入" size="small"></el-input>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">样品编号:</div>
            <div class="search_input"><el-input v-model="addInfo.sampleCode" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24">
          <div class="search_thing">
            <div class="search_label">投诉方式:</div>
            <div class="search_input"><el-input v-model="addInfo.complainMethod" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button :loading="addLoading" type="primary" @click="handleAdd">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <el-dialog :class="{ downPdf: title == '导出' }" :modal="title != '导出'" :title="title"
      :visible.sync="handleDialogVisible" width="800px">
      <div class="dialog-body">
        <div id="dialogBody">
          <h4 style="display: flex;align-items: center;flex-direction: column;justify-content: center;">
            <span style="font-size: 20px;">客户投诉受理单</span>
            <span>Customer complaint receipts</span>
          </h4>
          <p style="display: flex;justify-content: space-between;margin-top: 16px;">
            <span>{{ currentInfo0.complainNo }}</span>
            <span>NO:</span>
          </p>
          <table border="1" cellpadding="10" class="tables">
            <tr>
              <td colspan="3">
                <p>投诉方名称</p>
                <p class="en">Name of the complaining party</p>
              </td>
              <td colspan="3">{{ currentInfo0.complainName }}</td>
            </tr>
            <tr>
              <td>
                <p>检测报告编号</p>
                <p class="en">Test report number</p>
              </td>
              <td colspan="3">{{ currentInfo0.code }}</td>
              <td>
                <p>样品编号</p>
                <p class="en">Sample number</p>
              </td>
              <td>{{ currentInfo0.sampleCode }}</td>
            </tr>
            <tr>
              <td>
                <p>投诉人</p>
                <p class="en">Complainant</p>
              </td>
              <td>{{ currentInfo0.createUser }}</td>
              <td>
                <p>电话</p>
                <p class="en">Phone</p>
              </td>
              <td>{{ currentInfo0.phone }}</td>
              <td>
                <p>E-Mail</p>
                <p class="en">E-mail</p>
              </td>
              <td>{{ currentInfo0.email }}</td>
            </tr>
            <tr>
              <td>
                <p>投诉方式</p>
                <p class="en">Complaint method</p>
              </td>
              <td colspan="3">{{ currentInfo0.complainMethod }}</td>
              <td>
                <p>投诉日期</p>
                <p class="en">Date of complaint</p>
              </td>
              <td>{{ currentInfo0.createTime ? currentInfo0.createTime.split(' ')[0] : '' }}</td>
            </tr>
            <tr>
              <td>
                <p>问题记录</p>
                <p class="en">Problem logging</p>
              </td>
              <td colspan="5">
                <div class="user-content">
                  <el-input v-if="title == '处理投诉'" v-model="currentInfo0.problemRecords" :rows="3" placeholder="请输入内容"
                    type="textarea">
                  </el-input>
                  <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.problemRecords }}</p>
                </div>
                <div v-if="title != '处理投诉'" class="user-info">
                  <div style="width: 200px;margin-right: 10px;">
                    <p style="text-align: end;">质量负责人:</p>
                    <p class="en" style="text-align: end;">Quality Manager:</p>
                  </div>
                  <span>{{ currentInfo0.problemRecordsUserName }}</span>
                  <div style="width: 70px;">
                    <p>日期:</p>
                    <p class="en">Date:</p>
                  </div>
                  <span style="margin-right: 16px;">{{ currentInfo0.problemRecordsTime }}</span>
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <p>责任归属及投诉是否成立</p>
                <p class="en">Attribution of responsibility and whether the complaint is established</p>
              </td>
              <td colspan="5">
                <div class="user-content">
                  <el-input v-if="title == '处理投诉'" v-model="currentInfo0.dutyOwnership" :rows="3" placeholder="请输入内容"
                    type="textarea">
                  </el-input>
                  <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.dutyOwnership }}</p>
                </div>
                <div v-if="title != '处理投诉'" class="user-info">
                  <div style="width: 200px;margin-right: 10px;">
                    <p style="text-align: end;">质量负责人:</p>
                    <p class="en" style="text-align: end;">Quality Manager:</p>
                  </div>
                  <span>{{ currentInfo0.dutyOwnershipUserName }}</span>
                  <div style="width: 70px;">
                    <p>日期:</p>
                    <p class="en">Date:</p>
                  </div>
                  <span style="margin-right: 16px;">{{ currentInfo0.dutyOwnershipTime }}</span>
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <p>原因分析</p>
                <p class="en">Cause analysis</p>
              </td>
              <td colspan="5">
                <div class="user-content">
                  <el-input v-if="title == '处理投诉'" v-model="currentInfo0.causeAnalysis" :rows="3" placeholder="请输入内容"
                    type="textarea">
                  </el-input>
                  <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.causeAnalysis }}</p>
                </div>
                <div v-if="title != '处理投诉'" class="user-info">
                  <div style="width: 200px;margin-right: 10px;">
                    <p style="text-align: end;">责任部门负责人:</p>
                    <p class="en" style="text-align: end;">Head of Responsible Department:</p>
                  </div>
                  <span>{{ currentInfo0.causeAnalysisUserName }}</span>
                  <div style="width: 70px;">
                    <p>日期:</p>
                    <p class="en">Date:</p>
                  </div>
                  <span style="margin-right: 16px;">{{ currentInfo0.causeAnalysisTime }}</span>
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <p>纠正措施</p>
                <p class="en">Corrective actions</p>
              </td>
              <td colspan="5">
                <div class="user-content">
                  <el-input v-if="title == '处理投诉'" v-model="currentInfo0.correctiveAction" :rows="3" placeholder="请输入内容"
                    type="textarea">
                  </el-input>
                  <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveAction }}</p>
                </div>
                <div v-if="title != '处理投诉'" class="user-info">
                  <div style="width: 200px;margin-right: 10px;">
                    <p style="text-align: end;">责任部门负责人:</p>
                    <p class="en" style="text-align: end;">Head of Responsible Department:</p>
                  </div>
                  <span>{{ currentInfo0.correctiveActionUserName }}</span>
                  <div style="width: 70px;">
                    <p>日期:</p>
                    <p class="en">Date:</p>
                  </div>
                  <span style="margin-right: 16px;">{{ currentInfo0.correctiveActionTime }}</span>
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <p>纠正措施确认</p>
                <p class="en">Corrective actions confirmation</p>
              </td>
              <td colspan="5">
                <div class="user-content">
                  <el-input v-if="title == '处理投诉'" v-model="currentInfo0.correctiveActionConfirmation" :rows="3"
                    placeholder="请输入内容" type="textarea">
                  </el-input>
                  <p v-else style="text-align: left;line-height: 26px;">{{ currentInfo0.correctiveActionConfirmation }}
                  </p>
                </div>
                <div v-if="title != '处理投诉'" class="user-info">
                  <div style="width: 200px;margin-right: 10px;">
                    <p style="text-align: end;">质量负责人:</p>
                    <p class="en" style="text-align: end;">Quality Manager:</p>
                  </div>
                  <span>{{ currentInfo0.correctiveActionConfirmationUserName }}</span>
                  <div style="width: 70px;">
                    <p>日期:</p>
                    <p class="en">Date:</p>
                  </div>
                  <span style="margin-right: 16px;">{{ currentInfo0.correctiveActionConfirmationTime }}</span>
                </div>
              </td>
            </tr>
          </table>
        </div>
      </div>
      <span v-if="title == '处理投诉'" slot="footer" class="dialog-footer">
        <el-button @click="handleDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button :loading="addLoading" type="primary" @click="submit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import { getYearAndMonthAndDays } from '@/utils/date'
import { exportHtmlToPDF } from '@/utils/downHtmlToPDF'
import {
  addProcessComplain,
  getProcessComplain,
  doProcessComplain,
  exportProcessComplain,
  pageProcessComplain,
  delProcessComplain
} from '@/api/cnas/process/complaint.js'
import { mapGetters } from "vuex";
export default {
  components: {
    limsTable
  },
  data() {
    return {
      addPower: false,
      outLoading: false,
      addDialogVisible: false,
      addLoading: false,
      handleDialogVisible: false,
      title: '处理投诉',
      addInfo: {},//新增信息
      currentInfo: null,//接口请求回来的信息
      currentInfo0: {},//用户编辑过后的信息
      outPower: false,
      queryParams: {},
      tableData: [],
      column: [
        { label: "投诉名称", prop: "complainName" },
        { label: "投诉人", prop: "complainant" },
        { label: "投诉日期", prop: "createTime" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "查看",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
            {
              name: "处理",
              type: "text",
              clickFun: (row) => {
                this.handleWork(row);
              },
            },
            {
              name: "导出",
              type: "text",
              clickFun: (row) => {
                this.handleOut(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
    };
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  mounted() {
    // this.entityCopy = this.HaveJson(this.componentData.entity);
    this.getList()
  },
  methods: {
    // æƒé™åˆ†é…
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let up = false
      let del = false
      let add = false
      let out = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'doProcessComplain') {
          up = true
        }
        if (power[i].menuMethod == 'addProcessComplain') {
          add = true
        }
        if (power[i].menuMethod == 'delProcessComplain') {
          del = true
        }
        if (power[i].menuMethod == 'exportProcessComplain') {
          out = true
        }
      }
      if (!up) {
        this.componentData.do.splice(2, 1)
      }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      this.outPower = out
      this.addPower = add
    },
    openAdd() {
      this.addInfo = {}
      this.addDialogVisible = true
    },
    handleAdd() {
      this.addLoading = true
      addProcessComplain(this.addInfo).then((res) => {
        this.addLoading = false
        if (res.code == 201) {
          this.$message({
            type: 'error',
            message: '新增失败'
          })
          return
        }
        this.$message({
          type: 'success',
          message: '新增成功'
        })
        this.addDialogVisible = false
        this.refresh()
      })
    },
    // å¤„理投诉
    handleWork(row) {
      getProcessComplain({ id: row.id }).then((res) => {
        this.currentInfo = res.data
        this.currentInfo0 = this.HaveJson(res.data)
        this.title = '处理投诉'
        this.handleDialogVisible = true
      })
    },
    submit() {
      this.handleParam('problemRecords')
      this.handleParam('dutyOwnership')
      this.handleParam('causeAnalysis')
      this.handleParam('correctiveAction')
      this.handleParam('correctiveActionConfirmation')
      this.addLoading = true
      for (let i in this.currentInfo0) {
        if (!this.currentInfo0[i]) {
          delete this.currentInfo0[i]
        }
      }
      doProcessComplain(this.currentInfo0).then((res) => {
        this.addLoading = false
        if (res.code == 201) {
          this.$message({
            type: 'error',
            message: '提交失败'
          })
          return
        }
        this.$message({
          type: 'success',
          message: '提交成功'
        })
        this.handleDialogVisible = false
        this.refresh()
      })
    },
    /**
     * å¤„理参数
     *
     * @param {string} type - éœ€è¦å¤„理的参数类型
     */
    handleParam(type) {
      if (this.currentInfo0[type] != this.currentInfo[type]) {
        this.currentInfo0[type + 'User'] = this.userId
        this.currentInfo0[type + 'Time'] = getYearAndMonthAndDays()
      }
    },
    // æŸ¥çœ‹æŠ•诉
    handleLook(row) {
      addProcessComplain({ id: row.id }).then((res) => {
        this.currentInfo = res.data
        this.currentInfo0 = this.HaveJson(res.data)
        this.title = '查看投诉'
        this.handleDialogVisible = true
      })
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageProcessComplain({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData = res.data.records;
            this.page.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.getList();
    },
    refresh() {
      this.queryParams = {};
      this.page.current = 1;
      this.getList();
    },
    refreshTable() {
      this.page.current = 1;
      this.getList();
    },
    handleDown() {
      this.outLoading = true
      exportProcessComplain(this.queryParams).then(res => {
        this.outLoading = false
        if (res.code == 201) {
          return
        }
        const blob = new Blob([res], { type: 'application/octet-stream' });
        this.$download.saveAs(blob, '投诉情况汇总表.xlsx');
      })
    },
    handleOut(row) {
      getProcessComplain({ id: row.id }).then((res) => {
        if (res.code == 201) {
          return
        }
        this.currentInfo = res.data
        this.currentInfo0 = this.HaveJson(res.data)
        this.title = '导出'
        this.handleDialogVisible = true
        setTimeout(() => {
          this.$nextTick(() => {
            const element = document.getElementById("dialogBody");
            exportHtmlToPDF(element, '投诉详情').then(res => {
              this.handleDialogVisible = false
            })
          })
        }, 500);
      })
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProcessComplain({ id: row.id }).then((res) => {
            if (res.code == 201) return;
            this.$message.success("删除成功");
            this.refresh();
          });
        })
        .catch(() => { });
    },
  },
}
</script>
<style scoped>
.title {
  height: 60px;
  line-height: 60px;
}
.search {
  background-color: #fff;
  height: 80px;
  display: flex;
  align-items: center;
  position: relative;
}
.search_thing {
  width: 350px;
  display: flex;
  align-items: center;
}
.search_label {
  width: 110px;
  font-size: 14px;
  text-align: right;
}
.search_input {
  width: calc(100% - 110px);
}
.table {
  background-color: #fff;
  height: calc(100% - 60px - 80px - 10px - 40px);
  padding: 20px;
}
.dialog-body {
  max-height: 75vh;
  overflow-y: auto;
}
.tables {
  table-layout: fixed;
  width: 100%;
}
.tables td {
  height: 40px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
.en {
  font-size: 12px;
  word-break: break-word;
  /* è‡ªåŠ¨æ–­è¡Œ */
  overflow-wrap: break-word;
  /* é˜²æ­¢æº¢å‡º */
  white-space: normal;
  /* é»˜è®¤æ¢è¡Œ */
}
.user-info {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.user-content {
  min-height: 60px;
}
.downPdf {
  opacity: 0 !important;
}
.btn {
  position: absolute;
  top: 16px;
  right: 20px;
}
</style>
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/ViewRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,171 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="附件上传" width="80%" @closed="closeFilesLook">
      <div style="display: flex;justify-content: space-between;">
        <el-upload ref='upload' :action="fileAction" :auto-upload="true" :before-upload="fileBeforeUpload"
          :data="{ detailsEvaluateId: info.detailsEvaluateId }" :headers="uploadHeader" :on-error="onError"
          :on-success="handleSuccessUp" :show-file-list="false"
          accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar' style="width: 80px !important;">
          <el-button size="small" style="height: 38px" type="primary">附件上传</el-button>
        </el-upload>
      </div>
      <div>
        <limsTable ref="yearTable" :column="columnData" :height="'calc(100vh - 47em)'" :highlightCurrentRow="true"
          :table-data="tableData" :table-loading="tableLoading" style="margin-top: 0.5em;">
        </limsTable>
      </div>
    </el-dialog>
    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="查看附件" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="javaApi + '/word/' + currentInfo.fileUrl"
        style="height: 90vh;overflow-y: auto;top: 0" />
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import filePreview from "@/components/Preview/filePreview.vue";
import {
  delVerifyEvaluateFileList,
  getEvaluateFileList,
} from '@/api/cnas/process/ensureResults/ensureResultsValidity.js'
export default {
  name: 'ViewRecord',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { filePreview, limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          dataType: 'action',
          minWidth: '100',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '预览',
              type: 'text',
              clickFun: (row) => {
                this.handleLook(row)
              }
            },
            {
              name: '下载',
              type: 'text',
              clickFun: (row) => {
                this.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo: {},
      lookDialogVisible: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      console.log(1111, row)
      this.info = row
      this.searchTableList()
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList() {
      this.tableLoading = true
      getEvaluateFileList({ detailsEvaluateId: this.info.detailsEvaluateId }).then(res => {
        this.tableLoading = false
        if (res.code === 201) return
        this.tableData = res.data
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    closeFilesLook() {
      this.filesDialogVisible = false
    },
    // ä¸‹è½½
    upload(row) {
      let url = '';
      if (row.type == 1) {
        url = this.javaApi + '/img/' + row.fileUrl
        this.$download.saveAs(url, row.fileName)
      } else {
        url = this.javaApi + '/word/' + row.fileUrlrow.fileName;
        link.click();
        this.$download.saveAs(url, row.fileName)
      }
    },
    // åˆ é™¤
    delete(row) {
      this.tableLoading = true
      delVerifyEvaluateFileList({ evaluateFileId: row.evaluateFileId }).then(res => {
        this.tableLoading = false
        if (res.code === 201) return
        this.$message.success('删除成功')
        this.searchTableList()
      }).catch(err => {
        this.tableLoading = false
        console.log('err---', err);
      })
    },
    // ä¸Šä¼ éªŒè¯
    fileBeforeUpload(file) {
      let flag = true
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        flag = false
      }
      if (!flag) {
        return Promise.reject(flag); //正确的终止
      }
    },
    onError(err, file, fileList, type) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response,) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.searchTableList()
      }
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row) {
      this.currentInfo = row
      this.lookDialogVisible = true
    },
  },
  computed: {
    fileAction() {
      return this.javaApi + '/qualityMonitor/uploadEvaluateFile'
    }
  },
};
</script>
<style scoped></style>
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/carryOutDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,324 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="实施"
      width="60%" @close="closeCarryOutDia">
      <el-steps :active="currentStep" align-center finish-status="success">
        <el-step title="实施"></el-step>
        <el-step title="批准"></el-step>
      </el-steps>
      <div style="height: 620px;overflow-y: auto">
        <table border="1" cellspacing="10" class="tables">
          <tr>
            <td class="td-title">
              <p>监控项目:</p>
            </td>
            <td colspan="3">
              <el-input v-if="currentStep == 0" v-model="form.monitorProject" placeholder="请输入内容" size="small">
              </el-input>
              <span v-else class="td-info"> {{ form.monitorProject }}</span>
            </td>
            <td class="td-title">
              <p>监控时间:</p>
            </td>
            <td colspan="3">
              <el-input v-if="currentStep == 0" v-model="form.monitorData" placeholder="请输入内容" size="small">
              </el-input>
              <span v-else class="td-info"> {{ form.monitorData }}</span>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>监控目的:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.monitorPurpose" :rows="3" placeholder="请输入内容"
                  size="small" type="textarea">
                </el-input>
                <span v-else class="td-info2"> {{ form.monitorPurpose }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>监控方法:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.monitorMethod" :rows="4" placeholder="请输入内容"
                  size="small" type="textarea">
                </el-input>
                <span v-else class="td-info2"> {{ form.monitorMethod }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>参加人员:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.participant" :rows="3" placeholder="请输入内容" size="small"
                  type="textarea">
                </el-input>
                <span v-else class="td-info2"> {{ form.participant }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>过程控制:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.processControl" :rows="3" placeholder="请输入内容"
                  size="small" type="textarea">
                </el-input>
                <span v-else class="td-info2"> {{ form.processControl }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>结果评价标准(如何评价):</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.howEvaluate" :rows="3" placeholder="请输入内容" size="small"
                  type="textarea">
                </el-input>
                <span v-else class="td-info2"> {{ form.howEvaluate }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="8">
              <div>
                <p>经费预算:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.budget" placeholder="请输入内容" size="small">
                </el-input>
                <span v-else class="td-info2"> {{ form.budget }}</span>
              </div>
            </td>
          </tr>
          <tr>
            <td colspan="4">
              <div>
                <p>检测部门:</p>
              </div>
              <div>
                <el-input v-if="currentStep == 0" v-model="form.inspectionDepartment" placeholder="请输入内容" size="small">
                </el-input>
                <span v-else class="td-info2"> {{ form.inspectionDepartment }}</span>
              </div>
            </td>
            <td colspan="4">
              <div v-if="currentStep == 0">
                <div>选择批准人:</div>
                <div>
                  <el-select v-if="currentStep == 0" v-model="form.ratifyUserId" clearable filterable placeholder="请选择"
                    size="small">
                    <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
                    </el-option>
                  </el-select>
                  <span v-else class="td-info2"> {{ form.ratifyName }}</span>
                </div>
              </div>
              <div v-else>
                <div>
                  <p>批准意见:</p>
                </div>
                <div>
                  <el-input v-if="currentStep == 1" v-model="form.ratifyOpinion" :rows="3" placeholder="请输入内容"
                    size="small" type="textarea">
                  </el-input>
                  <span v-if="currentStep == 2" class="td-info2"> {{ form.ratifyOpinion }}</span>
                  <span v-if="currentStep == 2" class="td-info3"> {{ '批准人:' + form.ratifyName }}</span>
                </div>
              </div>
            </td>
          </tr>
        </table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeCarryOutDia">取 æ¶ˆ</el-button>
        <el-button v-if="currentStep != 2" :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  getQualityMonitorRatify,
  addQualityMonitorRatify,
  addQualityMonitorRatifyOpinion,
} from '@/api/cnas/process/ensureResults/ensureResultsValidity.js'
import { selectUserCondition } from "@/api/system/user";
export default {
  name: 'carryOutDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      currentStep: 0,
      form: {
        monitorProject: '',
        monitorData: '',
        monitorPurpose: '',
        monitorMethod: '',
        participant: '',
        processControl: '',
        howEvaluate: '',
        budget: '',
        inspectionDepartment: '',
        ratifyUserId: '',
        ratifyOpinion: '',
        qualityMonitorDetailsId: '',
        ratifyName: '',
      },
      personList: [],
      editLoad: false,
      isCarryOut: false, // æ˜¯å¦ä¸ºå®žæ–½
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.searchInfo(row)
      this.getAuthorizedPerson()
    },
    // æŸ¥è¯¢ç›‘控计划详情实施信息
    searchInfo(row) {
      getQualityMonitorRatify({ qualityMonitorDetailsId: row.qualityMonitorDetailsId }).then(res => {
        if (res.code === 201) return
        // æœ‰detailsRatifyId则说明提交过实施信息
        if (res.data.detailsRatifyId) {
          // æ˜¯å¦ç»“束0:未结束, 1:已结束
          if (res.data.isFinish == 0) {
            this.currentStep = 1
          } else if (res.data.isFinish == 1) {
            this.currentStep = 2
          }
        } else {
          this.currentStep = 0
        }
        this.form = res.data
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // æäº¤
    handleEdit() {
      this.editLoad = true
      if (this.currentStep == 0) {
        this.addInfo()
      } else {
        this.editInfo()
      }
    },
    // æäº¤å®žæ–½
    addInfo() {
      addQualityMonitorRatify(this.form).then(res => {
        this.editLoad = false
        if (res.code === 201) return
        this.$message.success('操作成功')
        this.closeCarryOutDia()
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // æäº¤æ‰¹å‡†
    editInfo() {
      addQualityMonitorRatifyOpinion(this.form).then(res => {
        this.editLoad = false
        if (res.code === 201) return
        this.$message.success('操作成功')
        this.closeCarryOutDia()
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // å…³é—­å¼¹æ¡†
    closeCarryOutDia() {
      this.formDia = false
      this.$emit('closeCarryOutDia')
    },
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin: 20px auto 50px !important;
}
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.td-title {
  height: 40px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 6px;
}
.td-info {
  display: inline-block;
  width: 100%;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
.td-info2 {
  display: inline-block;
  width: 90%;
  text-align: left;
  font-size: 16px;
  word-wrap: break-word;
  white-space: normal;
  margin-left: 20px;
}
.tables td {
  height: 40px;
  width: 100px;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 6px;
}
.td-info3 {
  width: 90%;
  display: inline-block;
  text-align: right;
}
</style>
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/detailFormDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,150 @@
<template>
  <div>
    <el-dialog title="编辑" :visible.sync="formDia" :close-on-click-modal="false" :close-on-press-escape="false"
      width="80%" @close="closeDia">
      <el-form :model="form" :rules="rules" ref="form" label-width="140px">
        <el-col :span="12">
          <el-form-item label="监控目的" prop="monitorPurpose">
            <el-input v-model="form.monitorPurpose" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="计划开展时间" prop="plannedTime">
            <el-input v-model="form.plannedTime" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="监控项目" prop="monitorProject">
            <el-input v-model="form.monitorProject" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="参加单位(人员)" prop="participant">
            <el-input v-model="form.participant" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="预算(元)" prop="budget">
            <el-input v-model="form.budget" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="组织人员" prop="organization">
            <el-input v-model="form.organization" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="监控方式" prop="monitorWay">
            <el-input v-model="form.monitorWay" size="small" clearable></el-input>
          </el-form-item>
        </el-col>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitForm" :loading="upLoad">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  addQualityMonitorDetail,
  updateQualityMonitorDetail,
} from '@/api/cnas/process/ensureResults/ensureResultsValidity.js'
export default {
  name: 'detailFormDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  props: ['qualityMonitorId'],
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        qualityMonitorDetailsId: '',
        monitorPurpose: '',
        plannedTime: '',
        monitorProject: '',
        participant: '',
        budget: '',
        organization: '',
        monitorWay: '',
      },
      rules: {
        monitorPurpose: [{ required: true, message: '请输入监控目的', trigger: 'blur' }],
        monitorProject: [{ required: true, message: '请输入监控项目', trigger: 'blur' }],
      },
      upLoad: false,
      operationType: '',
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(type, row) {
      this.formDia = true
      this.operationType = type
      if (type === 'edit') {
        this.searchInfo(row)
      }
    },
    searchInfo(row) {
      this.form = { ...row }
    },
    // æäº¤è¡¨å•
    submitForm() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          if (this.operationType === 'add') {
            this.handleAdd()
          } else {
            this.handleEdit()
          }
        }
      })
    },
    // æäº¤æ–°å¢ž
    handleAdd() {
      let entity = this.HaveJson(this.form)
      entity.qualityMonitorId = this.qualityMonitorId
      this.upLoad = true
      addQualityMonitorDetail(entity).then(res => {
        this.upLoad = false
        if (res.code === 201) return
        this.$message.success('新增成功')
        this.closeDia()
      }).catch(err => {
        console.log('err---', err);
        this.upLoad = false
      })
    },
    // æäº¤ä¿®æ”¹
    handleEdit() {
      const entity = this.HaveJson(this.form)
      this.upLoad = true
      updateQualityMonitorDetail(entity).then(res => {
        this.upLoad = false
        if (res.code === 201) return
        this.$message.success('修改成功')
        this.closeDia()
      }).catch(err => {
        console.log('err---', err);
        this.upLoad = false
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia() {
      this.$refs.form.resetFields();
      this.formDia = false
      this.$emit('closeDia')
    },
  }
};
</script>
<style scoped>
>>>.el-dialog__body {
  max-height: 720px;
  overflow-y: auto;
}
</style>
src/views/CNAS/process/ensureResults/ensureResultsValidity/components/evaluateDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,334 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="质量监控评价"
      width="60%" @close="closeEvaDia">
      <div style="text-align: right">
        <el-button size="small" type="primary" @click="viewTestRecord">附件上传</el-button>
      </div>
      <el-steps :active="currentStep" align-center finish-status="success">
        <el-step title="监控计划实施情况" @click.native="setStep(0)"></el-step>
        <el-step title="监控结果评价" @click.native="setStep(1)"></el-step>
        <el-step title="评审结论(是否采取措施)" @click.native="setStep(2)"></el-step>
      </el-steps>
      <div>
        <table border="1" cellspacing="10" class="tables">
          <tr v-if="showStep === 0">
            <td class="td-title">
              <p><span class="required-span">* </span>评审目的:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-input v-if="showStep === 0 && currentStep === 0" v-model="form.reviewPurpose" placeholder="请输入内容"
                size="small">
              </el-input>
              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewPurpose }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 0">
            <td class="td-title">
              <p><span class="required-span">* </span>评审人员:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-input v-if="showStep === 0 && currentStep === 0" v-model="form.reviewUser" placeholder="请输入内容"
                size="small">
              </el-input>
              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewUser }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 0">
            <td class="td-title">
              <p><span class="required-span">* </span>评审日期:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-input v-if="showStep === 0 && currentStep === 0" v-model="form.reviewTime" placeholder="请输入内容"
                size="small">
              </el-input>
              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.reviewTime }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 0">
            <td class="td-title">
              <p><span class="required-span">* </span>监控计划实施情况:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-input v-if="showStep === 0 && currentStep === 0" v-model="form.implementCondition" :rows="5"
                placeholder="请输入内容" size="small" type="textarea">
              </el-input>
              <span v-if="showStep === 0 && currentStep !== 0" class="td-info1"> {{ form.implementCondition }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 0">
            <td class="td-title">
              <p>实施部门:</p>
            </td>
            <td class="td-info">
              <span> {{ form.implementDepartment }}</span>
            </td>
            <td v-if="currentStep === 0" class="td-title">
              <p>请选择下一步负责人:</p>
            </td>
            <td v-if="currentStep === 0" class="td-info">
              <el-select v-model="form.implementUserId" clearable filterable placeholder="请选择" size="small">
                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </td>
          </tr>
          <tr v-if="showStep === 1">
            <td class="td-title">
              <p>监控结果评价:</p>
            </td>
            <td class="td-info" colspan="4">
              <el-input v-if="showStep === 1 && currentStep === 1" v-model="form.implementResult" :rows="5"
                placeholder="请输入内容" size="small" type="textarea">
              </el-input>
              <span v-if="showStep === 1 && currentStep !== 1" class="td-info1"> {{ form.implementResult }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 1">
            <td class="td-title">
              <p>当前负责人:</p>
            </td>
            <td class="td-info" colspan="4">
              {{ form.implementName }}
            </td>
          </tr>
          <tr v-if="showStep === 1">
            <td v-if="currentStep === 1" class="td-title">
              <p>请选择下一步负责人:</p>
            </td>
            <td v-if="currentStep === 1" class="td-info" colspan="4">
              <el-select v-model="form.ratifyUserId" clearable filterable placeholder="请选择" size="small">
                <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </td>
          </tr>
          <tr v-if="showStep === 2">
            <td class="td-title">
              <p>评审结论(是否采取措施):</p>
            </td>
            <td class="td-info" colspan="4">
              <el-input v-if="showStep === 2 && currentStep === 2" v-model="form.ratifyOpinion" :rows="5"
                placeholder="请输入内容" size="small" type="textarea">
              </el-input>
              <span v-if="showStep === 2 && currentStep !== 2" class="td-info1"> {{ form.ratifyOpinion }}</span>
            </td>
          </tr>
          <tr v-if="showStep === 2">
            <td class="td-title">
              <p>当前负责人:</p>
            </td>
            <td class="td-info" colspan="4">
              {{ form.ratifyUserName }}
            </td>
          </tr>
          <tr v-if="showStep === 2">
            <td class="td-title">
              <p>审批日期:</p>
            </td>
            <td class="td-info" colspan="4">
              {{ form.ratifyTime }}
            </td>
          </tr>
        </table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeEvaDia">取 æ¶ˆ</el-button>
        <el-button v-if="currentStep !== 3" :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
    <view-record v-if="ViewRecord" ref="ViewRecord"></view-record>
  </div>
</template>
<script>
import ViewRecord from './ViewRecord.vue';
import {
  getQualityMonitorEvaluate,
  addMonitorEvaluateOpinion,
  addQualityMonitorEvaluate,
} from '@/api/cnas/process/ensureResults/ensureResultsValidity.js'
import { selectUserCondition } from "@/api/system/user";
import { selectUserDepartmentLimsName } from "@/api/system/user";
export default {
  name: 'evaluateDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { ViewRecord },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      currentStep: 0,
      showStep: 0,
      form: {
        implementDepartment: '',
        reviewPurpose: '',
        reviewUser: '',
        reviewTime: '',
        implementCondition: '',
        implementName: '',
        implementUserId: '',
        implementResult: '',
        ratifyUserName: '',
        ratifyUserId: '',
        ratifyOpinion: '',
        qualityMonitorDetailsId: '',
        ratifyTime: '',
        detailsEvaluateId: '',
      },
      editLoad: false,
      personList: [],
      ViewRecord: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.searchInfo(row)
      this.getAuthorizedPerson()
      this.getDepartment()
    },
    // æŸ¥è¯¢ç›‘控计划详情实施信息
    searchInfo(row) {
      this.form.qualityMonitorDetailsId = row.qualityMonitorDetailsId
      getQualityMonitorEvaluate({ qualityMonitorDetailsId: row.qualityMonitorDetailsId }).then(res => {
        if (res.code === 201) return
        if (res.data === null) {
          this.showStep = 0
          this.currentStep = 0
        } else {
          this.form = res.data
          if (res.data.isFinish === 0) {
            if (res.data.implementUserId && !res.data.ratifyUserId) {
              this.showStep = 1
              this.currentStep = 1
            } else if (res.data.implementUserId && res.data.ratifyUserId) {
              this.showStep = 2
              this.currentStep = 2
            }
          } else {
            this.currentStep = 3
            this.showStep = 2
          }
        }
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // æäº¤
    handleEdit() {
      if (this.currentStep === 2) {
        addMonitorEvaluateOpinion(this.form).then(res => {
          this.editLoad = false
          if (res.code === 201) return
          this.$message.success('操作成功')
          this.closeEvaDia()
        }).catch(err => {
          console.log('err---', err);
          this.editLoad = false
        })
      } else {
        if (!this.form.reviewPurpose) {
          this.$message.warning('请填写评审目的')
          return
        }
        if (!this.form.reviewUser) {
          this.$message.warning('请填写评审人员')
          return
        }
        if (!this.form.reviewTime) {
          this.$message.warning('请填写评审日期')
          return
        }
        if (!this.form.implementCondition) {
          this.$message.warning('请填写监控计划实施情况')
          return
        }
        if (!this.form.implementUserId) {
          this.$message.warning('请选择下一步负责人')
          return
        }
        if (this.currentStep === 1) {
          if (!this.form.ratifyUserId) {
            this.$message.warning('请选择下一步负责人')
            return
          }
        }
        addQualityMonitorEvaluate(this.form).then(res => {
          this.editLoad = false
          if (res.code === 201) return
          this.$message.success('操作成功')
          this.closeEvaDia()
        }).catch(err => {
          console.log('err---', err);
          this.editLoad = false
        })
      }
    },
    // å…³é—­å¼¹æ¡†
    closeEvaDia() {
      this.formDia = false
      this.$emit('closeEvaDia')
    },
    setStep(step) {
      this.showStep = step
    },
    viewTestRecord() {
      this.ViewRecord = true
      this.$nextTick(() => {
        this.$refs.ViewRecord.openDia(this.form)
      })
    },
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    getDepartment() {
      selectUserDepartmentLimsName().then(res => {
        if (res.code === 201) return
        this.form.implementDepartment = res.data
      })
    },
  }
};
</script>
<style scoped>
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.td-title {
  height: 40px;
  width: 170px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 6px;
}
.td-info {
  padding: 6px;
}
.td-info1 {
  display: inline-block;
  width: 100%;
  text-align: left;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
</style>
src/views/CNAS/process/ensureResults/ensureResultsValidity/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,670 @@
<template>
  <!--  7.7质量监控计划-->
  <div>
    <div class="table-card">
      <TableCard title="年度计划表" style="margin-top: 10px;">
        <template v-slot:form>
          <div class="items_center">
            <span>计划名称:</span>
            <el-input v-model="yearForm.monitorName" class="search" placeholder="请输入" size="small"></el-input>
            <el-button size="small" type="primary" @click="getYearPlanList">查询</el-button>
            <el-button size="small" @click="clearYear">重置</el-button>
          </div>
          <div>
            <el-upload ref='upload' :action="action" :before-upload="beforeUpload" :headers="uploadHeader"
              :on-error="onError" :data="uploadData" :on-success="handleSuccessUp" :show-file-list="false"
              accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'>
              <el-button :loading="upLoading" size="small" type="primary">导入</el-button>
            </el-upload>
          </div>
        </template>
        <template v-slot:table>
          <limsTable ref="yearTable" :column="yearColumnData" :height="'28vh'" :highlightCurrentRow="true"
            :rowClick="rowClick" :table-data="yearTableData" :table-loading="yearLoading"
            style="margin-top: 0.5em;padding: 0 15px;" :page="yearPage">
          </limsTable>
        </template>
      </TableCard>
    </div>
    <div class="table-card">
      <TableCard title="年度计划明细表" style="margin-top: 10px;">
        <template v-slot:form>
          <div class="items_center">
            <span>监控目的:</span>
            <el-input v-model="yearDetailForm.monitorPurpose" class="search" placeholder="请输入" size="small"></el-input>
            <span>监控项目:</span>
            <el-input v-model="yearDetailForm.monitorProject" class="search" placeholder="请输入" size="small"></el-input>
            <el-button size="small" type="primary" @click="getYearDetailPlanList">查询</el-button>
            <el-button size="small" @click="clearDetail">重置</el-button>
          </div>
          <div>
            <el-button size="small" type="primary" @click="showDialog('add')">新增</el-button>
          </div>
        </template>
        <template v-slot:table>
          <limsTable :column="yearDetailColumnData" :height="'28vh'" :table-data="yearDetailTableData"
            :table-loading="yearDetailLoading" style="margin-top: 18px; padding: 0 15px;" :page="yearDetailPage">
          </limsTable>
        </template>
      </TableCard>
    </div>
    <!--新增修改弹框-->
    <detail-form-dialog v-if="formDia" ref="formDia" :qualityMonitorId="qualityMonitorId"
      @closeDia="closeDia"></detail-form-dialog>
    <!--实施流程弹框-->
    <carry-out-dialog v-if="carryOutDia" ref="carryOutDia" :qualityMonitorId="qualityMonitorId"
      @closeDia="closeCarryOutDia"></carry-out-dialog>
    <!--评价流程弹框-->
    <evaluate-dialog v-if="evaluateDialog" ref="evaluateDialog" @closeEvaDia="closeEvaDia"></evaluate-dialog>
    <el-dialog :visible.sync="examineDialog" title="审核" width="30%" @close="closeExamineDia">
      <span>
        å®¡æ ¸å¤‡æ³¨ï¼š
        <el-input v-model="examineInfo.examineRemark" type="textarea"></el-input>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="examineLoading" @click="handleReview(0)">不通过</el-button>
        <el-button :loading="examineLoading" type="primary" @click="handleReview(1)">通 è¿‡</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="ratifyDialog" title="批准" width="30%" @close="closeRatifyDia">
      <span>
        æ‰¹å‡†å¤‡æ³¨ï¼š
        <el-input v-model="ratifyInfo.ratifyRemark" type="textarea"></el-input>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button :loading="ratifyLoading" @click="handleRatify(0)">不批准</el-button>
        <el-button :loading="ratifyLoading" type="primary" @click="handleRatify(1)">批 å‡†</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="downloadDialog" title="导出" width="600px">
      <span>
        <el-button plain type="primary" @click="controlDown">实施计划导出</el-button>
        <el-button plain type="primary" @click="processingDown">评价导出</el-button>
      </span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="downloadDialog = false">取 æ¶ˆ</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import TableCard from '@/components/TableCard/index.vue';
import limsTable from "@/components/Table/lims-table.vue";
import DetailFormDialog from './components/detailFormDialog.vue';
import CarryOutDialog from './components/carryOutDialog.vue';
import EvaluateDialog from './components/evaluateDialog.vue';
import {
  pageQualityMonitor,
  examineQualityMonitor,
  ratifyQualityMonitor,
  exportQualityMonitorDetail,
  delQualitySupervise,
  pageQualityMonitorDetail,
  exportQualityMonitorRatify,
  exportQualityMonitorEvaluate,
  delQualityMonitorDetail,
} from '@/api/cnas/process/ensureResults/ensureResultsValidity.js'
export default {
  name: 'a7-Ensure-results-validity',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { EvaluateDialog, CarryOutDialog, DetailFormDialog, limsTable, TableCard },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      uploadData: {},
      yearForm: {
        monitorName: '',
      },
      yearPage: {
        current: 1,
        size: 20,
        total: 0
      },
      yearColumnData: [
        {
          label: '计划名称',
          prop: 'monitorName',
          minWidth: '150px'
        }, {
          label: '编制人',
          prop: 'writeName',
          minWidth: '100'
        }, {
          label: '编制日期',
          prop: 'writeTime',
          minWidth: '160'
        }, {
          dataType: 'tag',
          label: '审核状态',
          prop: 'examineStatus',
          minWidth: '100',
          formatData: (params) => {
            if (params === 0) {
              return '不通过';
            } else if (params === 1) {
              return '通过';
            } else {
              return null;
            }
          },
          formatType: (params) => {
            if (params === 0) {
              return 'danger';
            } else if (params === 1) {
              return 'success';
            } else {
              return null;
            }
          }
        }, {
          label: '审核内容',
          prop: 'examineRemark',
          minWidth: '100'
        }, {
          label: '审核人',
          prop: 'examineName',
          minWidth: '100'
        }, {
          label: '审核日期',
          prop: 'examineTime',
          minWidth: '160'
        }, {
          dataType: 'tag',
          label: '批准状态',
          prop: 'ratifyStatus',
          minWidth: '100',
          formatData: (params) => {
            if (params === 0) {
              return '不批准';
            } else if (params === 1) {
              return '批准';
            } else {
              return null;
            }
          },
          formatType: (params) => {
            if (params === 0) {
              return 'danger';
            } else if (params === 1) {
              return 'success';
            } else {
              return null;
            }
          }
        }, {
          label: '批准内容',
          prop: 'ratifyRemark',
          minWidth: '100'
        }, {
          label: '批准人',
          prop: 'ratifyName',
          minWidth: '100'
        }, {
          label: '批准日期',
          prop: 'ratifyTime',
          minWidth: '160'
        }, {
          label: '创建日期',
          prop: 'createTime',
          minWidth: '160'
        }, {
          label: '创建人',
          prop: 'createUser',
          minWidth: '100'
        }, {
          dataType: 'action',
          minWidth: '170',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '审核',
              type: 'text',
              disabled: (row) => {
                if (row.examineStatus === 1) {
                  return true
                } else {
                  return false
                }
              },
              clickFun: (row) => {
                this.examinePlan(row)
              }
            },
            {
              name: '批准',
              type: 'text',
              disabled: (row) => {
                if (row.ratifyStatus === 1 || row.examineStatus !== 1) {
                  return true
                } else {
                  return false
                }
              },
              clickFun: (row) => {
                this.approvalPlan(row)
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.handleDown(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delPlan(row)
              }
            }
          ]
        }],
      yearTableData: [],  // å¹´è¡¨
      yearLoading: false,
      yearDetailForm: {
        monitorPurpose: '',
        monitorProject: ''
      },
      yearDetailColumnData: [
        {
          label: '监控目的',
          prop: 'monitorPurpose',
          width: '150px',
          showOverflowTooltip: true,
        }, {
          label: '计划开展时间',
          prop: 'plannedTime',
          minWidth: '150px'
        }, {
          label: '监控项目',
          prop: 'monitorProject',
          minWidth: '150px'
        }, {
          label: '参加单位(人员)',
          prop: 'participant',
          minWidth: '150px'
        }, {
          label: '预算(元)',
          prop: 'budget',
          minWidth: '150px'
        }, {
          label: '组织人员',
          prop: 'organization',
          minWidth: '150px'
        }, {
          label: '监控方式',
          prop: 'monitorWay',
          minWidth: '150px'
        }, {
          dataType: 'action',
          width: '180',
          label: '操作',
          fixed: 'right',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.showDialog('edit', row)
              }
            },
            {
              name: '实施',
              type: 'text',
              clickFun: (row) => {
                this.carryOut(row)
              }
            },
            {
              name: '评价',
              type: 'text',
              clickFun: (row) => {
                this.evaluate(row)
              }
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delYearPlanDetail(row)
              }
            }
          ]
        }
      ],
      yearDetailTableData: [], // å¹´æ˜Žç»†è¡¨
      yearDetailLoading: false,
      yearDetailPage: {
        current: 1,
        size: 20,
        total: 0
      },
      formDia: false,
      qualityMonitorId: '',
      carryOutDia: false,
      evaluateDialog: false,
      examineDialog: false,
      examineLoading: false,
      ratifyDialog: false,
      ratifyLoading: false,
      examineInfo: {},
      ratifyInfo: {},
      upLoading: false,
      downloadDialog: false,
      download: {},
    };
  },
  mounted() {
    this.getYearPlanList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢å¹´åº¦è®¡åˆ’表
    getYearPlanList() {
      const entity = {
        monitorName: this.yearForm.monitorName,
      }
      const page = this.yearPage
      this.yearLoading = true
      pageQualityMonitor({ ...entity, ...page }).then(res => {
        this.yearLoading = false
        if (res.code === 201) return
        this.yearTableData = res.data.records
        this.yearPage.total = res.data.total
        if (this.yearTableData.length > 0) {
          this.rowClick(this.yearTableData[0])
        }
      }).catch(err => {
        console.log('err---', err);
        this.yearLoading = false
      })
    },
    clearYear() {
      this.yearForm.monitorName = ''
      this.getYearPlanList()
    },
    // å¯¼å…¥æµç¨‹
    beforeUpload(file) {
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        return false;
      } else {
        this.upLoading = true;
        let list = file.name.split(".")
        let suffix = list[list.length - 1]
        this.$set(this.uploadData, 'suffix', suffix)
        return true;
      }
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.getYearPlanList()
      }
    },
    // å®¡æ ¸
    examinePlan(row) {
      this.examineDialog = true
      this.examineInfo = row
    },
    handleReview(examineStatus) {
      // å®¡æ ¸çŠ¶æ€ , 0 ä¸é€šè¿‡, 1通过
      this.examineInfo.examineStatus = examineStatus
      this.examineLoading = true
      examineQualityMonitor(this.examineInfo).then(res => {
        this.examineLoading = false
        if (res.code === 201) return
        this.$message.success('操作成功')
        this.closeExamineDia()
      }).catch(err => {
        console.log('err---', err);
        this.examineLoading = false
      })
    },
    closeExamineDia() {
      this.examineDialog = false
      this.examineInfo.examineRemark = ''
      this.getYearPlanList()
    },
    // æ‰¹å‡†
    approvalPlan(row) {
      this.ratifyDialog = true
      this.ratifyInfo = row
    },
    handleRatify(ratifyStatus) {
      // æ‰¹å‡†çŠ¶æ€ , 0 ä¸é€šè¿‡, 1通过
      this.ratifyInfo.ratifyStatus = ratifyStatus
      this.ratifyLoading = true
      ratifyQualityMonitor(this.ratifyInfo).then(res => {
        this.ratifyLoading = false
        if (res.code === 201) return
        this.$message.success('操作成功')
        this.closeRatifyDia()
      }).catch(err => {
        console.log('err---', err);
        this.ratifyLoading = false
      })
    },
    closeRatifyDia() {
      this.ratifyDialog = false
      this.ratifyInfo.ratifyRemark = ''
      this.getYearPlanList()
    },
    // å¯¼å‡º
    handleDown(row) {
      exportQualityMonitorDetail({ qualityMonitorId: row.qualityMonitorId }).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/msword' });
        this.$download.saveAs(blob, row.monitorName + '.docx')
      })
    },
    // åˆ é™¤è¿›åº¦è®¡åˆ’表
    delPlan(row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.yearLoading = true
        delQualitySupervise({ qualityMonitorId: row.qualityMonitorId }).then(res => {
          this.yearLoading = false
          if (res.code === 201) return
          this.$message.success('删除成功')
          this.getYearPlanList();
        }).catch(err => {
          this.yearLoading = false
          console.log('err---', err);
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // å¹´åº¦è®¡åˆ’表格,点击行数据后刷新详情
    rowClick(row) {
      this.qualityMonitorId = row.qualityMonitorId
      this.getYearDetailPlanList()
    },
    // èŽ·å–å¹´åº¦æ˜Žç»†è¡¨
    getYearDetailPlanList() {
      const entity = {
        qualityMonitorId: this.qualityMonitorId,
        monitorPurpose: this.yearDetailForm.monitorPurpose,
        monitorProject: this.yearDetailForm.monitorProject,
      }
      const page = this.yearDetailPage
      this.yearDetailLoading = true
      pageQualityMonitorDetail({ ...entity, ...page }).then(res => {
        this.yearDetailLoading = false
        if (res.code === 201) return
        this.yearDetailTableData = res.data.records
        this.yearDetailPage.total = res.data.total
      }).catch(err => {
        console.log('err---', err);
        this.yearDetailLoading = false
      })
    },
    // é‡ç½®æ˜Žç»†è¡¨
    clearDetail() {
      this.yearDetailForm = {
        monitorPurpose: '',
        monitorProject: ''
      }
      this.getYearDetailPlanList()
    },
    // æ˜Žç»†è¡¨å®žæ–½
    carryOut(row) {
      this.carryOutDia = true
      this.$nextTick(() => {
        this.$refs.carryOutDia.openDia(row)
      })
    },
    closeCarryOutDia() {
      this.carryOutDia = false
      this.getYearDetailPlanList()
    },
    // æ‰“开评价弹框
    evaluate(row) {
      this.evaluateDialog = true
      this.$nextTick(() => {
        this.$refs.evaluateDialog.openDia(row)
      })
    },
    closeEvaDia() {
      this.evaluateDialog = false
      this.getYearDetailPlanList()
    },
    // æ‰“开导出弹框
    downLoadPost(row) {
      this.downloadDialog = true
      this.download = row
    },
    // æ‰“开年度明细新增、修改弹框
    showDialog(type, row) {
      this.formDia = true
      this.$nextTick(() => {
        this.$refs.formDia.openDia(type, row)
      })
    },
    closeDia() {
      this.formDia = false
      this.getYearDetailPlanList()
    },
    // æŽ§åˆ¶å•导出
    controlDown() {
      exportQualityMonitorRatify({
        qualityMonitorDetailsId: this.download.qualityMonitorDetailsId
      }).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/msword' });
        this.$download.saveAs(blob, '质量监控实施计划.docx')
      })
    },
    // å¤„理单导出
    processingDown() {
      exportQualityMonitorEvaluate({ qualityMonitorDetailsId: this.download.qualityMonitorDetailsId }).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/msword' });
        this.$download.saveAs(blob, '质量监控评价.docx')
      })
    },
    delYearPlanDetail(row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.yearDetailLoading = true
        delQualityMonitorDetail({ qualityMonitorDetailsId: row.qualityMonitorDetailsId }).then(res => {
          this.yearDetailLoading = false
          if (res.code === 201) return
          this.$message.success('删除成功')
          this.getYearDetailPlanList()
        }).catch(err => {
          this.yearDetailLoading = false
          console.log('err---', err);
        })
      })
    },
    // å¹´è®¡åˆ’分页
    handleYearCurrent(page) {
      this.yearPage.current = page
      this.getYearPlanList()
    },
    handleYearSizeChange(size) {
      this.yearPage.size = size
      this.getYearPlanList()
    },
    // å¹´æ˜Žç»†è®¡åˆ’分页
    handleYearDetailCurrent(page) {
      this.yearDetailPage.current = page
      this.getYearDetailPlanList()
    },
    handleYearDetailSizeChange(size) {
      this.yearDetailPage.size = size
      this.getYearDetailPlanList()
    },
  },
  // ç”¨äºŽä¸Šä¼ æ–‡ä»¶çš„信息
  computed: {
    action() {
      return this.javaApi + '/qualityMonitor/importQualityMonitor'
    }
  },
};
</script>
<style scoped>
.table-card {
  background-color: #ffffff;
}
.flex_column {
  display: flex;
  height: 80vh;
  flex-direction: column;
  overflow: auto;
  justify-content: space-between;
}
.pagination {
  display: flex;
  justify-content: space-between
}
.items_center {
  display: flex;
  align-items: center;
}
.date_box {
  margin: 0 5px;
}
.search {
  width: 150px;
  padding: 0 16px;
}
</style>
src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue
src/views/CNAS/process/nonconformingWork/nonconformingDistribution/components/formDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
<template>
  <div>
    <el-dialog v-loading="diaLoading" :close-on-click-modal="false" :close-on-press-escape="false"
      :visible.sync="formDia" title="不符合项的分布" width="90%" @close="closeDia">
      <table border="1" cellspacing="10" class="table">
        <tr>
          <td>章节号</td>
          <th class="div-with-line">
            <span style="float: left;">要素</span>
            <span style="float: right;">部门</span>
          </th>
          <th>主任</th>
          <th>技术负责人</th>
          <th>质量负责人</th>
          <th>综合室</th>
          <th>试验室</th>
          <th>合计</th>
          <th>占%</th>
        </tr>
        <tr v-for="(item, index) in distributionDetailList" :key="item.value">
          <td>{{ item.chapterNumber }}</td>
          <th>{{ item.essentials }}</th>
          <th>
            <el-input-number v-model="item.director" :precision="0" clearable size="small"></el-input-number>
          </th>
          <th>
            <el-input-number v-model="item.technology" :precision="0" clearable size="small"></el-input-number>
          </th>
          <th>
            <el-input-number v-model="item.quality" :precision="0" clearable size="small"></el-input-number>
          </th>
          <th>
            <el-input-number v-model="item.comprehensive" :precision="0" clearable size="small"></el-input-number>
          </th>
          <th>
            <el-input-number v-model="item.testing" :precision="0" clearable size="small"></el-input-number>
          </th>
          <th>
            {{ item.total }}
          </th>
          <th>
            {{ (item.proportion ? item.proportion : 0) + '%' }}
          </th>
        </tr>
        <tr>
          <td> </td>
          <th>
            å æ¯”
          </th>
          <th>
            {{ (distributionProportion.director ? distributionProportion.director : 0) + '%' }}
          </th>
          <th>
            {{ (distributionProportion.technology ? distributionProportion.technology : 0) + '%' }}
          </th>
          <th>
            {{ (distributionProportion.quality ? distributionProportion.quality : 0) + '%' }}
          </th>
          <th>
            {{ (distributionProportion.comprehensive ? distributionProportion.comprehensive : 0) + '%' }}
          </th>
          <th>
            {{ (distributionProportion.testing ? distributionProportion.testing : 0) + '%' }}
          </th>
          <th>
            {{ distributionProportion.total ? distributionProportion.total : 0 }}
          </th>
          <th> </th>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button :loading="loading" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import {
  getInconsistentDistributionOne,
  addInconsistentDistribution,
  updateInconsistentDistribution
} from '@/api/cnas/process/nonconformingWork.js'
export default {
  name: 'formDia',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      diaLoading: false,
      loading: false,
      distributionDetailList: [],
      form: {
      },
      distributionProportion: {}
    };
  },
  mounted() {
  },
  // æ–¹æ³•集合
  methods: {
    // æ‰“开弹框
    openDia(type, row) {
      this.formDia = true
      this.operationType = type
      if (type !== 'add') {
        this.searchInfo(row)
      } else {
        this.selectEnumByCategory()
      }
    },
    // æŸ¥è¯¢è¯¦æƒ…
    searchInfo(row) {
      this.diaLoading = true
      getInconsistentDistributionOne({ distributionId: row.distributionId }).then(res => {
        this.diaLoading = false
        if (res.code === 201) return
        this.form = res.data
        this.distributionDetailList = this.form.distributionDetailList
        this.distributionProportion = this.form.distributionProportion
      }).catch(err => {
        console.log(err)
        this.diaLoading = false
      })
    },
    // æäº¤å¼¹æ¡†æ•°æ®
    handleEdit() {
      const date = new Date();
      const year = date.getFullYear();
      this.loading = true
      const internalPlan = this.HaveJson(this.form)
      internalPlan.distributionYear = year
      internalPlan.distributionDetailList = this.HaveJson(this.distributionDetailList)
      if (this.operationType === 'add') {
        addInconsistentDistribution(internalPlan).then(res => {
          this.loading = false
          if (res.code === 201) return
          this.$message.success('操作成功')
          this.closeDia()
        }).catch(err => {
          console.log('err---', err);
          this.loading = false
        })
      } else if (this.operationType === 'edit') {
        updateInconsistentDistribution(internalPlan).then(res => {
          this.loading = false
          if (res.code === 201) return
          this.$message.success('操作成功')
          this.closeDia()
        }).catch(err => {
          console.log('err---', err);
          this.loading = false
        })
      }
    },
    closeDia() {
      this.formDia = false
      this.$emit('closeDia')
    },
    selectEnumByCategory() {
      this.distributionDetailList = []
      // è¦ç´ 
      this.getDicts("essential").then((response) => {
        let arr = this.dictToValue(response.data)
        arr.map((item) => {
          const obj = Object.assign({
            essentials: item.label,
            chapterNumber: item.value,
          })
          this.distributionDetailList.push(obj)
        })
      });
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin: 6vh auto 50px !important;
}
>>>.el-dialog__body {
  max-height: 68vh;
  overflow-y: auto;
}
>>>.is-required {
  margin-bottom: 6px;
}
.table {
  width: 100%;
  margin-top: 20px;
}
.table td {
  width: 30px;
  text-align: center;
}
.table th {
  width: 70px;
  height: 70px;
  text-align: center;
}
.div-with-line {
  width: 70px;
  height: 70px;
  position: relative;
  /*overflow: hidden; /* éšè—æº¢å‡ºå†…容 */
}
.div-with-line::after {
  content: '';
  position: absolute;
  bottom: 0;
  height: 1px;
  background-color: #000000;
  left: 50%;
  transform: translateX(-50%) rotate(45deg);
  transform-origin: center 50%;
  top: 50%;
  width: 100px;
}
</style>
src/views/CNAS/process/nonconformingWork/nonconformingDistribution/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,237 @@
<template>
  <div>
    <div>
      <!-- <div class="view-title">
        <span>不符合项的分布</span>
        <span>
          <el-button size="medium" type="primary" @click="openFormDia('add')">新 å¢ž</el-button>
        </span>
      </div> -->
      <div class="search-background">
        <span class="search-group">
          <span style="width: 120px">年份:</span>
          <el-input v-model="searchForm.distributionYear" clearable size="small"></el-input>
        </span>
        <span class="search-group">
          <el-button size="medium" @click="resetSearchForm">重 ç½®</el-button>
          <el-button size="medium" type="primary" @click="searchList">查 è¯¢</el-button>
        </span>
        <div class="btn">
          <el-button size="medium" type="primary" @click="openFormDia('add')">新 å¢ž</el-button>
        </div>
      </div>
      <div class="table">
        <div>
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <limsTable :column="tableColumn" :height="'calc(100vh - 19em)'" :table-data="tableData"
                :table-loading="tableLoading" style="padding: 0 15px;margin-bottom: 16px" :page="page"
                @pagination="pagination">
              </limsTable>
            </template>
          </TableCard>
        </div>
      </div>
    </div>
    <form-dia v-if="formDia" ref="formDia" @closeDia="closeDia"></form-dia>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import TableCard from '@/components/TableCard/index.vue';
import FormDia from './components/formDia.vue';
import {
  pageInconsistentDistribution,
  delInconsistentDistribution,
  exportInconsistentDistribution,
} from '@/api/cnas/process/nonconformingWork.js'
export default {
  name: 'a7-distribution-of-nonconforming',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { FormDia, TableCard, limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        distributionYear: '',
      },
      tableColumn: [
        {
          label: '年份',
          prop: 'distributionYear',
          minWidth: '100'
        },
        {
          label: '创建人',
          prop: 'createUserName',
          minWidth: '100'
        },
        {
          label: '创建时间',
          prop: 'createTime',
          minWidth: '100'
        },
        {
          label: '修改人',
          prop: 'updateUserName',
          minWidth: '100'
        },
        {
          label: '修改时间',
          prop: 'updateTime',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '220',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.handleDown(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delPlan(row)
              },
            }
          ]
        }
      ],
      tableData: [],
      tableLoading: false,
      page: {
        size: 20,
        current: 1,
        total: 0,
      },
      formDia: false,
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList() {
      const entity = this.searchForm
      const page = this.page
      this.tableLoading = true
      pageInconsistentDistribution({ ...entity, ...page }).then(res => {
        this.tableLoading = false
        if (res.code === 201) return
        this.tableData = res.data.records
        this.page.total = res.data.total
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading = false
      })
    },
    // åˆ é™¤
    delPlan(row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delInconsistentDistribution({ distributionId: row.distributionId }).then(res => {
          this.tableLoading = false
          if (res.code === 201) return
          this.$message.success('删除成功')
          this.searchList()
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // æ–°å¢žï¼Œç¼–辑,批准弹框
    openFormDia(type, row) {
      this.formDia = true
      this.$nextTick(() => {
        this.$refs.formDia.openDia(type, row)
      })
    },
    // å¯¼å‡º
    handleDown(row) {
      exportInconsistentDistribution({ distributionId: row.distributionId }).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/msword' });
        this.$download.saveAs(blob, '不符合项的分布' + '.docx');
      })
    },
    closeDia() {
      this.formDia = false
      this.searchList()
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm() {
      this.searchForm.distributionYear = '';
      this.searchList()
    },
    // åˆ†é¡µ
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.searchList();
    },
  }
};
</script>
<style scoped>
.view-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  padding-left: 20px;
}
.search-background {
  width: 100%;
  height: 80px;
  line-height: 80px;
  background-color: #ffffff;
  display: flex;
  position: relative;
}
.search-group {
  display: flex;
  align-items: center;
  margin: 0 20px;
}
.table {
  background-color: #ffffff;
}
.btn {
  position: absolute;
  right: 20px;
  top: 16px;
}
</style>
src/views/CNAS/process/nonconformingWork/nonconformingItem/components/qualityInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,322 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="formDia" title="不符合工作控制单"
      width="80%" @close="closeProcessingDia">
      <div style="height: 660px; overflow-y: auto">
        <table border="1" cellspacing="10" class="tables">
          <tr>
            <td class="first-title" rowspan="8">
              <p>不符合工作情况记录</p>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>发生部门:</p>
            </td>
            <td class="td-info">
              <span class="td-info1"> {{ form.occurrenceDepartment }}</span>
            </td>
            <td class="td-title">
              <p>部门负责人:</p>
            </td>
            <td class="td-info">
              <span class="td-info1"> {{ form.headDepartment }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>不符合工作发现途径:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-radio-group v-model="form.findWay" v-removeAriaHidden disabled>
                <el-radio :label="0">管理评审</el-radio>
                <el-radio :label="1">内部审核</el-radio>
                <el-radio :label="2">检测过程控制</el-radio>
                <el-radio :label="3">内部质量控制</el-radio>
                <el-radio :label="4">内部监督</el-radio>
                <el-radio :label="5">外部评审</el-radio>
                <el-radio :label="6">外部投诉</el-radio>
                <el-radio :label="7">其他</el-radio>
              </el-radio-group>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>不符合工作的详细记录:</p>
            </td>
            <td class="td-info" colspan="3">
              <span class="td-info1"> {{ form.recordDetail }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>不符合工作的以及及条款号:</p>
            </td>
            <td class="td-info" colspan="3">
              <span class="td-info1"> {{ form.recordAccording }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>被监督人:</p>
            </td>
            <td class="td-info">
              <span class="td-info1"> {{ form.supervisedUserName }}</span>
            </td>
            <td class="td-title">
              <p>被监督日期:</p>
            </td>
            <td class="td-info">
              <span class="td-info1"> {{ form.supervisedTime }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>发现部门:</p>
            </td>
            <td class="td-info">
              {{ form.foundDepartment }}
            </td>
            <td class="td-title">
              <p>时间:</p>
            </td>
            <td class="td-info">
              {{ form.recordTime }}
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>记录人:</p>
            </td>
            <td class="td-info">
              {{ form.recordUserName }}
            </td>
            <td class="td-title">
              <p>记录时间:</p>
            </td>
            <td class="td-info">
              {{ form.recordTime }}
            </td>
          </tr>
          <tr>
            <td class="first-title" rowspan="3">
              <p>处理措施</p>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>消除不符合工作所采取的措施:</p>
            </td>
            <td class="td-info" colspan="3">
              <span class="td-info1"> {{ form.eliminateMeasure }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>负责人:</p>
            </td>
            <td class="td-info">
              {{ form.actionsUserName }}
            </td>
            <td class="td-title">
              <p>处理时间:</p>
            </td>
            <td class="td-info">
              {{ form.actionsTime }}
            </td>
          </tr>
          <tr>
            <td class="first-title" rowspan="4">
              <p>纠正措施</p>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>是否需要采取纠正措施:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-radio-group v-model="form.isCorrect" v-removeAriaHidden disabled>
                <el-radio :label="0">否</el-radio>
                <el-radio :label="1">是</el-radio>
              </el-radio-group>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>纠正措施处理单跟踪:</p>
            </td>
            <td class="td-info" colspan="3">
              <span class="td-info1"> {{ form.correctContent }}</span>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>负责人:</p>
            </td>
            <td class="td-info">
              {{ form.correctUserName }}
            </td>
            <td class="td-title">
              <p>处理时间:</p>
            </td>
            <td class="td-info">
              {{ form.correctTime }}
            </td>
          </tr>
          <tr>
            <td class="first-title" rowspan="4">
              <p>是否通知客户及可恢复工作</p>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>通知客户:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-radio-group v-model="form.notifyCustomer" v-removeAriaHidden disabled>
                <el-radio :label="0">否</el-radio>
                <el-radio :label="1">是</el-radio>
              </el-radio-group>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>恢复工作:</p>
            </td>
            <td class="td-info" colspan="3">
              <el-radio-group v-model="form.backToWork" v-removeAriaHidden disabled>
                <el-radio :label="0">否</el-radio>
                <el-radio :label="1">是</el-radio>
              </el-radio-group>
            </td>
          </tr>
          <tr>
            <td class="td-title">
              <p>负责人:</p>
            </td>
            <td class="td-info">
              {{ form.qualityManagerUserName }}
            </td>
            <td class="td-title">
              <p>处理时间:</p>
            </td>
            <td class="td-info">
              {{ form.qualityManagerTime }}
            </td>
          </tr>
        </table>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  getSuperviseDetailAccording
} from '@/api/cnas/process/nonconformingWork.js'
export default {
  name: 'qualityInfo',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        occurrenceDepartment: '',
        headDepartment: '',
        findWay: '',
        recordDetail: '',
        recordAccording: '',
        supervisedUserName: '',
        supervisedTime: '',
        actionsUserName: '',
        eliminateMeasure: '',
        correctUserName: '',
        isCorrect: '',
        correctContent: '',
        recordUserName: '',
        recordTime: '',
        foundDepartment: '',
        actionsTime: '',
        correctTime: '',
        notifyCustomer: '',
        backToWork: '',
        qualityManagerUserName: '',
        qualityManagerTime: '',
      },
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.searchInfo(row)
    },
    // æŸ¥è¯¢ç›‘控计划详情实施信息
    searchInfo(row) {
      this.form.qualityMonitorDetailsId = row.qualityMonitorDetailsId
      getSuperviseDetailAccording({ superviseDetailsId: row.superviseDetailsId }).then(res => {
        if (res.code === 201) return
        this.form = res.data
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // å…³é—­å¼¹æ¡†
    closeProcessingDia() {
      this.formDia = false
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin: 5vh auto 50px !important;
}
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.first-title {
  display: table-cell;
  width: 100px;
  /* è®¾ç½®ä¸€ä¸ªå›ºå®šå®½åº¦ */
  height: 200px;
  /* è®¾ç½®ä¸€ä¸ªå›ºå®šé«˜åº¦ */
  text-align: center;
  /* æ°´å¹³å±…中 */
  vertical-align: middle;
  /* åž‚直居中 */
  writing-mode: vertical-rl;
  /* æ–‡å­—竖直排列 */
  padding: 10px 0;
}
.td-title {
  height: 40px;
  width: 170px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 6px;
}
.td-info {
  padding: 10px;
}
.td-info1 {
  display: inline-block;
  width: 100%;
  text-align: left;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
</style>
src/views/CNAS/process/nonconformingWork/nonconformingItem/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,196 @@
<template>
  <div>
    <div>
      <div class="search-background">
        <span class="search-group">
          <span style="width: 120px">发生部门:</span>
          <el-input v-model="searchForm.occurrenceDepartment" clearable size="small"></el-input>
        </span>
        <span class="search-group">
          <el-button size="medium" @click="resetSearchForm">重 ç½®</el-button>
          <el-button size="medium" type="primary" @click="searchList">查 è¯¢</el-button>
        </span>
      </div>
      <div class="table">
        <div>
          <TableCard :showForm="false" :showTitle="false">
            <template v-slot:table>
              <limsTable :column="tableColumn" :height="'calc(100vh - 19em)'" :table-data="tableData"
                :table-loading="tableLoading" style="padding: 0 15px;margin-bottom: 16px" :page="page"
                @pagination="pagination">
              </limsTable>
            </template>
          </TableCard>
        </div>
      </div>
    </div>
    <quality-info v-if="qualityInfo" ref="qualityInfo"></quality-info>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import TableCard from '@/components/TableCard/index.vue';
import QualityInfo from './components/qualityInfo.vue';
import {
  pageSuperviseDetailAccording,
  superviseDetailAccordingExport
} from '@/api/cnas/process/nonconformingWork.js'
export default {
  name: 'a7-nonconforming-item',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { QualityInfo, TableCard, limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        occurrenceDepartment: '',
      },
      tableColumn: [
        {
          label: '发生部门',
          prop: 'occurrenceDepartment',
          minWidth: '100'
        },
        {
          label: '部门负责人',
          prop: 'headDepartment',
          minWidth: '100'
        },
        {
          label: '发现途径',
          prop: 'findWay',
          minWidth: '100'
        },
        {
          label: '详细记录',
          prop: 'recordDetail',
          minWidth: '100'
        },
        {
          label: '依据和条款号',
          prop: 'recordAccording',
          minWidth: '100'
        },
        {
          label: '发现部门',
          prop: 'foundDepartment',
          minWidth: '100'
        },
        {
          label: '被监督人',
          prop: 'supervisedUserName',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '60',
          label: '操作',
          operation: [
            {
              name: '查看',
              type: 'text',
              clickFun: (row) => {
                this.viewInfo(row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.openDownloadDia(row);
              },
            },
          ]
        }
      ],
      tableData: [],
      tableLoading: false,
      page: {
        size: 20,
        current: 1,
        total: 0,
      },
      qualityInfo: false,
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList() {
      const entity = {
        occurrenceDepartment: this.searchForm.occurrenceDepartment,
      }
      const page = this.page
      this.tableLoading = true
      pageSuperviseDetailAccording({ ...entity, ...page }).then(res => {
        this.tableLoading = false
        if (res.code === 201) return
        this.tableData = res.data.records
        this.page.total = res.data.total
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading = false
      })
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm() {
      this.searchForm.occurrenceDepartment = '';
      this.searchList()
    },
    viewInfo(row) {
      this.qualityInfo = true
      this.$nextTick(() => {
        this.$refs.qualityInfo.openDia(row)
      })
    },
    // å¯¼å‡º
    openDownloadDia(row) {
      superviseDetailAccordingExport({ superviseDetailsId: row.superviseDetailsId }).then(res => {
        const blob = new Blob([res], { type: 'application/msword' });
        this.$download.saveAs(blob, '不符合项导出' + '.docx');
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // åˆ†é¡µ
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.searchList();
    },
  }
};
</script>
<style scoped>
.view-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  padding-left: 20px;
}
.search-background {
  width: 100%;
  height: 80px;
  line-height: 80px;
  background-color: #ffffff;
  display: flex;
}
.search-group {
  display: flex;
  align-items: center;
  margin: 0 20px;
}
.table {
  background-color: #ffffff;
}
</style>
src/views/CNAS/process/reportResults/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,409 @@
<template>
  <div class="report-results">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">检验报告编号:</div>
        <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="queryParams.insReportCode"
            @keyup.enter.native="refreshTable()"></el-input></div>
      </div>
      <div class="search_thing" style="padding-left: 30px;">
        <el-button size="small" @click="refresh()">重 ç½®</el-button>
        <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
      </div>
      <div class="btn">
        <el-button size="medium" type="primary" @click="handleDown" :loading="outLoading" v-if="outPower">导出</el-button>
        <el-button size="medium" type="primary" @click="openAdd" v-if="addPower">新增</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading" :height="'calc(100vh - 270px)'"
        :page="page" @pagination="pagination" :isSelection="true"
        :handleSelectionChange="handleSelectionChange"></lims-table>
    </div>
    <el-dialog :title="title" :visible.sync="addDialogVisible" width="400px" top="6vh">
      <el-row>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">检验报告编号:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.insReportCode"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">页数:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.pages"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发送份数:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.number"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发往何处:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.send"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发送方式:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.method"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发送日期:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.sendTime" type="date" size="small" placeholder="选择日期" format="yyyy-MM-dd"
                value-format="yyyy-MM-dd" style="width: 100%;">
              </el-date-picker>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发送人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.sendUser" placeholder="请选择" size="small" style="width: 100%;">
                <el-option v-for="item in personList" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">签收人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.signatory" placeholder="请选择" size="small" style="width: 100%;" multiple>
                <el-option v-for="item in personList" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">备注:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.remark"
                type="textarea" :rows="2"></el-input></div>
          </div>
        </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="handleAdd" :loading="addLoading">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {
  exportProcessReport,
  doProcessReport,
  addProcessReport,
  pageProcessReport,
  delProcessReport
} from '@/api/cnas/process/reportResults.js'
import {
  selectUserCondition,
} from "@/api/system/user.js";
export default {
  components: {
    limsTable
  },
  data() {
    return {
      outLoading: false,
      addPower: true,
      outPower: true,
      personList: [],
      title: '新增',
      addDialogVisible: false,
      addInfo: {
        signatory: []
      },
      addLoading: false,
      mutilSelect: [],
      queryParams: {},
      tableData: [],
      column: [
        { label: "检验报告编号", prop: "insReportCode" },
        { label: "页数", prop: "pages", width: "120px" },
        {
          label: "发送份数",
          prop: "number",
        },
        { label: "发往何处", prop: "send" },
        { label: "发送方式", prop: "method" },
        { label: "发送日期", prop: "sendTime" },
        { label: "发送人", prop: "sendUserName" },
        { label: "签收人", prop: "signatoryName" },
        { label: "备注", prop: "remark" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.handleWork(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  mounted() {
    // this.entityCopy = this.HaveJson(this.componentData.entity);
    this.getList()
    this.getAuthorizedPerson()
  },
  methods: {
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let up = false
      let del = false
      let add = false
      let out = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'doProcessReport') {
          up = true
        }
        if (power[i].menuMethod == 'addProcessReport') {
          add = true
        }
        if (power[i].menuMethod == 'delProcessReport') {
          del = true
        }
        if (power[i].menuMethod == 'exportProcessReport') {
          out = true
        }
      }
      if (!up) {
        this.componentData.do.splice(1, 1)
      }
      if (!del) {
        this.componentData.do.splice(0, 1)
      }
      this.outPower = out
      this.addPower = add
    },
    handleDown() {
      if (this.mutilSelect.length == 0) {
        this.$message.warning('请选择要导出的数据')
        return
      }
      this.outLoading = true
      exportProcessReport({ ids: this.mutilSelect.map(m => m.id) }).then(res => {
        this.outLoading = false
        if (res.code === 201) return
        const url = this.javaApi + '/word/' + res.data;
        this.$download.saveAs(url, "报告结果");
      })
    },
    openAdd() {
      this.title = '新增'
      this.addInfo = {
        signatory: []
      }
      this.addDialogVisible = true;
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageProcessReport({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData = res.data.records;
            this.page.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.getList();
    },
    refresh() {
      this.queryParams = {};
      this.page.current = 1;
      this.getList();
    },
    refreshTable() {
      this.page.current = 1;
      this.getList();
    },
    handleSelectionChange(val) {
      this.mutilSelect = val
    },
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    handleAdd() {
      this.addLoading = true
      delete this.addInfo.createTime
      delete this.addInfo.createUser
      delete this.addInfo.updateTime
      delete this.addInfo.signatoryUrl
      delete this.addInfo.updateUserer
      delete this.addInfo.sendUserName
      let addInfo = this.HaveJson(this.addInfo)
      addInfo.signatory = addInfo.signatory.join(',')
      if (this.title == '新增') {
        addProcessReport(addInfo).then(res => {
          this.addLoading = false
          if (res.code == 201) {
            return
          }
          this.addDialogVisible = false
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          this.refreshTable()
        }).catch(err => { })
      } else {
        doProcessReport(addInfo).then(res => {
          this.addLoading = false
          if (res.code == 201) {
            return
          }
          this.addDialogVisible = false
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          this.refreshTable()
        }).catch(err => { })
      }
    },
    handleWork(row) {
      this.title = '修改'
      this.addInfo = row
      console.log(this.addInfo)
      this.addInfo.signatory = this.addInfo.signatory ? this.addInfo.signatory.split(',').map(m => Number(m)) : []
      this.addDialogVisible = true;
    },
    handleChangeTask(list) {
      this.mutilSelect = list
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProcessReport({ id: row.id }).then((res) => {
            if (res.code == 201) return;
            this.$message.success("删除成功");
            this.refresh();
          });
        })
        .catch(() => { });
    },
  }
}
</script>
<style scoped>
.search {
  background-color: #fff;
  height: 80px;
  display: flex;
  align-items: center;
  position: relative;
}
.search_thing {
  width: 350px;
  display: flex;
  align-items: center;
}
.search_label {
  width: 110px;
  font-size: 14px;
  text-align: right;
}
.search_input {
  width: calc(100% - 110px);
}
.table {
  background-color: #fff;
  height: calc(100% - 60px - 80px - 10px - 40px);
  padding: 20px;
}
.tables {
  table-layout: fixed;
  width: 100%;
}
.tables td {
  height: 40px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
.en {
  font-size: 12px;
  word-break: break-word;
  /* è‡ªåŠ¨æ–­è¡Œ */
  overflow-wrap: break-word;
  /* é˜²æ­¢æº¢å‡º */
  white-space: normal;
  /* é»˜è®¤æ¢è¡Œ */
}
.btn {
  position: absolute;
  top: 16px;
  right: 20px;
}
</style>
src/views/CNAS/process/sampleDisposal/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,609 @@
<template>
  <div class="sample-disposal">
    <el-tabs type="border-card" v-model="activeName" style="height: 100%;" @tab-click="queryParams.totaldealId = ''">
      <el-tab-pane label="填写" name="填写" style="height: 100%;" :key="1">
        <el-button size="small" type="primary" @click="handleAdd0" style="margin-left: 20px;">新增</el-button>
        <div class="table" style="height: calc(100% - 200px)" v-if="activeName == '填写'">
          <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading"
            :height="'calc(100vh - 290px)'" :page="page" @pagination="pagination"></lims-table>
        </div>
      </el-tab-pane>
      <el-tab-pane label="历史记录" name="历史记录" style="height: 100%;" :key="2">
        <div class="search">
          <div class="search_thing">
            <div class="search_label">年月:</div>
            <div class="search_input">
              <el-date-picker v-model="queryParams0.month" type="month" placeholder="选择月" format="yyyy-MM"
                value-format="yyyy-MM" size="small" @change="refreshTable()">
              </el-date-picker>
            </div>
          </div>
          <div class="search_thing" style="padding-left: 30px;">
            <el-button size="small" @click="refresh()">重 ç½®</el-button>
            <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
          </div>
        </div>
        <div class="table">
          <lims-table :tableData="tableData0" :column="column0" :tableLoading="tableLoading"
            :height="'calc(100vh - 300px)'" :page="page0" @pagination="pagination0"></lims-table>
        </div>
      </el-tab-pane>
    </el-tabs>
    <!-- æ–°å¢žæ ·å“ -->
    <el-dialog :title="title" :visible.sync="addDialogVisible" width="400px">
      <el-row>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">样品名称:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.sampleName"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">样品编号:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.sampleCode"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">供样单位:</div>
            <div class="search_input">
              <el-select v-model="addInfo.sampleSupplier" size="small">
                <el-option :label="item.company" :value="item.company" v-for="(item, index) in customPageList"
                  :key="item.id"></el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">数量:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.num"></el-input>
            </div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">处理方式:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.dealMethod"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.dealTime" type="date" size="small" placeholder="选择日期" format="yyyy-MM-dd"
                value-format="yyyy-MM-dd" style="width: 100%;">
              </el-date-picker>
            </div>
          </div>
        </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="submitAdd" :loading="addLoading">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <!-- è¯¦æƒ…/下载/审核/批准 -->
    <el-dialog :title="title0" :visible.sync="lookDialogVisible" width="800px" :class="{ downPdf: title0 == '下载' }"
      :modal="title0 != '下载'" top="5vh">
      <filePreview v-if="lookDialogVisible" :fileUrl="javaApi + '/word/' + currentInfo.url" :currentFile="{}"
        style="max-height: 70vh;overflow-y: auto;" />
      <span slot="footer" class="dialog-footer" v-if="title0 == '审核' || title0 == '批准'">
        <el-button @click="submitCheck('不通过')" :loading="noCheckLoading">不通过</el-button>
        <el-button type="primary" @click="submitCheck('通过')" :loading="checkLoading">通 è¿‡</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import filePreview from "@/components/Preview/filePreview.vue";
import { selectCustomPageList } from "@/api/system/customer";
import {
  doProcessDeal,
  addProcessDeal,
  submitProcessTotaldeal,
  pageProcessDeal,
  checkProcessTotaldeal,
  ratifyProcessTotaldeal,
  delProcessDeal,
  pageProcessTotaldeal,
} from "@/api/cnas/process/sampleDisposal";
export default {
  components: {
    limsTable,
    filePreview,
  },
  name: "SampleDisposal",
  data() {
    return {
      activeName: '填写',
      title: '新增',
      addDialogVisible: false,
      addLoading: false,
      outLoading: false,
      editDialogVisible: false,
      lookDialogVisible: false,
      title0: '查看',
      noCheckLoading: false,
      checkLoading: false,
      // åŽ†å²åˆ—è¡¨
      addInfo: {},//新增样品
      customPageList: [],
      currentInfo: {
        arr: []
      },//查看的详情
      outPower: false,
      addPower: false,
      queryParams: {},
      tableData: [],
      column: [
        { label: "样品名称", prop: "sampleName" },
        { label: "样品编号", prop: "sampleCode" },
        { label: "供样单位", prop: "sampleSupplier" },
        { label: "数量", prop: "num" },
        { label: "处理方式", prop: "dealMethod" },
        { label: "时间", prop: "dealTime" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.handleAdd0(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
      queryParams0: {},
      tableData0: [],
      column0: [
        { label: "月份", prop: "month" },
        { label: "总数量", prop: "totalNum" },
        { label: "提交人", prop: "submitUserName" },
        { label: "审核人", prop: "examineUserName" },
        { label: "批准人", prop: "ratifyUserName" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "查看",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
            {
              name: "下载",
              type: "text",
              clickFun: (row) => {
                this.handleDown0(row);
              },
              disabled: (row) => {
                return !row.url
              }
            },
            {
              name: "提交",
              type: "text",
              clickFun: (row) => {
                this.handleSubmit(row);
              },
              disabled: (row) => {
                return !!row.submitState && row.submitState != '待提交'
              }
            },
            {
              name: "审核",
              type: "text",
              clickFun: (row) => {
                this.handleCheck(row);
              },
              disabled: (row) => {
                return row.examineState == '通过' || row.submitState == '待提交'
              }
            },
            {
              name: "批准",
              type: "text",
              clickFun: (row) => {
                this.handleApproval(row);
              },
              disabled: (row) => {
                return row.ratifyState == '通过' || row.submitState == '待提交'
              }
            },
          ],
        },
      ],
      page0: {
        total: 0,
        size: 10,
        current: 0,
      },
    };
  },
  mounted() {
    // this.entityCopy = this.HaveJson(this.componentData.entity);
    this.getCustomPageList()
    this.getList()
    this.getList0()
  },
  methods: {
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let add = false
      let out = false
      let submitProcessTotaldeal = false
      let checkProcessTotaldeal = false
      let ratifyProcessTotaldeal = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'addProcessDeal') {
          add = true
        }
        // if (power[i].menuMethod == 'exportProcessEvaluate') {
        //   out = true
        // }
        if (power[i].menuMethod == 'submitProcessTotaldeal') {
          submitProcessTotaldeal = true
        }
        if (power[i].menuMethod == 'checkProcessTotaldeal') {
          checkProcessTotaldeal = true
        }
        if (power[i].menuMethod == 'ratifyProcessTotaldeal') {
          ratifyProcessTotaldeal = true
        }
      }
      if (!ratifyProcessTotaldeal) {
        this.componentData.do.splice(4, 1)
      }
      if (!checkProcessTotaldeal) {
        this.componentData.do.splice(3, 1)
      }
      if (!submitProcessTotaldeal) {
        this.componentData.do.splice(2, 1)
      }
      if (!add) {
        this.componentData0.do.splice(1, 1)
        this.componentData0.do.splice(0, 1)
      }
      this.addPower = add
    },
    // èŽ·å–é€æ ·å•ä½åˆ—è¡¨
    getCustomPageList() {
      selectCustomPageList({
        current: -1,
        size: -1
      }).then(res => {
        this.customPageList = res.data.records
      }).catch(err => { });
    },
    handleDown() { },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageProcessDeal({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData = res.data.records;
            this.page.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.getList();
    },
    refresh() {
      this.queryParams0 = {};
      this.page0.current = 1;
      this.getList0();
    },
    refreshTable() {
      this.page0.current = 1;
      this.getList0();
    },
    getList0() {
      this.tableLoading = true;
      let param = { ...this.queryParams0, ...this.page };
      delete param.total;
      pageProcessTotaldeal({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData0 = res.data.records;
            this.page0.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination0({ page, limit }) {
      this.page0.current = page;
      this.page0.size = limit;
      this.getList0();
    },
    // å¡«å†™
    // handleAdd(row){
    //   this.componentData0.entity.totaldealId = row.id
    //   this.editDialogVisible = true
    // },
    // æ‰“开新增界面
    handleAdd0(row) {
      if (row) {
        this.addInfo = this.HaveJson(row)
        this.title = '编辑'
      } else {
        this.title = '新增'
        this.addInfo = {}
      }
      this.addDialogVisible = true
    },
    // æäº¤æ–°å¢ž
    submitAdd() {
      if (this.addInfo.id) {
        // ç¼–辑
        this.addLoading = true
        doProcessDeal({
          totaldealId: this.queryParams.totaldealId,
          ...this.addInfo
        }).then(res => {
          this.addLoading = false
          if (res.code === 201) return
          this.addDialogVisible = false
          this.$message({
            type: 'success',
            message: '编辑成功!'
          });
          this.page.current = 0;
          this.getList();
        }).catch(err => { });
      } else {
        // æ–°å¢ž
        this.addLoading = true
        addProcessDeal({
          totaldealId: this.queryParams.totaldealId,
          ...this.addInfo
        }).then(res => {
          this.addLoading = false
          if (res.code === 201) return
          this.addDialogVisible = false
          this.$message({
            type: 'success',
            message: '新增成功!'
          });
          this.page.current = 0;
          this.getList();
        }).catch(err => { });
      }
    },
    // æäº¤
    handleSubmit(row) {
      this.$confirm('是否提交 ' + row.month + ' æœˆä»½çš„æ•°æ®', '提交', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        submitProcessTotaldeal({
          id: row.id
        }).then(res => {
          if (res.code === 201) return
          this.$message({
            type: 'success',
            message: '提交成功!'
          });
          this.refreshTable()
        }).catch(err => { });
      })
    },
    // æŸ¥çœ‹
    handleLook(row) {
      // console.log(row)
      // this.title0 = '查看'
      // this.commonFun(row)
      this.activeName = '填写'
      this.queryParams.totaldealId = row.id
      this.$nextTick(() => {
        this.page.current = 0;
        this.getList();
      })
    },
    commonFun(row, callbanck) {
      this.currentInfo = row
      this.queryParams.totaldealId = row.id
      pageProcessDeal({
        current: -1,
        size: -1, ...this.queryParams
      }).then(res => {
        this.lookDialogVisible = true
        this.currentInfo.arr = res.data.records
        if (callbanck) {
          callbanck()
        }
      }).catch(err => { });
    },
    // å®¡æ ¸
    handleCheck(row) {
      this.title0 = '审核'
      this.commonFun(row)
    },
    // æ‰¹å‡†
    handleApproval(row) {
      this.title0 = '批准'
      this.commonFun(row)
    },
    // æäº¤å®¡æ ¸/批准
    submitCheck(state) {
      if (state == '通过') {
        this.checkLoading = true
      } else {
        this.noCheckLoading = true
      }
      if (this.title0 == '审核') {
        checkProcessTotaldeal({
          id: this.currentInfo.id,
          state: state
        }).then(res => {
          this.checkLoading = false
          this.noCheckLoading = false
          if (res.code === 201) return
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          this.refreshTable()
          this.lookDialogVisible = false
        }).catch(err => { });
      } else if (this.title0 == '批准') {
        ratifyProcessTotaldeal({
          id: this.currentInfo.id,
          state: state
        }).then(res => {
          this.checkLoading = false
          this.noCheckLoading = false
          if (res.code === 201) return
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          this.refreshTable()
          this.lookDialogVisible = false
        }).catch(err => { });
      }
    },
    // å¯¼å‡ºè¯¦æƒ…
    handleDown0(row) {
      // åŽç«¯ä¸‹è½½
      let url = this.javaApi + '/word/' + row.url
      this.$download.saveAs(url, row.month + ' æ ·å“å¤„理申请表');
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProcessDeal({ id: row.id }).then((res) => {
            if (res.code == 201) return;
            this.$message.success("删除成功");
            this.refresh();
          });
        })
        .catch(() => { });
    },
  },
}
</script>
<style scoped>
.title {
  height: 60px;
  line-height: 60px;
}
.search {
  background-color: #fff;
  height: 40px;
  display: flex;
  align-items: center;
  position: relative;
}
.search_thing {
  width: 350px;
  display: flex;
  align-items: center;
}
.search_label {
  width: 110px;
  font-size: 14px;
  text-align: right;
}
.search_input {
  width: calc(100% - 110px);
}
.table {
  background-color: #fff;
  height: calc(100% - 60px - 140px);
  padding: 20px;
}
.downPdf {
  opacity: 0 !important;
}
.tables {
  table-layout: fixed;
  width: 100%;
}
.tables td {
  height: 40px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
}
.en {
  font-size: 12px;
  word-break: break-word;
  /* è‡ªåŠ¨æ–­è¡Œ */
  overflow-wrap: break-word;
  /* é˜²æ­¢æº¢å‡º */
  white-space: normal;
  /* é»˜è®¤æ¢è¡Œ */
}
.user-info {
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  margin-top: 20px;
}
.user-info .el-button {
  margin: 0;
}
>>>.el-tabs__content {
  height: 100%;
}
</style>
src/views/CNAS/process/uncertainty/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,328 @@
<template>
  <div class="uncertainty-evaluation">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">报告名称:</div>
        <div class="search_input"><el-input v-model="queryParams.reportName" clearable placeholder="请输入" size="small"
            @keyup.enter.native="refreshTable()"></el-input></div>
      </div>
      <div class="search_thing" style="padding-left: 30px;">
        <el-button size="small" @click="refresh()">重 ç½®</el-button>
        <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
      </div>
      <div class="btn">
        <el-button :loading="outLoading" size="small" style="margin-right: 16px;margin-top: 3px;" type="primary"
          @click="handleDown0">导出</el-button>
        <el-upload ref='upload' :action="action" :headers="uploadHeader" :on-change="beforeUpload" :on-error="onError"
          :on-success="handleSuccessUp" :show-file-list="false"
          accept='.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'>
          <el-button :loading="upLoading" size="small" type="primary">导入</el-button></el-upload>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :tableLoading="tableLoading" :height="'calc(100vh - 270px)'"
        :page="page" @pagination="pagination"></lims-table>
    </div>
    <el-dialog :visible.sync="addDialogVisible" title="评价" width="400px">
      <el-row>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">评价:</div>
            <div class="search_input"><el-input v-model="addInfo.note" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="24" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">日期:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.evaluateTime" format="yyyy-MM-dd" placeholder="选择日期" size="small"
                style="width: 100%;" type="date" value-format="yyyy-MM-dd">
              </el-date-picker>
            </div>
          </div>
        </el-col>
      </el-row>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button :loading="addLoading" type="primary" @click="handleAdd">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <el-dialog :visible.sync="lookDialogVisible" fullscreen title="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}" :fileUrl="javaApi + '/word/' + currentInfo.reportUrl"
        style="max-height: 90vh;overflow-y: auto;" />
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import filePreview from "@/components/Preview/filePreview.vue";
import {
  exportProcessEvaluate,
  doProcessEvaluate,
  delProcessEvaluate,
  pageProcessEvaluate,
} from '@/api/cnas/process/uncertainty.js'
import { mapGetters } from "vuex";
export default {
  components: {
    limsTable,
    filePreview
  },
  data() {
    return {
      addPower: false,
      outPower: false,
      outLoading: false,
      upLoading: false,
      addDialogVisible: false,
      addInfo: {},
      addLoading: false,
      currentInfo: {},
      lookDialogVisible: false,
      queryParams: {},
      tableData: [],
      column: [
        { label: "报告名称", prop: "reportName" },
        { label: "评价人", prop: "evaluateUserName" },
        { label: "评价日期", prop: "evaluateTime" },
        { label: "备注", prop: "note" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "评价",
              type: "text",
              clickFun: (row) => {
                this.handleTell(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
            },
            {
              name: "下载",
              type: "text",
              clickFun: (row) => {
                this.handleDown(row);
              },
            },
            {
              name: "查看附件",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  // ç”¨äºŽä¸Šä¼ æ–‡ä»¶çš„信息
  computed: {
    ...mapGetters(["userId"]),
    action() {
      return this.javaApi + '/processEvaluate/addProcessEvaluate'
    }
  },
  mounted() {
    // this.entityCopy = this.HaveJson(this.componentData.entity);
    this.getList()
  },
  methods: {
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let up = false
      let del = false
      let add = false
      let out = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'doProcessEvaluate') {
          up = true
        }
        if (power[i].menuMethod == 'addProcessEvaluate') {
          add = true
        }
        if (power[i].menuMethod == 'delProcessEvaluate') {
          del = true
        }
        if (power[i].menuMethod == 'exportProcessEvaluate') {
          out = true
        }
      }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      if (!up) {
        this.componentData.do.splice(0, 1)
      }
      this.outPower = out
      this.addPower = add
    },
    handleDown0() {
      this.outLoading = true
      exportProcessEvaluate(this.queryParams).then(res => {
        this.outLoading = false
        if (res.code === 201) return
        const blob = new Blob([res], { type: 'application/octet-stream' });
        this.$download.saveAs(blob, '测量不确定度的评定.xlsx');
      })
    },
    handleDown(row) {
      let url = this.javaApi + '/word/' + row.reportUrl
      this.$download.saveAs(url, row.reportName);
    },
    beforeUpload(file) {
      if (file.size > 1024 * 1024 * 10) {
        this.$message.error('上传文件不超过10M');
        this.$refs.upload.clearFiles()
        return false;
      } else {
        // this.upLoading = true;
        return true;
      }
    },
    onError(err, file, fileList) {
      this.$message.error('上传失败')
      this.$refs.upload.clearFiles()
    },
    handleSuccessUp(response) {
      this.upLoading = false;
      if (response.code == 200) {
        this.$message.success('上传成功');
        this.refreshTable()
      }
    },
    handleTell(row) {
      this.addInfo = row;
      this.addDialogVisible = true;
    },
    handleAdd() {
      this.addLoading = true;
      doProcessEvaluate({
        id: this.addInfo.id,
        note: this.addInfo.note,
        evaluateTime: this.addInfo.evaluateTime,
        evaluateUser: this.userId
      }).then((res) => {
        this.addLoading = false;
        if (res.code == 201) {
          this.$message.error('评价失败');
          return;
        }
        this.$message.success('评价成功');
        this.addDialogVisible = false;
        this.refreshTable()
      })
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageProcessEvaluate({ ...param })
        .then((res) => {
          this.tableLoading = false;
          if (res.code === 200) {
            this.tableData = res.data.records;
            this.page.total = res.data.total;
          }
        })
        .catch((err) => {
          this.tableLoading = false;
        });
    },
    pagination({ page, limit }) {
      this.page.current = page;
      this.page.size = limit;
      this.getList();
    },
    refresh() {
      this.queryParams = {};
      this.page.current = 1;
      this.getList();
    },
    refreshTable() {
      this.page.current = 1;
      this.getList();
    },
    handleLook(row) {
      this.currentInfo = row;
      this.lookDialogVisible = true;
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delProcessEvaluate({ id: row.id }).then((res) => {
            if (res.code == 201) return;
            this.$message.success("删除成功");
            this.refresh();
          });
        })
        .catch(() => { });
    },
  }
}
</script>
<style scoped>
.title {
  height: 60px;
  line-height: 60px;
}
.search {
  background-color: #fff;
  height: 80px;
  display: flex;
  align-items: center;
  position: relative;
}
.search_thing {
  width: 350px;
  display: flex;
  align-items: center;
}
.search_label {
  width: 80px;
  font-size: 14px;
  text-align: right;
}
.search_input {
  width: calc(100% - 80px);
}
.table {
  background-color: #fff;
  height: calc(100% - 60px - 80px - 10px - 40px);
  padding: 20px;
}
.btn {
  position: absolute;
  top: 16px;
  right: 20px;
  display: flex;
  align-items: center;
}
</style>