研发图纸文件管理系统-前端项目
he wei
2022-08-23 b5e45fc9e85db6b484f800df42708cb000b32c0d
DUA 大的调整
15 文件已重命名
7个文件已删除
1个文件已修改
7个文件已添加
2998 ■■■■ 已修改文件
src/pages/drawManage/drawCenter/DrawCenter.vue 469 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/drawCenter/apis.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/drawCenter/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/parts/apis.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/parts/editLink.vue 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/product/details/apis.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/product/list.vue 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/details/apis.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/details/details.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/details/index.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/details/yclist.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/SubmitForm.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/apis.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/editLink.vue 443 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/i18n.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/index.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/index.less 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/materialsCenter/list.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/apis.js 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/changeParts.vue 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/apis.js 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/details.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/index.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/details/list.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/index.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/product/list.vue 546 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/software/apis.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/software/index.js 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/resourceManage/software/list.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/config.js 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/drawManage/drawCenter/DrawCenter.vue
File was deleted
src/pages/drawManage/drawCenter/apis.js
File was deleted
src/pages/drawManage/drawCenter/index.js
File was deleted
src/pages/drawManage/parts/apis.js
File was deleted
src/pages/drawManage/parts/editLink.vue
File was deleted
src/pages/drawManage/product/details/apis.js
File was deleted
src/pages/drawManage/product/list.vue
File was deleted
src/pages/resourceManage/details/apis.js
src/pages/resourceManage/details/details.vue
src/pages/resourceManage/details/index.js
src/pages/resourceManage/details/yclist.vue
src/pages/resourceManage/materialsCenter/SubmitForm.vue
src/pages/resourceManage/materialsCenter/apis.js
New file
@@ -0,0 +1,64 @@
import axios from "@/assets/axios";
/**
 * 图纸查询分类检索
 * @returns
 */
// export const searchCadDrawer = (params, data) => {
//   return axios({
//     method: "POST",
//     url: "productBom/searchCadDrawer",
//     params,
//     data
//   })
// }
/**
 * 图纸打包下载
 * @returns
 */
// export const packageDoc = (pictureUrls) => {
//   return axios({
//     method: "POST",
//     url: "productBom/downloadCadDrawer",
//     responseType: "blob",
//     data: pictureUrls
//   })
// }
/**
 * 查询所有物料 分页
 */
export const getList = (pageCurr, pageSize, data) => {
  return axios({
    method: "GET",
    url: "material/getMaterialLimit",
    params: {
      pageCurr,
      pageSize,
      ...data
    }
  })
}
/**
 * 建立关联时查询所有的物料(不分页)
 */
export const getAllMaterialNoLimit = () => {
  return axios({
    method: "GET",
    url: "product/getAllMaterialNoLimit",
  })
}
/**
 * zip解析 新增物料
 * @returns
 */
 export const zipParse = (data) => {
  return axios({
    method: "POST",
    url: "componentApproving/zipParse",
    headers: {
      "Content-Type": "multipart/form-data"
    },
    data
  })
}
src/pages/resourceManage/materialsCenter/editLink.vue
New file
@@ -0,0 +1,443 @@
<template>
  <div class="">
    <a-form-model
      ref="formRef"
      name="advanced_search"
      class="ant-advanced-search-form"
      :model="info"
      :rules="rules"
    >
      <a-layout class="transbg">
        <a-layout-content>
          <a-row class="title row" type="flex" :gutter="gutter">
            <a-col flex="7em" class="text-right">
              <span>物料</span>
            </a-col>
            <a-col flex="auto">
              <div class="lab">{{ comData.subCode }} {{ comData.subName }}</div>
            </a-col>
          </a-row>
          <a-row class="row" type="flex" :gutter="gutter">
            <a-col flex="7em" class="text-right">
              <span>所属产品</span>
            </a-col>
            <a-col flex="1">
              <a-table
                :bordered="true"
                :columns="columns"
                :dataSource="prodList"
                size="small"
                :row-selection="{
                  selectedRowKeys,
                  onChange: onSelectChange,
                }"
                :pagination="false"
                rowKey="id"
              >
              </a-table>
            </a-col>
          </a-row>
          <a-row class="row" type="flex" :gutter="gutter">
            <a-col flex="7em" class="text-right">
              <span>替换件</span>
            </a-col>
            <a-col flex="1">
              <a-spin class="" :spinning="spinning" tip="拼命加载中...">
                <a-transfer
                  :data-source="optionsData"
                  show-search
                  :titles="['可用物料', '已选中']"
                  :list-style="{
                    width: '374px',
                    height: '200px',
                  }"
                  :operations="['添加', '移除']"
                  :operationStyle="{
                    width: '92px',
                    textAlign: 'center'
                  }"
                  :target-keys="targetKeys"
                  :render="(item) => `${item.subCode}  ${item.subName}`"
                  @change="handleChange"
                >
                  <span slot="notFoundContent"> 没数据 </span>
                </a-transfer>
              </a-spin>
            </a-col>
          </a-row>
          <a-row class="row" type="flex" :gutter="gutter">
            <a-col flex="7em" class="text-right">
              <span class="required">审核人</span>
            </a-col>
            <a-col flex="2">
              <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-col>
            <a-col flex="7em" class="text-right">
              <span>工单描述</span>
            </a-col>
            <a-col flex="3">
              <a-textarea
                placeholder="请输入图纸描述"
                v-model="info.description"
                :rows="4"
              />
            </a-col>
          </a-row>
        </a-layout-content>
        <a-layout-footer class="footer">
          <a-button key="cancel" @click="cancel">取消</a-button>
          <a-button type="primary" key="back" @click="checkForm">确定</a-button>
        </a-layout-footer>
      </a-layout>
    </a-form-model>
  </div>
