研发图纸文件管理系统-前端项目
he wei
2022-09-05 b3945dc681bc4fde4d551093efdc40478304f227
UA 产品历史比较差异 上传BOM比较差异等
13个文件已修改
4个文件已添加
1539 ■■■■ 已修改文件
src/pages/components/diffList.vue 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/components/drawUpload/DrawUpload.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/components/filesTable.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/details/details.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/apis.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/history/history.vue 464 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/history/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/history/list.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/list.vue 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/apis.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/apis.js 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/details.vue 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/list.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/list.vue 252 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/prodUpload.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/workplace/myDraw/apis.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/config.js 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/components/diffList.vue
New file
@@ -0,0 +1,185 @@
<template>
  <div class="">
    <a-collapse v-model="activeKey" accordion>
      <a-collapse-panel
        class="add"
        key="1"
        :header="headerAdd"
        :disabled="!addList.length"
      >
        <a-table
          :scroll="{ y: 200 }"
          bordered
          size="small"
          :columns="columns"
          :data-source="addList"
          :pagination="false"
          :expandRowByClick="true"
          :row-key="(record, index) => index"
        >
        </a-table>
      </a-collapse-panel>
      <a-collapse-panel
        class="del"
        key="2"
        :header="headerDel"
        :disabled="!delList.length"
      >
        <a-table
          :scroll="{ y: 200 }"
          bordered
          size="small"
          :columns="columns"
          :data-source="delList"
          :pagination="false"
          :expandRowByClick="true"
          :row-key="(record, index) => index"
        >
        </a-table>
      </a-collapse-panel>
      <a-collapse-panel
        class="update"
        key="3"
        :header="headerUpdate"
        :disabled="!updateList.length"
      >
        <a-table
          :scroll="{ y: 200 }"
          bordered
          size="small"
          :columns="updateColumns"
          :data-source="updateList"
          :pagination="false"
          :expandRowByClick="true"
          :row-key="(record, index) => index"
        >
        </a-table>
      </a-collapse-panel>
    </a-collapse>
  </div>
</template>
<script>
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { dwgReview } from "@/pages/workplace/apis";
import { downloadLog } from "@/pages/system/logs/apis";
export default {
  name: "",
  props: {
    list: {
      type: Object,
      default() {
        return {};
      },
    },
    width: {
      type: Number,
      default: 600,
    },
  },
  data() {
    return {
      // activeKey: 0,
      columns: [
        {
          title: "料号",
          dataIndex: "subCode",
          align: "center",
        },
        {
          title: "料名",
          dataIndex: "subName",
          align: "center",
        },
        {
          title: "型号",
          dataIndex: "subModel",
          align: "center",
        },
      ],
      updateColumns: [
        {
          title: "料号",
          dataIndex: "materialObj.subCode",
          align: "center",
        },
        {
          title: "料名",
          dataIndex: "materialObj.subName",
          align: "center",
        },
        {
          title: "型号",
          dataIndex: "materialObj.subModel",
          align: "center",
        },
        {
          title: "变化",
          dataIndex: "notes",
          align: "center",
        }
      ]
    };
  },
  methods: {
    handleClick() {
      this.$emit("success", this.list);
    },
    handleCancel() {
      this.previewVisible = false;
    },
  },
  computed: {
    addList() {
      return this.list.addList || [];
    },
    delList() {
      return this.list.delList || [];
    },
    updateList() {
      return this.list.updateList || [];
    },
    headerAdd() {
      return `新增 (${this.addList.length})`;
    },
    headerDel() {
      return `删除 (${this.delList.length})`;
    },
    headerUpdate() {
      return `修改 (${this.updateList.length})`;
    },
    activeKey() {
      if (this.addList.length) {
        return 1;
      } else if (this.delList.length) {
        return 2;
      } else if (this.updateList.length) {
        return 3;
      } else {
        return 0;
      }
    }
  },
  mounted() {},
};
</script>
<style lang="less" scoped>
/deep/ .ant-collapse-header.ant-collapse-header {
  padding: 4px 0 4px 40px;
  font-weight: 700;
}
.add /deep/ .ant-collapse-header {
  color: #090;
}
.del /deep/ .ant-collapse-header {
  color: #f50;
}
.update /deep/ .ant-collapse-header {
  color: #fed400;
}
/deep/ .ant-collapse-item-disabled .ant-collapse-header {
  color: rgba(0, 0, 0, 0.6);
  font-weight: normal;
}
</style>
src/pages/components/drawUpload/DrawUpload.vue
@@ -29,10 +29,7 @@
      >
        <template slot="pictureUrl" slot-scope="text">
          <div class="img-wraper">
            <image-view
              v-if="text"
              :url="webUrl + text"
            ></image-view>
            <image-view v-if="text" :url="webUrl + text"></image-view>
          </div>
        </template>
        <template slot="dwgExist" slot-scope="text, record">
