研发图纸文件管理系统-前端项目
he wei
2025-02-26 75d229e997cba687ecbda2d7e41d42ed01bf8bfd
src/pages/resourceManage/product/details/details.vue
@@ -84,8 +84,8 @@
                    <template
                      v-if="
                        record.softwares &&
                        record.softwares.length &&
                        canDownloadSoftware
                          record.softwares.length &&
                          canDownloadSoftware
                      "
                    >
                      <a-divider
@@ -120,12 +120,42 @@
                      <a-divider
                        v-if="
                          record.softwares &&
                          record.softwares.length &&
                          canDownloadSoftware
                            record.softwares.length &&
                            canDownloadSoftware
                        "
                        type="vertical"
                      ></a-divider>
                      <a href="javascript:;" @click="toDetails0120(record)"
                        >详情</a
                      >
                    </template>
                    <template v-if="/^08|^09/.test(record.subCode)">
                      <a-divider
                        v-if="
                          record.softwares &&
                            record.softwares.length &&
                            canDownloadSoftware
                        "
                        type="vertical"
                      ></a-divider>
                      <a
                        href="javascript:;"
                        @click="toDetails_type(record, '0809')"
                        >详情</a
                      >
                    </template>
                    <template v-if="/^0235/.test(record.subCode)">
                      <a-divider
                        v-if="
                          record.softwares &&
                            record.softwares.length &&
                            canDownloadSoftware
                        "
                        type="vertical"
                      ></a-divider>
                      <a
                        href="javascript:;"
                        @click="toDetails_type(record, '0235')"
                        >详情</a
                      >
                    </template>
@@ -154,13 +184,16 @@
            <a-button type="primary" @click="viewLog">状态日志</a-button>
            <a-button type="primary" @click="downloadLogs">下载日志</a-button>
            <a-button
              v-if="otherDoc.length && currentVersion.enabled"
              v-if="otherDoc.length && currentVersion.enabled == 1"
              type="primary"
              @click="showOtherDoc"
              >其他附件</a-button
            >
            <a-button
              v-if="(canDownloadBom && currentVersion.enabled) || isTester"
              v-if="
                ((canDownloadBom && currentVersion.enabled == 1) || isTester) &&
                  !is0120
              "
              type="primary"
              @click="checkLock('zipDownload')"
              >bom下载</a-button
@@ -168,20 +201,27 @@
            <a-button
              v-if="
                (((canDownloadBom || canDownloadOriginBom) &&
                  currentVersion.enabled) ||
                  currentVersion.enabled == 1) ||
                  isTester) &&
                originalZipUrl
                  originalZipUrl &&
                  !is0120
              "
              type="primary"
              @click="checkLock('OriginalZipDownload')"
              >下载原始包</a-button
            >
            <a-button
              v-if="isTester && originalZipUrl"
              type="primary"
              @click="viewRar"
              >查看原始包</a-button
            >
            <a-button
              type="primary"
              v-if="
                softwareList.length &&
                canDownloadSoftware &&
                currentVersion.enabled
                  canDownloadSoftware &&
                  currentVersion.enabled == 1
              "
              @click="showSoftwareDownload"
              >软件下载</a-button
@@ -190,8 +230,8 @@
              type="primary"
              v-if="
                currentVersion.enabled == 0 &&
                canLockBom &&
                (!is0120 || maxVersionid == currentVersion.id)
                  canLockBom &&
                  (!is0120 || maxVersionid == currentVersion.id)
              "
              @click="changeStatus"
              >激活版本</a-button
@@ -207,6 +247,10 @@
              v-if="currentVersion.enabled == 1 && canLockBom"
              @click="changeStatus"
              >锁定版本</a-button
            >
            <a-button type="primary" @click="viewSopFile">SOP查看</a-button>
            <a-button v-if="originalZipUrl" type="primary" @click="preview"
              >原始包预览</a-button
            >
          </template>
        </a-card>
