spring
2025-03-04 31c9c1d214f17a9e6a060565ada7937741c4bca5
搬迁管理体系文件的控制
已添加8个文件
已修改2个文件
3170 ■■■■■ 文件已修改
src/api/standard/model.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/UpPdfStamp/index.vue 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/customerManagement/base.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue 578 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/components/DistributionCollectionRecord.vue 596 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/components/FileChangeRequest.vue 703 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/components/FileList.vue 438 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/components/FileObsoletionRequest.vue 492 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/systemManagement/documentControl/index.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/standard/model/index.vue 111 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/standard/model.js
@@ -9,15 +9,6 @@
  });
}
// æ¨¡ç‰ˆå¤åˆ¶
export function copyStandardTemplate(data) {
  return request({
    url: "/StandardTemplate/copyStandardTemplate",
    method: "post",
    data: data,
  });
}
// æ·»åŠ æ£€éªŒæ¨¡æ¿
export function addStandardTemplate(data) {
  return request({
src/components/UpPdfStamp/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
<template>
  <div class="up-pdf-stamp">
    <div class="work" style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;"
      v-if="isUpFile">
      <input type="file" @change="handleFileUpload" accept="application/pdf" ref="fileInput" />
    </div>
    <p style="color: red;font-size: 12px;margin: 16px 0;" v-if="canvasNumPages > 0">提示:在文件范围内,单击鼠标盖章,双击鼠标已盖好章处可删除当前章</p>
    <canvas ref="pdfCanvas" @click="e => handleCanvasClick(e, index)" style="border: 1px solid #000;"
      @dblclick="e => removeStamp(e, index)" v-for="(item, index) in canvasNumPages" :key="index"></canvas>
  </div>
</template>
<script>
import jsPDF from "jspdf";
import file from '@/utils/file.js'
export default {
  props: ['isUpFile'],
  data() {
    return {
      pdfDoc: null, // å­˜å‚¨ä¸Šä¼ çš„ PDF æ•°æ®
      stamps: [], // è®°å½•盖章的位置
      contextList: [],//canvas列表
      canvasNumPages: 0,// å­˜å‚¨ PDF æ€»é¡µæ•°
      stampWidth: 120, // ç›–章宽度
      stampHeight: 80, // ç›–章高度
      stampsName: '',
      stampsList: ['主任', '质量负责人', '技术负责人', '综合室', '通信', '电力', '装备', '储能', '射频'],
      fileName: '文件名'
    };
  },
  methods: {
    handleFileUpload(event) {
      const file = event.target.files[0];
      if (file.size > 20 * 1024 * 1024) {
        this.$refs.fileInput.value = ""; // æ¸…空文件输入框内容
        return this.$message.error('文件大小不能超过20M')
      }
      this.lookFile(file)
    },
    lookFile(file, currentStamp) {
      this.fileName = file.name
      if (currentStamp) {
        this.stampsName = currentStamp
      } else {
        const index = this.stampsList.indexOf(m => file.name.includes(m))
        if (index > -1) {
          this.stampsName = this.stampsList[index]
        } else {
          this.stampsName = '综合室'
        }
      }
      if (file && file.type === 'application/pdf') {
        const reader = new FileReader();
        reader.onload = (e) => {
          const typedArray = new Uint8Array(e.target.result);
          this.loadPDF(typedArray);
        };
        reader.readAsArrayBuffer(file);
      } else {
        this.$message.error('请选择 PDF æ–‡ä»¶');
      }
    },
    loadPDF(typedArray) {
      pdfjsLib.getDocument(typedArray).promise.then(pdfDoc_ => {
        this.pdfDoc = pdfDoc_;
        this.canvasNumPages = this.pdfDoc._pdfInfo.numPages
        this.stamps = []
        this.contextList = []
        for (let i = 1; i <= this.canvasNumPages; i++) {
          this.$nextTick(() => {
            this.renderPage(i); // æ¸²æŸ“页面
          });
          this.stamps.push([])
        }
      });
    },
    // æ¸²æŸ“指定页面
    renderPage(pageNum) {
      this.pdfDoc.getPage(pageNum).then(page => {
        const canvas = this.$refs.pdfCanvas[pageNum - 1];
        this.contextList.push(canvas.getContext("2d"))
        const viewport = page.getViewport({ scale: 1.5 });
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        page.render({
          canvasContext: this.contextList[pageNum - 1],
          viewport: viewport
        }).promise.then(() => {
          this.stamps[pageNum - 1].forEach(m => {
            this.drawStamps(m.x, m.y, pageNum - 1)
          })
        });
      });
    },
    // å•击--添加章
    handleCanvasClick(event, i) {
      const x = event.offsetX;
      const y = event.offsetY;
      const index = this.stamps[i].findIndex(stamp => {
        let x0 = x - stamp.x;
        let y0 = y - stamp.y;
        return x0 > 0 && x0 < this.stampWidth && y0 > 0 && y0 < this.stampHeight;
      });
      if (index > -1) return;
      this.drawStamps(x, y, i)
      this.stamps[i].push({ x, y });
    },
    // åŒå‡»--删除盖章
    removeStamp(event, i) {
      const x = event.offsetX;
      const y = event.offsetY;
      // æŸ¥æ‰¾è¢«åŒå‡»çš„ç›–ç« 
      const index = this.stamps[i].findIndex(stamp => {
        let x0 = x - stamp.x;
        let y0 = y - stamp.y;
        return x0 > 0 && x0 < this.stampWidth && y0 > 0 && y0 < this.stampHeight;
      });
      if (index === -1) return;
      this.stamps[i].splice(index, 1); // åˆ é™¤æŒ‡å®šçš„ç›–ç« 
      this.contextList[i].clearRect(0, 0, this.contextList[i].width, this.contextList[i].height);
      this.renderPage(i + 1)
    },
    // æ¸²æŸ“ç« 
    drawStamps(x, y, index) {
      var img = new Image();
      console.log(this.stampsName)
      // è®¾ç½®å›¾ç‰‡æº
      img.src = require("@/assets/stamps/" + this.stampsName + ".png"); // æ›¿æ¢ä¸ºä½ çš„图片链接
      let that = this
      img.onload = function () {
        // å›¾ç‰‡åŠ è½½å®ŒæˆåŽï¼Œå°†å›¾ç‰‡ç»˜åˆ¶åˆ°canvas上
        that.contextList[index].drawImage(img, x, y, that.stampWidth, that.stampHeight);
      };
    },
    // ç”Ÿæˆ PDF çš„函数
    async generatePDF() {
      if (this.contextList.length === 0) {
        this.$message({ message: '请先上传PDF文件', type: 'error' });
        this.$emit('uploadPDFErr')
        return false
      }
      const pdf = new jsPDF("p", "mm", "a4");
      for (let i = 0; i < this.contextList.length; i++) {
        const imgData = this.$refs.pdfCanvas[i].toDataURL('image/jpeg', 0.7);
        const pdfWidth = pdf.internal.pageSize.getWidth();
        const pdfHeight = (this.$refs.pdfCanvas[i].height * pdfWidth) / this.$refs.pdfCanvas[i].width;
        pdf.addImage(imgData, "JPEG", 0, 0, pdfWidth, pdfHeight); // å°†å›¾ç‰‡æ·»åŠ åˆ° PDF
        if (i !== this.contextList.length - 1) {
          pdf.addPage(); // æ·»åŠ æ–°çš„ä¸€é¡µ
        }
      }
      // å°† PDF æ–‡ä»¶ä¿å­˜æˆ–上传
      const pdfOutput = pdf.output('blob'); // èŽ·å– PDF æ–‡ä»¶çš„ Blob å¯¹è±¡
      // ä¸Šä¼ åˆ°åŽç«¯
      return this.$emit('uploadPDF', pdfOutput, this.fileName)
    },
  }
}
</script>
<style scoped></style>
src/views/CNAS/systemManagement/customerManagement/base.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
<template>
  <div>客户基本信息管理</div>
</template>
<script>
export default {
}
</script>
<style></style>
src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,578 @@
<template>
  <!-- æ–‡ä»¶å—控申请 -->
  <div class="controlled-file-application" style="height: 100%;">
    <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.documentCode"
            @keyup.enter.native="refreshTable()"></el-input></div>
      </div>
      <!-- <div class="search_thing">
        <div class="search_label">申请人:</div>
        <div class="search_input"><el-input size="small" placeholder="请输入" clearable
            v-model="queryParams.createUserName" @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="btns" style="padding-left: 30px;">
        <el-button size="small" type="primary"
          @click="addDialogVisible = true, addInfo = {}, file = null">文件受控申请</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
        :height="'calc(100vh - 290px)'" @pagination="pagination"></lims-table>
    </div>
    <el-dialog title="文件受控申请" :visible.sync="addDialogVisible" width="800px" top="10vh">
      <el-row>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>申请编号:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable
                v-model="addInfo.documentCode"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">责任人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.dutyUser" size="small" style="width: 100%;" filterable>
                <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="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件类别:</div>
            <div class="search_input">
              <el-select v-model="addInfo.type" size="small" style="width: 100%;">
                <el-option v-for="item in fileType" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="12" 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.name"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" 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.version"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">上传附件:</div>
            <div class="search_input"><el-upload style="margin: 8px 0 0px 50px;" action="#" :auto-upload="false"
                :multiple="false" accept='.pdf' :on-change="handleChangeUpload" v-if="addDialogVisible">
                <el-button size="small" type="primary">上传附件</el-button>
              </el-upload></div>
          </div>
        </el-col>
        <el-col :span="12" 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.writer"></el-input> -->
              <el-select v-model="addInfo.writer" size="small" style="width: 100%;" filterable>
                <el-option v-for="item in personList" :key="item.value" :label="item.label" :value="item.label">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">提交日期:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.submitDate" 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="12" 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.instructions"
                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>
    <el-dialog title="查看附件" :visible.sync="lookDialogVisible" width="800px" top="5vh" fullscreen>
      <filePreview v-if="lookDialogVisible" :fileUrl="javaApi + '/word/' + currentInfo.url" :currentFile="{}"
        style="height: 90vh;overflow-y: auto;" />
    </el-dialog>
    <el-dialog title="审核" :visible.sync="checkDialogVisible" width="1000px" top="5vh">
      <UpPdfStamp ref="UpPdfStamp" v-if="checkDialogVisible" @uploadPDF="uploadPDF" :isUpFile="false"></UpPdfStamp>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleCheckSub('不通过')" :loading="noCheckLoading">不通过</el-button>
        <el-button type="primary" @click="handleCheckSub('通过')" :loading="checkLoading">通 è¿‡</el-button>
      </span>
    </el-dialog>
    <el-dialog title="选择受控章" :visible.sync="checkStampDialogVisible" width="600px" top="5vh">
      <div class="stamp-list">
        <img :src="require('@/assets/stamps/' + item + '.png')" alt="" v-for="(item, index) in stampsList" :key="index"
          style="width: 120px;height: 80px;margin: 6px;" class="stamp" :class="{ active: currentStamp == item }"
          @click="currentStamp = item">
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="checkStampDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="handleCheck0(currentInfo)">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import UpPdfStamp from '@/components/UpPdfStamp/index.vue'
import filePreview from '@/components/Preview/filePreview.vue'
import limsTable from "@/components/Table/lims-table.vue";
import {
  selectUserCondition,
} from "@/api/system/user.js";
import {
  addManageDocumentControlled,
  doManageDocumentControlled,
  checkManageDocumentControlledPdf,
  delManageDocumentControlled,
  pageManageDocumentControlled,
  checkManageDocumentControlled,
} from '@/api/cnas/systemManagement/documentControl.js'
import { mapGetters } from "vuex";
export default {
  components: {
    filePreview,
    UpPdfStamp,
    limsTable
  },
  computed: {
    ...mapGetters(["nickName"]),
  },
  data() {
    return {
      upLoading: false,
      addPower: false,
      addDialogVisible: false,
      addLoading: false,
      lookDialogVisible: false,
      checkDialogVisible: false,
      checkStampDialogVisible: false,
      addInfo: {},
      personList: [],
      fileType: [],
      file: null,
      currentInfo: {},
      checkLoading: false,
      noCheckLoading: false,
      type: '',
      stampsList: ['主任', '质量负责人', '技术负责人', '综合室', '通信', '电力', '装备', '储能', '射频'],
      currentStamp: '主任',
      queryParams: {},
      tableData: [],
      column: [
        { label: "申请文件编号", prop: "documentCode" },
        {
          label: "文件类别", prop: "type", width: "120px", dataType: "tag",
          formatData: (params) => {
            return this.fileType.find((m) => m.value == params).label;
          },
          formatType: (params) => {
            return this.fileType.find((m) => m.value == params).type;
          },
        },
        {
          label: "申请人",
          prop: "createUserName",
        },
        { label: "申请时间", prop: "createTime" },
        { label: "说明", prop: "instructions" },
        { label: "提交日期", prop: "submitDate" },
        { label: "责任人", prop: "dutyUserName" },
        {
          label: "申请状态", prop: "state", dataType: "tag",
          formatData: (params) => {
            return params;
          },
          formatType: (params) => {
            if (params == '通过') {
              return 'success'
            } else {
              return 'danger'
            }
          },
        },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.handleUpdate(row);
              },
              disabled: (row) => {
                return row.state == '通过'
              }
            },
            {
              name: "审核",
              type: "text",
              clickFun: (row) => {
                this.handleCheck(row);
              },
              disabled: (row) => {
                return !row.dutyUserName.includes(this.nickName) || row.state == '通过'
              }
            },
            {
              name: "查看附件",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
            {
              name: "下载",
              type: "text",
              clickFun: (row) => {
                this.handleDown(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
              disabled: (row, index) => {
                return row.state == '通过'
              }
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  mounted() {
    this.getList()
    this.getAuthorizedPerson()
    this.selectEnumByCategory()
  },
  methods: {
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageManageDocumentControlled({ ...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();
    },
    refreshTable() {
      this.page.current = 1;
      this.getList();
    },
    refresh() {
      this.queryParams = {};
      this.page.current = 1;
      this.getList();
    },
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let up = false
      let del = false
      let add = false
      // let check = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'addManageDocumentControlled') {
          up = true
        }
        if (power[i].menuMethod == 'addManageDocumentControlled') {
          add = true
        }
        if (power[i].menuMethod == 'delManageDocumentControlled') {
          del = true
        }
        // if (power[i].menuMethod == 'checkManageDocumentControlled') {
        //   check = true
        // }
      }
      // if (!check) {
      //   this.componentData.do.splice(2, 1)
      // }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      if (!up) {
        this.componentData.do.splice(0, 1)
      }
      this.addPower = add
    },
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    selectEnumByCategory() {
      // æ–‡ä»¶ç±»åˆ«
      this.getDicts("document_type").then((response) => {
        this.fileType = this.dictToValue(response.data);
      });
    },
    // æäº¤
    handleAdd() {
      if (!this.addInfo.documentCode) return this.$message({ type: 'error', message: "请输入编号" })
      if (!this.addInfo.id) {
        // æ–°å¢ž
        let fd = new FormData();
        //文件信息中raw才是真的文件
        if (this.file) {
          fd.append("file", this.file.raw);
        }
        for (let m in this.addInfo) {
          fd.append(m, this.addInfo[m])
        }
        this.addLoading = true
        addManageDocumentControlled(fd).then(res => {
          this.addLoading = false
          if (res.code == 200) {
            this.$message({
              type: 'success',
              message: '添加成功'
            })
            this.refreshTable()
            this.addDialogVisible = false
          } else {
            this.$message({
              type: 'error',
              message: '添加失败'
            })
          }
        })
      } else {
        // ä¿®æ”¹
        let { id, documentCode, dutyUser, type, name, version, writer, submitDate, instructions } = this.addInfo
        let fd = new FormData();
        //文件信息中raw才是真的文件
        if (this.file) {
          fd.append("file", this.file.raw);
        }
        fd.append("id", id);
        fd.append("documentCode", documentCode);
        fd.append("dutyUser", dutyUser);
        fd.append("type", type);
        fd.append("name", name);
        fd.append("version", version);
        fd.append("writer", writer);
        fd.append("submitDate", submitDate);
        fd.append("instructions", instructions);
        this.addLoading = true
        doManageDocumentControlled(fd).then(res => {
          this.addLoading = false
          if (res.code == 200) {
            this.refreshTable()
            this.addDialogVisible = false
          } else {
            this.$message({
              type: 'error',
              message: '添加失败'
            })
          }
        })
      }
    },
    handleChangeUpload(file, fileLists) {
      this.file = file
      this.$set(this.addInfo, 'name', file.name)
    },
    // ç¼–辑
    handleUpdate(row) {
      this.title = '文件变更申请'
      this.addInfo = this.HaveJson(row)
      this.addDialogVisible = true
    },
    // æŸ¥çœ‹é™„ä»¶
    handleLook(row) {
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    // å®¡æ ¸
    handleCheck(row) {
      this.title = '审核'
      this.currentInfo = row
      if (!row.url) return this.$message.warning('文件未上传')
      this.checkStampDialogVisible = true
    },
    handleCheck0(row) {
      this.checkStampDialogVisible = false
      this.checkDialogVisible = true
      checkManageDocumentControlledPdf({ id: row.id }).then(res => {
        const blob = new Blob([res]);
        const file = new File([blob], row.name, { type: 'application/pdf' })
        this.$refs.UpPdfStamp.lookFile(file, this.currentStamp)
      }).catch(err => {
        console.log(err)
      })
    },
    handleDown(row) {
      if (!row.url) return this.$message.warning('文件未上传')
      let url = this.javaApi + '/word/' + row.url
      this.$download.saveAs(url, row.url);
    },
    async uploadPDF(pdfBlob) {
      const formData = new FormData();
      formData.append('file', pdfBlob, this.fileName + '.pdf'); // æ–‡ä»¶å­—段
      formData.append('id', this.currentInfo.id); // æ–‡ä»¶åå­—段
      formData.append('state', this.type); // æ–‡ä»¶åå­—段
      formData.append('writer', this.currentInfo.writer); // æ–‡ä»¶åå­—段
      try {
        let res = await checkManageDocumentControlled(formData)
        this.checkLoading = false
        this.noCheckLoading = false
        if (res.code == 200) {
          this.$message({ message: '操作成功', type: 'success' });
          this.checkDialogVisible = false;
          this.refreshTable()
          return true
        } else {
          this.$message({ message: '操作失败', type: 'error' });
          return false
        }
      } catch (e) {
        this.checkLoading = false
        this.noCheckLoading = false
      }
    },
    handleCheckSub(type) {
      this.type = type
      if (type == '通过') {
        this.checkLoading = true
      } else {
        this.noCheckLoading = true
      }
      this.addLoading = true
      this.$refs['UpPdfStamp'].generatePDF()
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delManageDocumentControlled({ 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 - 80px);
  padding: 20px;
}
.btns {
  position: absolute;
  right: 20px;
  top: 5px;
}
.stamp {
  cursor: pointer;
  border: #fff 1px solid;
}
.stamp:hover {
  border: #3A7BFA 1px solid;
  box-shadow: inset 0px 0px 15px #3A7BFA;
}
.stamp.active {
  border: #3A7BFA 1px solid;
  box-shadow: inset 0px 0px 15px #3A7BFA;
}
</style>
src/views/CNAS/systemManagement/documentControl/components/DistributionCollectionRecord.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,596 @@
<template>
  <!-- å‘放回收记录 -->
  <div class="distribution-collection-record" style="height: 100%;">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">文件编号:</div>
        <div class="search_input"><el-input v-model="queryParams.documentCode" 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.name" 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="btns" style="padding-left: 30px;">
        <el-button v-if="addPower" size="small" type="primary"
          @click="addDialogVisible = true, addInfo = {}, radio = '发放'">添加发放记录</el-button>
        <el-button v-if="outPower" :loading="outLoading" size="small" type="primary" @click="handleOut">导出</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
        :height="'calc(100vh - 290px)'" @pagination="pagination"></lims-table>
    </div>
    <el-dialog :title="'添加' + radio + '记录'" :visible.sync="addDialogVisible" top="10vh" width="800px">
      <el-row v-if="addDialogVisible">
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>申请编号:</div>
            <div class="search_input">
              <el-select v-model="addInfo.documentCode" :disabled="radio == '回收'" allow-create clearable filterable
                size="small" style="width: 100%;" @change="changeFileList">
                <el-option v-for="item in fileList" :key="item.documentCode" :label="item.documentCode"
                  :value="item.documentCode">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col v-if="radio == '发放'" :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>发放人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.issueUser" filterable 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 v-else :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>回收人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.recycleUser" filterable 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="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>审批人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.receiveUser" :disabled="radio != '发放'" filterable 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="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件名称:</div>
            <div class="search_input"><el-input v-model="addInfo.name" :disabled="radio == '回收'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件版本:</div>
            <div class="search_input"><el-input v-model="addInfo.version" :disabled="radio == '回收'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件状态:</div>
            <div class="search_input">
              <el-select v-model="addInfo.state" :disabled="radio == '回收'" size="small" style="width: 100%;">
                <el-option v-for="(item, index) in fileState" :key="index" :label="item.label"
                  :value="item.value"></el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col v-if="radio == '发放'" :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发放编号:</div>
            <div class="search_input"><el-input v-model="addInfo.issueCode" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col v-else :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">回收编号:</div>
            <div class="search_input"><el-input v-model="addInfo.recycleCode" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col v-if="radio == '发放'" :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发放时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.issueDate" 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-col v-else :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">回收时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.recycleDate" 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-col v-if="radio == '发放'" :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">发放说明:</div>
            <div class="search_input"><el-input v-model="addInfo.issueNote" :rows="2" clearable placeholder="请输入"
                size="small" type="textarea"></el-input></div>
          </div>
        </el-col>
        <el-col v-else :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">回收说明:</div>
            <div class="search_input"><el-input v-model="addInfo.recycleNote" :rows="2" clearable placeholder="请输入"
                size="small" type="textarea"></el-input></div>
          </div>
        </el-col>
        <el-col v-if="radio == '发放'" :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">上传附件:</div>
            <div class="search_input"><el-upload :auto-upload="false" :multiple="false" :on-change="handleChangeUpload"
                accept='.pdf,.doc,.docx,.xls,.xlsx' action="#" style="margin: 8px 0 0px 50px;">
                <el-button size="small" type="primary">上传附件</el-button>
              </el-upload></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.url"
        style="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 {
  selectUserCondition,
} from "@/api/system/user.js";
import {
  pageManageDocumentList,
  pageManageDocumentCancel,
  exportManageDocumentIssueRecycle,
  addManageDocumentIssueRecycle,
  doManageDocumentIssueRecycle,
  checkManageDocumentIssueRecycle,
  pageManageDocumentIssueRecycle,
  delManageDocumentIssueRecycle,
} from '@/api/cnas/systemManagement/documentControl.js'
import { mapGetters } from "vuex";
export default {
  components: {
    filePreview,
    limsTable
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      ddPower: false,
      outPower: true,
      addInfo: {},
      addPower: true,
      addLoading: false,
      addDialogVisible: false,
      outLoading: false,
      personList: [],
      fileList: [],
      fileList0: [],
      radio: '发放',
      fileState: [],
      file: null,
      currentInfo: {},
      lookDialogVisible: false,
      queryParams: {},
      tableData: [],
      column: [
        { label: "文件编号", prop: "documentCode" },
        { label: "文件名称", prop: "name" },
        {
          label: "文件版本",
          prop: "version",
        },
        { label: "文件状态", prop: "documentState" },
        { label: "发放编号", prop: "issueCode" },
        { label: "发放人", prop: "issueUserName" },
        { label: "发放日期", prop: "issueDate" },
        { label: "回收人", prop: "recycleUserName" },
        { label: "回收日期", prop: "recycleDate" },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "回收记录",
              type: "text",
              clickFun: (row) => {
                this.handleUpdate(row);
              }
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
              disabFun: (row, index) => {
                return row.documentState == '通过'
              }
            },
            {
              name: "查看附件",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
              disabFun: (row, index) => {
                return !row.url
              }
            },
            {
              name: "审核",
              type: "text",
              clickFun: (row) => {
                this.handleCheck(row);
              },
              disabFun: (row, index) => {
                return row.receiveUser != this.userId || row.documentState == '通过'
              }
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  mounted() {
    this.getList()
    this.getAuthorizedPerson()
    this.getFileList()
    this.getFileList0()
    this.selectEnumByCategory()
  },
  methods: {
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let out = false
      let del = false
      let add = false
      // let check = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'exportManageDocumentIssueRecycle') {
          out = true
        }
        if (power[i].menuMethod == 'addManageDocumentIssueRecycle') {
          add = true
        }
        if (power[i].menuMethod == 'delManageDocumentIssueRecycle') {
          del = true
        }
        // if (power[i].menuMethod == 'checkManageDocumentControlled') {
        //   check = true
        // }
      }
      // if (!check) {
      //   this.componentData.do.splice(2, 1)
      // }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      if (!add) {
        this.componentData.do.splice(0, 1)
      }
      this.addPower = add
      this.outPower = out
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageManageDocumentIssueRecycle({ ...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();
    },
    selectEnumByCategory() {
      // æ–‡ä»¶çŠ¶æ€
      this.getDicts("document_state").then((response) => {
        this.fileState = this.dictToValue(response.data);
      });
    },
    // èŽ·å–äººå‘˜åˆ—è¡¨
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    // èŽ·å–æ–‡ä»¶åˆ—è¡¨--文件清单
    getFileList() {
      pageManageDocumentList({
        current: -1,
        size: -1
      }).then(res => {
        this.fileList = res.data.records
      }).catch(err => { })
    },
    // èŽ·å–æ–‡ä»¶åˆ—è¡¨--作废文件
    getFileList0() {
      pageManageDocumentCancel({
        current: -1,
        size: -1
      }).then(res => {
        this.fileList0 = res.data.records
      }).catch(err => { })
    },
    // å¯¼å‡º
    handleOut() {
      this.outLoading = true
      // queryParams
      exportManageDocumentIssueRecycle(this.queryParams).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/octet-stream' });
        this.$download.saveAs(blob, '发放回收记录.xlsx');
      })
    },
    changeFileList(e) {
      if (e) {
        let obj = this.fileList.find(a => a.documentCode == e)
        if (obj) {
          this.addInfo.name = obj.name
          this.addInfo.version = obj.version
          this.addInfo.state = obj.state
        }
      }
    },
    // æäº¤
    handleAdd() {
      if (!this.addInfo.documentCode) {
        this.$message.error('请选择文件')
        return
      }
      if (!this.addInfo.receiveUser) {
        this.$message.error('请选择审批人')
        return
      }
      if (this.radio == '发放') {
        if (!this.addInfo.issueUser) {
          this.$message.error('请选择发放人')
          return
        }
      } else {
        if (!this.addInfo.recycleUser) {
          this.$message.error('请选择回收人')
          return
        }
      }
      this.addLoading = true;
      if (!this.addInfo.id) {
        // æ–°å¢žå‘放记录
        let fd = new FormData();
        //文件信息中raw才是真的文件
        if (this.file) {
          fd.append("file", this.file.raw);
        }
        for (let key in this.addInfo) {
          fd.append(key, this.addInfo[key])
        }
        addManageDocumentIssueRecycle(fd).then(res => {
          this.addLoading = false;
          if (res.code == 200) {
            this.$message.success('发放成功')
            this.addDialogVisible = false
            this.refreshTable()
          }
        })
      } else {
        let { documentCode, id, issueUser, recycleUser, receiveUser, name, version, documentState, issueCode, recycleCode, issueDate, recycleDate, issueNote, recycleNote } = this.addInfo
        // æ·»åŠ å›žæ”¶è®°å½•
        doManageDocumentIssueRecycle({
          documentCode,
          id,
          issueUser,
          recycleUser,
          receiveUser,
          name,
          version,
          documentState,
          issueCode,
          recycleCode,
          issueDate,
          recycleDate,
          issueNote,
          recycleNote
        }).then(res => {
          this.addLoading = false;
          if (res.code == 200) {
            this.$message.success('提交成功')
            this.addDialogVisible = false
            this.refreshTable()
          }
        })
      }
    },
    // æ·»åŠ å›žæ”¶
    handleUpdate(row) {
      this.addInfo = this.HaveJson(row)
      this.radio = '回收'
      this.addDialogVisible = true
    },
    // å®¡æ ¸
    handleCheck(row) {
      this.$confirm('是否审核通过?', '提示', {
        confirmButtonText: '通过',
        cancelButtonText: '不通过',
        type: 'warning',
        closeOnClickModal: false, // ç¦æ­¢ç‚¹å‡»é®ç½©å±‚关闭
        distinguishCancelAndClose: true,
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            // ç‚¹å‡»â€œç¡®å®šâ€æŒ‰é’®ï¼Œå…è®¸å…³é—­
            checkManageDocumentIssueRecycle({ id: row.id, documentState: '通过' }).then(res => {
              this.refreshTable()
              done();
              this.$message({
                type: 'success',
                message: '提交成功'
              })
            })
              .catch(err => {
              })
          } else if (action === 'cancel') {
            // ç‚¹å‡»â€œå–消”按钮,不允许关闭
            checkManageDocumentIssueRecycle({ id: row.id, documentState: '不通过' }).then(res => {
              this.refreshTable()
              done();
              this.$message({
                type: 'success',
                message: '提交成功'
              })
            })
              .catch(err => {
              })
          } else if (action === 'close') {
            // ç‚¹å‡»â€œÃ—”按钮,不允许关闭
            done();
            console.log("×按钮点击事件,不关闭弹框");
          }
        }
      })
    },
    handleChangeUpload(file, fileLists) {
      this.file = file
      this.$set(this.addInfo, 'name', file.name)
    },
    // æŸ¥çœ‹é™„ä»¶
    handleLook(row) {
      this.currentInfo = this.HaveJson(row)
      this.lookDialogVisible = true
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delManageDocumentIssueRecycle({ 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 - 80px);
  padding: 20px;
}
.btns {
  position: absolute;
  right: 20px;
  top: 5px;
}
</style>
src/views/CNAS/systemManagement/documentControl/components/FileChangeRequest.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,703 @@
<template>
  <!-- æ–‡ä»¶å˜æ›´ç”³è¯· -->
  <div class="file-change-request" style="height: 100%;">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">申请文件编号:</div>
        <div class="search_input"><el-input v-model="queryParams.code" 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="btns">
        <el-button size="small" type="primary"
          @click="addDialogVisible = true, addInfo = {}, currentFile = {}, title = '文件变更申请'">文件变更申请</el-button>
        <el-button :loading="outLoading" size="small" type="primary" @click="handleOut">导出</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
        :height="'calc(100vh - 290px)'" @pagination="pagination"></lims-table>
    </div>
    <el-dialog :title="title" :visible.sync="addDialogVisible" top="0vh" width="950px">
      <el-row>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>申请编号:</div>
            <div class="search_input"><el-input v-model="addInfo.code" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">审批人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.checkUser" :disabled="title == '审核'" filterable 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="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">期望变更时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.expectAlterDate" :disabled="title == '审核'" 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-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">实际变更时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.actuallyAlterDate" :disabled="title == '审核'" 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-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.alterBeforeCode" :disabled="title == '审核'" allow-create clearable filterable
                size="small" style="width: 100%;" @change="getCurrentFile">
                <el-option v-for="item in fileList" :key="item.documentCode" :label="item.title"
                  :value="item.documentCode">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="24">
          <h4 class="title">当前文件信息</h4>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">文件编号:</div>
            <div class="search_input"><el-input v-model="currentFile.documentCode" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">文件名称:</div>
            <div class="search_input"><el-input v-model="currentFile.name" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">文件版本:</div>
            <div class="search_input"><el-input v-model="currentFile.version" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">提交人:</div>
            <div class="search_input"><el-select v-model="currentFile.createUser" disabled filterable 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="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">审核人:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.version" disabled></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">作废人:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.version" disabled></el-input></div>
          </div>
        </el-col> -->
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">提交时间:</div>
            <div class="search_input"><el-input v-model="currentFile.createTime" clearable disabled placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">审核时间:</div>
            <div class="search_input"><el-input v-model="currentFile.effectiveDate" clearable disabled placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <!-- <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">作废时间:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.version" disabled></el-input></div>
          </div>
        </el-col> -->
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">文件状态:</div>
            <div class="search_input">
              <el-select v-model="currentFile.state" disabled size="small" style="width: 100%;">
                <el-option v-for="item in fileState" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <!-- <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">文件说明:</div>
            <div class="search_input"><el-input size="small" placeholder="请输入" clearable v-model="addInfo.instructions" type="textarea"
              :rows="2" disabled></el-input></div>
          </div>
        </el-col> -->
        <el-col :span="24">
          <h4 class="title">文件变更申请</h4>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">变更后编号:</div>
            <div class="search_input"><el-input v-model="addInfo.alterAfterCode" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">变更后名称:</div>
            <div class="search_input"><el-input v-model="addInfo.alterAfterName" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">前一版本处理:</div>
            <div class="search_input">
              <el-select v-model="addInfo.method" :disabled="title == '审核'" size="small" style="width: 100%;">
                <el-option label="作废" value="作废"></el-option>
                <el-option label="存档不可用" value="存档不可用">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="8" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">变更后版本:</div>
            <div class="search_input"><el-input v-model="addInfo.alterAfterVersion" :disabled="title == '审核'" clearable
                placeholder="请输入" size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="16" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">变更说明:</div>
            <div class="search_input"><el-input v-model="addInfo.alterNote" :disabled="title == '审核'" :rows="2"
                clearable placeholder="请输入" size="small" type="textarea"></el-input></div>
          </div>
        </el-col>
        <el-col v-if="title != '审核'" :span="24" style="margin-bottom: 16px;">
          <div class="search_thing" style="width: 100%;">
            <div class="search_label">相关附件:</div>
            <div class="search_input"><el-upload v-if="addDialogVisible" :auto-upload="false" :multiple="false"
                :on-change="handleChangeUpload" accept='.pdf' action="#" style="margin: 8px 0 0px 50px;">
                <el-button size="small" type="primary">上传附件</el-button>
              </el-upload></div>
          </div>
        </el-col>
        <UpPdfStamp v-if="title == '审核' && addDialogVisible" ref="UpPdfStamp" :isUpFile="false" @uploadPDF="uploadPDF">
        </UpPdfStamp>
      </el-row>
      <span v-if="title != '审核'" slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button :loading="addLoading" type="primary" @click="handleAdd">ç¡® å®š</el-button>
      </span>
      <span v-else slot="footer" class="dialog-footer">
        <el-button :loading="noCheckLoading" @click="handleCheckSub('不通过')">不通过</el-button>
        <el-button :loading="checkLoading" type="primary" @click="handleCheckSub('通过')">通 è¿‡</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.alterAfterUrl"
        style="height: 90vh;overflow-y: auto;" />
    </el-dialog>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import UpPdfStamp from '@/components/UpPdfStamp/index.vue'
import filePreview from '@/components/Preview/filePreview.vue'
import {
  selectUserCondition,
} from "@/api/system/user.js";
import {
  exportManageDocumentAlter,
  pageManageDocumentList,
  addManageDocumentAlter,
  doManageDocumentAlter,
  checkManageDocumentAlterPdf,
  checkManageDocumentAlter,
  delManageDocumentAlter,
  pageManageDocumentAlter,
} from '@/api/cnas/systemManagement/documentControl.js'
import { mapGetters } from "vuex";
export default {
  components: {
    limsTable,
    filePreview,
    UpPdfStamp,
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      title: '文件变更申请',
      noCheckLoading: false,
      checkLoading: false,
      addDialogVisible: false,
      addInfo: {},
      addPower: false,
      outPower: false,
      outLoading: false,
      personList: [],
      fileList: [],
      currentFile: {},
      fileState: [],
      file: null,
      addLoading: false,
      lookDialogVisible: false,
      currentInfo: {
      },
      type: null,
      fileName: null,
      queryParams: {},
      tableData: [],
      column: [
        { label: "申请编号", prop: "code" },
        { label: "申请人", prop: "createUserName", width: "120px" },
        {
          label: "变更说明",
          prop: "alterNote",
        },
        { label: "期望变更时间", prop: "expectAlterDate" },
        { label: "实际变更时间", prop: "actuallyAlterDate" },
        {
          label: "状态", prop: "state", dataType: "tag",
          formatData: (params) => {
            return params;
          },
          formatType: (params) => {
            if (params == '通过') {
              return 'success'
            } else {
              return 'danger'
            }
          },
        },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.handleUpdate(row);
              },
              disabled: (row, index) => {
                return row.state == '通过'
              }
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
              disabled: (row, index) => {
                return row.state == '通过'
              }
            },
            {
              name: "审核",
              type: "text",
              clickFun: (row) => {
                this.handleCheck(row);
              },
              disabled: (row, index) => {
                return row.checkUser != this.userId || row.state == '通过'
              }
            },
            {
              name: "查看附件",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
            {
              name: "下载附件",
              type: "text",
              clickFun: (row) => {
                this.handleDown(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  mounted() {
    this.getList()
    this.getAuthorizedPerson()
    this.getFileList()
    this.selectEnumByCategory()
  },
  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 == 'addManageDocumentAlter') {
          up = true
        }
        if (power[i].menuMethod == 'addManageDocumentAlter') {
          add = true
        }
        if (power[i].menuMethod == 'delManageDocumentAlter') {
          del = true
        }
        if (power[i].menuMethod == 'exportManageDocumentAlter') {
          out = true
        }
      }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      if (!up) {
        this.componentData.do.splice(0, 1)
      }
      this.addPower = add
      this.outPower = out
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageManageDocumentAlter({ ...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();
    },
    // å¯¼å‡º
    handleOut() {
      this.outLoading = true
      exportManageDocumentAlter(this.queryParams).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/octet-stream' });
        this.$download.saveAs(blob, '文件变更记录.xlsx')
      })
    },
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    // èŽ·å–æ–‡ä»¶åˆ—è¡¨--文件清单
    getFileList() {
      pageManageDocumentList({
        current: -1,
        size: -1
      }).then(res => {
        this.fileList = res.data.records.map(m => {
          m.title = m.documentCode + ':' + m.name
          return m
        })
      }).catch(err => { })
    },
    // å½“前文件
    getCurrentFile(e) {
      this.currentFile = this.fileList.find(m => m.documentCode == e)
      if (!this.currentFile) {
        this.currentFile = {}
      }
    },
    selectEnumByCategory() {
      // æ–‡ä»¶çŠ¶æ€
      this.getDicts("document_state").then((response) => {
        this.fileState = this.dictToValue(response.data);
      });
    },
    handleChangeUpload(file, fileLists) {
      this.file = file
      this.$set(this.addInfo, 'alterAfterName', file.name)
    },
    handleAdd() {
      if (!this.addInfo.code) return this.$message({ type: 'error', message: "请输入申请编号" })
      if (!this.addInfo.id) {
        // æ–°å¢ž
        let fd = new FormData();
        //文件信息中raw才是真的文件
        if (this.file) {
          fd.append("file", this.file.raw);
        }
        for (let m in this.addInfo) {
          fd.append(m, this.addInfo[m])
        }
        let { name, version, documentCode } = this.currentFile;
        fd.append("alterBeforeName", name);
        fd.append("alterBeforeVersion", version);
        // fd.append("alterBeforeCode",documentCode);
        this.addLoading = true
        addManageDocumentAlter(fd).then(res => {
          this.addLoading = false
          if (res.code == 200) {
            this.$message({
              type: 'success',
              message: '添加成功'
            })
            this.refreshTable()
            this.addDialogVisible = false
          } else {
            this.$message({
              type: 'error',
              message: '添加失败'
            })
          }
        })
      } else {
        // ä¿®æ”¹
        let fd = new FormData();
        //文件信息中raw才是真的文件
        if (this.file) {
          fd.append("file", this.file.raw);
        }
        let { name, version } = this.currentFile;
        fd.append("alterBeforeName", name);
        fd.append("alterBeforeVersion", version);
        let { code, checkUser, expectAlterDate, actuallyAlterDate, alterAfterCode, method, alterAfterVersion, alterNote, alterAfterName, id } = this.addInfo
        fd.append("code", code);
        fd.append("checkUser", checkUser);
        fd.append("expectAlterDate", expectAlterDate);
        fd.append("actuallyAlterDate", actuallyAlterDate);
        fd.append("alterAfterCode", alterAfterCode);
        fd.append("method", method);
        fd.append("alterAfterVersion", alterAfterVersion);
        fd.append("alterNote", alterNote);
        fd.append("alterAfterName", alterAfterName);
        fd.append("id", id);
        this.addLoading = true
        doManageDocumentAlter(fd).then(res => {
          this.addLoading = false
          if (res.code == 200) {
            this.$message({
              type: 'success',
              message: '修改成功'
            })
            this.refreshTable()
            this.addDialogVisible = false
          } else {
            this.$message({
              type: 'error',
              message: '修改失败'
            })
          }
        })
      }
    },
    // ç¼–辑
    handleUpdate(row) {
      this.title = '文件变更申请'
      this.addInfo = this.HaveJson(row)
      let alterBeforeCode = this.addInfo.alterBeforeCode
      this.getCurrentFile(alterBeforeCode)
      this.addDialogVisible = true
    },
    // é¢„览
    handleLook(row) {
      this.currentInfo = this.HaveJson(row)
      this.lookDialogVisible = true
    },
    // ä¸‹è½½é™„ä»¶
    handleDown(row) {
      if (!row.alterAfterUrl) return this.$message.warning('文件未上传')
      let url = this.javaApi + '/word/' + row.alterAfterUrl
      this.$download.saveAs(url, row.alterAfterUrl)
    },
    // æ‰“开审核弹框
    handleCheck(row) {
      this.title = '审核'
      this.fileName = row.alterAfterName
      if (!row.alterAfterUrl) return this.$message.warning('文件未上传')
      this.addInfo = this.HaveJson(row)
      let alterBeforeCode = this.addInfo.alterBeforeCode
      this.getCurrentFile(alterBeforeCode)
      this.addDialogVisible = true
      checkManageDocumentAlterPdf({ id: row.id }).then(res => {
        //
        const blob = new Blob([res]);
        const file = new File([blob], row.name, { type: 'application/pdf' })
        this.$refs.UpPdfStamp.lookFile(file)
        this.currentInfo = row
      }).catch(err => {
        console.log(err)
      })
    },
    // å®¡æ ¸ä¿å­˜
    async uploadPDF(pdfBlob) {
      const formData = new FormData();
      formData.append('file', pdfBlob, this.fileName + '.pdf'); // æ–‡ä»¶å­—段
      formData.append('id', this.currentInfo.id); // æ–‡ä»¶åå­—段
      formData.append('state', this.type); // æ–‡ä»¶åå­—段
      let res = await checkManageDocumentAlter(formData)
      this.checkLoading = false
      this.noCheckLoading = false
      if (res.code == 200) {
        this.$message({ message: '操作成功', type: 'success' });
        this.addDialogVisible = false;
        this.refreshTable()
        return true
      } else {
        this.$message({ message: '操作失败', type: 'error' });
        return false
      }
    },
    // æäº¤å®¡æ ¸
    handleCheckSub(type) {
      this.type = type
      if (type == '通过') {
        this.checkLoading = true
      } else {
        this.noCheckLoading = true
      }
      this.addLoading = true
      this.$refs['UpPdfStamp'].generatePDF()
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delManageDocumentAlter({ 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 - 80px);
  padding: 20px;
}
.btns {
  position: absolute;
  right: 20px;
  top: 5px;
}
h4.title {
  position: relative;
  height: 30px;
  line-height: 30px;
  box-sizing: border-box;
  padding-left: 16px;
  margin-left: 10px;
  margin-bottom: 10px;
}
h4.title::after {
  content: '';
  width: 4px;
  height: 20px;
  background: #3A7BFA;
  position: absolute;
  top: 5px;
  left: 0;
}
</style>
src/views/CNAS/systemManagement/documentControl/components/FileList.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,438 @@
<template>
  <!-- æ–‡ä»¶æ¸…单 -->
  <div class="file-list" style="height: 100%;">
    <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.name"
            @keyup.enter.native="refreshTable()"></el-input></div>
      </div>
      <div class="search_thing">
        <div class="search_label">文件状态:</div>
        <div class="search_input">
          <el-select v-model="queryParams.state" size="small" @change="refreshTable()">
            <el-option :label="item.label" :value="item.value" v-for="(item, index) in fileState"
              :key="index"></el-option>
          </el-select>
        </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="btns" style="padding-left: 30px;">
        <el-upload :action="action" :multiple="false" accept='.xls,.xlsx' :headers="uploadHeader"
          :on-change="beforeUpload" :on-error="onError" ref='upload' :on-success="handleSuccessUp"
          :show-file-list="false">
          <el-button size="small" type="primary" :loading="upLoading">导入</el-button></el-upload>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
        :height="'calc(100vh - 290px)'" @pagination="pagination"></lims-table>
    </div>
    <el-dialog title="上传" :visible.sync="addDialogVisible" width="1000px" top="3vh">
      <UpPdfStamp ref="UpPdfStamp" v-if="addDialogVisible" @uploadPDF="uploadPDF" :isUpFile="true"
        @uploadPDFErr="uploadPDFErr"></UpPdfStamp>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialogVisible = false">取 æ¶ˆ</el-button>
        <el-button type="primary" @click="handleAdd" v-loading="addLoading">ç¡® å®š</el-button>
      </span>
    </el-dialog>
    <el-dialog title="查看附件" :visible.sync="lookDialogVisible" width="800px" top="5vh" fullscreen>
      <filePreview v-if="lookDialogVisible" :fileUrl="javaApi + '/word/' + currentInfo.url" :currentFile="{}"
        style="max-height: 90vh;overflow-y: auto;" />
    </el-dialog>
    <!-- æ–°å¢ž/编辑 -->
    <el-dialog :title="title" :visible.sync="addDia" width="500px">
      <el-form :model="currentInfo" ref="currentInfoForm" :rules="rules" label-position="right" label-width="120px">
        <el-form-item label="文件编号" prop="documentCode">
          <el-input size="small" placeholder="请输入" clearable v-model="currentInfo.documentCode"></el-input>
        </el-form-item>
        <el-form-item label="类别" prop="type">
          <el-select v-model="currentInfo.type" size="small" clearable placeholder="请选择" style="width: 100%">
            <el-option v-for="item in fileType" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input size="small" placeholder="请输入" clearable v-model="currentInfo.name">
          </el-input>
        </el-form-item>
        <el-form-item label="文件版本" prop="version">
          <el-input size="small" placeholder="请输入" clearable v-model="currentInfo.version">
          </el-input>
        </el-form-item>
        <el-form-item label="作者" prop="writer">
          <el-input size="small" placeholder="请输入" clearable v-model="currentInfo.writer">
          </el-input>
        </el-form-item>
        <el-form-item label="生效日期" prop="effectiveDate">
          <el-date-picker v-model="currentInfo.effectiveDate" format="yyyy-MM-dd" value-format="yyyy-MM-dd" type="date"
            size="small" placeholder="选择日期">
          </el-date-picker>
        </el-form-item>
        <el-form-item label="文件状态" prop="state">
          <el-select v-model="currentInfo.state" size="small" clearable placeholder="请选择" style="width: 100%">
            <el-option v-for="item in fileState" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDia = false">取 æ¶ˆ</el-button>
        <el-button :loading="uploading" type="primary" @click="submitProduct('currentInfoForm')">ç¡® è®¤</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import UpPdfStamp from '@/components/UpPdfStamp/index.vue'
import filePreview from '@/components/Preview/filePreview.vue'
import limsTable from "@/components/Table/lims-table.vue";
import {
  uploadFileManageDocumentList,
  pageManageDocumentList,
  delManageDocumentList,
  doManageDocumentList,
} from '@/api/cnas/systemManagement/documentControl.js'
export default {
  components: {
    UpPdfStamp,
    filePreview,
    limsTable,
  },
  data() {
    return {
      addDialogVisible: false,
      lookDialogVisible: false,
      addPower: false,
      upLoading: false,
      addLoading: false,
      currentInfo: {},
      fileType: [],
      fileState: [],
      title: '新增',
      queryParams: {},
      tableData: [],
      column: [
        { label: "文件编号", prop: "documentCode" },
        {
          label: "类别", prop: "type", width: "120px", dataType: "tag",
          formatData: (params) => {
            return this.fileType.find((m) => m.value == params).label;
          },
          formatType: (params) => {
            return this.fileType.find((m) => m.value == params).type;
          },
        },
        {
          label: "名称",
          prop: "name",
        },
        { label: "文件版本", prop: "version" },
        { label: "作者", prop: "writer" },
        { label: "生效日期", prop: "effectiveDate" },
        {
          label: "文件状态", prop: "state", dataType: "tag",
          formatData: (params) => {
            return this.fileState.find((m) => m.value == params).label;
          },
          formatType: (params) => {
            return this.fileState.find((m) => m.value == params).type;
          },
        },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.openAdd("编辑", row);
              },
            },
            {
              name: "上传",
              type: "text",
              clickFun: (row) => {
                this.handleUp(row);
              },
            },
            {
              name: "下载",
              type: "text",
              clickFun: (row) => {
                this.handleDown(row);
              },
            },
            {
              name: "查看附件",
              type: "text",
              clickFun: (row) => {
                this.handleLook(row);
              },
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
      addDia: false,
      rules: {
        documentCode: [{ required: true, message: "请输入文件编号", trigger: "blur" }],
      },
      uploading: false,
    }
  },
  // ç”¨äºŽä¸Šä¼ æ–‡ä»¶çš„信息
  computed: {
    action() {
      return this.javaApi + '/manageDocumentList/exportManageDocumentList'
    }
  },
  mounted() {
    this.getList()
    this.selectEnumByCategory()
  },
  methods: {
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageManageDocumentList({ ...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();
    },
    refreshTable() {
      this.page.current = 1;
      this.getList();
    },
    refresh() {
      this.queryParams = {};
      this.page.current = 1;
      this.getList();
    },
    openAdd(title, row) {
      this.title = title;
      if (row) {
        this.currentInfo = row;
      } else {
        this.currentInfo = {};
      }
      this.addDia = true;
    },
    // ä¸‹è½½æ–‡ä»¶
    handleDown(row) {
      if (!row.url) return this.$message.warning('文件未上传')
      let url = this.javaApi + '/word/' + row.url
      this.$download.saveAs(url, row.url);
    },
    // æŸ¥çœ‹æ–‡ä»¶
    handleLook(row) {
      if (!row.url) return this.$message.warning('文件未上传')
      this.currentInfo = row
      this.lookDialogVisible = true
    },
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let up = false
      let upFile = false
      let add = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'doManageDocumentList') {
          up = true
        }
        if (power[i].menuMethod == 'exportManageDocumentList') {
          add = true
        }
        if (power[i].menuMethod == 'uploadFileManageDocumentList') {
          upFile = true
        }
      }
      if (!upFile) {
        this.componentData.do.splice(1, 1)
      }
      if (!up) {
        this.componentData.do.splice(0, 1)
      }
      this.addPower = add
    },
    // ä¸Šä¼ æ–‡ä»¶
    handleUp(row) {
      this.currentInfo = row
      this.addDialogVisible = true;
    },
    // æäº¤ä¸Šä¼ 
    handleAdd() {
      this.addLoading = true
      this.$refs['UpPdfStamp'].generatePDF()
    },
    uploadPDFErr() {
      this.addLoading = false
    },
    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()
      }else {
        this.$message.error(response.msg);
      }
    },
    selectEnumByCategory() {
      // æ–‡ä»¶ç±»åˆ«
      this.getDicts("document_type").then((response) => {
        this.fileType = this.dictToValue(response.data);
      });
      // æ–‡ä»¶çŠ¶æ€
      this.getDicts("document_state").then((response) => {
        this.fileState = this.dictToValue(response.data);
      });
    },
    async uploadPDF(pdfBlob, fileName) {
      const formData = new FormData();
      formData.append('file', pdfBlob, fileName); // æ–‡ä»¶å­—段
      formData.append('id', this.currentInfo.id); // æ–‡ä»¶åå­—段
      try {
        let res = await uploadFileManageDocumentList(formData)
        this.addLoading = false
        if (res.code == 200) {
          this.$message({ message: '上传成功', type: 'success' });
          this.addDialogVisible = false;
          this.refreshTable()
          return true
        } else {
          this.$message({ message: '上传失败', type: 'error' });
          return false
        }
      } catch (e) {
        this.addLoading = false
      }
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delManageDocumentList({ id: row.id }).then((res) => {
            if (res.code == 201) return;
            this.$message.success("删除成功");
            this.refresh();
          });
        })
        .catch(() => { });
    },
    submitProduct(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.uploading = true;
          doManageDocumentList(this.currentInfo)
            .then((res) => {
              this.uploading = false;
              if (res.code != 200) {
                return;
              }
              this.$message.success("提交成功");
              this.refresh();
              this.addDia = false;
            })
            .catch((err) => {
              this.uploading = false;
            });
        } else {
          return false;
        }
      });
    },
  }
}
</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 - 80px);
  padding: 20px;
}
.btns {
  position: absolute;
  right: 20px;
  top: 5px;
}
</style>
src/views/CNAS/systemManagement/documentControl/components/FileObsoletionRequest.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,492 @@
<template>
  <!-- æ–‡ä»¶ä½œåºŸç”³è¯· -->
  <div class="file-obsoletion-request" style="height: 100%;">
    <div class="search">
      <div class="search_thing">
        <div class="search_label">文件编号:</div>
        <div class="search_input"><el-input v-model="queryParams.documentCode" 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="btns" style="padding-left: 30px;">
        <el-button size="small" type="primary" @click="addDialogVisible = true, addInfo = {}">文件作废申请</el-button>
        <el-button :loading="outLoading" size="small" type="primary" @click="handleOut">导出</el-button>
      </div>
    </div>
    <div class="table">
      <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
        :height="'calc(100vh - 290px)'" @pagination="pagination"></lims-table>
    </div>
    <el-dialog :visible.sync="addDialogVisible" title="文件作废申请" top="10vh" width="800px">
      <el-row>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label"><span style="color:red;margin-right: 4px;">*</span>申请编号:</div>
            <div class="search_input">
              <el-select v-model="addInfo.documentCode" allow-create clearable filterable size="small"
                style="width: 100%;" @change="changeFileList">
                <el-option v-for="item in fileList" :key="item.documentCode" :label="item.documentCode"
                  :value="item.documentCode">
                </el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">审批人:</div>
            <div class="search_input">
              <el-select v-model="addInfo.checkUser" filterable 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="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件名称:</div>
            <div class="search_input"><el-input v-model="addInfo.name" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件版本:</div>
            <div class="search_input"><el-input v-model="addInfo.version" clearable placeholder="请输入"
                size="small"></el-input></div>
          </div>
        </el-col>
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">文件状态:</div>
            <div class="search_input">
              <el-select v-model="addInfo.state" size="small" style="width: 100%;">
                <el-option v-for="(item, index) in fileState" :key="index" :label="item.label"
                  :value="item.value"></el-option>
              </el-select>
            </div>
          </div>
        </el-col>
        <!-- <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">作废方式:</div>
            <div class="search_input">
              <el-select v-model="addInfo.method" size="small" style="width: 100%;">
                <el-option label="作废" value="作废"></el-option>
                <el-option label="无效" value="无效"></el-option>
              </el-select>
            </div>
          </div>
        </el-col> -->
        <el-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">期望作废时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.expectCancelDate" 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-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">实际作废时间:</div>
            <div class="search_input">
              <el-date-picker v-model="addInfo.actuallyCancelDate" 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-col :span="12" style="margin-bottom: 16px;">
          <div class="search_thing">
            <div class="search_label">作废说明:</div>
            <div class="search_input"><el-input v-model="addInfo.cancelNote" :rows="2" clearable placeholder="请输入"
                size="small" type="textarea"></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>
  </div>