@@ -66,14 +63,14 @@
  components: { ImageView },
  props: {
    list: {
      type: Array,
      type: Object,
      default() {
        return [];
        return {};
      },
    },
    text: {
      type: String,
      default: "提交审核",
      default: "提交",
    },
    noFooter: {
      type: Boolean,
@@ -81,8 +78,8 @@
    },
    y: {
      type: Number,
      default: 500
    }
      default: 500,
    },
  },
  data() {
    const columns = [
@@ -211,23 +208,17 @@
  },
  computed: {
    dataSource() {
      return this.list.map((item) => {
      return this.list.bomList.map((item) => {
        return item;
      });
    },
    parentInfo() {
      let info = {
        parentCode: "",
        parentModel: "",
        parentName: "",
      let list = this.list;
      return {
        parentCode: list.parentCode,
        parentModel: list.parentModel,
        parentName: list.parentName,
      };
      if (this.list.length !== 0) {
        let item = this.list[0];
        info.parentCode = item.parentCode;
        info.parentModel = item.parentModel;
        info.parentName = item.parentName;
      }
      return info;
    },
  },
  mounted() {},
src/pages/components/filesTable.vue
@@ -1,5 +1,5 @@
<template>
  <div class="" :style="{width: width + 'px'}">
  <div class="" :style="{ width: width + 'px' }">
    <a-table
      ref="aTable"
      size="small"
@@ -8,7 +8,7 @@
      :columns="columns"
      :data-source="dataSource"
      :pagination="false"
      rowKey="subCode"
      :rowKey="(record, index) => index"
    >
      <template slot="action" slot-scope="text, record">
        <div v-if="record.url">
@@ -18,7 +18,12 @@
        </div>
      </template>
    </a-table>
    <a-modal :width="600" :visible="previewVisible" :footer="null" @cancel="handleCancel">
    <a-modal
      :width="600"
      :visible="previewVisible"
      :footer="null"
      @cancel="handleCancel"
    >
      <img alt="example" style="width: 100%" :src="imgUrl" />
    </a-modal>
  </div>
@@ -39,8 +44,8 @@
    },
    width: {
      type: Number,
      default: 600
    }
      default: 600,
    },
  },
  data() {
    const columns = [
@@ -68,7 +73,7 @@
    return {
      columns,
      y: 500,
      imgUrl: '',
      imgUrl: "",
      previewVisible: false,
      webUrl: getWebUrl(),
    };
@@ -78,20 +83,25 @@
      this.$emit("success", this.list);
    },
    view(obj) {
      switch(obj.fileType) {
      switch (obj.fileType) {
        // 图片
        case 'bmp':
        case 'jpg':
        case 'jpeg':
        case 'png':
        case "bmp":
        case "jpg":
        case "jpeg":
        case "png":
          this.imgUrl = this.webUrl + obj.url;
          this.previewVisible = true;
          break;
        case 'pdf':
        case "pdf":
          window.open(this.webUrl + obj.url);
          break;
        case 'dwg':
        case "doc":
        case "docx":
        case "dwg":
          this.dwgReview(obj.url);
          break;
        default:
          this.$message.warn('该类型文件暂不支持预览');
          break;
      }
    },
@@ -99,17 +109,20 @@
      this.previewVisible = false;
    },
    dwgReview(url) {
      let loading = this.$layer.loading();
      dwgReview(url)
        .then((res) => {
          let { code, data, msg }= res.data;
          let { code, data, msg } = res.data;
          if (code && data) {
            window.open(this.webUrl + data);
          } else {
            this.$message.error(msg);
          }
          this.$layer.close(loading);
        })
        .catch((error) => {
          console.log(error);
          this.$layer.close(loading);
        });
    },
    downloadLog(record) {
@@ -130,12 +143,12 @@
      let reg = /(.*\\+)*(.*)$/;
      return this.list.map((item) => {
        let fileName = item.match(reg)[2];
        let arr = fileName.split('.');
        let fileType = arr.length ? arr[arr.length - 1].toLowerCase() : '';
        let arr = fileName.split(".");
        let fileType = arr.length ? arr[arr.length - 1].toLowerCase() : "";
        return {
          fileName,
          fileType,
          url: item
          url: item,
        };
      });
    },
src/pages/resourceManage/details/details.vue
@@ -250,6 +250,7 @@
  .img-wraper {
    width: 160px;
    height: 100px;
    display: inline-block;
    .image-view {
      width: 100%;
      height: 100%;
src/pages/resourceManage/materialsCenter/apis.js
@@ -72,4 +72,55 @@
    url: "worksheetMain/materialSubmit",
    data
  })
}
/**
 * 物料审批提交
 * @returns
 */
export const getFileList = (materialId) => {
  return axios({
    method: "GET",
    url: "material/getAttachByMaterialId",
    params: { materialId }
  })
}
/**
 * 查询物料的历史版本
 * @returns
 */
export const getVersions = (subModel) => {
  return axios({
    method: "GET",
    url: "material/getMaterialVersion",
    params: { subModel }
  })
}
/**
 * 根据物料id查询物料信息
 * @returns
 */
export const getMaterialById = (materialId) => {
  return axios({
    method: "GET",
    url: "material/getMaterialById",
    params: { materialId }
  })
}
/**
 * 根据物料id查询物料信息
 * @returns
 */
export const uploadOthers = (data) => {
  return axios({
    method: "POST",
    url: "material/attachment",
    headers: {
      "Content-Type": "multipart/form-data"
    },
    data
  })
}
src/pages/resourceManage/materialsCenter/history/history.vue
New file
@@ -0,0 +1,464 @@
<template>
  <a-layout class="main">
    <a-layout-sider width="260">
      <list class="list" :list="versionList" @select="selectChanged"></list>
    </a-layout-sider>
    <a-layout>
      <a-layout-header>
        <a-card>
          <div class="title">物料所属产品</div>
          <a-table
            ref="aTable"
            size="small"
            :scroll="{ y: 300 }"
            bordered
            :columns="columns"
            :data-source="dataSource"
            :pagination="false"
            rowKey="subCode"
          >
          </a-table>
        </a-card>
      </a-layout-header>
      <a-layout-content>
        <div class="wraper" ref="wraper">
          <div class="inner">
            <a-spin :spinning="spinning" tip="拼命加载中...">
              <a-descriptions title="详情" bordered>
                <a-descriptions-item label="料号">{{
                  record.subCode
                }}</a-descriptions-item>
                <a-descriptions-item label="型号">{{
                  record.subModel
                }}</a-descriptions-item>
                <a-descriptions-item label="名称">{{
                  record.subName
                }}</a-descriptions-item>
                <a-descriptions-item label="单位">{{
                  record.unit
                }}</a-descriptions-item>
                <a-descriptions-item label="生产商">{{
                  record.producer
                }}</a-descriptions-item>
                <a-descriptions-item label="封装类型/材质">{{
                  record.material
                }}</a-descriptions-item>
                <a-descriptions-item label="元件编号/料厚">{{
                  record.thickness
                }}</a-descriptions-item>
                <a-descriptions-item label="表面处理/物料详情">{{
                  record.surfaceDetail
                }}</a-descriptions-item>
                <a-descriptions-item label="创建日期">{{
                  record.createDate
                }}</a-descriptions-item>
                <a-descriptions-item label="更新日期">{{
                  record.updateDate
                }}</a-descriptions-item>
                <a-descriptions-item label="备注">{{
                  record.notes
                }}</a-descriptions-item>
                <a-descriptions-item label="图片">
                  <div class="img-wraper">
                    <image-view
                      v-if="record"
                      :url="webUrl + record.pictureUrl"
                    ></image-view>
                  </div>
                </a-descriptions-item>
              </a-descriptions>
            </a-spin>
          </div>
        </div>
      </a-layout-content>
      <a-layout-footer>
        <a-card>
          <template v-if="dataSource.length">
            <a-popover title="" v-if="otherDoc.length">
              <files-table slot="content" :list="otherDoc"></files-table>
              <a-button type="primary">其他附件</a-button>
            </a-popover>
            <a-button
              type="primary"
              v-if="softwareList.length"
              @click="showSoftwareDownload"
              >软件下载</a-button
            >
          </template>
        </a-card>
      </a-layout-footer>
    </a-layout>
    <!-- 下载软件 -->
    <a-modal
      :visible="softwareDownloadShow"
      :footer="null"
      :width="600"
      title="软件下载"
      :destroyOnClose="true"
      :maskClosable="false"
      @cancel="softwareDownloadCancel"
    >
      <a-table
        ref="aTable"
        size="small"
        :scroll="{ y: 300 }"
        bordered
        :columns="softwareColumns"
        :data-source="softwareList"
        :pagination="false"
        :expandRowByClick="true"
        :row-key="(record, index) => index"
      >
        <template slot="action" slot-scope="text, record">
          <a @click="downloadLog(record)">下载</a>
        </template>
      </a-table>
    </a-modal>
  </a-layout>
</template>
<script>
import ImageView from "@/pages/components/ImageView";
import FilesTable from "@/pages/components/filesTable";
import DiffList from "@/pages/components/diffList";
import List from "./list";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getVersions, getMaterialById } from "../apis";
import { dwgReview } from "@/pages/workplace/apis";
import { downloadLog } from "@/pages/system/logs/apis";
import { mapGetters } from "vuex";
export default {
  name: "",
  data() {
    return {
      diffShow: false,
      diffData: [],
      softwareDownloadShow: false,
      rootModel: this.$route.query.rootModel,
      versionList: [],
      info: {},
      webUrl: getWebUrl(),
      record: {},
      currentVersion: -1,
      spinning: false,
      loading: false,
      total: 0,
      y: 400,
      update: -1,
      columns: [
        {
          title: "产品名称",
          dataIndex: "parentName",
          align: "center",
        },
        {
          title: "型号",
          dataIndex: "parentModel",
          align: "center",
          width: 200,
        },
        {
          title: "编码",
          dataIndex: "parentCode",
          align: "center",
          width: 200,
        },
        {
          title: "定制单号",
          dataIndex: "cutsomCode",
          align: "center",
        },
        {
          title: "版本时间",
          dataIndex: "versionTime",
          align: "center",
          width: 200,
        },
      ],
      dataSource: [],
      otherDoc: [],
      softwareList: [],
      softwareColumns: [
        {
          title: "软件名称",
          dataIndex: "softwareName",
          align: "center",
          // width: 180,
        },
        {
          title: "上传时间",
          dataIndex: "submitTime",
          align: "center",
          width: 180,
        },
        {
          title: "操作",
          dataIndex: "operation",
          align: "center",
          width: 100,
          scopedSlots: { customRender: "action" },
        },
      ],
    };
  },
  components: {
    List,
    ImageView,
    FilesTable,
    DiffList,
  },
  computed: {
    ...mapGetters("setting", ["affixed"]),
  },
  watch: {
    update(n) {
      if (-1 != n) {
        this.$nextTick(() => {
          const wraper = this.$refs.wraper;
          const wraperH = wraper.clientHeight;
          const header = document.querySelectorAll(
            ".wraper .ant-table-header"
          )[0].clientHeight;
          const { paddingBottom, paddingTop } = window.getComputedStyle(
            wraper,
            null
          );
          const h =
            wraperH - header - parseInt(paddingBottom) - parseInt(paddingTop);
          // console.log(h, "h", wraperH, header, paddingBottom, paddingTop);
          this.y = h;
        });
      }
    },
    affixed() {
      setTimeout(() => {
        this.update = Math.random();
      }, 200);
    },
  },
  methods: {
    getVersions() {
      getVersions(this.rootModel).then((res) => {
        const { code, data, data2 } = res.data;
        let list = [];
        if (code && data) {
          list = data2;
        }
        this.versionList = list;
      });
    },
    selectChanged(obj) {
      // console.log(obj, "--==");
      this.currentVersion = obj;
      this.getInfo();
    },
    getInfo() {
      const {
        currentVersion: { id },
        info,
      } = this;
      this.spinning = true;
      getMaterialById(id).then((res) => {
        let { code, data, data2, data3 } = res.data;
        // console.log(res, '909009')
        let list = [];
        let prods = [];
        let softwareList = [];
        let otherDoc = [];
        this.spinning = false;
        if (code && data) {
          list = data2;
          prods = data2.products;
          otherDoc = data3;
          // otherDoc = data4;
        }
        this.dataSource = prods;
        this.record = list;
        this.softwareList = softwareList;
        this.otherDoc = otherDoc;
        if (this.record.dwgUrl) {
          this.otherDoc.unshift(this.record.dwgUrl);
        }
        if (-1 == this.update) {
          this.update = Math.random();
        }
      });
    },
    dwgReview(url) {
      this.spinning = true;
      dwgReview(url)
        .then((res) => {
          this.spinning = false;
          let rs = res.data;
          if (rs.code == 1 && rs.data) {
            window.open(this.webUrl + rs.data);
          } else {
            this.$message.error(rs.msg);
          }
        })
        .catch((error) => {
          this.spinning = false;
          console.log(error);
        });
    },
    downloadLog(record) {
      const { parentCode, subModel, dwgUrl, softwareUrl } = record;
      const url = softwareUrl
        ? this.webUrl + softwareUrl
        : this.webUrl + dwgUrl;
      let link = document.createElement("a");
      link.style.display = "none";
      link.href = url;
      // link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      // downloadLog(parentCode, subModel);
    },
    zipDownload() {
      // const { parentCode, currentVersion } = this;
      const {
        currentVersion: { id, version },
      } = this;
      // zipDownload(id, version).then((res) => {
      //   // console.log(res, "===========");
      //   let { headers, data, status } = res;
      //   if (200 == status && data) {
      //     let url = window.URL.createObjectURL(data);
      //     const matchRes = /filename=(.*)/.exec(headers["content-disposition"]);
      //     const fileName = matchRes ? matchRes[1].trim() : "未知文件名.zip";
      //     let link = document.createElement("a");
      //     link.style.display = "none";
      //     link.href = url;
      //     link.download = fileName;
      //     document.body.appendChild(link);
      //     link.click();
      //     document.body.removeChild(link);
      //     window.URL.revokeObjectURL(url);
      //   } else {
      //     this.$message.error("操作失败");
      //   }
      // });
    },
    resize() {
      this.update = Math.random();
    },
    showSoftwareDownload() {
      this.softwareDownloadShow = true;
    },
    softwareDownloadCancel() {
      this.softwareDownloadShow = false;
    },
  },
  mounted() {
    this.getVersions();
    // this.searchData();
    window.addEventListener("resize", this.resize);
  },
  destroyed() {
    window.removeEventListener("resize", this.resize);
  },
};
</script>
<style scoped lang="less">
.main {
  height: 100%;
  .ant-layout-header,
  .ant-layout-sider {
    background: transparent;
  }
  .ant-layout-header {
    height: auto;
  }
  .list {
    height: 100%;
  }
  .wraper {
    height: 100%;
    position: relative;
    .inner {
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      bottom: 0;
    }
  }
  /deep/.ant-layout {
    margin-left: 10px;
  }
  .ant-layout-header {
    padding: 0;
    line-height: inherit;
    margin-bottom: 10px;
  }
  .ant-btn + .ant-btn {
    margin-left: 1em;
  }
  .ant-layout-content {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    color: rgba(0, 0, 0, 0.65);
    font-size: 14px;
    font-variant: tabular-nums;
    line-height: 1.5;
    list-style: none;
    -webkit-font-feature-settings: "tnum";
    font-feature-settings: "tnum";
    position: relative;
    background: #fff;
    border-radius: 2px;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
    padding: 24px;
    zoom: 1;
    /deep/.ant-descriptions-item-label {
      width: 12rem;
      text-align: right;
    }
  }
  .ant-layout-footer {
    padding: 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/.is-replace > td {
    background: #00eaff;
  }
  /deep/.is-replace.is-replace.ant-table-row-hover > td,
  /deep/.is-replace.is-replace:hover > td {
    background: #affaff;
  }
  /deep/.ant-table-row-level-1 > td {
    background: #ff8ea2;
  }
  /deep/.ant-table-row-level-1.ant-table-row-level-1.ant-table-row-hover > td,
  /deep/.ant-table-row-level-1.ant-table-row-level-1:hover > td {
    background: #ffbcc9;
  }
  .title {
    margin-bottom: 20px;
    color: rgba(0, 0, 0, 0.85);
    font-weight: bold;
    font-size: 16px;
    line-height: 1.5;
  }
}
</style>
src/pages/resourceManage/materialsCenter/history/index.js
New file
@@ -0,0 +1,2 @@
import history from './history.vue'
export default history;
src/pages/resourceManage/materialsCenter/history/list.vue
New file
@@ -0,0 +1,132 @@
<template>
  <div class="posR">
    <div class="inner">
      <a-card class="main">
        <!-- <a-input v-model="keyword" placeholder="输入关键字过滤" /> -->
        <!-- 列表 -->
        <div class="contain">
          <div
            :class="['item', { selected: currentV == item.id }]"
            v-for="(item, idx) in list"
            :key="'item_' + idx"
            @click="selectHandle(item)"
          >
            <div class="version">{{ item.subModel }}</div>
          </div>
        </div>
      </a-card>
    </div>
  </div>
</template>
<script>
export default {
  name: "",
  props: {
    list: {
      type: Array,
      default() {
        return [];
      },
    },
    // keyword: {
    //   type: String,
    //   default: "",
    // },
  },
  computed: {
    // data() {
    //   return this.list.filter((v) => {
    //     const reg = new RegExp(this.keyword, "i");
    //     return reg.test(v.subModel);
    //   });
    // },
  },
  watch: {
    list(n) {
      if (n.length) {
        this.selectHandle(this.list[0]);
      }
    },
  },
  data() {
    return {
      // keyword: '',
      currentV: "-1",
    };
  },
  components: {},
  methods: {
    selectHandle(item) {
      this.currentV = item.id;
      this.$emit("select", item);
    },
  },
  mounted() {},
};
</script>
<style scoped lang="less">
.posR {
  position: relative;
}
.inner {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}
.main {
  height: 100%;
  /deep/.ant-card-body {
    height: 100%;
    display: flex;
    flex-direction: column;
  }
}
.contain {
  margin-top: 8px;
  border: 1px solid #e8e8e8;
  flex: 1;
  overflow: auto;
  padding: 0 4px;
}
.item {
  cursor: pointer;
  box-shadow: 0px 4px 5px -2px #000;
  padding: 6px 0;
  border-radius: 4px;
  display: flex;
  flex-direction: row;
  align-items: center;
  & + .item {
    margin-top: 4px;
  }
  &:hover {
    transform: scale(0.98, 0.9);
    box-shadow: 0px 2px 5px -2px #000;
    background: #f0f0f0;
  }
  &.selected {
    transform: scale(0.98, 0.9);
    box-shadow: 0px 2px 5px -2px #000;
    color: #13C2C2;
    font-weight: bold;
  }
  .version {
    flex: 1;
  }
  .status {
    display: inline-block;
    width: 10px;
    height: 10px;
    background: #aaa;
    border-radius: 50%;
    &.actived {
      background: #00ff79;
    }
  }
}
</style>
src/pages/resourceManage/materialsCenter/list.vue
@@ -57,14 +57,20 @@
                <a-divider type="vertical"></a-divider>
                <a @click="removeLink(record)">解除关联</a>
              </template>
              <template v-if="record.dwgUrl">
              <a-divider type="vertical"></a-divider>
              <a @click="panelShow(record)">附件</a>
              <template v-if="record.rootModel">
                <a-divider type="vertical"></a-divider>
                <a @click="goHistory(record)">历史</a>
              </template>
              <!-- <template v-if="record.dwgUrl">
                <a-divider type="vertical"></a-divider>
                <a @click="dwgReview(record.dwgUrl)">预览</a>
                <template>
                  <a-divider type="vertical"></a-divider>
                  <a @click="downloadLog(record)">下载</a>
                </template>
              </template>
              </template> -->
            </template>
          </advance-table>
        </a-card>
@@ -116,6 +122,31 @@
        @cancel="cancelSubmit"
      ></submit-form>
    </a-modal>
    <!-- 附件 -->
    <a-modal
      :visible="fileListShow"
      title="附件"
      :destroyOnClose="true"
      :maskClosable="false"
      :width="650"
      :footer="null"
      @cancel="fileListCancel"
    >
      <files-table :list="fileList"></files-table>
      <div class="footer">
        <a-space>
          <a-button @click="fileListCancel">关闭</a-button>
          <a-upload
            :before-upload="beforeUpload"
            @change="fileUploadChange"
            :showUploadList="false"
            accept=".zip"
          >
            <a-button type="primary">上传附件</a-button>
          </a-upload>
        </a-space>
      </div>
    </a-modal>
  </div>
</template>
@@ -125,9 +156,10 @@
import ImageView from "@/pages/components/ImageView";
import EditLink from "./editLink";
import SubmitForm from "./SubmitForm";
import FilesTable from "@/pages/components/filesTable";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getList, zipParse } from "./apis";
import { uploadOthers, zipParse, getFileList } from "./apis";
import { dwgReview } from "@/pages/workplace/apis";
import { downloadLog } from "@/pages/system/logs/apis";
import { mapGetters } from "vuex";
@@ -139,8 +171,11 @@
  mixins: [WSMixin],
  data() {
    return {
      fileListShow: false,
      fileList: [],
      resShow: false,
      submitShow: false,
      currentObj: null,
      title: "",
      resList: [],
      // 是否为新增关联 false表示为删除关联
@@ -304,6 +339,7 @@
    EditLink,
    PartsUpload,
    SubmitForm,
    FilesTable,
  },
  methods: {
    onSearch(conditions, searchOptions) {
@@ -361,13 +397,17 @@
    searchData(res) {
      if (res) {
        // res = res.data;
        console.log(res);
        // console.log(res);
        let data = [];
        let total = 0;
        if (res.code && res.data) {
          data = res.data2.list.map((v) => {
            const model = v.subModel;
            const reg = /(.*)(-|_)A/;
            const rootModel = reg.test(model) ? model.match(reg)[1] : "";
            return {
              ...v,
              rootModel,
            };
          });
          total = res.data2.total;
@@ -438,6 +478,32 @@
          console.log(error);
        });
    },
    fileUploadChange(data) {
      let loading = this.$layer.loading();
      const formData = new FormData();
      const { id, subModel, subCode } = this.currentObj;
      const obj = {
        id,
        subCode,
        subModel,
      };
      formData.append("multipartFile", data.file);
      formData.append("materialStr", JSON.stringify(obj));
      uploadOthers(formData)
        .then((res) => {
          this.$layer.close(loading);
          const { code, data, msg } = res.data;
          if (code && data) {
            this.$message.success(msg);
          } else {
            this.$message.error(msg);
          }
        })
        .catch((error) => {
          this.$layer.close(loading);
          console.log(error);
        });
    },
    resCancel() {
      this.resShow = false;
    },
@@ -484,7 +550,33 @@
    },
    activeFN() {
      this.resize();
    }
    },
    panelShow(obj) {
      const { id, dwgUrl } = obj;
      this.currentObj = obj;
      getFileList(id).then((res) => {
        const { code, data, data2 } = res.data;
        let list = [];
        if (code && data) {
          list = data2;
        }
        this.fileList = list;
        if (dwgUrl) {
          this.fileList.unshift(dwgUrl);
        }
        this.fileListShow = true;
      });
    },
    fileListCancel() {
      this.fileListShow = false;
    },
    goHistory(record) {
      const { rootModel } = record;
      this.$router.push({
        path: "/resource/material-history",
        query: { rootModel },
      });
    },
  },
  watch: {
    update(n) {
@@ -545,6 +637,7 @@
.img-wraper {
  width: 80px;
  height: 50px;
  display: inline-block;
  .image-view {
    width: 100%;
    height: 100%;
@@ -558,4 +651,9 @@
/deep/table {
  table-layout: fixed;
}
.footer {
  padding-top: 10px;
  display: flex;
  justify-content: flex-end;
}
</style>
src/pages/resourceManage/product/apis.js
@@ -12,6 +12,16 @@
  })
}
/**
 * 产品列表 不分页
 * @returns
 */
export const getAllProducts = () => {
  return axios({
    method: "GET",
    url: "product/getUpBomUseProduct"
  })
}
/**
 * 产品下载(产品id和版本<当前最新版本>)
 * @returns 
 */
@@ -54,7 +64,7 @@
export const addProduct = (data) => {
  return axios({
    method: "POST",
    url: "worksheetMain/submit",
    url: "product",
    data
  })
}
src/pages/resourceManage/product/details/apis.js
@@ -4,22 +4,22 @@
 * 产品版本信息 列表
 * @returns 
 */
export const getVersions = (parentModel, customCode) => {
export const getVersions = (parentCode, customCode) => {
  return axios({
    method: "GET",
    url: "product/getProductVersion",
    params: { parentModel, customCode }
    params: { parentCode, customCode }
  })
}
/**
 * 产品指定版本详情
 * @returns 
 */
export const getInfo = (parentModel, version) => {
export const getInfo = (parentCode, version) => {
  return axios({
    method: "GET",
    url: "productBomHistory/getBoomByVersion",
    params: { parentModel, version }
    params: { parentCode, version }
  })
}
@@ -47,3 +47,14 @@
    params: { productId, version }
  })
}
/**
 * 产品指定版本 对比
 * @returns
 */