@@ -348,7 +392,9 @@
            <div>
              <span class="user">{{ item.owner }}</span> 在
              <span class="time">{{ item.createTime }}</span>
              {{ item.lockFlag ? "锁定" : "激活" }}了版本
              {{
                { "-1": "上传", "0": "激活", "1": "锁定" }[item.lockFlag]
              }}了版本
              <span class="version">{{ item.versionTime }}</span>
            </div>
            <div>操作原因: {{ item.reason ? item.reason : "无" }}</div>
@@ -368,6 +414,96 @@
      :type="12"
      :oprate-info="oprateInfo"
    ></download-logs>
    <a-modal
      :visible="fileTreeVisible"
      :footer="null"
      :width="860"
      title="文件列表"
      :destroyOnClose="true"
      @cancel="fileTreeVisible = false"
    >
      <div class="log-content">
        <a-tree
          v-if="fileTree.length"
          :show-line="true"
          defaultExpandAll
          :tree-data="fileTree"
        />
        <a-empty v-else />
      </div>
    </a-modal>
    <a-modal
      :visible="fileTreeViewVisible"
      :footer="null"
      :width="860"
      title="文件列表"
      :destroyOnClose="true"
      @cancel="fileTreeViewVisible = false"
    >
      <a-input-search
        style="margin-bottom: 8px"
        v-model="searchValue"
        placeholder="输入关键词搜索文件名"
        @change="searchChanged"
      />
      <div class="log-content">
        <a-tree
          class="file-tree-view"
          v-if="fileTreeView.length && treeReset"
          :show-line="true"
          defaultExpandAll
          :tree-data="fileTreeViewRes"
        >
          <template slot="custom" slot-scope="item">
            <div class="flex-r space-between">
              <span v-if="item.title.indexOf(searchValue) > -1"
                >{{ item.title.substr(0, item.title.indexOf(searchValue))
                }}<span style="color: #f50">{{ searchValue }}</span
                >{{
                  item.title.substr(
                    item.title.indexOf(searchValue) + searchValue.length
                  )
                }}</span
              >
              <span v-else class="node-title">{{ item.title }} </span>
              <span
                class="icon-wrap"
                v-if="item.isLeaf && viewAble(item.type)"
                title="预览"
                @click="view(item)"
              >
                <a-icon type="file-search" />
              </span>
            </div>
          </template>
        </a-tree>
        <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>
    <!-- <a-modal
      :width="600"
      :visible="previewVisible"
      :footer="null"
      @cancel="handleCancel"
    >
      <img alt="" style="width: 100%" :src="imgUrl" />
    </a-modal> -->
    <!-- <viewer :images="imgUrl">
      <img alt="" style="width: 100%" :src="imgUrl" />
    </viewer> -->
  </div>
