chenrui
2025-02-28 4ec7b4a558e952cca2ac27a73483fe9395ba0a93
标准方法的变更代码迁移
已添加8个文件
1548 ■■■■■ 文件已修改
src/api/cnas/process/method/standardMethodsChange.js 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue 456 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/process/method/standardMethodsChange/index.vue 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/tool/file-preview.vue 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/cnas/process/method/standardMethodsChange.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,102 @@
// å®žéªŒå®¤çš„æ£€æµ‹èƒ½åŠ›æ¡£æ¡ˆç›¸å…³æŽ¥å£
import request from "@/utils/request";
//标准方法更新验证列表
export function pagesMethodVerify(query) {
  return request({
    url: "/processMethodVerify/pagesMethodVerify",
    method: "get",
    params: query,
  });
}
//获取用户列表
export function selectUserCondition(query) {
  return request({
    url: "/system/newUser/selectUserCondition",
    method: "get",
    params: query,
  });
}
//查询标准方法验证详情
export function getMethodVerifyOne(query) {
  return request({
    url: "/processMethodVerify/getMethodVerifyOne",
    method: "get",
    params: query,
  });
}
// é€šè¿‡è®¾å¤‡åˆ†ç±»èŽ·å–è®¾å¤‡åˆ—è¡¨
export function deviceScopeSearch(query) {
  return request({
    url: '/deviceScope/search',
    method: 'get',
    params: query
  })
}
// æ–°å¢žæ ‡å‡†æ–¹æ³•验证
export function addMethodVerify(data) {
  return request({
    url: "/processMethodVerify/addMethodVerify",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æ ‡å‡†æ–¹æ³•验证
export function updateMethodVerify(data) {
  return request({
    url: "/processMethodVerify/updateMethodVerify",
    method: "post",
    data: data,
  });
}
// å¯¼å‡ºæ ‡å‡†æ–¹æ³•更新验证
export function exportMethodVerify(query) {
  return request({
    url: '/processMethodVerify/exportMethodVerify',
    method: "get",
    responseType: "blob",
    params: query,
  })
}
// éªŒè¯ç¡®è®¤
export function methodVerifyAffirm(query) {
  return request({
    url: '/processMethodVerify/methodVerifyAffirm',
    method: 'get',
    params: query
  })
}
// åˆ é™¤æ ‡å‡†æ–¹æ³•更新验证
export function delMethodVerify(query) {
  return request({
    url: '/processMethodVerify/delMethodVerify',
    method: 'delete',
    params: query
  })
}
// åŽŸå§‹è®°å½•åˆ—è¡¨
export function getVerifyMethodFileList(query) {
  return request({
    url: '/processMethodVerify/getVerifyMethodFileList',
    method: 'get',
    params: query
  })
}
// åˆ é™¤éªŒè¯åŽŸå§‹è®°å½•åˆ—è¡¨
export function delVerifyMethodFileList(query) {
  return request({
    url: '/processMethodVerify/delVerifyMethodFileList',
    method: 'delete',
    params: query
  })
}
src/views/CNAS/process/method/standardMethodsChange/component/ViewDeviceDialog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="viewDeviceDialog" title="查看设备" width="80%" @close="closeDia">
      <div style="text-align: right;margin-bottom: 10px">
        <el-button size="small" type="primary" @click="addRow">添加</el-button>
        <el-button size="small" type="danger" @click="clearTable">清空</el-button>
      </div>
      <div>
        <el-table :data="machineAttachmentList" border height="500" style="width: 100%">
          <el-table-column header-align="center" label="名称" prop="machineName" width="200">
            <template slot="header" slot-scope="scope">
              <p>名称</p>
            </template>
            <template slot-scope="scope">
              <el-select v-model="scope.row.machineName"
                         class="table_input"
                         clearable
                         filterable
                         placeholder="设备名称"
                         size="small" @change="(val)=>changeMachineName(val, scope.$index)">
                <el-option v-for="item in equipOptions" :key="item.value"  :label="item.label" :value="item.value">
                  {{item.label + item.value}}
                </el-option>
              </el-select>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="型号规格" prop="machineSpecification" width="180">
            <template slot="header" slot-scope="scope">
              <p>型号规格</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.machineSpecification" size="small"/>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="测量范围" prop="machineMeasuringRange">
            <template slot="header" slot-scope="scope">
              <p>测量范围</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.machineMeasuringRange" size="small" type="textarea"/>
            </template>
          </el-table-column>
          <el-table-column header-align="center" label="①扩展不确定度②最大允差③准确度等级" prop="other">
            <template slot="header" slot-scope="scope">
              <p>①扩展不确定度②最大允差③准确度等级</p>
            </template>
            <template slot-scope="{row}">
              <el-input v-model="row.other" size="small" type="textarea"/>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="handleDeviceInfo">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { deviceScopeSearch } from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'ViewDeviceDialog',
  // import å¼•入的组件需要注入到对象中才能使用
  components: {},
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      viewDeviceDialog: false,
      machineAttachmentList: [],
      equipOptions: [],
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(info) {
      this.viewDeviceDialog = true
      this.machineAttachmentList = info.machineAttachmentList
      this.getEquipOptions()
    },
    // å¢žåŠ è¡¨æ ¼è¡Œæ•°æ®
    addRow () {
      this.machineAttachmentList.push({
        machineName: '',
        machineSpecification: '',
        machineMeasuringRange: '',
        other: '',
      })
    },
    // æ¸…空表格数据
    clearTable () {
      this.machineAttachmentList = []
    },
    // é€‰æ‹©è®¾å¤‡çš„回调
    changeMachineName (val, index) {
      const index1 = this.equipOptions.findIndex(item => item.value === val);
      if (index1 !== -1) {
        this.machineAttachmentList[index].deviceId = this.equipOptions[index1].id;
        this.machineAttachmentList[index].machineName = this.equipOptions[index1].deviceName;
      }
      this.machineAttachmentList[index].machineSpecification = val
    },
    // æäº¤è®¾å¤‡ä¿¡æ¯
    handleDeviceInfo () {
      if (this.machineAttachmentList.length === 0) {
        this.$message.warning('请添加信息')
        return
      }
      this.viewDeviceDialog = false
      this.$emit('handleDeviceInfo', this.machineAttachmentList)
    },
    closeDia () {
      this.viewDeviceDialog = false
      this.$emit('closDeviceDia')
    },
    // èŽ·å–æ‰€æœ‰è®¾å¤‡
    getEquipOptions() {
      this.equipOptions = []
      deviceScopeSearch({status:'0'}).then(res => {
        if (res.code === 200 && res.data) {
          this.equipOptions = res.data.map(m => {
            m.value = m.managementNumber
            m.label = m.deviceName
            return m
          })
        }
      }).catch(error => {
        console.error(error)
      })
    },
  }
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/ViewTestRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,172 @@
<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="{methodVerifyId: info.methodVerifyId}"
                   :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>
        <lims-table
          ref="yearTable"
          :column="columnData"
          :height="'calc(100vh - 47em)'"
          :highlightCurrentRow="true"
          :table-data="tableData"
          :table-loading="tableLoading"
          style="margin-top: 0.5em;">
        </lims-table>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import limsTable from '@/components/Table/lims-table.vue'
import file from "@/utils/file";
import { delVerifyMethodFileList, getVerifyMethodFileList } from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'ViewTestRecord',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { 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.upload(row)
              }
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.delete(row)
              }
            }
          ]
        }
      ],
      tableData: [],
      info: {}
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      if (this.info === undefined) {
        this.info = {
          methodVerifyId: ''
        }
      }
      this.searchTableList()
    },
    // æŸ¥è¯¢é™„件列表
    searchTableList () {
      this.tableLoading = true
      getVerifyMethodFileList({methodVerifyId:this.info.methodVerifyId}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          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
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
    // åˆ é™¤
    delete (row) {
      this.tableLoading = true
      delVerifyMethodFileList({methodFileId:row.methodFileId}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          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()
      }
    },
  },
  computed: {
    fileAction() {
      return this.javaApi + '/processMethodVerify/uploadVerifyMethodFile'
    }
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/calibrationsFileDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,123 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="查看校准证书" width="80%" @closed="closeFilesLook">
      <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="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
    </el-dialog>
  </div>
</template>
<script>
import filePreview from '@/views/tool/file-preview.vue';
import limsTable from '@/components/Table/lims-table.vue'
import file from '@/utils/file';
export default {
  name: 'calibrationsFileDia',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable, filePreview },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          label: '设备名称',
          prop: 'deviceName',
          minWidth: '150px'
        },
        {
          label: '设备编号',
          prop: 'managementNumber',
          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)
              }
            },
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  mounted() {
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.tableData = this.info.calibrationsFileList
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
  }
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/component/formDIaChange.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,456 @@
<template>
  <div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
               :title="operationType === 'edit' ? '编辑' : '新增'"
               :visible.sync="formDia"
               width="90%" @close="closeDia">
      <div v-if="operationType === 'edit'" style="text-align: right">
        <el-button :disabled="form.confirmDate !== '' && form.confirmDate !== null && form.confirmDate !== undefined" size="medium" type="primary" @click="validation">验证确认</el-button>
      </div>
      <table border="1" cellspacing="10" class="tables">
        <tr>
          <td>
            <p>标准方法</p>
          </td>
          <td>
            <p>验证原因</p>
          </td>
          <td>
            <p>主要技术变化</p>
          </td>
          <td>
            <p>涉及方面</p>
          </td>
          <td>
            <p>标准要求</p>
          </td>
          <td>
            <p>准备情况</p>
          </td>
          <td>
            <p>是否满足</p>
          </td>
          <td>
            <p>备注</p>
          </td>
        </tr>
        <tr>
          <td rowspan="9">
            <el-input v-model="form.methodName" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
          <td rowspan="9">
            <el-input v-model="form.verifyReason" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
          <td rowspan="9">
            <el-input v-model="form.technologyChange" :rows="6"
                      placeholder="请输入内容"
                      size="small"
                      type="textarea">
            </el-input>
          </td>
        </tr>
        <tr>
          <td>人:</td>
          <td>
            <el-input v-model="form.personRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.personReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.personIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewWorkPermit">查看上岗证</el-link>
          </td>
        </tr>
        <tr>
          <td>机:</td>
          <td>
            <el-input v-model="form.machineRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.machineReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.machineIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewDevice">查看设备</el-link>
          </td>
        </tr>
        <tr>
          <td>料:</td>
          <td>
            <el-input v-model="form.materialRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.materialReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.materialIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.materialRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>法:</td>
          <td>
            <el-input v-model="form.methodRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.methodReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.methodIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewTestRecord">查看检测记录</el-link>
          </td>
        </tr>
        <tr>
          <td>环:</td>
          <td>
            <el-input v-model="form.environmentRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.environmentReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.environmentIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.traceabilityRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>测量溯源性:</td>
          <td>
            <el-input v-model="form.traceabilityRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.traceabilityReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.traceabilityIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-link type="primary" @click="viewCalibrationsFileDia">查看校准证书</el-link>
          </td>
        </tr>
        <tr>
          <td>样品管理需求:</td>
          <td>
            <el-input v-model="form.managementRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.managementReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.managementIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.managementRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td>其他:</td>
          <td>
            <el-input v-model="form.otherRequirements" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-input v-model="form.otherReadiness" size="small" type="textarea"></el-input>
          </td>
          <td>
            <el-radio-group v-model="form.otherIsSatisfied" v-removeAriaHidden>
              <el-radio :label="0">否</el-radio>
              <el-radio :label="1">是</el-radio>
            </el-radio-group>
          </td>
          <td>
            <el-input v-model="form.otherRemark" size="small"></el-input>
          </td>
        </tr>
        <tr>
          <td colspan="3">
            <p>是否引用此标准开展检测:</p>
          </td>
          <td colspan="3">可以引用此标准开展检测</td>
          <td>
            <p>确认时间:</p>
          </td>
          <td>{{form.confirmDate}}</td>
        </tr>
        <tr>
          <td colspan="3">
            <p>参加确认人签名:</p>
          </td>
          <td colspan="5">
            <el-select v-model="form.confirmUser" multiple placeholder="请选择" size="small" style="width: 100%" :multiple-limit="5">
              <el-option v-for="item in userList" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </td>
        </tr>
      </table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDia">取 æ¶ˆ</el-button>
        <el-button :loading="editLoad" type="primary" @click="handleEdit">提 äº¤</el-button>
      </span>
    </el-dialog>
    <ViewDeviceDialog v-if="viewDeviceDialog" ref="viewDeviceDialog" @closDeviceDia="closDeviceDia" @handleDeviceInfo="handleDeviceInfo"></ViewDeviceDialog>
    <ViewTestRecord v-if="viewTestRecordDialog" ref="viewTestRecordDialog"></ViewTestRecord>
    <ViewWorkPermitDia v-if="viewWorkPermitDia" ref="viewWorkPermitDia"></ViewWorkPermitDia>
    <calibrations-file-dia v-if="calibrationsFileDia" ref="calibrationsFileDia"></calibrations-file-dia>
  </div>
