gaoluyang
2025-02-24 717dc9fa42e09e8befe970496877e7178e59ca76
检验任务复核
已添加3个文件
614 ■■■■■ 文件已修改
src/assets/images/no-full.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Onlyoffice/onlyoffice.vue 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/inspectionReview/index.vue 407 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/no-full.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1712111454775" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5950" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M354.133333 682.666667H256v-42.666667h170.666667v170.666667H384v-98.133334L243.2 853.333333l-29.866667-29.866666L354.133333 682.666667z m358.4 0l140.8 140.8-29.866666 29.866666-140.8-140.8V810.666667h-42.666667v-170.666667h170.666667v42.666667h-98.133334zM354.133333 384L213.333333 243.2l29.866667-29.866667L384 354.133333V256h42.666667v170.666667H256V384h98.133333z m358.4 0H810.666667v42.666667h-170.666667V256h42.666667v98.133333L823.466667 213.333333l29.866666 29.866667L712.533333 384z" fill="#606266" p-id="5951"></path></svg>
src/components/Onlyoffice/onlyoffice.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,206 @@
<!--onlyoffice ç¼–辑器-->
<template>
  <div id="vabOnlyOffice"></div>
</template>
<script>
export default {
  name: "VabOnlyOffice",
  props: ['options'],
  data() {
    return {
      doctype: "",
      docEditor: null,
      //参考vabOnlyOffice组件参数配置
      option: {
        url: "",
        isEdit: false,
        fileType: "",
        title: "",
        lang: "zh-CN",
        isPrint: true,
        user: {},
        editUrl: ""
      }
    };
  },
  created() {
    if(this.options){
      const option = this.options
      this.option.url = option.url
      this.option.isEdit = option.isEdit === "true" ? true : false
      this.option.fileType = option.fileType
      this.option.title = option.title
      this.option.lang = option.lang
      this.option.isPrint = option.isPrint
      this.option.user.id = option.user_id
      this.option.user.name = option.user_name
      this.option.editUrl = option.editUrl
    }else{
      const option = this.$route.query
      this.option.url = option.url
      this.option.isEdit = option.isEdit === "true" ? true : false
      this.option.fileType = option.fileType
      this.option.title = option.title
      this.option.lang = option.lang
      this.option.isPrint = option.isPrint
      this.option.user.id = option.user_id
      this.option.user.name = option.user_name
      this.option.editUrl = option.editUrl
    }
  },
  beforeDestroy() {
    if (this.docEditor !== null) {
      this.docEditor.destroyEditor();
      this.docEditor = null;
    }
  },
  watch: {
    option: {
      handler: function(n) {
        this.setEditor(n);
        this.doctype = this.getFileType(n.fileType);
      },
      deep: true
    }
  },
  mounted() {
    if (this.option.url) {
      this.setEditor(this.option);
    }
  },
  methods: {
    async setEditor(option) {
      if (this.docEditor !== null) {
        this.docEditor.destroyEditor();
        this.docEditor = null;
      }
      this.doctype = this.getFileType(option.fileType);
      let config = {
        document: {
          //后缀
          fileType: option.fileType,
          key: option.key || "",
          title: option.title,
          permissions: {
            edit: option.isEdit, //是否可以编辑: åªèƒ½æŸ¥çœ‹ï¼Œä¼ false
            print: option.isPrint,
            download: false
            // "fillForms": true,//是否可以填写表格,如果将mode参数设置为edit,则填写表单仅对文档编辑器可用。 é»˜è®¤å€¼ä¸Žedit或review参数的值一致。
            // "review": true //跟踪变化
          },
          url: option.url
        },
        documentType: this.doctype,
        editorConfig: {
          callbackUrl: option.editUrl, //"编辑word后保存时回调的地址,这个api需要自己写了,将编辑后的文件通过这个api保存到自己想要的位置
          lang: option.lang, //语言设置
          //定制
          customization: {
            autosave: true, //是否自动保存
            chat: true,
            comments: false,
            help: false,
            "hideRightMenu": false,//定义在第一次加载时是显示还是隐藏右侧菜单。 é»˜è®¤å€¼ä¸ºfalse
            //是否显示插件
            plugins: false
          },
          user: {
            id: option.user.id,
            name: option.user.name
          },
          mode: option.model ? option.model : "edit"
        },
        width: "100%",
        height: "100%",
        token: option.token || ""
      };
      // eslint-disable-next-line no-undef,no-unused-vars
      this.docEditor = new DocsAPI.DocEditor("vabOnlyOffice", config);
    },
    getFileType(fileType) {
      let docType = "";
      let fileTypesDoc = [
        "doc",
        "docm",
        "docx",
        "dot",
        "dotm",
        "dotx",
        "epub",
        "fodt",
        "htm",
        "html",
        "mht",
        "odt",
        "ott",
        "pdf",
        "rtf",
        "txt",
        "djvu",
        "xps"
      ];
      let fileTypesCsv = [
        "csv",
        "fods",
        "ods",
        "ots",
        "xls",
        "xlsm",
        "xlsx",
        "xlt",
        "xltm",
        "xltx"
      ];
      let fileTypesPPt = [
        "fodp",
        "odp",
        "otp",
        "pot",
        "potm",
        "potx",
        "pps",
        "ppsm",
        "ppsx",
        "ppt",
        "pptm",
        "pptx"
      ];
      if (fileTypesDoc.includes(fileType)) {
        docType = "text";
      }
      if (fileTypesCsv.includes(fileType)) {
        docType = "spreadsheet";
      }
      if (fileTypesPPt.includes(fileType)) {
        docType = "presentation";
      }
      return docType;
    }
  }
};
</script>
<style>
html,
body {
  height: 100%;
}
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  height: 100%;
}
.qualityManual-container {
  padding: 0 !important;
  height: 100%;
}
.qualityManual-container-office {
  width: 100%;
  height: calc(100% - 55px);
}
</style>
src/views/business/inspectionReview/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,407 @@
<template>
  <div class="app-container">
    <div>
      <el-form :model="entity" ref="entity" size="small" :inline="true">
        <el-form-item label="委托编号" prop="entrustCode">
          <el-input size="small" placeholder="请输入" clearable
                    v-model="entity.entrustCode"
                    @keyup.enter.native="refreshTable()"></el-input>
        </el-form-item>
        <el-form-item label="下单类别" prop="entrustCode">
          <el-select size="small" v-model="entity.typeSource" clearable style="width: 100%;" @change="refreshTable()">
            <el-option v-for="(a, i) in typeSourceList" :key="i" :label="a.label" :value="a.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-refresh" size="mini" @click="refresh">重 ç½®</el-button>
          <el-button type="primary" icon="el-icon-search" size="mini" @click="refreshTable">查 è¯¢</el-button>
        </el-form-item>
      </el-form>
      <div class="page_total">
        <span>总计任务数量:</span>
        <span>{{page.total}}</span>
      </div>
    </div>
    <div>
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
                  :rowClassName="rowClassName" :height="'calc(100vh - 250px)'" @pagination="pagination"
                  key="tableData0"></lims-table>
    </div>
