研发图纸文件管理系统-前端项目
longyvfengyun
2023-12-08 cf907e2df0a06f55540113b59f5b9d340f72104d
产品中心查看SOP信息
3个文件已修改
2个文件已添加
1068 ■■■■■ 已修改文件
package.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/tools/getFileTypeAndName.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/details.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/sopFile/list.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/sopFile/sopList.vue 974 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json
@@ -79,6 +79,7 @@
    "rules": {
      "no-debugger": "off",
      "no-unused-vars": "off",
      "no-mixed-spaces-and-tabs": "off",
      "vue/no-unused-components": "off"
    }
  },
src/assets/js/tools/getFileTypeAndName.js
New file
@@ -0,0 +1,16 @@
/**
 * 获取路径中文件的名称和后缀
 * @param path 路径名称
 * @return {{name: *, type: (string|string)}}
 */
function getFileTypeAndName(path) {
  let reg = /(.*\\+)*(.*)$/;
  let fileName = path.match(reg)[2];
  let arr = fileName.split(".");
  return {
    type: arr.length ? arr[arr.length - 1].toLowerCase() : "",
    name: fileName,
  };
}
export default getFileTypeAndName;
src/pages/resourceManage/product/details/details.vue
@@ -248,6 +248,7 @@
              @click="changeStatus"
              >锁定版本</a-button
            >
              <a-button type="primary" @click="viewSopFile">SOP查看</a-button>
          </template>
        </a-card>
      </a-layout-footer>
@@ -428,6 +429,17 @@
        <a-empty v-else />
      </div>
    </a-modal>
      <a-modal
          :visible="showSop"
          :footer="null"
          :width="1366"
          title="SOP查看"
          :destroyOnClose="true"
          @cancel="showSop = false">
          <div style="height: 600px">
              <sop-list :parentCode="parentCode"></sop-list>
          </div>
      </a-modal>
  </div>