</template>
<script>
import { dateFormat } from '@/utils/date'
import ViewTestRecord from '../component/ViewTestRecord.vue';
import ViewDeviceDialog from '../component/ViewDeviceDialog.vue';
import ViewWorkPermitDia from '../component/viewWorkPermitDia.vue';
import CalibrationsFileDia from '../component/calibrationsFileDia.vue';
import {
  addMethodVerify, deviceScopeSearch,
  getMethodVerifyOne,
  selectUserCondition,
  updateMethodVerify
} from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'formDIaChange',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { CalibrationsFileDia, ViewWorkPermitDia, ViewDeviceDialog, ViewTestRecord },
  props: {
    operationType: {
      type: String,
      default: () => ''
    }
  },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      formDia: false,
      form: {
        methodName: '',
        verifyReason: '',
        technologyChange: '',
        personRequirements: '',
        personReadiness: '',
        personIsSatisfied: '',
        personRemark: '',
        machineRequirements: '',
        machineReadiness: '',
        machineIsSatisfied: '',
        materialRequirements: '',
        materialReadiness: '',
        materialIsSatisfied: '',
        materialRemark: '',
        methodRequirements: '',
        methodReadiness: '',
        methodIsSatisfied: '',
        environmentRequirements: '',
        environmentReadiness: '',
        environmentIsSatisfied: '',
        traceabilityRequirements: '',
        traceabilityReadiness: '',
        traceabilityIsSatisfied: '',
        traceabilityRemark: '',
        managementRequirements: '',
        managementReadiness: '',
        managementIsSatisfied: '',
        managementRemark: '',
        otherRequirements: '',
        otherReadiness: '',
        otherIsSatisfied: '',
        otherRemark: '',
        machineAttachmentList: []
      },
      editLoad: false,
      info: {
        methodVerifyId: ''
      },
      userList: [],
      viewDeviceDialog: false,
      viewTestRecordDialog: false,
      viewWorkPermitDia: false,
      calibrationsFileDia: false,
    };
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.formDia = true
      this.info = row
      this.getUserList()
      if (this.operationType === 'edit') {
        this.searchInfo(row)
      }
    },
    // æŸ¥è¯¢è¯¦æƒ…信息
    searchInfo (row) {
      getMethodVerifyOne({methodVerifyId:row.methodVerifyId}).then(res => {
        if (res.code === 200) {
          this.form = {...res.data}
          if (this.form.confirmUser) {
            this.form.confirmUser = this.form.confirmUser.split(',').map(Number)
          }
        }
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // æäº¤
    handleEdit() {
      this.editLoad = true
      const processMethodSearchNews = this.HaveJson(this.form)
      processMethodSearchNews.confirmUser = processMethodSearchNews.confirmUser && processMethodSearchNews.confirmUser.join(',')
      processMethodSearchNews.operationType = 0
      if (this.operationType === 'edit') {
        this.editInfo(processMethodSearchNews)
      } else {
        this.addInfo(processMethodSearchNews)
      }
    },
    // æŸ¥çœ‹ä¸Šå²—证
    viewWorkPermit () {
      this.viewWorkPermitDia = true
      this.$nextTick(() => {
        this.$refs.viewWorkPermitDia.openDia(this.form)
      })
    },
    // æŸ¥çœ‹æ ¡å‡†è¯ä¹¦
    viewCalibrationsFileDia () {
      this.calibrationsFileDia = true
      this.$nextTick(() => {
        this.$refs.calibrationsFileDia.openDia(this.form)
      })
    },
    // æŸ¥çœ‹è®¾å¤‡
    viewDevice () {
      this.viewDeviceDialog = true
      this.$nextTick(() => {
        this.$refs.viewDeviceDialog.openDia(this.form)
      })
    },
    // å…³é—­è®¾å¤‡å¼¹æ¡†
    closDeviceDia () {
      this.viewDeviceDialog = false
    },
    // æäº¤è®¾å¤‡ä¿¡æ¯
    handleDeviceInfo (machineAttachmentList) {
      this.viewDeviceDialog = false
      this.form.machineAttachmentList = machineAttachmentList
    },
    // æŸ¥çœ‹æ£€æµ‹è®°å½•
    viewTestRecord () {
      this.viewTestRecordDialog = true
      this.$nextTick(() => {
        this.$refs.viewTestRecordDialog.openDia(this.info)
      })
    },
    // æäº¤ç¼–辑
    editInfo (processMethodSearchNews) {
      updateMethodVerify(processMethodSearchNews).then(res => {
        this.editLoad = false
        if (res.code === 200){
          this.$message.success('操作成功')
          this.closeDia()
        }
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // æäº¤æ–°å¢ž
    addInfo (processMethodSearchNews) {
      addMethodVerify(processMethodSearchNews).then(res => {
        this.editLoad = false
        if (res.code === 200) {
          this.$message.success('操作成功')
          this.closeDia()
        }
      }).catch(err => {
        console.log('err---', err);
        this.editLoad = false
      })
    },
    // éªŒè¯ç¡®è®¤
    validation () {
      deviceScopeSearch({methodVerifyId:this.info.methodVerifyId}).then(res => {
        if (res.code === 200){
          this.form.confirmDate = dateFormat(new Date())
        }
      }).catch(err => {
        console.log('err---', err);
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia() {
      this.formDia = false
      this.$emit('closeDia');
    },
    getUserList(){
      selectUserCondition().then(res => {
        if (res.code === 200) {
          this.userList = res.data
        }
      })
    },
  }
};
</script>
<style scoped>
>>>.el-dialog {
  margin-top: 2vh !important;
}
>>>.el-dialog__body {
  max-height: 720px;
  overflow-y: auto;
}
.tables {
  table-layout: fixed;
  width: 100%;
  margin-top: 10px;
}
.tables td {
  height: 34px;
  width: 100px;
  text-align: center;
  font-size: 14px;
  word-wrap: break-word;
  white-space: normal;
  padding: 4px;
}
</style>
src/views/CNAS/process/method/standardMethodsChange/component/viewWorkPermitDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,118 @@
<template>
  <div>
    <el-dialog :visible.sync="filesDialogVisible" title="查看上岗证" width="80%" @closed="closeFilesLook">
      <div>
        <limsTable
          ref="yearTable"
          :column="columnData"
          :height="'calc(100vh - 400px)'"
          :highlightCurrentRow="true"
          :table-data="tableData"
          :table-loading="tableLoading"
          style="margin-top: 0.5em;">
        </limsTable>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="lookDialogVisible"
      fullscreen
      title="查看附件" top="5vh" width="800px">
      <filePreview v-if="lookDialogVisible" :currentFile="{}"
                   :fileUrl="javaApi+'/img/'+currentInfo.fileUrl" style="max-height: 90vh;overflow-y: auto;"/>
    </el-dialog>
  </div>
</template>
<script>
import file from '@/utils/file';
import filePreview from '@/views/tool/file-preview.vue';
import limsTable from '@/components/Table/lims-table.vue'
export default {
  name: 'viewWorkPermitDia',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { filePreview, limsTable },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      filesDialogVisible: false,
      tableLoading: false,
      filesLookInfo: {},
      columnData: [
        {
          label: '文件名称',
          prop: 'fileName',
          minWidth: '150px'
        },
        {
          label: '持有人',
          prop: 'userName',
          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)
              }
            },
          ]
        }
      ],
      tableData: [],
      info: {},
      currentInfo:{},
      lookDialogVisible: false,
    };
  },
  mounted() {
  },
  // æ–¹æ³•集合
  methods: {
    openDia(row) {
      this.filesDialogVisible = true
      this.info = row
      this.tableData = this.info.workFileList
    },
    closeFilesLook () {
      this.filesDialogVisible = false
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row){
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // ä¸‹è½½
    upload (row) {
      let url = '';
      if(row.type==1){
        url = this.javaApi+'/img/'+row.fileUrl
        file.downloadIamge(url,row.fileName)
      }else{
        url = this.javaApi+'/word/'+row.fileUrl
        const link = document.createElement('a');
        link.href = url;
        link.download = row.fileName;
        link.click();
      }
    },
  },
};
</script>
<style scoped>
</style>
src/views/CNAS/process/method/standardMethodsChange/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,201 @@
<template>
  <div class="capacity-scope">
    <div class="search">
      <div>
        <el-form :model="searchForm" ref="searchForm" size="small" :inline="true">
          <el-form-item label="标准方法" prop="methodName">
            <el-input size="small" placeholder="请输入" clearable v-model="searchForm.methodName"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="searchList">查 è¯¢</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetSearchForm">重 ç½®</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div>
        <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>
            <lims-table :tableData="tableData" :column="tableColumn" :height="'calc(100vh - 250px)'" @pagination="pagination"
                        :page="page" :tableLoading="tableLoading"></lims-table>
          </template>
        </TableCard>
      </div>
    </div>
    <formDIaChange v-if="formDIa" ref="formDIa" :operationType="operationType" @closeDia="closeDia"></formDIaChange>
  </div>
</template>
<script>
import TableCard from '@/views/CNAS/externalService/serviceAndSupplyPro/component/index.vue';
import formDIaChange from './component/formDIaChange.vue';
import limsTable from '@/components/Table/lims-table.vue'
import {
  delMethodVerify,
  exportMethodVerify,
  pagesMethodVerify
} from '@/api/cnas/process/method/standardMethodsChange'
export default {
  name: 'a7-changes-standard-methods',
  // import å¼•入的组件需要注入到对象中才能使用
  components: { limsTable, formDIaChange, TableCard },
  data() {
    // è¿™é‡Œå­˜æ”¾æ•°æ®
    return {
      searchForm: {
        methodName: '',
        operationType: 0,
      },
      options: [
        { label: '上半年', value: '1' },
        { label: '下半年', value: '2' },
      ],
      tableColumn: [
        {
          label: '标准方法',
          prop: 'methodName',
          minWidth: '100'
        },
        {
          label: '验证原因',
          prop: 'verifyReason',
          minWidth: '100'
        },
        {
          label: '主要技术变化',
          prop: 'technologyChange',
          minWidth: '100'
        },
        {
          dataType: 'action',
          minWidth: '60',
          label: '操作',
          operation: [
            {
              name: '编辑',
              type: 'text',
              clickFun: (row) => {
                this.openFormDia('edit', row);
              },
            },
            {
              name: '导出',
              type: 'text',
              clickFun: (row) => {
                this.downLoadPost(row);
              },
            },
            {
              name: '删除',
              type: 'text',
              color: '#f56c6c',
              clickFun: (row) => {
                this.deleteRow(row);
              },
            }
          ]
        }
      ],
      tableData: [],
      tableLoading: false,
      page: {
        size: 10,
        current: 1,
        total: 0,
      },
      formDIa: false,
      operationType: '',
    };
  },
  mounted() {
    this.searchList()
  },
  // æ–¹æ³•集合
  methods: {
    // æŸ¥è¯¢åˆ—表
    searchList() {
      const entity = {
        methodName: this.searchForm.methodName,
        operationType: this.searchForm.operationType,
      }
      this.tableLoading = true
      pagesMethodVerify({... this.page,...entity}).then(res => {
        this.tableLoading = false
        if (res.code === 200){
          this.tableData = res.data.records
          this.page.total = res.data.total
        }
      }).catch(err => {
        console.log('err---', err);
        this.tableLoading = false
      })
    },
    // åˆ é™¤
    deleteRow (row) {
      this.$confirm('此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.tableLoading = true
        delMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
          this.tableLoading = false
          if (res.code === 200){
            this.$message.success('删除成功')
            this.searchList()
          }
        }).catch(err => {
          this.tableLoading = false
          console.log('err---', err);
        })
      })
    },
    // é‡ç½®æŸ¥è¯¢æ¡ä»¶
    resetSearchForm() {
      this.searchForm.methodName = '';
      this.searchList()
    },
    openFormDia (type, row) {
      this.formDIa = true
      this.operationType = type
      this.$nextTick(() => {
        this.$refs.formDIa.openDia(row)
      })
    },
    // å…³é—­å¼¹æ¡†
    closeDia () {
      this.formDIa = false
      this.searchList()
    },
    // å¯¼å‡º
    downLoadPost(row) {
      this.outLoading = true
      exportMethodVerify({methodVerifyId:row.methodVerifyId}).then(res => {
        this.outLoading = false
        const blob = new Blob([res],{ type: 'application/msword' });
        this.$download.saveAs(blob, '标准(方法)确认记录.docx')
        this.$message.success('导出成功')
      })
    },
    // åˆ†é¡µåˆ‡æ¢
    pagination(page) {
      this.page.size = page.limit
      this.searchList();
    },
  }
};
</script>
<style scoped>
.search {
  height: 46px;
  display: flex;
  justify-content: space-between;
}
</style>
src/views/tool/file-preview.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,238 @@
<template>
  <div>
    <div v-if="isImage">
      <img :src="imgUrl" alt="Image Preview" />
    </div>
    <div v-if="isPdf">
      <object :data="fileUrl" type="application/pdf" width="100%" height="750px">
        <p>您的浏览器不支持 PDF é¢„览。<a :href="fileUrl">下载 PDF æ–‡ä»¶</a></p>
      </object>
    </div>
    <div v-if="isDoc">
      <p v-if="!isDocShow">文档无法直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="!isDocShow">下载文件</a>
      <vue-office-docx v-else
                       :src="fileUrl"
                       style="height: 100vh;"
                       @rendered="renderedHandler"
                       @error="errorHandler"
      />
    </div>
    <div v-if="isXls">
      <p v-if="!isDocShow">文档无法直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="!isDocShow">下载文件</a>
      <vue-office-excel v-else
                        :src="fileUrl"
                        :options="options"
                        style="height: 100vh;"
                        @rendered="renderedHandler"
                        @error="errorHandler"
      />
    </div>
    <div v-if="isZipOrRar">
      <p>压缩文件无法直接预览,请下载查看。</p>
      <a :href="fileUrl">下载文件</a>
    </div>
    <div v-if="isCsv">
      <p v-if="csvList.length==0">CSV æ–‡ä»¶æ— æ³•直接预览,请下载查看。</p>
      <a :href="fileUrl" v-if="csvList.length==0">下载文件</a>
      <el-tabs type="border-card" v-if="csvList.length>0" tab-position="bottom">
        <el-tab-pane :label="item.sheetName" v-for="(item,index) in csvList" :key="index">
          <el-table :data="item.tableData" height="75vh">
            <el-table-column :label="m.label" :prop="m.prop" v-for="(m,i) in item.column" :key="i" min-width="120px" show-overflow-tooltip>
              <template slot-scope="scope" slot="header">
                <div>
                  <el-tooltip  :content="m.label" placement="top">
                    <div class="oneLine">
                      <span>{{m.label}}</span>
                    </div>
                  </el-tooltip>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </div>
    <div v-if="!isSupported">
      <p>不支持的文件格式</p>
    </div>
  </div>