</template>
<script>
import limsTable from "@/components/Table/lims-table.vue";
import {
  selectUserCondition,
} from "@/api/system/user.js";
import {
  addManageDocumentCancel,
  pageManageDocumentList,
  doManageDocumentCancel,
  checkManageDocumentCancel,
  exportManageDocumentCancel,
  delManageDocumentCancel,
  pageManageDocumentCancel,
} from '@/api/cnas/systemManagement/documentControl.js'
import { mapGetters } from "vuex";
export default {
  components: {
    limsTable
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      addPower: false,
      outPower: false,
      addInfo: {},
      addLoading: false,
      addDialogVisible: false,
      personList: [],
      fileList: [],
      outLoading: false,
      fileState: [],
      queryParams: {},
      tableData: [],
      column: [
        { label: "文件编号", prop: "documentCode" },
        { label: "申请人", prop: "createUserName", width: "120px" },
        {
          label: "作废说明",
          prop: "cancelNote",
        },
        { label: "期望作废时间", prop: "expectCancelDate" },
        { label: "实际作废日期", prop: "actuallyCancelDate" },
        {
          label: "作废状态", prop: "state", dataType: "tag",
          formatData: (params) => {
            return params;
          },
          formatType: (params) => {
            if (params == '通过') {
              return 'success'
            } else {
              return 'danger'
            }
          }
        },
        {
          dataType: "action",
          fixed: "right",
          label: "操作",
          operation: [
            {
              name: "编辑",
              type: "text",
              clickFun: (row) => {
                this.handleUpdate(row);
              },
              disabled: (row, index) => {
                return row.state == '通过'
              }
            },
            {
              name: "删除",
              type: "text",
              clickFun: (row) => {
                this.handleDelete(row);
              },
              disabled: (row, index) => {
                return row.state == '通过'
              }
            },
            {
              name: "审核",
              type: "text",
              clickFun: (row) => {
                this.handleCheck(row);
              },
              disabled: (row, index) => {
                return row.checkUser != this.userId || row.state == '通过'
              }
            },
          ],
        },
      ],
      page: {
        total: 0,
        size: 10,
        current: 0,
      },
      tableLoading: false,
    }
  },
  mounted() {
    this.getList()
    this.getAuthorizedPerson()
    this.getFileList()
    this.selectEnumByCategory()
  },
  methods: {
    getPower() {
      let power = JSON.parse(sessionStorage.getItem('power'))
      let out = false
      let del = false
      let add = false
      // let check = false
      for (var i = 0; i < power.length; i++) {
        if (power[i].menuMethod == 'exportManageDocumentCancel') {
          out = true
        }
        if (power[i].menuMethod == 'addManageDocumentCancel') {
          add = true
        }
        if (power[i].menuMethod == 'delManageDocumentCancel') {
          del = true
        }
        // if (power[i].menuMethod == 'checkManageDocumentControlled') {
        //   check = true
        // }
      }
      // if (!check) {
      //   this.componentData.do.splice(2, 1)
      // }
      if (!del) {
        this.componentData.do.splice(1, 1)
      }
      if (!add) {
        this.componentData.do.splice(0, 1)
      }
      this.addPower = add
      this.outPower = out
    },
    getList() {
      this.tableLoading = true;
      let param = { ...this.queryParams, ...this.page };
      delete param.total;
      pageManageDocumentCancel({ ...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();
    },
    selectEnumByCategory() {
      // æ–‡ä»¶çŠ¶æ€
      this.getDicts("document_state").then((response) => {
        this.fileState = this.dictToValue(response.data);
      });
    },
    // èŽ·å–äººå‘˜åˆ—è¡¨
    getAuthorizedPerson() {
      selectUserCondition().then(res => {
        let data = []
        res.data.forEach(a => {
          data.push({
            label: a.name,
            value: a.id
          })
        })
        this.personList = data
      })
    },
    // èŽ·å–æ–‡ä»¶åˆ—è¡¨
    getFileList() {
      pageManageDocumentList({
        current: -1,
        size: -1
      }).then(res => {
        this.fileList = res.data.records
      }).catch(err => { })
    },
    // æäº¤
    handleAdd() {
      if (!this.addInfo.documentCode) {
        this.$message.error('请输入申请编号')
        return false
      }
      this.addInfo.method = '作废'
      this.addLoading = true
      if (!this.addInfo.id) {
        // æ–°å¢ž
        addManageDocumentCancel(this.addInfo).then(res => {
          this.addLoading = false
          this.refreshTable()
          this.$message({
            type: 'success',
            message: '提交成功'
          })
          this.addDialogVisible = false
        }).catch(err => { })
      } else {
        // ç¼–辑
        doManageDocumentCancel({
          id: this.addInfo.id,
          method: '作废',
          documentCode: this.addInfo.documentCode,
          checkUser: this.addInfo.checkUser,
          name: this.addInfo.name,
          version: this.addInfo.version,
          documentState: this.addInfo.documentState,
          expectCancelDate: this.addInfo.expectCancelDate,
          actuallyCancelDate: this.addInfo.actuallyCancelDate,
          cancelNote: this.addInfo.cancelNote,
        }).then(res => {
          this.addLoading = false
          this.refreshTable()
          this.$message({
            type: 'success',
            message: '提交成功'
          })
          this.addDialogVisible = false
        }).catch(err => { })
      }
    },
    // é€‰ä¸­æ–‡ä»¶
    changeFileList(e) {
      if (e) {
        let obj = this.fileList.find(a => a.documentCode == e)
        if (obj) {
          this.addInfo.name = obj.name
          this.addInfo.version = obj.version
          this.addInfo.documentState = obj.state
        }
      }
    },
    handleUpdate(row) {
      this.addInfo = this.HaveJson(row)
      this.addDialogVisible = true
    },
    // å®¡æ ¸
    handleCheck(row) {
      this.$confirm('是否审核通过?', '提示', {
        confirmButtonText: '通过',
        cancelButtonText: '不通过',
        type: 'warning',
        closeOnClickModal: false, // ç¦æ­¢ç‚¹å‡»é®ç½©å±‚关闭
        distinguishCancelAndClose: true,
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            // ç‚¹å‡»â€œç¡®å®šâ€æŒ‰é’®ï¼Œå…è®¸å…³é—­
            checkManageDocumentCancel({ id: row.id, state: '通过' }).then(res => {
              this.refreshTable()
              done();
              this.$message({
                type: 'success',
                message: '提交成功'
              })
            })
              .catch(err => {
              })
          } else if (action === 'cancel') {
            // ç‚¹å‡»â€œå–消”按钮,不允许关闭
            checkManageDocumentCancel({ id: row.id, state: '不通过' }).then(res => {
              this.refreshTable()
              done();
              this.$message({
                type: 'success',
                message: '提交成功'
              })
            })
              .catch(err => {
              })
          } else if (action === 'close') {
            // ç‚¹å‡»â€œÃ—”按钮,不允许关闭
            done();
            console.log("×按钮点击事件,不关闭弹框");
          }
        }
      })
    },
    // å¯¼å‡º
    handleOut() {
      this.outLoading = true
      exportManageDocumentCancel(this.queryParams).then(res => {
        this.outLoading = false
        const blob = new Blob([res], { type: 'application/octet-stream' });
        this.$download.saveAs(blob, '文件作废表.xlsx')
      })
    },
    handleDelete(row) {
      this.$confirm("是否删除该条数据?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          delManageDocumentCancel({ 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 - 80px);
  padding: 20px;
}
.btns {
  position: absolute;
  right: 20px;
  top: 5px;
}
</style>
src/views/CNAS/systemManagement/documentControl/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <div class="file-handling">
    <el-tabs type="border-card" v-model="activeName" style="height: 100%;">
      <el-tab-pane :label="item.name" :name="item.component" v-for="(item, index) in tabList" :key="index"
        style="height: 100%;">
        <component :is="item.component" :key="item.component"></component>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script>
import FileList from './components/FileList.vue'
import ControlledFileApplication from './components/ControlledFileApplication.vue'
import DistributionCollectionRecord from './components/DistributionCollectionRecord.vue'
import FileChangeRequest from './components/FileChangeRequest.vue'
import FileObsoletionRequest from './components/FileObsoletionRequest.vue'
export default {
  components: {
    FileList,
    ControlledFileApplication,
    DistributionCollectionRecord,
    FileChangeRequest,
    FileObsoletionRequest
  },
  data() {
    return {
      tabList: [
        {
          name: '文件清单',
          component: 'FileList'
        },
        {
          name: '文件受控申请',
          component: 'ControlledFileApplication'
        },
        {
          name: '发放回收记录',
          component: 'DistributionCollectionRecord'
        },
        {
          name: '文件变更申请',
          component: 'FileChangeRequest'
        },
        {
          name: '文件作废申请',
          component: 'FileObsoletionRequest'
        },
      ],
      activeName: 'FileList'
    };
  },
}
</script>
<style scoped>
.file-handling {
  margin-top: 10px;
  height: calc(100% - 20px);
}
>>>.el-tabs__content {
  height: 100%;
  padding: 0;
  padding-top: 10px;
}
</style>
src/views/standard/model/index.vue
@@ -4,77 +4,29 @@
      <div class="search_thing">
        <div class="search_label">模板名称:</div>
        <div class="search_input">
          <el-input
            v-model="queryParams.name"
            clearable
            placeholder="请输入"
            size="small"
            @keyup.enter.native="refreshTable()"
          ></el-input>
          <el-input v-model="queryParams.name" 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
        >
        <el-button size="small" type="primary" @click="refreshTable()">查 è¯¢</el-button>
      </div>
      <div class="btn">
        <el-button
          v-if="checkPermi(['standard:model:add'])"
          size="small"
          type="primary"
          @click="openAdd"
          >新增</el-button
        >
        <!-- <el-button
          v-if="checkPermi(['standard:model:copy'])"
          size="small"
          @click="copyTemplate"
          >复制模版</el-button
        > -->
        <el-button v-if="checkPermi(['standard:model:add'])" size="small" type="primary" @click="openAdd">新增</el-button>
      </div>
    </div>
    <lims-table
      :tableData="tableData"
      :column="column"
      :page="page"
      :tableLoading="tableLoading"
      :height="'calc(100vh - 240px)'"
      style="padding: 20px; padding-top: 0"
      @pagination="pagination"
    ></lims-table>
    <el-dialog
      :before-close="isClose"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :visible.sync="isShow"
      title="模板编制"
      width="85%"
    >
    <lims-table :tableData="tableData" :column="column" :page="page" :tableLoading="tableLoading"
      :height="'calc(100vh - 240px)'" style="padding: 20px; padding-top: 0" @pagination="pagination"></lims-table>
    <el-dialog :before-close="isClose" :close-on-click-modal="false" :close-on-press-escape="false"
      :visible.sync="isShow" title="模板编制" width="85%">
      <div v-if="isShow" style="width: 100%; height: 82vh; overflow: auto">
        <Excel
          v-loading="loading"
          :data="row.thing"
          :execlTitle="row.name"
        ></Excel>
        <Excel v-loading="loading" :data="row.thing" :execlTitle="row.name"></Excel>
      </div>
    </el-dialog>
    <el-dialog
      :before-close="closeCopyTem"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :visible.sync="isShowCopyTem"
      :title="title"
      width="35%"
    >
      <el-form
        ref="copyForm"
        :model="copyForm"
        :rules="copyFormRules"
        label-position="right"
        label-width="80px"
      >
    <el-dialog :before-close="closeCopyTem" :close-on-click-modal="false" :close-on-press-escape="false"
      :visible.sync="isShowCopyTem" :title="title" width="35%">
      <el-form ref="copyForm" :model="copyForm" :rules="copyFormRules" label-position="right" label-width="80px">
        <el-form-item label="模版编号" prop="number">
          <el-input v-model="copyForm.number" clearable size="small"></el-input>
        </el-form-item>
@@ -87,12 +39,7 @@
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeCopyTem">取 æ¶ˆ</el-button>
        <el-button
          :loading="submitCopyInfoLoading"
          type="primary"
          @click="submitCopyInfo"
          >ç¡® å®š</el-button
        >
        <el-button :loading="submitCopyInfoLoading" type="primary" @click="submitCopyInfo">ç¡® å®š</el-button>
      </span>
    </el-dialog>
  </div>
@@ -103,7 +50,6 @@
import Excel from "@/components/Excel/luckysheet.vue";
import {
  selectStandardTemplatePageList,
  copyStandardTemplate,
  addStandardTemplate,
  upStandardTemplate,
  delStandardTemplate,
@@ -177,16 +123,6 @@
                return this.checkPermi(["standard:model:del"]);
              },
            },
            // {
            //   name: "复制模板",
            //   type: "text",
            //   clickFun: (row) => {
            //     this.copyTemplate(row);
            //   },
            //   showHide: (row) => {
            //     return this.checkPermi(["standard:model:copy"]);
            //   },
            // },
            {
              name: "模板编制",
              type: "text",
@@ -253,12 +189,6 @@
      this.copyForm = {};
      this.isShowCopyTem = true;
    },
    // å¤åˆ¶æ¨¡ç‰ˆ
    copyTemplate(row) {
      this.title = "复制模版";
      this.isShowCopyTem = true;
      this.copyForm.id = row.id;
    },
    // æ–°å¢ž/编辑/复制模板
    submitCopyInfo() {
      this.$refs["copyForm"].validate((valid) => {
@@ -294,20 +224,6 @@
                  this.isShowCopyTem = false;
                  this.submitCopyInfoLoading = false;
                  this.$message.success("修改成功");
                  this.refreshTable("page");
                })
                .catch((err) => {
                  console.log("copyTemplate----", err);
                  this.submitCopyInfoLoading = false;
                });
              break;
            case "复制模版":
              copyStandardTemplate(params)
                .then((res) => {
                  if (res.code == 201) return;
                  this.isShowCopyTem = false;
                  this.submitCopyInfoLoading = false;
                  this.$message.success("复制成功");
                  this.refreshTable("page");
                })
                .catch((err) => {
@@ -456,6 +372,7 @@
.search_input {
  width: calc(100% - 110px);
}
.btn {
  position: absolute;
  right: 14px;