</template>
<script>
import { componentRelatedSubmit } from "../product/apis";
import { getAllMaterialNoLimit, addCompentConnectBom } from "./apis";
import { mapGetters } from "vuex";
export default {
  name: "",
  props: {
    comData: {
      type: Object,
      default() {
        return {};
      },
    },
    isAdd: {
      type: Boolean,
      default: true,
    },
    prodList: {
      type: Array,
      default() {
        return [];
      },
    },
  },
  data() {
    const gutter = 10;
    return {
      gutter,
      targetKeys: [],
      optionsData: [],
      spinning: false,
      editShow: false,
      selectedRowKeys: [],
      selectedRows: [],
      columns: [
        {
          title: "母料编号",
          dataIndex: "parentCode",
          key: "parentCode",
          align: "center",
          width: 80,
        },
        {
          title: "定制单号",
          dataIndex: "customCode",
          key: "customCode",
          align: "center",
          width: 80,
        },
        {
          title: "母料名称",
          dataIndex: "parentName",
          key: "parentName",
          align: "center",
          width: 80,
        },
      ],
      userList: [],
      info: {
        subModel: "",
        removeId: "",
        replace: false,
        nextUser: "",
        description: "",
      },
      subList: [],
      rules: {
        subModel: [
          {
            required: true,
            message: "请选择要关联的产品子件",
            trigger: "blur",
          },
        ],
        removeId: [
          {
            required: true,
            message: "请选择要解除关联的产品子件",
            trigger: "blur",
          },
        ],
        nextUser: [
          {
            required: true,
            message: "请选择审核人",
            trigger: "blur",
          },
        ],
      },
    };
  },
  computed: {
    subObj() {
      const list = this.subList;
      let res = null;
      for (let i = 0, len = list.length; i < len; i++) {
        if (list[i].subModel == this.info.subModel) {
          res = list[i];
          break;
        }
      }
      return res;
    },
    linkList() {
      if (this.isAdd) {
        return [];
      } else {
        return this.comData.mproductHistorys;
      }
    },
    ...mapGetters("account", [
      "roles",
      "projectManagerList",
      "generalManagerList",
    ]),
  },
  components: {},
  methods: {
    ok() {
      let { curRecord, optionsData, targetKeys } = this;
      this.editShow = false;
      // curRecord.components = optionsData.filter((v) =>
      //   targetKeys.some((val) => v.id == val)
      // );
      optionsData = [];
      targetKeys = [];
    },
    editCancel() {
      this.editShow = false;
      this.optionsData = [];
      this.targetKeys = [];
    },
    showEdit() {
      this.editShow = true;
      this.spinning = true;
      this.getAllMaterialNoLimit();
    },
    handleChange(targetKeys, direction, moveKeys) {
      console.log(targetKeys, direction, moveKeys);
      this.targetKeys = targetKeys;
    },
    getAllMaterialNoLimit() {
      const {
        comData: { mproductHistorys: components },
      } = this;
      getAllMaterialNoLimit().then((res) => {
        res = res.data;
        const { code, data, data2 } = res;
        // console.log(res, "=====-00");
        let list = [];
        this.spinning = false;
        if (code && data) {
          list = data2.map((v) => {
            return {
              ...v,
              title: v.subModel,
              key: "" + v.subCode,
            };
          });
        }
        this.optionsData = [...list];
        this.targetKeys = components.map((v) => "" + v.subCode);
      });
    },
    getUserByRoleId() {
      if (this.roles[0].id == 1002) {
        this.userList = this.generalManagerList.map((item) => item);
      } else {
        this.userList = this.projectManagerList.map((item) => item);
      }
    },
    replaceChange(checked) {
      // console.log(checked, 99)
      this.info.replace = checked;
    },
    checkForm() {
      this.$refs.formRef.validate((valid) => {
        if (!valid) {
          this.$message.error("存在未通过检验的表单项");
          return false;
        } else {
          if (this.isAdd) {
            this.addLink();
          } else {
            this.removeLink();
          }
        }
      });
    },
    addLink() {
      let {
        subObj,
        info: { replace },
        comData: { id },
      } = this;
      let item = {
        componentId: id,
        parentModel: subObj.parentModel,
        subName: subObj.subName,
        quantity: subObj.quantity,
      };
      let addedList = [],
        removedList = [],
        replacedList = [];
      if (replace) {
        replacedList = [item];
      } else {
        addedList = [item];
      }
      let obj = {
        addedList,
        removedList,
        replacedList,
        main: {
          nextUser: this.info.nextUser,
          title: `对${subObj.parentModel}的修改`,
          description: this.info.description,
        },
      };
      componentRelatedSubmit(obj).then((res) => {
        res = res.data;
        let { code, data, data2, msg } = res;
        if (code && data) {
          this.$message.success("成功提交流程");
          this.$emit("close");
        } else {
          this.$message.error(`提交失败, ${msg}`);
        }
      });
    },
    removeLink() {
      let {
        linkList,
        info: { removeId },
        comData: { id, subModel, subName },
      } = this;
      let removeO = linkList.filter((v) => removeId == v.id)[0];
      let obj = {
        addedList: [],
        removedList: [
          {
            componentId: id,
            parentModel: removeO.parentModel,
            subName: removeO.subName,
            quantity: removeO.quantity,
          },
        ],
        replacedList: [],
        main: {
          nextUser: this.info.nextUser,
          title: `解除${subModel} ${subName} 与${removeO.parentModel} ${removeO.subName}的关联`,
          description: this.info.description,
        },
      };
      componentRelatedSubmit(obj).then((res) => {
        res = res.data;
        let { code, data, data2, msg } = res;
        if (code && data) {
          this.$message.success("成功提交流程");
          this.$emit("close");
        } else {
          this.$message.error(`提交失败, ${msg}`);
        }
      });
    },
    cancel() {
      this.$emit("close");
    },
    onSelectChange(selectedRowKeys, selectedRows) {
      // console.log("selectedRowKeys changed: ", selectedRowKeys, selectedRows);
      this.selectedRowKeys = selectedRowKeys;
      this.selectedRows = selectedRows;
    },
  },
  mounted() {
    // this.getAllSubWithOutComponent();
    this.spinning = true;
    this.getAllMaterialNoLimit();
    this.getUserByRoleId();
    console.log(this.linkList, "90909");
  },
};
</script>
<style lang="less" scoped>
.text-right {
  text-align: right;
  span::after {
    content: ":";
    position: relative;
    top: -0.5px;
    margin: 0 8px 0 2px;
  }
  span.required::before {
    display: inline-block;
    margin-right: 4px;
    color: #f5222d;
    font-size: 14px;
    font-family: SimSun, sans-serif;
    line-height: 1;
    content: "*";
  }
}
.transbg {
  background: transparent;
  .ant-layout-content {
    padding: 0 5px;
  }
}
.footer {
  padding: 4px;
  text-align: right;
}
.footer button + button {
  margin-left: 8px;
}
.title {
  /* text-align: center; */
  color: rgba(0, 0, 0, 0.85);
  font-size: 14px;
  padding-top: 4px;
  padding-bottom: 4px;
}
.row {
  background: #f0f0f0;
  margin-bottom: 10px;
  padding: 4px 0;
  border-radius: 4px;
}
/deep/.ant-transfer-operation button {
  margin-left: auto;
  margin-right: auto;
}
</style>
src/pages/resourceManage/materialsCenter/i18n.js
src/pages/resourceManage/materialsCenter/index.js
New file
@@ -0,0 +1,2 @@
import list from "./list";
export default list;
src/pages/resourceManage/materialsCenter/index.less
src/pages/resourceManage/materialsCenter/list.vue
File was renamed from src/pages/drawManage/parts/list.vue
@@ -15,7 +15,7 @@
            @refresh="onRefresh"
            @reset="onReset"
            :format-conditions="true"
            :scroll="{ x: 2700, y }"
            :scroll="{ x: 2500, y }"
            :pagination="{
              current: pageCurr,
              pageSize: pageSize,