</template>
<script>
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'
export default {
  components: {
    VueOfficeDocx,
    VueOfficeExcel,
  },
  props: {
    fileUrl: {
      type: String,
      required: true
    },
    currentFile: {
      type: Object,
      required: true
    },
  },
  data(){
    return {
      isDocShow:true,
      options:{
        xls: false,       //预览xlsx文件设为false;预览xls文件设为true
        minColLength: 0,  // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0.
        minRowLength: 0,  // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0.
        widthOffset: 10,  //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽
        heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
        beforeTransformData: (workbookData) => {return workbookData}, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
        transformData: (workbookData) => {return workbookData}, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容
      },
      csvList:[],//csv文件数据
      imgUrl:''
    }
  },
  computed: {
    isImage() {
      let state = /\.(jpg|jpeg|png|gif)$/i.test(this.fileUrl)
      this.imgUrl = this.fileUrl
      if(state){
        this.imgUrl = this.fileUrl.replaceAll('word', 'img')
      }
      return state;
    },
    isPdf() {
      return /\.pdf$/i.test(this.fileUrl);
    },
    isDoc() {
      return /\.(doc|docx)$/i.test(this.fileUrl);
    },
    isXls(){
      let state = /\.(xls|xlsx)$/i.test(this.fileUrl)
      if(state){
        if(/\.(xlsx)$/i.test(this.fileUrl)){
          this.options.xls = false
        }else{
          this.options.xls = true
        }
      }
      return state;
    },
    isZipOrRar() {
      return /\.(zip|rar)$/i.test(this.fileUrl);
    },
    isCsv() {
      let state = /\.csv$/i.test(this.fileUrl)
      if(state){
        this.loadCSVData();
        // this.main()
      }
      return state;
    },
    isSupported() {
      return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv||this.isXls;
    }
  },
  methods:{
    renderedHandler() {
      console.log("渲染完成")
      this.isDocShow = true
      this.resetStyle()
    },
    errorHandler() {
      console.log("渲染失败")
      this.isDocShow = false
    },
    async loadCSVData() {
      this.$axios.post(this.$api.insOrderPlan.preview, {
        id: this.currentFile.id,
      }).then( res => {
        let arr = res.data
        arr = arr.map(m=>{
          let obj = {
            sheetName:m.sheetName,
            tableData:[],
            column:[]
          }
          obj.tableData = this.formatCSVToTable(m.content.replaceAll('null',' '))
          // .replaceAll('MIN','=MIN').replaceAll('MAX','=MAX').replaceAll('AVERAGE','=AVERAGE')
          for (let item in obj.tableData[0]) {
            obj.column.push({
              label: item,
              prop: item,
            })
          }
          return obj
        })
        this.csvList = arr
      }).catch( err => {
        console.log(err)
      })
    },
    formatCSVToTable(str){
      const result = [];
      const jsonObj = str.split("\n");
      let arrHeader = [];
      for (const i in jsonObj) {
        if (typeof jsonObj[i] === 'string' && jsonObj[i].length > 0) {
          const row = `${jsonObj[i]}`;
          if (row.trim().length > 0) {
            const kv = jsonObj[i].split(',');
            if (i == 0) {
              // èŽ·å–column表头
              arrHeader = kv;
            } else {
              const obj = {};
              for (let index = 0; index < arrHeader.length; index++) {
                // ç»„装表格数据
                const name = String(arrHeader[index]);
                if (!arrHeader[index]) continue
                if (!obj[name]) {
                  try {
                    if (kv[index]) {
                      obj[name] = String(kv[index]);
                    } else {
                      obj[name] = '';
                    }
                  } catch (err) {
                    obj[name] = '';
                  }
                }
              }
              result.push(obj);
            }
          }
        }
      }
      return result
    },
    resetStyle(){
      const elements = document.querySelectorAll('[style*="pt"]');
      for (const element of elements) {
        const style = element.getAttribute('style');
        if (!!style) {
          element.setAttribute('style', style.replace(/pt/g, 'px'));
        }
      }
    },
  }
}
</script>
<style scoped>
img {
  max-width: 100%;
}
.oneLine {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>