</template>
@@ -383,6 +519,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 {
@@ -391,6 +528,9 @@
  getBomHistoryAndMaterial,
  compare,
  getOriginalZip,
  checkExist,
  getzipAndRarInfo,
  decompress,
} from "./apis";
import {
  searchDefaultMailUser,
@@ -410,6 +550,15 @@
  mixins: [WSMixin],
  data() {
    return {
      treeReset: true,
      searchValue: "",
      imgUrl: "",
      previewVisible: false,
      showSop: false,
      fileTreeVisible: false,
      fileTree: [],
      fileTreeViewVisible: false,
      fileTreeView: [],
      userListAll: [],
      mailList: [],
      tester: [],
@@ -661,6 +810,7 @@
    Pop,
    DownloadReason,
    DownloadLogs,
    SopList,
  },
  computed: {
    ...mapGetters("setting", ["affixed"]),
@@ -693,6 +843,21 @@
    hasLock() {
      return this.versionList.some((v) => v.enabled == -1);
    },
    fileTreeViewRes() {
      let resList = this.fileTreeView.filter((v) => {
        let fileName = v.split("\\").pop();
        return fileName.indexOf(this.searchValue) > -1;
      });
      let {
        children: [
          {
            children: [{ children: list }],
          },
        ],
      } = this.format(resList, false);
      return list;
    },
  },
  watch: {
    update(n) {
@@ -721,6 +886,9 @@
    },
  },
  methods: {
    viewSopFile() {
      this.showSop = true;
    },
    getRoleUser() {
      getRoleUser(1)
        .then((res) => {
@@ -841,15 +1009,17 @@
    },
    getOriginalZip() {
      const {
        currentVersion: { parentModel, customCode, version },
        currentVersion: { parentCode, parentModel, customCode, version },
      } = this;
      this.originalZipUrl = "";
      getOriginalZip(parentModel, customCode, version).then((res) => {
        const { code, data, data2 } = res.data;
        if (code && data) {
          this.originalZipUrl = data2;
      getOriginalZip(parentCode, parentModel, customCode, version).then(
        (res) => {
          const { code, data, data2 } = res.data;
          if (code && data) {
            this.originalZipUrl = data2;
          }
        }
      });
      );
    },
    getInfo(force) {
      const {
@@ -1215,6 +1385,10 @@
      if (/^0120/.test(record.subCode)) {
        classList.push("is-0120");
      }
      // 08 09 开头的半成品
      if (/^08|^09/.test(record.subCode)) {
        classList.push("is-08_09");
      }
      return classList;
    },
    toDetails0120(record) {
@@ -1226,6 +1400,228 @@
      this.$router.push({
        path: "/resource/product-details-0120",
        query: { parentCode, customCode: "", parentModel, parentName },
      });
    },
    toDetails_type(record, type) {
      const {
        subCode: parentCode,
        subModel: parentModel,
        subName: parentName,
      } = record;
      checkExist(parentCode, "")
        .then((res) => {
          let { code, data } = res.data;
          if (code && data) {
            this.$router.push({
              path: "/resource/product-details-" + type,
              query: { parentCode, customCode: "", parentModel, parentName },
            });
            // console.log(data);
          } else {
            this.$message.error("产品未上传");
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    getParent(obj, arr, i) {
      let len = arr.length - 1;
      if (i > len) {
        return false;
      }
      // if (i == 0) {
      //   return obj;
      // }
      // if (i == 1) {
      //   return obj[arr[0]];
      // }
      let res = obj;
      let tmp = {};
      for (let m = 1; m <= i; m++) {
        // tmp[arr[m]] = {};
        // tmp = tmp[arr[m]];
        tmp = arr[m - 1];
        res = res[tmp];
      }
      return res;
    },
    format(list, needTime = true) {
      let counter = this.counter();
      let obj = {
        counter,
        key: "root",
        children: [],
      };
      // let root = {
      //   counter,
      //   key: "root",
      //   children: [],
      // };
      list.forEach((v) => {
        let url = needTime ? v.fileName : v;
        let fileTime = v.fileTime;
        let splitStr = needTime ? "/" : "\\";
        let arr = url.split(splitStr);
        let fileName = arr.pop();
        let files = fileName.split(".");
        let type = files.length ? files[files.length - 1].toLowerCase() : "";
        let tmp = obj;
        for (let i = 0, len = arr.length; i < len; i++) {
          let parent = this.getParent(obj, arr, i);
          if (!tmp[arr[i]]) {
            tmp[arr[i]] = {
              parent,
              title: arr[i],
              key: parent.key + "-" + parent.counter(),
              children: [],
              scopedSlots: { title: "custom" },
              counter: this.counter(),
            };
            // tmp[arr[i]].parent.children.push(tmp[arr[i]]);
            parent.children.push(tmp[arr[i]]);
          }
          tmp = tmp[arr[i]];
        }
        // console.log(tmp.children, 'children')
        tmp.children.push({
          url,
          type,
          fileName,
          fileTime,
          key: tmp.key + "-" + tmp.counter(),
          title: needTime ? fileName + "  " + fileTime : fileName,
          scopedSlots: { title: "custom" },
          isLeaf: true,
        });
        // console.log(obj, '......')
        // for (let i = 0, len = arr.length; i < len; i++) {
        //   // 判断有没有父级 i为0没有 i为大于1就有
        //   let parent = i > 0 ? tmp[arr[i - 1]] : root;
        //   if (!obj[item]) {
        //     obj[item] = {
        //       title: item,
        //       key: parent.key + "-" + parent.counter(),
        //       children: [],
        //       counter: this.counter(),
        //     };
        //   }
        // }
      });
      return obj;
    },
    counter() {
      let count = 0;
      return () => {
        return count++;
      };
    },
    // 查看压缩包内文件目录结构
    viewRar() {
      let loading = this.$layer.loading();
      // console.log(this.originalZipUrl);
      getzipAndRarInfo(this.originalZipUrl)
        .then((res) => {
          let { code, data, data2 } = res.data;
          let list = { children: [] };
          if (code && data) {
            console.log(data2);
            list = this.format(data2);
          }
          this.$layer.close(loading);
          this.fileTree = list.children;
          this.fileTreeVisible = true;
          // { title: 'Tree Node', key: '2', isLeaf: true },
          console.log(list, "===list");
        })
        .catch((err) => {
          this.$layer.close(loading);
          console.log(err);
        });
    },
    // 解压压缩包到服务器 然后返回内部文件的结构和路径 路径可用来预览
    preview() {
      this.searchValue = '';
      let loading = this.$layer.loading();
      decompress(this.originalZipUrl)
        .then((res) => {
          let { code, data, data2, msg } = res.data;
          let list = [];
          if (code && data) {
            // console.log(data);
            this.$message.success("解析成功");
            // let {
            //   children: [
            //     {
            //       children: [{ children: list1 }],
            //     },
            //   ],
            // } = this.format(data2, false);
            // list = list1;
            list = data2;
          } else {
            this.$message.error(msg);
          }
          this.$layer.close(loading);
          this.fileTreeView = list;
          // this.fileTreeView = list.children[0]["children"][0]["children"];
          this.fileTreeViewVisible = true;
          // console.log(list, "===list111");
        })
        .catch((err) => {
          console.log(err);
          this.$layer.close(loading);
        });
    },
    viewAble(type) {
      return ["bmp", "jpg", "jpeg", "png", "pdf", "doc", "docx", "dwg"].some(
        (v) => v == type
      );
    },
    view(obj) {
      switch (obj.type) {
        // 图片
        case "bmp":
        case "jpg":
        case "jpeg":
        case "png":
          this.imgUrl = this.webUrl + obj.url;
          this.viewerImg();
          // this.previewVisible = true;
          break;
        case "pdf":
          window.open(this.webUrl + obj.url);
          break;
        case "doc":
        case "docx":
        case "dwg":
          this.dwgReview(obj.url);
          break;
        // default:
        //   this.$message.warn("该类型文件暂不支持预览");
        //   break;
      }
    },
    handleCancel() {
      this.previewVisible = false;
    },
    viewerImg() {
      this.$viewerApi({
        images: [this.imgUrl],
        options: {
          initialViewIndex: 0,
        },
      });
    },
    searchChanged() {
      this.treeReset = false;
      this.$nextTick(() => {
        this.treeReset = true;
      });
    },
  },
@@ -1377,9 +1773,12 @@
  /deep/.ant-table-row-level-1.ant-table-row-level-1:hover > td {
    background: #ffbcc9;
  }
  /deep/.is-08_09 > td,
  /deep/.is-0120 > td {
    background: #ffae00;
  }
  /deep/.is-08_09.is-08_09.ant-table-row-hover > td,
  /deep/.is-08_09.is-08_09:hover > td,
  /deep/.is-0120.is-0120.ant-table-row-hover > td,
  /deep/.is-0120.is-0120:hover > td {
    background: #f8c34f;
@@ -1415,4 +1814,32 @@
/deep/.ant-descriptions-row .ant-descriptions-item:first-child {
  width: 180px;
}
.file-tree-view /deep/ li {
  // display: flex;
  // flex-direction: row;
  .ant-tree-switcher {
    float: left;
  }
  .ant-tree-node-content-wrapper {
    display: block;
    cursor: auto;
    .ant-tree-title {
      display: block;
    }
  }
  .ant-tree-child-tree {
    flex-basis: 100%;
  }
  .icon-wrap {
    cursor: pointer;
    font-size: 22px;
  }
}
.flex-r {
  display: flex;
  flex-direction: row;
  &.space-between {
    justify-content: space-between;
  }
}
</style>