@@ -31,7 +31,7 @@
            }"
          >
            <template slot="title">
              <span class="title">散装件(替换件)</span>
              <span class="title">物料中心</span>
              <a-space class="operator" style="margin-left: 1em">
                <a-upload
                  :before-upload="beforeUpload"
@@ -51,67 +51,15 @@
                ></image-view>
              </div>
            </template>
            <template slot="cProductHistorys" slot-scope="{ record }">
              <a-space direction="vertical">
                <template v-if="record.cProductHistorys.length <= 3">
                  <a-tag
                    v-for="(item, idx) in record.cProductHistorys"
                    :key="'pboms_' + idx"
                    :color="item.linkType == 2 ? '#87d068' : 'gray'"
                    >{{ item.parentModel }} {{ item.subName }}</a-tag
                  >
                </template>
                <template v-else>
                  <a-tag
                    v-for="(item, idx) in record.cProductHistorys.slice(0, 2)"
                    :key="'pboms_' + idx"
                    :color="item.linkType == 2 ? '#87d068' : 'gray'"
                    >{{ item.parentModel }} {{ item.subName }}</a-tag
                  >
                  <a-popover title="关联列表" trigger="hover">
                    <template #content>
                      <div class="" style="width: 500px">
                        <a-table
                          size="small"
                          :scroll="{ y: 500 }"
                          bordered
                          :columns="linkColumns"
                          :data-source="record.cProductHistorys"
                          :pagination="false"
                          rowKey="idx"
                        >
                          <template slot="linkType" slot-scope="text1, record1">
                            <a-tag
                              :color="record1.linkType == 2 ? 'blue' : 'red'"
                              >{{
                                record1.linkType == 2 ? "替换" : "关联"
                              }}</a-tag
                            >
                          </template>
                        </a-table>
                      </div>
                    </template>
                    <a-tag>全部</a-tag>
                  </a-popover>
                </template>
              </a-space>
            </template>
            <template slot="action" slot-scope="{ record }">
              <div>
                <a @click="addLink(record)">增加关联</a>
                <a-divider type="vertical"></a-divider>
                <a
                  v-if="record.cProductHistorys1.length"
                  v-if="record.mproductHistorys.length"
                  @click="removeLink(record)"
                  >解除关联</a
                >
                <a-popconfirm
                  v-else-if="!record.cProductHistorys.length"
                  title="是否删除?"
                  @confirm="remove(record)"
                >
                  <a>删除</a>
                </a-popconfirm>
              </div>
            </template>
          </advance-table>
@@ -124,11 +72,13 @@
      :footer="null"
      :title="editTitle"
      :destroyOnClose="true"
      :width="1200"
      :maskClosable="false"
      @cancel="cancel"
    >
      <edit-link
        :com-data="component"
        :prod-list="prodList"
        :is-add="isAdd"
        @close="cancel"
      ></edit-link>