export const compare = (preProductId, productId) => {
  return axios({
    method: "GET",
    url: "productBomHistory/compare",
    params: { preProductId, productId }
  })
}
src/pages/resourceManage/product/details/details.vue
@@ -12,8 +12,8 @@
      <a-layout-header>
        <a-card>
          <a-descriptions title="产品信息">
            <a-descriptions-item label="母料型号">{{
              parentModel
            <a-descriptions-item label="母料编号">{{
              parentCode
            }}</a-descriptions-item>
            <!-- <a-descriptions-item label="母料名称">{{
              info.parentName
@@ -77,9 +77,7 @@
              <files-table slot="content" :list="otherDoc"></files-table>
              <a-button type="primary">其他附件</a-button>
            </a-popover>
            <a-button type="primary" @click="zipDownload"
              >bom下载</a-button
            >
            <a-button type="primary" @click="zipDownload">bom下载</a-button>
            <a-button
              type="primary"
              v-if="softwareList.length"
@@ -128,26 +126,50 @@
        </template>
      </a-table>
    </a-modal>
    <!-- 差异 -->
    <a-modal
      :visible="diffShow"
      :footer="null"
      :width="860"
      title="差异"
      :destroyOnClose="true"
      :maskClosable="false"
      @cancel="diffCancel"
    >
      <diff-list :list="diffData"></diff-list>
    </a-modal>
  </a-layout>
</template>
<script>
import ImageView from "@/pages/components/ImageView";
import FilesTable from "@/pages/components/filesTable";
import DiffList from "@/pages/components/diffList";
import List from "./list";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getVersions, zipDownload, getBomHistoryAndMaterial } from "./apis";
import {
  getVersions,
  zipDownload,
  getBomHistoryAndMaterial,
  compare,
} from "./apis";
import { setpHistoryEnable } from "../apis";
import { dwgReview } from "@/pages/workplace/apis";
import { downloadLog } from "@/pages/system/logs/apis";
import { mapGetters } from "vuex";
import createWs from "@/assets/js/websocket";
const WSMixin = createWs("version");
export default {
  name: "",
  mixins: [WSMixin],
  data() {
    return {
      lastId: undefined,
      diffShow: false,
      diffData: [],
      softwareDownloadShow: false,
      parentModel: this.$route.query.parentModel,
      parentCode: this.$route.query.parentCode,
      customCode: this.$route.query.customCode,
      versionList: [],
      info: {},
@@ -307,6 +329,7 @@
    List,
    ImageView,
    FilesTable,
    DiffList,
  },
  computed: {
    ...mapGetters("setting", ["affixed"]),
@@ -338,16 +361,38 @@
    },
  },
  methods: {
    getVersions() {
      getVersions(this.parentModel, this.customCode).then((res) => {
        res = res.data;
    getVersions(res) {
      if (res) {
        // res = res.data;
        const { code, data, data2 } = res;
        let list = [];
        if (code && data) {
          list = data2;
        }
        this.versionList = list;
      }
    },
    onWSOpen() {
      this.$nextTick(() => {
        this.sendMessage();
      });
    },
    sendMessage() {
      if (!this.isWSOpen) {
        return false;
      }
      const { parentCode, customCode } = this;
      let data = {
        parentCode,
        customCode,
      };
      console.log("=====9=", data, JSON.stringify(data));
      this.SOCKET.send(JSON.stringify(data));
    },
    onWSMessage(res) {
      res = JSON.parse(res.data);
      // // console.log(res, "=====111data");
      this.getVersions(res);
    },
    selectChanged(obj) {
      // console.log(obj, "--==");
@@ -359,7 +404,12 @@
      const {
        currentVersion: { id, version },
        info,
        lastId
      } = this;
      if (id == lastId) {
        return false;
      }
      this.lastId = id;
      this.spinning = true;
      getBomHistoryAndMaterial(id, version).then((res) => {
        let { code, data, data2, data3, data4 } = res.data;
@@ -404,7 +454,7 @@
        });
    },
    downloadLog(record) {
      const { parentModel, subModel, dwgUrl, softwareUrl } = record;
      const { parentCode, subModel, dwgUrl, softwareUrl } = record;
      const url = softwareUrl
        ? this.webUrl + softwareUrl
        : this.webUrl + dwgUrl;
@@ -415,10 +465,10 @@
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      downloadLog(parentModel, subModel);
      downloadLog(parentCode, subModel);
    },
    zipDownload() {
      // const { parentModel, currentVersion } = this;
      // const { parentCode, currentVersion } = this;
      const {
        currentVersion: { id, version },
      } = this;
@@ -453,28 +503,44 @@
    },
    diff(data) {
      console.log("比较两个版本", data);
      let params = data.map((v) => v * 1).sort();
      compare(...params).then((res) => {
        const { code, data, data2, data3 } = res.data;
        if (code) {
          this.diffData = {
            addList: data2.map((v) => v.materialObj),
            delList: data3.map((v) => v.materialObj),
            updateList: data,
          };
          this.diffShow = true;
        } else {
          this.$message.error("比较差异失败");
        }
      });
    },
    diffCancel() {
      this.diffShow = false;
    },
    changeStatus() {
      let {
        currentVersion: { customCode, parentCode, enabled, version },
      } = this;
      enabled = !enabled * 1;
      setpHistoryEnable({customCode, parentCode, enabled, version}).then((res) => {
        let {
          code,
          data,
        } = res.data;
        if (code && data) {
          this.$message.success('操作成功');
        } else {
          this.$message.error('操作失败');
      setpHistoryEnable({ customCode, parentCode, enabled, version }).then(
        (res) => {
          let { code, data } = res.data;
          if (code && data) {
            this.$message.success("操作成功");
          } else {
            this.$message.error("操作失败");
          }
        }
      });
      );
    },
  },
  mounted() {
    this.getVersions();
    this.sendMessage();
    // this.searchData();
    window.addEventListener("resize", this.resize);
  },
@@ -549,6 +615,7 @@
  .img-wraper {
    width: 80px;
    height: 50px;
    display: inline-block;
    .image-view {
      width: 100%;
      height: 100%;
src/pages/resourceManage/product/details/list.vue
@@ -4,7 +4,10 @@
      <a-card class="main">
        <!-- <a-input v-model="keyword" placeholder="输入关键字过滤" /> -->
        <!-- 列表 -->
        <a-button type="primary" :disabled="selectedKeys.length != 2" @click="diff"
        <a-button
          type="primary"
          :disabled="selectedKeys.length != 2"
          @click="diff"
          >比较差异</a-button
        >
        <div class="contain">
@@ -15,7 +18,7 @@
            @click="selectHandle(item)"
          >
            <span :class="['status', { actived: item.enabled }]"></span>
            <div class="version">{{ item.createTime }}</div>
            <div class="version">{{ item.versionTime }}</div>
            <a-checkbox
              @click.stop
              :checked="item.selected"
@@ -52,8 +55,12 @@
    // },
  },
  watch: {
    list(n) {
      if (n.length) {
    list(n, o) {
      this.selectedKeys = this.selectedKeys.filter((v) => n.some((val) => val.id == v));
      this.list.forEach((v) => {
        v.selected = this.selectedKeys.some((val) => val == v.id);
      });
      if ((n.length && !o.length) || !n.some((v) => v.id == this.currentV)) {
        this.selectHandle(this.list[0]);
      }
    },
@@ -143,7 +150,7 @@
  &.selected {
    transform: scale(0.98, 0.9);
    box-shadow: 0px 2px 5px -2px #000;
    color: #13C2C2;
    color: #13c2c2;
    font-weight: bold;
  }
  .version {
src/pages/resourceManage/product/list.vue
@@ -31,16 +31,9 @@
            }"
          >
            <template slot="title">
              <span class="title">产品中心</span>
              <a-space class="operator" style="margin-left: 1em">
                <a-upload
                  :before-upload="beforeUpload"
                  :showUploadList="false"
                  @change="pordUploadChange"
                  accept=".zip"
                >
                  <a-button type="primary">新增</a-button>
                </a-upload>
              <a-space class="operator">
                <span class="title">产品中心</span>
                <a-button type="primary" @click="uploadBom">新增</a-button>
              </a-space>
            </template>
            <template slot="isNormal" slot-scope="{ record }">
@@ -54,10 +47,7 @@
              <a-popover title="" trigger="hover">
                <a-space direction="vertical" slot="content">
                  <a-button type="primary" @click="edit(record)">编辑</a-button>
                  <a-button
                    type="primary"
                    @click="download(record)"
                  <a-button type="primary" @click="download(record)"
                    >下载</a-button
                  >
                  <a-button type="primary" @click="showCustom(record)"
@@ -168,7 +158,53 @@
    >
      <change-parts :parent-data="editObj" @close="cancel"></change-parts>
    </a-modal>
    <!-- 上传Bom -->
    <!-- 上传bom -->
    <a-modal
      :visible="bomUploadShow"
      :width="760"
      title="上传产品BOM"
      :destroyOnClose="true"
      :maskClosable="false"
      @cancel="bomUploadCancel"
      @ok="bomUploadOk"
    >
      <a-row class="upload" type="flex">
        <a-col flex="7em"></a-col>
        <a-col flex="1">
          <a-upload
            :before-upload="beforeUpload"
            @change="uploadChange"
            accept=".zip"
          >
            <a-button type="primary">上传BOM</a-button>
          </a-upload>
        </a-col>
      </a-row>
      <a-row type="flex">
        <a-col class="label" flex="7em"><span>基于产品</span></a-col>
        <a-col flex="1">
          <a-select
            class="from"
            show-search
            allowClear
            :filterOption="prodFilter"
            v-model="fromProd"
            placeholder="请选择是从哪款产品升级来的"
          >
            <a-select-option
              v-for="(item, key) in prodList"
              :key="'prod_' + key"
              :value="item.id"
              :title="item.name"
            >
              {{ item.parentName }} ({{ item.parentCode }})
              {{ item.customCode }}
            </a-select-option>
          </a-select>
        </a-col>
      </a-row>
    </a-modal>
    <!-- 解析Bom -->
    <a-modal
      :visible="prodUploadShow"
      :footer="null"
@@ -178,7 +214,19 @@
      :maskClosable="false"
      @cancel="prodUploadCancel"
    >
      <draw-upload :list="resList" :y="320" :no-footer="true"></draw-upload>
      <a-tabs type="card" tabPosition="left">
        <a-tab-pane key="1" tab="清单">
          <draw-upload
            class="bom-list"
            :list="resList"
            :y="320"
            :no-footer="true"
          ></draw-upload>
        </a-tab-pane>
        <a-tab-pane key="2" tab="差异">
          <diff-list :list="diffData"></diff-list>
        </a-tab-pane>
      </a-tabs>
      <prod-upload
        class="mt8"
        @ok="submit"
@@ -189,7 +237,7 @@
    <a-modal
      :visible="customShow"
      :footer="null"
      :width="700"
      :width="800"
      title="产品定制"
      :destroyOnClose="true"
      :maskClosable="false"
@@ -212,12 +260,13 @@
import DrawUpload from "@/pages/components/drawUpload";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { addProduct, downloadBom } from "./apis";
import { addProduct, downloadBom, getAllProducts } from "./apis";
import { productSoftwareSubmit } from "../software/apis";
import { zipParse } from "@/pages/workplace/myDraw/apis";
import { mapGetters } from "vuex";
import createWs from "@/assets/js/websocket";
import DiffList from "@/pages/components/diffList";
const WSMixin = createWs("product");
export default {
@@ -225,6 +274,10 @@
  mixins: [WSMixin],
  data() {
    return {
      fromProd: undefined,
      prodList: [],
      diffData: {},
      bomUploadShow: false,
      prodUploadShow: false,
      info: {
        nextUser: "",
@@ -242,7 +295,7 @@
      prodData: {},
      userList: [],
      file: null,
      title: "",
      // title: "",
      fileUrl: "",
      resList: [],
      uploadShow: false,
@@ -303,18 +356,18 @@
          width: 100,
          scopedSlots: { customRender: "isNormal" },
        },
        // {
        //   title: "创建时间",
        //   dataIndex: "createTime",
        //   key: "createTime",
        //   align: "center",
        //   noSearch: true,
        //   width: 160,
        // },
        {
          title: "创建时间",
          dataIndex: "createTime",
          key: "createTime",
          align: "center",
          noSearch: true,
          width: 160,
        },
        {
          title: "版本号",
          dataIndex: "version",
          key: "version",
          title: "版本时间",
          dataIndex: "versionTime",
          key: "versionTime",
          align: "center",
          noSearch: true,
          width: 160,
@@ -337,6 +390,7 @@
    ChangeParts,
    ProdUpload,
    DrawUpload,
    DiffList,
  },
  methods: {
    onSearch(conditions, searchOptions) {
@@ -366,10 +420,10 @@
    },
    goDetails(record) {
      // console.log(record);
      const { parentModel, customCode } = record;
      const { parentCode, customCode } = record;
      this.$router.push({
        path: "/resource/product-details",
        query: { parentModel, customCode },
        query: { parentCode, customCode },
      });
    },
    searchData(res) {
@@ -464,6 +518,7 @@
    },
    upload(record) {
      this.prodData = record;
      this.file = null;
      this.uploadShow = true;
    },
    uploadChange(data) {
@@ -508,8 +563,8 @@
            if (conditions[v]) {
              params["customCode"] = "";
              columns.forEach((val) => {
                if(val.dataIndex == 'customCode') {
                  val.search.value = '';
                if (val.dataIndex == "customCode") {
                  val.search.value = "";
                }
              });
            }
@@ -544,48 +599,20 @@
        this.userList = this.projectManagerList.map((item) => item);
      }
    },
    // 新增产品 bom导入
    pordUploadChange(data) {
      let loading = this.$layer.loading();
      const formData = new FormData();
      formData.append("file", data.file);
      zipParse(formData)
        .then((res) => {
          this.$layer.close(loading);
          let { code, data, data2, data3, msg } = res.data;
          if (code && data) {
            this.resList = data2;
            this.title = data3;
            this.fileUrl = msg;
            this.prodUploadShow = true;
            this.$message.success("解析成功");
          } else {
            this.$message.error(msg);
          }
        })
        .catch((error) => {
          this.$layer.close(loading);
          console.log(error);
        });
    },
    prodUploadCancel() {
      this.prodUploadShow = false;
    },
    submit(data) {
      // console.log(data);
      const { parentCode, parentModel, parentName } = this.resList[0];
      const { parentCode, parentModel, parentName, bomList } = this.resList;
      const param = {
        nextUser: data.nextUser,
        description: data.description,
        title: this.title,
        productApproving: {
          bomApprovingList: this.resList.map((v) => ({ ...v, id: undefined })),
          fileUrl: this.fileUrl,
          customCode: data.customCode,
          parentCode,
          parentModel,
          parentName,
        },
        versionTime: data.versionTime,
        bomList: bomList.map((v) => ({ ...v, id: undefined })),
        fileUrl: this.fileUrl,
        customCode: data.customCode,
        parentCode,
        parentModel,
        parentName,
      };
      addProduct(param).then((res) => {
        const { code, data, msg } = res.data;
@@ -605,9 +632,7 @@
      console.log(11);
      const { id, parentCode, parentModel, parentName } = this.customProd;
      const param = {
        nextUser: data.nextUser,
        description: data.description,
        title: `对产品${parentName}的定制`,
        versionTime: data.versionTime,
        productApproving: {
          bomApprovingList: [
            {
@@ -635,7 +660,72 @@
    },
    activeFN() {
      this.resize();
    }
    },
    uploadBom() {
      this.file = null;
      this.bomUploadShow = true;
    },
    bomUploadCancel() {
      this.bomUploadShow = false;
    },
    bomUploadOk() {
      if (!this.file) {
        this.$message.warn("请选择要上传的压缩包");
        return false;
      }
      let loading = this.$layer.loading();
      const formData = new FormData();
      formData.append("file", this.file);
      if (this.fromProd) {
        const prod = this.prodList
          .filter((v) => v.id == this.fromProd)
          .map((v) => ({
            parentCode: v.parentCode,
            customCode: v.customCode,
          }))[0];
        formData.append("baseStr", JSON.stringify(prod));
      }
      zipParse(formData)
        .then((res) => {
          this.$layer.close(loading);
          let { code, data, data2, data3, msg } = res.data;
          if (code && data) {
            this.resList = data2;
            this.diffData = {
              addList: data3.addList,
              delList: data3.deleteList,
              updateList: data3.diffList
            };
            this.fileUrl = msg;
            this.prodUploadShow = true;
            this.$message.success("解析成功");
          } else {
            this.$message.error(msg);
          }
        })
        .catch((error) => {
          this.$layer.close(loading);
          console.log(error);
        });
      this.bomUploadShow = false;
      this.$layer.close(loading);
    },
    getAllProducts() {
      getAllProducts().then((res) => {
        let { code, data, data2, msg } = res.data;
        let list = [];
        if (code && data) {
          list = data2;
        }
        this.prodList = list;
      });
    },
    prodFilter(str, option) {
      const txt = option.componentOptions.children[0].text;
      str = str.trim();
      const reg = new RegExp(str, "ig");
      return reg.test(txt);
    },
  },
  watch: {
    update(n) {
@@ -682,6 +772,7 @@
  mounted() {
    this.getUserByRoleId();
    this.sendMessage();
    this.getAllProducts();
    window.addEventListener("resize", this.resize);
  },
  destroyed() {
@@ -705,6 +796,7 @@
.img-wraper {
  width: 80px;
  height: 50px;
  display: inline-block;
  .image-view {
    width: 100%;
    height: 100%;
@@ -739,4 +831,16 @@
.mt8 {
  margin-top: 8px;
}
.from {
  width: 100%;
}
.label {
  display: flex;
  justify-content: flex-end;
  padding-right: 1em;
  align-items: center;
}
.bom-list /deep/ .ant-card-body {
  padding: 8px 24px;
}
</style>
src/pages/resourceManage/product/prodUpload.vue
@@ -14,7 +14,24 @@
      :rules="rules"
    >
      <a-row>
        <a-col :span="24">
        <a-col :span="10">
          <a-form-model-item
            class="ant-row-flex"
            label="版本时间"
            :labelCol="{ flex: '8em' }"
            :wrapperCol="{ flex: 1 }"
            prop="versionTime"
          >
            <a-date-picker
              format="YYYY-MM-DD HH:mm:ss"
              :allowClear="false"
              :disabled-date="disabledDate"
              :show-time="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }"
              v-model="info.versionTime"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="14">
          <a-form-model-item
            v-if="prodInfo"
            class="ant-row-flex"
@@ -23,9 +40,10 @@
            :wrapperCol="{ flex: 1 }"
            prop="customCode1"
          >
            <a-input
            <a-textarea
              placeholder="请输入定制单号"
              v-model.trim="info.customCode1"
              :rows="2"
            />
          </a-form-model-item>
          <a-form-model-item
@@ -36,47 +54,9 @@
            :wrapperCol="{ flex: 1 }"
            prop="customCode"
          >
            <a-input
            <a-textarea
              placeholder="请输入定制单号"
              v-model.trim="info.customCode"
            />
          </a-form-model-item>
        </a-col>
        <a-col :span="10">
          <a-form-model-item
            class="ant-row-flex"
            label="审核人"
            :labelCol="{ flex: '8em' }"
            :wrapperCol="{ flex: 1 }"
            prop="nextUser"
          >
            <a-select
              show-search
              v-model="info.nextUser"
              placeholder="请选择审核人"
            >
              <a-select-option
                v-for="(item, key) in userList"
                :key="'key' + key"
                :value="item.id"
                :title="item.name"
              >
                {{ item.name }}
              </a-select-option>
            </a-select>
          </a-form-model-item>
        </a-col>
        <a-col :span="14">
          <a-form-model-item
            class="ant-row-flex"
            label="工单描述"
            :labelCol="{ flex: '8em' }"
            :wrapperCol="{ flex: 1 }"
            prop="description"
          >
            <a-textarea
              placeholder="请输入工单描述"
              v-model="info.description"
              :rows="2"
            />
          </a-form-model-item>
@@ -85,13 +65,14 @@
    </a-form-model>
    <div class="modal-footer">
      <a-button type="danger" @click="cancel"> 取消 </a-button>
      <a-button type="primary" @click="ok"> 提交审核 </a-button>
      <a-button type="primary" @click="ok"> 提交 </a-button>
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import moment from 'moment';
export default {
  name: "",
  props: {
@@ -107,6 +88,7 @@
        description: "",
        customCode: "",
        customCode1: "",
        versionTime: moment().format('YYYY-MM-DD HH:mm:ss'),
      },
      rules: {
        nextUser: [
@@ -135,6 +117,7 @@
    ]),
  },
  methods: {
    moment,
    getUserByRoleId() {
      if (this.roles[0].id == 1002) {
        this.userList = this.generalManagerList.map((item) => item);
@@ -152,16 +135,20 @@
          return false;
        } else {
          let {
            info: { nextUser, description, customCode, customCode1 },
            info: { nextUser, description, customCode, customCode1, versionTime },
            prodInfo,
          } = this;
          let obj = prodInfo
            ? { nextUser, description, customCode: customCode1 }
            : { nextUser, description, customCode };
            ? { nextUser, description, customCode: customCode1, versionTime }
            : { nextUser, description, customCode, versionTime };
          this.$emit("ok", obj);
        }
      });
    },
    disabledDate(current) {
      // Can not select days before today and today
      return current > moment().endOf("day");
    },
  },
  mounted() {
src/pages/workplace/myDraw/apis.js
@@ -23,7 +23,7 @@
export const zipParse = (data) => {
  return axios({
    method: "POST",
    url: "bomApproving/zipParse",
    url: "product/zipParse",
    headers: {
      "Content-Type": "multipart/form-data"
    },
src/router/config.js
@@ -56,15 +56,15 @@
              name: '物料中心',
              component: () => import('@/pages/resourceManage/materialsCenter'),
            },
            // {
            //   path: 'details',
            //   name: '图纸详情',
            //   meta: {
            //     invisible: true,
            //     highlight: '/resource/center'
            //   },
            //   component: () => import('@/pages/resourceManage/details'),
            // },
            {
              path: 'material-history',
              name: '物料历史',
              meta: {
                invisible: true,
                highlight: '/resource/materials'
              },
              component: () => import('@/pages/resourceManage/materialsCenter/history'),
            },
            {
              path: 'product',
              name: '产品中心',