<!--    <div style="width: 100%;height: 100%;" v-if="activeFace >0 && isCopper == null">-->
<!--      <Add :active="activeFace" :currentId="currentId"/>-->
<!--    </div>-->
<!--    <div style="width: 100%;height: 100%;" v-if="activeFace >0 && isCopper == 0">-->
<!--      <CustomsInspection :active="activeFace" :customsInspection="customsInspection" :currentId="currentId"/>-->
<!--    </div>-->
<!--    <div style="width: 100%;height: 100%;" v-if="activeFace >0 && isCopper == 1">-->
<!--      <CopperOrder :active="activeFace" :currentId="currentId"></CopperOrder>-->
<!--    </div>-->
<!--    <Inspection v-if="state>0" @goback="goback" :orderId="orderId" :sonLaboratory="componentData.entity.sonLaboratory" :typeSource="typeSource" :state="state"/>-->
<!--    &lt;!&ndash;产业链信息查看&ndash;&gt;-->
<!--    <ShowInfo v-if="showInfoDialog" :showInfoDialog="showInfoDialog" ref="showInfoDialog"></ShowInfo>-->
    <!--报告查看-->
    <el-dialog title="报告查看" :visible.sync="issuedVisible" width="80vw" :modal-append-to-body="false"
               :fullscreen="fullscreen">
      <div class="full-screen">
        <i class="el-icon-full-screen" style="cursor: pointer;font-size: 18px" @click="fullscreen=true;" v-if="!fullscreen"></i>
        <img src="@/assets/images/no-full.svg" alt="" v-else style="cursor: pointer;" @click="fullscreen=false;" >
      </div>
      <div style="height: 80vh;" v-if="issuedVisible">
        <onlyoffice ref="onlyoffice" :options="option" style="width: 100%;height: 100%;" />
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getYearAndMonthAndDays } from "@/utils/date";
// import ShowInfo from "../do/b1-material-ins-order/showInfo.vue";
import onlyoffice from "@/components/Onlyoffice/onlyoffice.vue";
import limsTable from "@/components/Table/lims-table.vue";
import {selectInsOrderPlanList, selectUserCondition} from "@/api/business/inspectionTask";
import {mapGetters} from "vuex";
export default {
  components: {
    onlyoffice,
    limsTable,
    // ShowInfo,
  },
  dicts: ["urgency_level", "inspection_task_state"],
  computed: {
    ...mapGetters(["nickName", "userId"]),
  },
  data() {
    return {
      alone: false,
      tabList: [],
      active: 1,
      tabIndex: 0,
      entity: {
        sonLaboratory: null,
        insState: '3',
        userId: 0,
        typeSource: null,
        isCheck: 1
      },
      tableData: [],
      column: [
        {
          label: "委托编号",
          prop: "entrustCode",
          width: "160px",
          dataType: "link",
          linkMethod: "selectAllByOne",
        },
        { label: "样品名称", prop: "sample", width: "160px" },
        {
          label: "下单类别",
          prop: "typeSource",
          width: "100px",
          dataType: "tag",
          formatData: (params) => {
            if (params == 0) {
              return "成品下单";
            } else {
              return "原材料下单";
            }
          },
        },
        { label: "样品型号", prop: "sampleModel", width: "120px" },
        {
          label: "紧急程度",
          prop: "type",
          dataType: "tag",
          formatData: (params) => {
            return this.urgencyLevel.find((m) => m.value == params).label;
          },
        },
        {
          label: "检验类型",
          prop: "orderType",
          width: "100px",
          dataType: "tag",
          formatData: (params) => {
            return this.orderTypeList.find((m) => m.value == params).label;
          },
          formatType: (params) => {
            return this.orderTypeList.find((m) => m.value == params).type;
          },
        },
        {
          label: "状态",
          prop: "insState",
          dataType: "tag",
          formatData: (params) => {
            return this.inspectionTaskState.find((m) => m.value == params)
              .label;
          },
          formatType: (params) => {
            return this.inspectionTaskState.find((m) => m.value == params).type;
          },
        },
        { label: "检验人", prop: "userName" },
        { label: "复核人", prop: "checkName" },
        { label: "约定时间", prop: "appointed" },
        { label: "下发时间", prop: "sendTime", width: "140px" },
        { label: "检验开始时间", prop: "insTime", width: "140px" },
        { label: "理由", prop: "verifyTell", width: "140px" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "复核",
              type: "text",
              clickFun: (row) => {
                this.handleReview(row);
              },
              disabled: (row) => {
                return row.userName == null || row.userName && !row.userName.includes(this.nickName)
              }
            },
            {
              name: "下载报告",
              type: "text",
              clickFun: (row) => {
                this.download(row);
              },
            },
            {
              name: "上传",
              type: "text",
              clickFun: (row) => {
                this.handleUpload(row);
              },
            },
            {
              name: "还原",
              type: "text",
              clickFun: (row) => {
                this.handleRestore(row);
              },
            },
            {
              name: "查看报告",
              type: "text",
              clickFun: (row) => {
                this.handleIssued(row);
              }
            },
            // {
            //   name: "产业链",
            //   type: "text",
            //   clickFun: (row) => {
            //     this.openInfoDialog(row);
            //   },
            //   disabled: (row) => {
            //     return row.typeSource !== 1
            //   },
            // }
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
      upIndex: 0,
      planTotal: 0,
      insStateList: [],
      state:0,//0:台账页,1:检验页面,2检验页面(复核),默认为0
      activeFace: 0, //1:下单,2:查看,3:审核,默认为0
      examine: null,
      isReport: 0,
      currentId: null,
      orderId: 0,
      personList:[],
      currentTime: null,
      sonLaboratoryList:[],
      typeSourceList: [
        {label: '成品下单', value: 0},
        {label: '原材料下单', value: 1},
      ],
      isCopper: null,
      customsInspection: {},
      typeSource: null,// 0:成品下单,1:原材料下单
      showInfoDialog: false, // äº§ä¸šé“¾ä¿¡æ¯æŸ¥çœ‹
      issuedVisible: false,
      fullscreen: false,
      option:null,
    }
  },
  created() {
    this.getDicts("urgency_level").then((response) => {
      this.urgencyLevel = this.dictToValue(response.data);
    });
    this.getDicts("inspection_task_state").then((response) => {
      this.inspectionTaskState = this.dictToValue(response.data);
    });
    this.getAuthorizedPerson()
    this.currentTime = getYearAndMonthAndDays()
  },
  mounted() {
    this.refreshTable()
  },
  methods: {
    refreshTable(e) {
      this.tableLoading = true;
      let param = { ...this.entity, ...this.page };
      delete param.total;
      selectInsOrderPlanList({ ...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.refreshTable();
    },
    refresh() {
      this.resetForm('entity')
      this.refreshTable()
    },
    rowClassName({ row, rowIndex }) {
      if (this.currentTime == row.appointed) {
        return "highlight-warning-row-border";
      } else if (this.currentTime > row.appointed) {
        return "highlight-danger-row-border";
      }
      return "";
    },
    // æŸ¥çœ‹äº§ä¸šé“¾ä¿¡æ¯
    // openInfoDialog (row) {
    //   this.showInfoDialog = true
    //   this.$nextTick(() => {
    //     this.$refs.showInfoDialog.getInfo(row.ifsInventoryId)
    //   })
    // },
    selectAllByOne(row) {
      this.isCopper = row.isCopper
      this.customsInspection = row
      this.activeFace = 2;
      this.examine = 1;
      this.isReport = 0;
      this.currentId = parseInt(row.id)
      switch (row.isCopper) {
        case 0:
          // åŽŸææ–™
          this.$router.push({
            path: "/materialOrder/customsInspection", query: {
              customsInspection: row,
              active: this.activeFace,
              currentId: this.currentId,
              isReport: this.isReport
            }
          });
          break;
        case null:
          // æˆå“
          this.$router.push({
            path: "/productOrder/add", query: {
              examine: this.examine,
              active: this.activeFace,
              currentId: this.currentId
            }
          });
          break;
        case 1:
          // é“œæ
          this.$router.push({
            path: "/materialOrder/copperOrder", query: {
              active: this.activeFace,
              currentId: this.currentId
            }
          });
          break;
      }
    },
    // å¤æ ¸å›žè°ƒ
    handleReview(row){
      this.$router.push({
        path: "/inspectionTask/inspection",
        query: {
          sonLaboratory: row.sonLaboratory,
          state: 2,
          typeSource: row.typeSource,
          orderId: row.id,
        },
      })
    },
    // ä¸Šä¼ æŠ¥å‘Š
    handleUpload () {
    },
    // ä¸‹è½½æŠ¥å‘Š
    download(row) {
      let url = (row.urlS===null||row.urlS==='')?row.url:row.urlS
      const link = document.createElement('a');
      link.href = this.javaApi + url;
      link.target = '_blank';
      document.body.appendChild(link);
      link.click();
    },
    // è¿˜åŽŸæ“ä½œ
    handleRestore(row) {
      this.$axios.post(this.$api.insReport.upReportUrl, {
        id: row.insReportId
      }).then(res => {
        if (res.code === 200) {
          this.$message.success('操作成功')
          this.refreshTable('page')
        }
      })
    },
    // æŸ¥çœ‹æŠ¥å‘Š
    handleIssued(row) {
      this.currentInfo = row;
      let fileName = row.url
      let fileType = "docx"
      if (row.tempUrlPdf != null || row.tempUrlPdf === '') {
        fileName = row.tempUrlPdf
        fileType = "pdf"
      }
      fileName = fileName.replace('/word/','')
      const userName = JSON.parse(localStorage.getItem("user")).name;
      this.option = {
        url: this.javaApi + "/word/" + fileName,
        isEdit: false,
        fileType: fileType,
        title: fileName,
        lang: 'zh-CN',
        isPrint: false,
        user_id: 1,
        user_name: userName,
        editUrl: this.javaApi + "/insReport/onlyOffice/save?fileName=" + fileName
      }
      this.issuedVisible = true;
    },
    getAuthorizedPerson() {
      selectUserCondition({ type: 1 }).then((res) => {
        let data = [];
        res.data.forEach((a) => {
          data.push({
            label: a.name,
            value: a.id,
          });
        });
        this.personList = data;
      });
    },
  }
}
</script>
<style scoped>
.page_total {
  margin-bottom: 10px;
}
</style>