@@ -175,9 +125,12 @@
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getList, zipParse } from "./apis";
import { mapGetters } from "vuex";
import createWs from "@/assets/js/websocket";
const WSMixin = createWs("material");
export default {
  name: "",
  mixins: [WSMixin],
  data() {
    return {
      resShow: false,
@@ -187,6 +140,7 @@
      // 是否为新增关联 false表示为删除关联
      isAdd: true,
      component: null,
      prodList: [],
      editShow: false,
      selectedRowKeys: [],
      selectedRows: [],
@@ -255,23 +209,6 @@
          align: "center",
          width: 80,
          noSearch: true,
        },
        {
          title: "封装类型/材质",
          dataIndex: "material",
          key: "material",
          align: "center",
          width: 180,
          noSearch: true,
        },
        {
          title: "关联列表",
          dataIndex: "cProductHistorys",
          key: "cProductHistorys",
          align: "center",
          width: 180,
          noSearch: true,
          scopedSlots: { customRender: "cProductHistorys" },
        },
        {
          title: "元件编号/料厚",
@@ -359,7 +296,7 @@
  },
  computed: {
    editTitle() {
      return this.isAdd ? "新增关联关系" : "解除关联关系";
      return this.isAdd ? "批量增加关联关系" : "批量解除关联关系";
    },
    ...mapGetters("setting", ["affixed"]),
  },
@@ -376,44 +313,63 @@
      // console.log(searchOptions);
      this.pageCurr = 1;
      this.conditions = conditions;
      this.searchData();
      this.sendMessage();
    },
    onPageChange(page, pageSize) {
      this.pageCurr = page;
      this.pageSize = pageSize;
      this.searchData();
      this.sendMessage();
    },
    onSizeChange(current, size) {
      this.pageCurr = 1;
      this.pageSize = size;
      this.searchData();
      this.sendMessage();
    },
    onRefresh(conditions) {
      this.conditions = conditions;
      this.searchData();
      this.sendMessage();
    },
    onReset(conditions) {
      this.conditions = conditions;
      this.searchData();
      this.sendMessage();
    },
    searchData() {
    onWSOpen() {
      this.$nextTick(() => {
        this.sendMessage();
      });
    },
    sendMessage() {
      if (!this.isWSOpen) {
        return false;
      }
      const { pageCurr, pageSize, conditions } = this;
      let params = {};
      Object.keys(conditions).forEach((v) => {
        params[v] = conditions[v];
      });
      getList(pageCurr, pageSize, params).then((res) => {
        res = res.data;
        // console.log(res);
      let data = {
        pageSize,
        pageCurr,
        ...params,
      };
      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.searchData(res);
    },
    searchData(res) {
      if (res) {
        // res = res.data;
        console.log(res);
        let data = [];
        let total = 0;
        if (res.code && res.data) {
          data = res.data2.list.map((v) => {
            return {
              ...v,
              cProductHistorys1: v.cProductHistorys.filter(
                (item) => item.linkType == 1
              ),
            };
          });
          total = res.data2.total;
@@ -423,17 +379,18 @@
        if (-1 == this.update) {
          this.update = Math.random();
        }
      });
      }
    },
    // 添加关联
    addLink(obj) {
      // console.log("addlink", obj);
      const { id } = obj;
      const { id, products } = obj;
      if (!id) {
        return false;
      }
      this.isAdd = true;
      this.component = obj;
      this.prodList = products;
      this.editShow = true;
    },
    removeLink(obj) {
@@ -533,7 +490,7 @@
    },
  },
  mounted() {
    this.searchData();
    this.sendMessage();
    window.addEventListener("resize", this.resize);
  },
  destroyed() {
src/pages/resourceManage/product/apis.js
File was renamed from src/pages/drawManage/product/apis.js
@@ -7,19 +7,19 @@
export const getList = (pageCurr, pageSize, data) => {
  return axios({
    method: "GET",
    url: "productBom/getAllBom",
    url: "product/getAllProduct",
    params: { pageCurr, pageSize, ...data }
  })
}
/**
 * 产品下载 最新版本
 * 产品下载(产品id和版本<当前最新版本>)
 * @returns 
 */
export const downloadBom = (parentModel) => {
export const downloadBom = (productId, version) => {
  return axios({
    method: "GET",
    url: "productBom/downloadBom",
    params: { parentModel },
    url: "product/downloadProduct",
    params: { productId, version },
    responseType: "blob"
  })
}
@@ -28,11 +28,11 @@
 * 根据母料型号查询子件信息及有关联的散装件信息
 * @returns 
 */
export const getSubByComponentProduct = (parentModel) => {
export const getBomAndMaterial = (productId, version) => {
  return axios({
    method: "GET",
    url: "productBom/getSubByComponentProduct",
    params: { parentModel }
    url: "product/getBomAndMaterial",
    params: { productId, version }
  })
}
src/pages/resourceManage/product/changeParts.vue
File was renamed from src/pages/drawManage/product/changeParts.vue
@@ -17,26 +17,6 @@
        <!-- :defaultValue="record.replaceObj.id" -->
        <a-row type="flex" align="middle">
          <a-col :span="20">
            <a-select
              v-model="record.replaceId"
              placeholder="请选替换件"
              style="width: 260px"
              :allowClear="true"
              :getPopupContainer="(tiggerNode) => tiggerNode.parentNode"
              @change="
                (value) => {
                  selectChange(value, record);
                }
              "
            >
              <a-select-option
                v-for="(item, idx) in record.components"
                :key="'components_' + idx"
                :value="item.id"
                :title="item.subName + ' ' + item.subModel"
                >{{ item.subName + " " + item.subModel }}</a-select-option
              >
            </a-select>
            <a-button class="btn" @click="editOptions(record)"
              >编辑关联</a-button
            >
@@ -109,14 +89,14 @@
        <a-transfer
          :data-source="optionsData"
          show-search
          :titles="['可用备件', '已选中']"
          :titles="['可用物料', '已选中']"
          :list-style="{
            width: '330px',
            height: '400px',
          }"
          :operations="['添加', '移除']"
          :target-keys="targetKeys"
          :render="(item) => `${item.subName}  ${item.title}`"
          :render="(item) => `${item.subCode}  ${item.subName}`"
          @change="handleChange"
        >
          <span slot="notFoundContent"> 没数据 </span>
@@ -127,8 +107,8 @@
</template>
<script>
import { getSubByComponentProduct, componentRelatedSubmit } from "./apis";
import { getComponentWithoutSub } from "../parts/apis";
import { getBomAndMaterial, componentRelatedSubmit } from "./apis";
import { getAllMaterialNoLimit } from "../materialsCenter/apis";
import { mapGetters } from "vuex";
export default {
@@ -206,32 +186,25 @@
      }
    },
    getSubByComponentProduct() {
      const { parentModel } = this.parentData;
      if (!parentModel) {
      const { id, version } = this.parentData;
      if (!id) {
        return false;
      }
      getSubByComponentProduct(parentModel).then((res) => {
      getBomAndMaterial(id, version).then((res) => {
        res = res.data;
        let list = [];
        console.log(res, "9-9-9-");
        if (res.code && res.data) {
          list = res.data2.map((v) => {
            let components = v.components.map((value) => ({
            let components = v.materials.map((value) => ({
              ...value,
              title: value.subModel,
              key: "" + value.id,
            }));
            return {
              ...v,
              subName: v.replaceStatus
                ? `${v.subName}(${v.oldSubName})`
                : v.subName,
              subName1: v.subName,
              oldSubName: v.replaceStatus ? v.oldSubName : v.subName,
              components,
              componentsBak: JSON.parse(JSON.stringify(components)),
              replaceList: [],
              replaceId: undefined,
            };
          });
        }
@@ -239,8 +212,8 @@
      });
    },
    checkList(obj) {
      const { parentModel, oldSubName, version, components } = obj;
      getComponentWithoutSub(parentModel, oldSubName, version).then((res) => {
      const { components } = obj;
      getAllMaterialNoLimit().then((res) => {
        res = res.data;
        const { code, data, data2 } = res;
        // console.log(res, "=====-00");
@@ -255,7 +228,7 @@
            };
          });
        }
        this.optionsData = [...list, ...components];
        this.optionsData = [...list];
        this.targetKeys = components.map((v) => "" + v.id);
      });
    },
src/pages/resourceManage/product/details/apis.js
New file
@@ -0,0 +1,37 @@
import axios from "@/assets/axios";
/**
 * 产品版本信息 列表
 * @returns
 */
export const getVersions = (parentModel, customCode) => {
  return axios({
    method: "GET",
    url: "product/getProductVersion",
    params: { parentModel, customCode }
  })
}
/**
 * 产品指定版本详情
 * @returns
 */
export const getInfo = (parentModel, version) => {
  return axios({
    method: "GET",
    url: "productBomHistory/getBoomByVersion",
    params: { parentModel, version }
  })
}
/**
 * 下载指定版本的产品
 * @returns
 */
export const zipDownload = (productId, version) => {
  return axios({
    method: "GET",
    url: "product/downloadProductHistory",
    params: { productId, version },
    responseType: 'blob'
  })
}
src/pages/resourceManage/product/details/details.vue
File was renamed from src/pages/drawManage/product/details/details.vue
@@ -8,13 +8,16 @@
        <a-card>
          <a-descriptions title="产品信息">
            <a-descriptions-item label="母料型号">{{
              info.parentModel
              parentModel
            }}</a-descriptions-item>
            <a-descriptions-item label="母料名称">{{
            <!-- <a-descriptions-item label="母料名称">{{
              info.parentName
            }}</a-descriptions-item>
            <a-descriptions-item label="母料编号">{{
              info.parentCode
            }}</a-descriptions-item> -->
            <a-descriptions-item label="定制单号" :span="2">{{
              customCode
            }}</a-descriptions-item>
          </a-descriptions>
        </a-card>
@@ -27,15 +30,16 @@
                <a-table
                  ref="aTable"
                  size="small"
                  :scroll="{ x: 1920, y }"
                  :scroll="{ x: 2420, y }"
                  bordered
                  :columns="columns"
                  :data-source="dataSource"
                  :pagination="false"
                  :expandRowByClick="true"
                  :rowClassName="
                    (record) => (1 == record.replaceStatus ? 'is-replace' : '')
                    (record) => (record.children && record.children.length ? 'is-replace' : '')
                  "
                  rowKey="subName"
                  rowKey="subcode"
                >
                  <template slot="pictureUrl" slot-scope="text">
                    <div class="img-wraper">
@@ -62,7 +66,7 @@
        <a-card>
          <template v-if="dataSource.length">
            <a-button type="primary" v-if="downloadFlag" @click="zipDownload"
              >打包下载</a-button
              >下载</a-button
            >
          </template>
        </a-card>
@@ -75,7 +79,8 @@
import ImageView from "@/pages/components/ImageView";
import List from "./list";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getInfo, zipDownload } from "./apis";
import { getVersions, zipDownload } from "./apis";
import { getBomAndMaterial } from "../apis";
import { dwgReview } from "@/pages/workplace/apis";
import { downloadLog } from "@/pages/system/logs/apis";
import { mapGetters } from "vuex";
@@ -85,7 +90,8 @@
  data() {
    return {
      parentModel: this.$route.query.parentModel,
      maxVersion: this.$route.query.version,
      customCode: this.$route.query.customCode,
      versionList: [],
      info: {},
      webUrl: getWebUrl(),
      record: {},
@@ -101,7 +107,8 @@
          dataIndex: "category",
          key: "category",
          align: "center",
          width: 80,
          fixed: "left",
          width: 180,
          searchAble: true,
        },
        {
@@ -220,14 +227,6 @@
    ImageView,
  },
  computed: {
    versionList() {
      const maxV = this.maxVersion;
      let arr = [];
      for (let i = maxV; i >= 0; i--) {
        arr.push(i);
      }
      return arr;
    },
    ...mapGetters("account", ["downloadFlag"]),
    ...mapGetters("setting", ["affixed"]),
  },
@@ -258,6 +257,17 @@
    },
  },
  methods: {
    getVersions() {
      getVersions(this.parentModel, this.customCode).then((res) => {
        res = res.data;
        const { code, data, data2 } = res;
        let list = [];
        if (code && data) {
          list = data2;
        }
        this.versionList = list;
      });
    },
    selectChanged(obj) {
      // console.log(obj, "--==");
      // this.record = obj;
@@ -265,24 +275,28 @@
      this.getInfo();
    },
    getInfo() {
      const { parentModel, currentVersion, info } = this;
      const {
        currentVersion: { id, version },
        info,
      } = this;
      this.spinning = true;
      getInfo(parentModel, currentVersion).then((res) => {
      getBomAndMaterial(id, version).then((res) => {
        res = res.data;
        console.log(res, '909009')
        let list = [];
        this.spinning = false;
        if (res.code && res.data) {
          list = res.data2.map((v) => ({
            ...v,
            subName: v.replaceStatus
              ? `${v.subName} (${v.oldSubName})`
              : v.subName,
            children: v.materials
          }));
          if (!info.parentModel) {
            const obj = list[0];
            debugger;
            info.parentModel = obj.parentModel;
            info.parentName = obj.parentName;
            info.parentCode = obj.parentCode;
            info.customCode = obj.customCode;
          }
        }
        this.dataSource = list;
@@ -321,8 +335,11 @@
      downloadLog(parentModel, subModel);
    },
    zipDownload() {
      const { parentModel, currentVersion } = this;
      zipDownload(parentModel, currentVersion).then((res) => {
      // const { parentModel, currentVersion } = this;
      const {
        currentVersion: { id, version }
      } = this;
      zipDownload(id, version).then((res) => {
        // console.log(res, "===========");
        let { headers, data, status } = res;
        if (200 == status && data) {
@@ -347,6 +364,7 @@
    },
  },
  mounted() {
    this.getVersions();
    // this.searchData();
    window.addEventListener("resize", this.resize);
  },
src/pages/resourceManage/product/details/index.js
src/pages/resourceManage/product/details/list.vue
File was renamed from src/pages/drawManage/product/details/list.vue
@@ -6,12 +6,12 @@
        <!-- 列表 -->
        <div class="contain">
          <div
            :class="['item', {'selected': currentV == item}]"
            :class="['item', {'selected': currentV == item.id}]"
            v-for="(item, idx) in list"
            :key="'item_' + idx"
            @click="selectHandle(item)"
          >
            <div class=""><span>版本号:</span> {{item}}</div>
            <div class="">{{item.createTime}}</div>
          </div>
        </div>
      </a-card>
@@ -42,6 +42,13 @@
    //   });
    // },
  },
  watch: {
    list(n) {
      if (n.length) {
        this.selectHandle(this.list[0]);
      }
    }
  },
  data() {
    return {
      // keyword: '',
@@ -51,13 +58,12 @@
  components: {},
  methods: {
    selectHandle(item) {
      this.currentV = item;
      this.currentV = item.id;
      this.$emit("select", item);
    },
  },
  mounted() {
    this.selectHandle(this.list[0]);
  },
};
</script>
src/pages/resourceManage/product/index.js
src/pages/resourceManage/product/list.vue
New file
@@ -0,0 +1,546 @@
<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"
            :loading="loading"
            title=""
            row-key="parentModel"
            @search="onSearch"
            @refresh="onRefresh"
            @reset="onReset"
            :format-conditions="true"
            :scroll="{ x: 400, 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="title">
              <span class="title">产品中心</span>
            </template>
            <template slot="action" slot-scope="{ record }">
              <a @click="upload(record)">上传软件</a>
              <a-divider type="vertical"></a-divider>
              <template v-if="downloadFlag">
                <a @click="download(record)">下载</a>
                <a-divider type="vertical"></a-divider>
              </template>
              <a @click="edit(record)">编辑</a>
              <a-divider type="vertical"></a-divider>
              <a @click="goDetails(record)">详情</a>
            </template>
          </advance-table>
        </a-card>
      </a-spin>
    </div>
    <!-- 上传软件 -->
    <a-modal
      :visible="uploadShow"
      :footer="null"
      :width="500"
      title="上传软件"
      :destroyOnClose="true"
      :maskClosable="false"
      @cancel="uploadCancel"
    >
      <div class="">
        <a-row class="title">
          <a-col :span="6" class="text-right">
            <span>产品信息</span>
          </a-col>
          <a-col :span="15" :offset="1">
            <div class="lab">
              {{ prodData.parentModel }} {{ prodData.parentName }}
            </div>
          </a-col>
        </a-row>
        <a-row class="upload">
          <a-col :span="15" :offset="7">
            <a-upload
              :before-upload="beforeUpload"
              @change="uploadChange"
              accept=".zip"
            >
              <a-button type="primary">上传软件</a-button>
            </a-upload>
          </a-col>
        </a-row>
        <a-form-model
          ref="formRef"
          name="advanced_search"
          class="ant-advanced-search-form"
          :model="info"
          :rules="rules"
        >
          <a-row>
            <a-col :span="24">
              <a-form-model-item
                label="审核人"
                :labelCol="{ span: 6 }"
                :wrapperCol="{ span: 15, offset: 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="24">
              <a-form-model-item
                label="工单描述"
                :labelCol="{ span: 6 }"
                :wrapperCol="{ span: 15, offset: 1 }"
                prop="description"
              >
                <a-textarea
                  placeholder="请输入工单描述"
                  v-model="info.description"
                  :rows="4"
                />
              </a-form-model-item>
            </a-col>
          </a-row>
        </a-form-model>
        <div class="modal-footer">
          <a-button type="danger" @click="uploadCancel"> 取消 </a-button>
          <a-button type="primary" @click="uploadSoftware"> 提交审核 </a-button>
        </div>
      </div>
    </a-modal>
    <!-- 编辑产品 -->
    <a-modal
      :visible="editShow"
      :footer="null"
      :width="1200"
      title="修改产品替换件信息"
      :destroyOnClose="true"
      :maskClosable="false"
      @cancel="cancel"
    >
      <change-parts :parent-data="editObj" @close="cancel"></change-parts>
    </a-modal>
  </div>
</template>
<script>
import AdvanceTable from "@/components/table/advance/AdvanceTable";
import ChangeParts from "./changeParts";
import getWebUrl from "@/assets/js/tools/getWebUrl";
import { getList, downloadBom } from "./apis";
import { productSoftwareSubmit } from "../software/apis";
import { mapGetters } from "vuex";
import createWs from "@/assets/js/websocket";
const WSMixin = createWs("product");
export default {
  name: "",
  mixins: [WSMixin],
  data() {
    return {
      info: {
        nextUser: "",
        description: "",
      },
      rules: {
        nextUser: [
          {
            required: true,
            message: "请选择审核人",
            trigger: "blur",
          },
        ],
      },
      prodData: {},
      userList: [],
      file: null,
      uploadShow: false,
      editShow: false,
      editObj: undefined,
      selectedRowKeys: [],
      selectedRows: [],
      spinning: false,
      loading: false,
      pageCurr: 1,
      pageSize: 10,
      total: 0,
      y: 400,
      update: -1,
      webUrl: getWebUrl(),
      conditions: {},
      columns: [
        {
          title: "母料编号",
          dataIndex: "parentCode",
          key: "parentCode",
          width: 130,
          align: "center",
          searchAble: true,
        },
        {
          title: "母料型号",
          dataIndex: "parentModel",
          key: "parentModel",
          align: "center",
          width: 180,
          searchAble: true,
        },
        {
          title: "母料名称",
          dataIndex: "parentName",
          key: "parentName",
          align: "center",
          width: 180,
          searchAble: true,
        },
        {
          title: "定制单号",
          dataIndex: "customCode",
          key: "customCode",
          align: "center",
          noSearch: true,
          width: 160,
        },
        {
          title: "创建时间",
          dataIndex: "createTime",
          key: "createTime",
          align: "center",
          noSearch: true,
          width: 160,
        },
        {
          title: "版本号",
          dataIndex: "version",
          key: "version",
          align: "center",
          noSearch: true,
          width: 160,
        },
        {
          title: "操作",
          dataIndex: "operation",
          key: "operation",
          align: "center",
          width: 228,
          fixed: "right",
          scopedSlots: { customRender: "action" },
        },
      ],
      dataSource: [],
    };
  },
  components: {
    AdvanceTable,
    ChangeParts,
  },
  methods: {
    onSearch(conditions, searchOptions) {
      // console.log(conditions);
      // console.log(searchOptions);
      this.pageCurr = 1;
      this.conditions = conditions;
      this.sendMessage();
    },
    onPageChange(page, pageSize) {
      this.pageCurr = page;
      this.pageSize = pageSize;
      this.sendMessage();
    },
    onSizeChange(current, size) {
      this.pageCurr = 1;
      this.pageSize = size;
      this.sendMessage();
    },
    onRefresh(conditions) {
      this.conditions = conditions;
      this.sendMessage();
    },
    onReset(conditions) {
      this.conditions = conditions;
      this.sendMessage();
    },
    goDetails(record) {
      // console.log(record);
      const { parentModel, customCode } = record;
      this.$router.push({
        path: "/resource/product-details",
        query: { parentModel, customCode },
      });
    },
    searchData(res) {
      if (res) {
        // res = res.data;
        // console.log(res, "======");
        let data = [];
        let total = 0;
        if (res.code && res.data) {
          data = res.data2.list;
          total = res.data2.total;
        }
        this.dataSource = data;
        this.total = total;
        if (-1 == this.update) {
          this.update = Math.random();
        }
      }
    },
    edit(obj) {
      console.log(obj, 99);
      this.editObj = obj;
      this.editShow = true;
    },
    download(obj) {
      const { id, version } = obj;
      downloadBom(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("操作失败");
        }
      });
    },
    beforeUpload() {
      return false;
    },
    uploadSoftware() {
      let obj = {
        approving: {
          parentModel: this.prodData.parentModel,
        },
        main: {
          nextUser: this.info.nextUser,
          title: `为产品${this.prodData.parentModel}上传软件`,
          description: this.info.description,
        },
      };
      if (!this.file) {
        this.$message.warning("请选择要上传的软件包");
        return false;
      }
      this.$refs.formRef.validate((valid) => {
        if (!valid) {
          this.$message.error("存在未通过检验的表单项");
          return false;
        } else {
          const formData = new FormData();
          formData.append("multipartFile", this.file);
          formData.append("mainDTOString", JSON.stringify(obj));
          productSoftwareSubmit(formData)
            .then((res) => {
              // this.$layer.close(loadinobjobj
              let rs = res.data;
              if (rs.code == 1 && rs.data) {
                this.resList = rs.data2;
                this.title = rs.data3;
                this.resShow = true;
                this.$message.success(rs.msg);
              } else {
                this.$message.error(rs.msg);
              }
            })
            .catch((error) => {
              // this.$layer.close(loading);
              console.log(error);
            });
        }
      });
    },
    upload(record) {
      this.prodData = record;
      this.uploadShow = true;
    },
    uploadChange(data) {
      const { file, fileList } = data;
      if (fileList.length > 1) {
        fileList.shift();
        // console.log(file, fileList, "90909090");
      }
      if (fileList.length) {
        // this.file = fileList[0];
        // console.log(file == fileList[0], file == fileList[0].originFileObj)
        this.file = fileList[0].originFileObj;
      } else {
        this.file = null;
      }
    },
    uploadCancel() {
      this.uploadShow = false;
    },
    cancel() {
      this.editShow = false;
    },
    resize() {
      setTimeout(() => {
        this.update = Math.random();
      }, 200);
    },
    onWSOpen() {
      this.$nextTick(() => {
        this.sendMessage();
      });
    },
    sendMessage() {
      if (!this.isWSOpen) {
        return false;
      }
      const { pageCurr, pageSize, conditions } = this;
      let params = {};
      Object.keys(conditions).forEach((v) => {
        params[v] = conditions[v];
      });
      let data = {
        pageSize,
        pageCurr,
        ...params,
      };
      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.searchData(res);
    },
    getUserByRoleId() {
      if (this.roles[0].id == 1002) {
        this.userList = this.generalManagerList.map((item) => item);
      } else {
        this.userList = this.projectManagerList.map((item) => item);
      }
    },
  },
  watch: {
    update(n) {
      if (-1 != n) {
        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);
            // console.log(h, "h",wraper, header, bar );
            this.y = h;
          }
        });
      }
    },
  },
  computed: {
    ...mapGetters("account", [
      "downloadFlag",
      "roles",
      "projectManagerList",
      "generalManagerList",
    ]),
  },
  mounted() {
    this.getUserByRoleId();
    this.sendMessage();
    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;
  .image-view {
    width: 100%;
    height: 100%;
    /deep/img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
}
/deep/table {
  table-layout: fixed;
}
.text-right {
  text-align: right;
  span::after {
    content: ":";
    position: relative;
    top: -0.5px;
    margin: 0 8px 0 2px;
  }
}
.upload {
  padding: 10px 0;
}
.modal-footer {
  text-align: right;
  button + button {
    margin-left: 8px;
  }
}
</style>
src/pages/resourceManage/software/apis.js
New file
@@ -0,0 +1,41 @@
import axios from "@/assets/axios";
/**
 * 查询所有的软件 列表
 * @returns
 */
export const getList = (pageCurr, pageSize, data) => {
  return axios({
    method: "GET",
    url: "productSoftware/getAllSoftware",
    params: { pageCurr, pageSize, ...data }
  })
}
/**
 * 产品软件审批提交
 * @returns
 */
export const productSoftwareSubmit = (data) => {
  return axios({
    method: "POST",
    url: "worksheetMain/productSoftwareSubmit",
    headers: {
      "Content-Type": "multipart/form-data"
    },
    data
  })
}
/**
 * 产品软件下载
 * @returns
 */
export const downLoadSoftware = (softwareName) => {
  return axios({
    method: "GET",
    url: "productSoftware/downLoadSoftware",
    responseType: "blob",
    params: {
      softwareName
    }
  })
}
src/pages/resourceManage/software/index.js
src/pages/resourceManage/software/list.vue
New file
@@ -0,0 +1,237 @@
<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="parentModel"
            @search="onSearch"
            @refresh="onRefresh"
            @reset="onReset"
            :format-conditions="true"
            :scroll="{ x: 400, 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="title">
              <span class="title">软件中心</span>
            </template>
            <template slot="action" slot-scope="{ record }">
              <template v-if="downloadFlag">
                <a @click="download(record)">下载</a>
                <a-divider type="vertical"></a-divider>
              </template>
            </template>
          </advance-table>
        </a-card>
      </a-spin>
    </div>
  </div>
</template>
<script>
import AdvanceTable from "@/components/table/advance/AdvanceTable";
import { getList, downLoadSoftware } from "./apis";
import { mapGetters } from "vuex";
export default {
  name: "",
  data() {
    return {
      spinning: false,
      loading: false,
      pageCurr: 1,
      pageSize: 10,
      total: 0,
      y: 400,
      update: -1,
      conditions: {},
      columns: [
        {
          title: "关联产品母料型号",
          dataIndex: "parentModel",
          key: "parentModel",
          align: "center",
          width: 180,
          searchAble: true,
        },
        {
          title: "软件名称",
          dataIndex: "softwareName",
          key: "softwareName",
          align: "center",
          noSearch: true,
          width: 160,
        },
        {
          title: "操作",
          dataIndex: "operation",
          key: "operation",
          align: "center",
          width: 168,
          fixed: "right",
          scopedSlots: { customRender: "action" },
        },
      ],
      dataSource: [],
    };
  },
  components: {
    AdvanceTable,
  },
  methods: {
    onSearch(conditions, searchOptions) {
      // console.log(conditions);
      // console.log(searchOptions);
      this.pageCurr = 1;
      this.conditions = conditions;
      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();
    },
    searchData() {
      const { pageCurr, pageSize, conditions } = this;
      let params = {};
      Object.keys(conditions).forEach((v) => {
        params[v] = conditions[v];
      });
      let data = {
        pageSize,
        pageCurr,
        ...params,
      };
      getList(pageCurr, pageSize, params).then((res) => {
        res = res.data;
        console.log(res);
        let data = [];
        let total = 0;
        if (res.code && res.data) {
          data = res.data2.list;
          total = res.data2.total;
        }
        this.dataSource = data;
        this.total = total;
        if (-1 == this.update) {
          this.update = Math.random();
        }
      });
    },
    download(obj) {
      const { parentModel, softwareName } = obj;
      downLoadSoftware(softwareName).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 ? decodeURI(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() {
      setTimeout(() => {
        this.update = Math.random();
      }, 200);
    },
  },
  watch: {
    update(n) {
      if (-1 != n) {
        // 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);
        //     // console.log(h, "h",wraper, header, bar );
        //     this.y = h;
        //   }
        // });
      }
    },
  },
  computed: {
    ...mapGetters("account", ["downloadFlag"]),
  },
  mounted() {
    this.searchData();
    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;
  }
}
/deep/table {
  table-layout: fixed;
}
</style>
src/router/config.js
@@ -41,8 +41,8 @@
          component: () => import('@/pages/workplace'),
        },
        {
          path: 'draw',
          name: '图纸管理',
          path: 'resource',
          name: '资源管理',
          meta: {
            icon: 'dashboard',
            authority: {
@@ -52,37 +52,37 @@
          component: BlankView,
          children: [
            {
              path: 'center',
              name: '图纸中心',
              component: () => import('@/pages/drawManage/drawCenter'),
              path: 'materials',
              name: '物料中心',
              component: () => import('@/pages/resourceManage/materialsCenter'),
            },
            {
              path: 'details',
              name: '图纸详情',
              meta: {
                invisible: true,
                highlight: '/draw/center'
              },
              component: () => import('@/pages/drawManage/details'),
            },
            {
              path: 'parts',
              name: '散装件(替换件)',
              component: () => import('@/pages/drawManage/parts'),
            },
            // {
            //   path: 'details',
            //   name: '图纸详情',
            //   meta: {
            //     invisible: true,
            //     highlight: '/resource/center'
            //   },
            //   component: () => import('@/pages/resourceManage/details'),
            // },
            {
              path: 'product',
              name: '产品中心',
              component: () => import('@/pages/drawManage/product'),
              component: () => import('@/pages/resourceManage/product'),
            },
            {
              path: 'product-details',
              name: '产品详情',
              meta: {
                invisible: true,
                highlight: '/draw/product'
                highlight: '/resource/product'
              },
              component: () => import('@/pages/drawManage/product/details'),
              component: () => import('@/pages/resourceManage/product/details'),
            },
            {
              path: 'software',
              name: '软件中心',
              component: () => import('@/pages/resourceManage/software'),
            }
          ]
        },