</template>
@@ -443,6 +455,7 @@
import DownloadReason from "@/pages/components/downloadReason";
import DownloadLogs from "@/pages/components/downloadLogs";
import SopList from "@/pages/resourceManage/sopFile/sopList.vue";
import List from "./list";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import {
@@ -472,6 +485,7 @@
  mixins: [WSMixin],
  data() {
    return {
            showSop: false,
      fileTreeVisible: false,
      fileTree: [],
      userListAll: [],
@@ -725,6 +739,7 @@
    Pop,
    DownloadReason,
    DownloadLogs,
      SopList,
  },
  computed: {
    ...mapGetters("setting", ["affixed"]),
@@ -785,6 +800,9 @@
    },
  },
  methods: {
      viewSopFile() {
            this.showSop = true;
      },
    getRoleUser() {
      getRoleUser(1)
        .then((res) => {
src/pages/resourceManage/sopFile/list.vue
@@ -60,9 +60,8 @@
              <a-tag v-else class="tag-all" color="#f50"> 适用全部 </a-tag>
              <template v-if="canDownload">
                <a-divider type="vertical"></a-divider>
                <a :disabled="!record.status" @click="downloadFile(record)"
                  >下载</a
                >
                <a v-if="record.isCanPreview" :disabled="!record.status" @click="downloadFile(record)">预览</a>
                  <a v-else :disabled="!record.status" @click="downloadFile(record)">下载</a>
              </template>
              <a-divider type="vertical"></a-divider>
              <a-popover title="" trigger="hover">
@@ -221,6 +220,20 @@
        <a-empty v-else />
      </div>
    </a-modal>
      <!-- 日志 -->
      <a-modal
          :visible="pdfInfo.visible"
          :footer="null"
          :width="960"
          title="文件预览"
          :destroyOnClose="true"
          @cancel="pdfCancel">
          <div style="height:600px; overflow-y: auto">
              <iframe :src="pdfInfo.src"></iframe>
          </div>
      </a-modal>
  </div>
</template>
@@ -245,6 +258,9 @@
import offset from "@/assets/js/tools/offset";
import Pop from "./pop";
import DescRes from "./descRes";
import getFileTypeAndName from "@/assets/js/tools/getFileTypeAndName";
import VuePdf from "vue-pdf";
export default {
  components: {
@@ -252,10 +268,19 @@
    Pop,
    DescRes,
    EmailCard,
      VuePdf,
  },
  name: "list",
  data() {
    return {
        pdfInfo: {
                visible: false,
            src: "",
            loadedRatio: 0,
            page: 1,
            numPages: 0,
            rotate: 0,
        },
      rowFileName: '',
      logList: [],
      logVisible: false,
@@ -409,6 +434,15 @@
          customCell: this.customCell,
        },
        {
              title: "是否锁定",
              dataIndex: "status",
              dataType: "boolean",
              align: "center",
              searchAble: true,
              width: 100,
              scopedSlots: { customRender: "status" },
          },
        {
          title: "操作",
          dataIndex: "operation",
          align: "center",
@@ -556,6 +590,7 @@
      let name2 = fileName + fileVersion;
      if (name1.toLowerCase() != name2.toLowerCase()) {
                console.log(name1.toLowerCase()+"&&&&&&"+ name2.toLowerCase());
        this.$message.error("sop与说明文件可能不匹配");
        return false;
      }
@@ -806,6 +841,9 @@
          case "model":
            params[v] = conditions[v];
            break;
            case "status":
                params[v] = conditions[v]?1:0;
                        break;
          case "parentType":
          case "chileType":
            data[v] = conditions[v];
@@ -823,7 +861,11 @@
            list = data2.list;
            total = data2.total;
          }
          this.dataSource = list;
          this.dataSource = list.map(item=>{
              const fileInfo = getFileTypeAndName(item.fileUrl);
                        item.isCanPreview = fileInfo.type === "pdf";
                        return item;
          });
          this.total = total;
          this.getSopType1();
          if (-1 == this.update) {
@@ -835,7 +877,10 @@
        });
    },
    downloadFile(record) {
      // console.log(record);
            const fileInfo = getFileTypeAndName(record.fileUrl);
            if(fileInfo.type === 'pdf') {  // 预览
                window.open("http://localhost:8092/cad/"+record.fileUrl);
            }else {     // 下载
      let loading = this.$layer.loading();
      let link = document.createElement("a");
      link.style.display = "none";
@@ -847,6 +892,7 @@
      link.click();
      this.$layer.close(loading);
      document.body.removeChild(link);
            }
    },
    reasonCancel() {
      this.reasonVisible = false;
@@ -887,6 +933,9 @@
    logCancel() {
      this.logVisible = false;
    },
      pdfCancel() {
            this.pdfInfo.visible = false;
      },
    goHistory(record) {
      let { fileName } = record;
      this.$router.push({
src/pages/resourceManage/sopFile/sopList.vue
New file
@@ -0,0 +1,974 @@
<template>
    <div class="main">
        <div class="inner" ref="wraper">
            <a-spin class="" :spinning="spinning" tip="拼命加载中...">
                <a-card>
                    <advance-table
                        ref="table"
                        class="doc-center-table"
                        :data-source="dataSource"
                        :columns="columns"
                        title=" "
                        :row-key="(record, index) => index"
                        @search="onSearch"
                        @refresh="onRefresh"
                        @reset="onReset"
                        :format-conditions="true"
                        :scroll="{ y }"
                        :pagination="{
              current: pageCurr,
              pageSize: pageSize,
              total: total,
              showSizeChanger: true,
              showLessItems: true,
              showQuickJumper: true,
              pageSizeOptions: ['10', '20', '50', '100'],
              showTotal: (total, range) =>
                `第 ${range[0]}-${range[1]} 条,总计 ${total} 条`,
              onChange: onPageChange,
              onShowSizeChange: onSizeChange,
            }">
                        <template slot="action" slot-scope="{ record }">
                            <a-popover v-if="!record.currentFlag" title="" trigger="hover">
                                <div class="" slot="content" style="width: 450px">
                                    <a-table
                                        size="small"
                                        :scroll="{ y: 300 }"
                                        bordered
                                        :columns="prodsColumns"
                                        :data-source="record.sopProductList"
                                        :pagination="false"
                                        :expandRowByClick="true"
                                        :row-key="(record1, index) => index"
                                    >
                                        <!-- <template slot="action" slot-scope="record1">
                                            123{{ record1 }}
                                        </template> -->
                                    </a-table>
                                </div>
                                <a>适用产品</a>
                            </a-popover>
                            <a-tag v-else class="tag-all" color="#f50"> 适用全部 </a-tag>
                            <template v-if="canDownload">
                                <a-divider type="vertical"></a-divider>
                                <a v-if="record.isCanPreview" :disabled="!record.status" @click="downloadFile(record)">预览</a>
                                <a v-else :disabled="!record.status" @click="downloadFile(record)">下载</a>
                            </template>
                            <a-divider type="vertical"></a-divider>
                            <a-popover title="" trigger="hover">
                                <a-space class="btn-grp" direction="vertical" slot="content">
                                    <a-button
                                        v-if="canUpload"
                                        type="primary"
                                        @click="updateDesc(record)"
                                    >更新说明</a-button
                                    >
                                    <a-button
                                        v-if="canUpload"
                                        type="primary"
                                        @click="lock(record)"
                                    >{{ record.status == 0 ? "解锁" : "锁定" }}</a-button
                                    >
                                    <a-button
                                        v-if="canUpload"
                                        type="primary"
                                        @click="handleEmailShow(record)"
                                    >邮件通知</a-button
                                    >
                                    <a-button type="primary" @click="viewLog(record)"
                                    >锁定日志</a-button
                                    >
                                    <a-button type="primary" @click="goHistory(record)"
                                    >历史版本</a-button
                                    >
                                </a-space>
                                <a>更多</a>
                            </a-popover>
                        </template>
                    </advance-table>
                </a-card>
            </a-spin>
        </div>
        <pop
            :visible.sync="popVisible"
            :x="popPosition.x"
            :y="popPosition.y"
            :position="popPosition.dir"
            :info="popInfo"
        ></pop>
        <a-modal
            :visible="uploadShow"
            :footer="null"
            :width="800"
            title="上传软件"
            :destroyOnClose="true"
            :maskClosable="false"
            @cancel="uploadCancel"
        >
            <div class="">
                <template v-if="!onlyXls">
                    <a-row type="flex" class="row">
                        <a-col flex="6em" class="label">sop包</a-col>
                        <a-col :flex="1">
                            <a-upload
                                class="upload"
                                :before-upload="beforeUpload"
                                @change="uploadChange"
                                accept=".zip,.rar"
                            >
                                <a-button type="primary">选压缩包</a-button>
                            </a-upload>
                        </a-col>
                    </a-row>
                </template>
                <a-row type="flex" class="row">
                    <a-col flex="6em" class="label">SOP说明</a-col>
                    <a-col :flex="1">
                        <a-upload
                            class="upload"
                            :before-upload="beforeUpload"
                            @change="uploadChange1"
                            accept=".xls,.xlsx"
                        >
                            <a-button type="primary">说明文件</a-button>
                        </a-upload>
                    </a-col>
                </a-row>
                <div class="sub-title">说明文件解析结果</div>
                <div class="res-content">
                    <desc-res :info="resObj"></desc-res>
                </div>
                <div class="modal-footer">
                    <a-button type="danger" @click="uploadCancel"> 取消 </a-button>
                    <a-button v-if="!onlyXls" type="primary" @click="uploadSop">
                        提交
                    </a-button>
                    <a-button v-else type="primary" @click="applyModel"> 提交 </a-button>
                </div>
            </div>
        </a-modal>
        <a-modal
            :visible="emailShow"
            :footer="null"
            :width="760"
            title="邮件发送"
            :destroyOnClose="true"
            :maskClosable="false"
            @cancel="emailCancel"
        >
            <email-card
                :visible.sync="emailShow"
                :users="userList"
                :title="emailInfo.title"
                :content="emailInfo.content"
                :type="2"
                v-if="emailShow"
            ></email-card>
        </a-modal>
        <!-- 操作原因 -->
        <a-modal
            :visible="reasonVisible"
            :width="460"
            title="操作原因"
            :destroyOnClose="true"
            :maskClosable="false"
            @cancel="reasonCancel"
            @ok="reasonOk"
        >
            <a-form-model-item ref="name" label="操作原因">
                <a-input
                    type="textarea"
                    v-model="reason"
                    placeHolder="请输入操作原因"
                />
            </a-form-model-item>
        </a-modal>
        <!-- 日志 -->
        <a-modal
            :visible="logVisible"
            :footer="null"
            :width="800"
            title="操作日志"
            :destroyOnClose="true"
            @cancel="logCancel"
        >
            <div class="log-content">
                <a-timeline v-if="logList.length">
                    <a-timeline-item
                        v-for="(item, idx) in logList"
                        :key="'log_' + idx"
                        :color="item.status == 0 ? 'red' : 'green'"
                    >
                        <div>
                            <span class="user">{{ item.userName }}</span> 在
                            <span class="time">{{ item.createTime }}</span>
                            {{ item.status == 0 ? "锁定" : "解锁" }}了版本
                            <span class="version">{{ item.fileVersion }}</span>
                        </div>
                        <div>操作原因: {{ item.reason ? item.reason : "无" }}</div>
                    </a-timeline-item>
                </a-timeline>
                <a-empty v-else />
            </div>
        </a-modal>
        <!-- 日志 -->
        <a-modal
            :visible="pdfInfo.visible"
            :footer="null"
            :width="960"
            title="文件预览"
            :destroyOnClose="true"
            @cancel="pdfCancel">
            <div style="height:600px; overflow-y: auto">
                <iframe :src="pdfInfo.src"></iframe>
            </div>
        </a-modal>
    </div>
</template>
<script>
import AdvanceTable from "@/components/table/advance/AdvanceTable";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import checkPermit from "@/assets/js/tools/checkPermit";
import PERMITS from "@/assets/js/const/const_permits";
import { mapGetters } from "vuex";
import EmailCard from "../../components/emailCard";
import { getUserList } from "../../permission/apis";
import {
    fileParse,
    addSop,
    getList,
    getSopType1,
    getSopType2,
    updateSop,
    sopLock,
    getLogList,
} from "./apis";
import offset from "@/assets/js/tools/offset";
import Pop from "./pop";
import DescRes from "./descRes";
import getFileTypeAndName from "@/assets/js/tools/getFileTypeAndName";
import VuePdf from "vue-pdf";
export default {
    props: {
        parentCode: {
            type: [String, Number],
            default: 0
        }
    },
    components: {
        AdvanceTable,
        Pop,
        DescRes,
        EmailCard,
        VuePdf,
    },
    name: "list",
    data() {
        return {
            pdfInfo: {
                visible: false,
                src: "",
                loadedRatio: 0,
                page: 1,
                numPages: 0,
                rotate: 0,
            },
            rowFileName: '',
            logList: [],
            logVisible: false,
            currentObj: null,
            reasonVisible: false,
            reason: "",
            emailShow: false,
            emailInfo: {
                title: "",
                content: "",
            },
            userList: [],
            onlyXls: false,
            uploadShow: false,
            webUrl: getWebUrl(),
            prodsColumns: [
                {
                    title: "物料编码",
                    dataIndex: "code",
                    align: "center",
                },
                {
                    title: "型/板号",
                    dataIndex: "model",
                    align: "center",
                    width: 180,
                },
                // {
                //   title: "操作",
                //   dataIndex: "operation",
                //   align: "center",
                //   width: 180,
                //   scopedSlots: { customRender: "action" },
                // },
            ],
            file: null,
            file1: null,
            resObj: {},
            popInfo: {},
            popVisible: false,
            popPosition: {
                x: 500,
                y: 100,
                dir: "bottom",
            },
            spinning: false,
            loading: false,
            pageCurr: 1,
            pageSize: 20,
            total: 0,
            y: 400,
            update: -1,
            conditions: {},
            columns: [
                {
                    title: "发布时间",
                    dataIndex: "releaseDate",
                    align: "center",
                    width: 160,
                    customCell: this.customCell,
                },
                {
                    title: "负责人",
                    dataIndex: "editor",
                    align: "center",
                    width: 90,
                    customCell: this.customCell,
                },
                {
                    title: "审核人",
                    dataIndex: "auditor",
                    align: "center",
                    width: 90,
                    customCell: this.customCell,
                },
                {
                    title: "发布说明",
                    dataIndex: "releaseNotes",
                    align: "center",
                    width: 260,
                    customCell: this.customCell,
                },
                {
                    title: "操作",
                    dataIndex: "operation",
                    align: "center",
                    width: 200,
                    fixed: "right",
                    scopedSlots: { customRender: "action" },
                    noSearch: true,
                },
            ],
            dataSource: [],
        };
    },
    computed: {
        ...mapGetters("account", ["permits"]),
        ...mapGetters("setting", ["affixed"]),
        canUpload() {
            return checkPermit(PERMITS.uploadSoftware, this.permits);
        },
        canDownload() {
            return checkPermit(PERMITS.downloadSop, this.permits);
        },
    },
    watch: {
        update(n) {
            if (-1 != n && !this._inactive) {
                this.$nextTick(() => {
                    const table = this.$refs.table;
                    const header = document.querySelectorAll(
                        ".doc-center-table .ant-table-header"
                    )[0].clientHeight;
                    const bar = document.querySelectorAll(".header-bar")[0].clientHeight;
                    if (table.fullScreen) {
                        this.y = table.$el.clientHeight - bar - header - 64;
                    } else {
                        const wraper = this.$refs.wraper.clientHeight;
                        const card = document.querySelectorAll(".ant-card-body")[0];
                        const { paddingBottom, paddingTop } = getComputedStyle(card, null);
                        const h =
                            wraper -
                            header -
                            64 -
                            bar -
                            parseInt(paddingBottom) -
                            parseInt(paddingTop);
                        this.y = h;
                    }
                });
            }
        },
        affixed() {
            setTimeout(() => {
                this.update = Math.random();
            }, 200);
        },
    },
    methods: {
        searchAllUserList() {
            getUserList()
                .then((res) => {
                    let rs = res.data;
                    if (rs.code && rs.data) {
                        this.userList = rs.data2;
                    }
                })
                .catch((error) => {
                    console.log(error);
                });
        },
        showUpload() {
            this.file = null;
            this.file1 = null;
            this.resObj = {};
            this.onlyXls = false;
            this.uploadShow = true;
        },
        updateDesc(row) {
            this.file = null;
            this.file1 = null;
            this.resObj = { rowId: row.id };
            this.rowFileName = row.fileName;
            this.onlyXls = true;
            this.uploadShow = true;
        },
        uploadCancel() {
            this.uploadShow = false;
        },
        handleEmailShow(record) {
            this.emailInfo.title =
                "[sop发布记录]" + record.fileName + " 版本号:" + record.fileVersion;
            let sopProductListText = record.sopProductList
                .map((item) => {
                    return "物料编码:" + item.code + " 型/板号:" + item.model;
                })
                .join("\n");
            this.emailInfo.content =
                "文件基础信息\n" +
                "文件名称:" +
                record.fileName +
                "\n" +
                "文件类型:" +
                record.fileType +
                "\n" +
                "文件版本:" +
                record.fileVersion +
                "\n" +
                "关联版本:" +
                record.fileRelatedVersion +
                "\n" +
                "编制:" +
                record.editor +
                "\n" +
                "审核:" +
                record.auditor +
                "\n" +
                "发布日期:" +
                record.releaseDate +
                "\n" +
                "文件适用产品\n" +
                sopProductListText +
                "\n" +
                "发布说明:" +
                record.releaseNotes;
            this.emailShow = true;
        },
        emailCancel() {
            this.emailShow = false;
        },
        uploadSop() {
            if (!this.file) {
                this.$message.error("请选择要上传的压缩包");
                return false;
            }
            if (!this.file1) {
                this.$message.error("请选择sop说明文件");
                return false;
            }
            if (!this.resObj.fileName) {
                this.$message.error("sop说明文件解析异常");
                return false;
            }
            // 如果sop文件名称 != sop说明里的文件名称 + 文件版本  则报错拒绝
            let reg = /(.*)\..{1,5}$/;
            let name1 = this.file.name.match(reg)[1];
            let { fileName, fileVersion } = this.resObj;
            let name2 = fileName + fileVersion;
            if (name1.toLowerCase() != name2.toLowerCase()) {
                console.log(name1.toLowerCase()+"&&&&&&"+ name2.toLowerCase());
                this.$message.error("sop与说明文件可能不匹配");
                return false;
            }
            let loading = this.$layer.loading();
            const formData = new FormData();
            formData.append("multipartFile", this.file);
            // formData.append("file2", this.file1);
            formData.append("sopStr", JSON.stringify(this.resObj));
            addSop(formData)
                .then((res) => {
                    let { code, data, msg } = res.data;
                    if (code) {
                        this.uploadShow = false;
                        this.$message.success("上传成功");
                        this.searchData();
                    } else {
                        this.$message.error(msg);
                    }
                    this.$layer.close(loading);
                })
                .catch((error) => {
                    this.$layer.close(loading);
                    console.log(error);
                });
        },
        applyModel() {
            if (!this.file1) {
                this.$message.error("请选择sop说明文件");
                return false;
            }
            if (!this.resObj.fileName) {
                this.$message.error("sop说明文件解析异常");
                return false;
            }
            if (this.rowFileName.toLowerCase() != this.resObj.fileName.toLowerCase()) {
                this.$message.error("说明文件与该条记录可能不匹配");
                return false;
            }
            let loading = this.$layer.loading();
            updateSop(this.resObj)
                .then((res) => {
                    let { code, data, msg } = res.data;
                    if (code) {
                        this.uploadShow = false;
                        this.$message.success("上传成功");
                        this.searchData();
                    } else {
                        this.$message.error("解析失败");
                    }
                    this.$layer.close(loading);
                })
                .catch((error) => {
                    this.$layer.close(loading);
                    console.log(error);
                });
        },
        getSopType1() {
            getSopType1()
                .then((res) => {
                    let { code, data } = res.data;
                    let list = [];
                    if (code) {
                        list = data.map((v) => ({
                            title: v.type1,
                            value: v.type1,
                        }));
                    }
                    this.columns[0].search.selectOptions = list;
                })
                .catch((err) => {
                    console.log(err);
                });
        },
        getSopType2(type) {
            if (type) {
                getSopType2(type)
                    .then((res) => {
                        let { code, data } = res.data;
                        let list = [];
                        if (code) {
                            list = data.map((v) => ({
                                title: v.type2,
                                value: v.type2,
                            }));
                        }
                        this.columns[1].search.selectOptions = list;
                    })
                    .catch((err) => {
                        console.log(err);
                    });
            } else {
                this.columns[1].search.selectOptions = [];
            }
        },
        cellMouseenter(e, obj) {
            // console.log("enter", e, obj);
            const wraper = this.$refs.wraper;
            const { clientHeight, clientWidth } = wraper;
            const { target, clientX, clientY } = e;
            let { left: x, top: y } = offset(wraper);
            x = clientX - x;
            y = clientY - y;
            // 如果clientHeight 小于380 * 2 则左右布局
            let dir = "bottom";
            if (clientHeight < 380 * 2) {
                if (x + 420 + 18 > clientWidth) {
                    dir = "left";
                } else {
                    dir = "right";
                }
                if (y < 180) {
                    y = 180;
                } else if (y > clientHeight - 378) {
                    y = clientHeight / 2;
                }
            } else {
                if (y + 18 + 360 > clientHeight) {
                    // y = clientHeight - 378;
                    dir = "top";
                } else {
                    dir = "bottom";
                }
                if (x < 400) {
                    x = 400;
                }
                if (x + 400 > clientWidth) {
                    x = clientWidth - 400;
                }
            }
            this.popPosition.x = x;
            this.popPosition.y = y;
            this.popPosition.dir = dir;
            this.popInfo = obj;
            this.popVisible = true;
        },
        cellMouseleave(e, obj) {
            // console.log("leave", obj);
            this.popVisible = false;
        },
        customCell(record) {
            return {
                on: {
                    mouseenter: (e) => this.cellMouseenter(e, record),
                    mouseleave: (e) => this.cellMouseleave(e, record),
                },
            };
        },
        beforeUpload() {
            return false;
        },
        uploadChange(data) {
            const { file, fileList } = data;
            if (fileList.length > 1) {
                fileList.shift();
            }
            if (fileList.length) {
                this.file = fileList[0].originFileObj;
            } else {
                this.file = null;
            }
        },
        uploadChange1(data) {
            const { file, fileList } = data;
            if (fileList.length > 1) {
                fileList.shift();
            }
            if (fileList.length) {
                this.file1 = fileList[0].originFileObj;
            } else {
                this.file1 = null;
                this.resObj = [];
                return false;
            }
            let loading = this.$layer.loading();
            const formData = new FormData();
            formData.append("multipartFile", this.file1);
            fileParse(formData)
                .then((res) => {
                    this.$layer.close(loading);
                    let { code, data, data2, msg } = res.data;
                    if (code && data) {
                        let rowId = this.resObj.rowId;
                        this.resObj = data2;
                        this.resObj.id = rowId;
                        this.$message.success("解析成功");
                    } else {
                        this.$message.error(msg);
                    }
                })
                .catch((error) => {
                    this.$layer.close(loading);
                    console.log(error);
                });
        },
        resize() {
            setTimeout(() => {
                this.update = Math.random();
            }, 200);
        },
        activeFN() {
            this.resize();
        },
        onSearch(conditions, searchOptions, col) {
            // console.log(conditions);
            // console.log(searchOptions, "00", col);
            this.pageCurr = 1;
            this.conditions = conditions;
            if ("parentType" == col.dataIndex) {
                this.parentTypeChange(col.search.value);
            }
            this.searchData();
        },
        onPageChange(page, pageSize) {
            this.pageCurr = page;
            this.pageSize = pageSize;
            this.searchData();
        },
        onSizeChange(current, size) {
            this.pageCurr = 1;
            this.pageSize = size;
            this.searchData();
        },
        onRefresh(conditions) {
            this.conditions = conditions;
            this.searchData();
        },
        onReset(conditions) {
            this.conditions = conditions;
            this.searchData();
        },
        // 文件类型查询条件发生变化  查询子文件类型列表 重置子文件类型值
        parentTypeChange(val) {
            let _search = this.columns[1].search;
            _search.value = [];
            this.conditions["chileType"] = [];
            this.getSopType2(val);
        },
        searchData() {
            const { pageCurr, pageSize, conditions, columns } = this;
            let params = { pageCurr, pageSize };
            let data = {};
            Object.keys(conditions).forEach((v) => {
                switch (v) {
                    case "code":
                    case "model":
                        params[v] = conditions[v];
                        break;
                    case "status":
                        params[v] = conditions[v]?1:0;
                        break;
                    case "parentType":
                    case "chileType":
                        data[v] = conditions[v];
                        break;
                }
            });
            params.status = 1;
            params.code = this.parentCode;
            let list = [];
            let params2 = "{}" == JSON.stringify(data) ? [] : [data];
            getList(params, params2)
                .then((res) => {
                    let { code, data, data2 } = res.data;
                    let total = 0;
                    if (code && data) {
                        // console.log(data2);
                        list = data2.list;
                        total = data2.total;
                    }
                    this.dataSource = list.map(item=>{
                        const fileInfo = getFileTypeAndName(item.fileUrl);
                        item.isCanPreview = fileInfo.type === "pdf";
                        return item;
                    });
                    this.total = total;
                    this.getSopType1();
                    if (-1 == this.update) {
                        this.update = Math.random();
                    }
                })
                .catch((err) => {
                    console.log(err);
                });
        },
        downloadFile(record) {
            const fileInfo = getFileTypeAndName(record.fileUrl);
            if(fileInfo.type === 'pdf') {  // 预览
                window.open("http://localhost:8092/cad/"+record.fileUrl);
            }else {     // 下载
                let loading = this.$layer.loading();
                let link = document.createElement("a");
                link.style.display = "none";
                let url = this.webUrl + record.fileUrl;
                let fileName = record.fileUrl.split("/").pop();
                link.href = url;
                link.download = fileName;
                document.body.appendChild(link);
                link.click();
                this.$layer.close(loading);
                document.body.removeChild(link);
            }
        },
        reasonCancel() {
            this.reasonVisible = false;
        },
        reasonOk() {
            let { id, status } = this.currentObj;
            let reason = this.reason;
            status = status == 0 ? 1 : 0;
            sopLock(id, status, reason).then((res) => {
                const { code } = res.data;
                if (code) {
                    this.$message.success("操作成功");
                    this.reasonVisible = false;
                    this.searchData();
                } else {
                    this.$message.error("操作失败");
                }
            });
        },
        lock(record) {
            this.reason = "";
            this.currentObj = record;
            this.reasonVisible = true;
        },
        viewLog(obj) {
            // console.log(obj);
            const { id, fileVersion } = obj;
            getLogList(id).then((res) => {
                const { code, data, data2 } = res.data;
                if (code) {
                    this.logList = data2.map((v) => ({ ...v, fileVersion }));
                    this.logVisible = true;
                } else {
                    this.$message.error("日志查询失败");
                }
            });
        },
        logCancel() {
            this.logVisible = false;
        },
        pdfCancel() {
            this.pdfInfo.visible = false;
        },
        goHistory(record) {
            let { fileName } = record;
            this.$router.push({
                path: "/resource/sop-history",
                query: { fileName },
            });
        },
    },
    mounted() {
        this.searchData();
        this.searchAllUserList();
        this.getSopType1();
        window.addEventListener("resize", this.resize);
    },
    destroyed() {
        window.removeEventListener("resize", this.resize);
    },
};
</script>
<style scoped lang="less">
.main {
    height: 100%;
    position: relative;
    .inner {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
    }
}
.img-wraper {
    width: 80px;
    height: 50px;
    display: inline-block;
    .image-view {
        width: 100%;
        height: 100%;
        /deep/img {
            width: 100%;
            height: 100%;
            object-fit: contain;
        }
    }
}
/deep/table {
    table-layout: fixed;
}
.modal-footer {
    text-align: right;
    button + button {
        margin-left: 8px;
    }
}
.label {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding-right: 0.4em;
    height: 32px;
    &::after {
        content: ":";
    }
}
.row ~ .row {
    margin-top: 10px;
}
.sub-title {
    font-size: 14px;
    font-weight: 700;
    margin-top: 10px;
}
.res-content {
    max-height: 260px;
    overflow-y: auto;
    margin-bottom: 10px;
}
.btn-grp button {
    width: 6.4em;
}
.tag-all {
    margin: 0;
}
/deep/ .ant-table-fixed-right {
    .ant-table-body-outer {
        margin-bottom: 0 !important;
    }
    .ant-table-body-inner {
        overflow-x: hidden;
    }
}
.log-content {
    max-height: 400px;
    overflow-y: auto;
    .user {
        color: #23aaf2;
        font-weight: 700;
    }
    .time {
        color: #f9be13;
        font-weight: 700;
    }
    .version {
        color: #0aedb2;
        font-weight: 700;
    }
    .ant-timeline-item:first-of-type {
        padding-top: 6px;
    }
}
</style>