Browse Source

文档管理

2213980799@qq.com 1 year ago
parent
commit
68a6954d3e

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "el-table-infinite-scroll": "^2.0.2",
     "ele-admin": "^1.11.2",
     "element-china-category-data": "^1.0.4",
+    "element-tree-line": "^0.2.1",
     "element-ui": "2.15.7",
     "github-markdown-css": "^5.1.0",
     "highlight.js": "9.18.5",

BIN
src/assets/wjj.png


+ 113 - 0
src/components/addDoc/api/index.js

@@ -0,0 +1,113 @@
+import request from '@/utils/request';
+
+/**
+ * 查询文件夹分类数据
+ * @data data
+ */
+export async function getDocTreeListAPI(data) {
+  const res = await request.post('/fm/directory/selectTreeList', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+* 查询文件数据
+* @data data
+*/
+export async function filePageAPI(data) {
+  const res = await request.post('/fm/file/pageBusiness', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 保存
+ * @data data
+ */
+export async function fileSaveAPI(data) {
+  const res = await request.post('/fm/file/save', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 详情
+ * @id id
+ */
+export async function fileGetByIdAPI(id) {
+  const res = await request.get(`/fm/file/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * ids查询文件列表
+ * @data data
+ */
+ export async function queryIds(data) {
+  const res = await request.post('/fm/file/queryIds', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+
+
+
+// 获取编码树
+export async function selectTreeList(data) {
+  const res = await request.post(`/main/business_code_category/selectTreeList`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取右侧列表
+export async function listParentId(data) {
+  const res = await request.post(`/main/business_code_category/listPageParentId`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取右侧码段列表
+export async function pageSegment(data) {
+  const res = await request.post(`/main/business_code_manage/page`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+
+// 生成编码
+export async function getCode(id) {
+  const res = await request.get(`/main/business_code_category/applyForCode/`+id);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 上传文件
+ * @param file 文件
+ */
+ export async function uploadFileNew (data) {
+  const formData = new FormData();
+  formData.append('multiPartFile', data.multiPartFile);
+  formData.append('module', data.module);
+  const res = await request.post('/main/file/uploadFile', formData);
+  if (res.data.code === '0') {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 58 - 0
src/components/addDoc/browse.vue

@@ -0,0 +1,58 @@
+<template>
+  <ele-modal
+    :visible.sync="showEditFlag"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    append-to-body
+    :fullscreen="true"
+  >
+    <iframe
+      :src="fileUrl"
+      width="100%"
+      v-if="showEditFlag"
+      style="height: calc(100vh - 100px)"
+      frameborder="0"
+      allowfullscreen="true"
+    ></iframe
+  ></ele-modal>
+</template>
+
+<script>
+import { getFileType } from './util.js';
+
+export default {
+  data() {
+    return {
+      fileUrl: '',
+      showEditFlag: false
+    };
+  },
+
+  methods: {
+    open(row){
+      this.showEditFlag=true
+      this.setFileUrl(row)
+    },
+    setFileUrl(row) {
+      let file = row.storagePath[0];
+      let url = sessionStorage.filePath + file.storePath;
+      const fileExt = file.name.substr(file.name.lastIndexOf('.') + 1);
+      this.fileType = getFileType().includes(fileExt) ? 2 : 1;
+      if (this.fileType == 2) {
+        this.fileUrl =
+          '/fm/' +
+          (['dxf', 'dwg'].includes(fileExt) ? '2DViewer' : '3DViewer') +
+          '/view.html?url=' +
+          sessionStorage.filePath +
+          '/' +
+          row.outputNdsFiles;
+      } else {
+        this.fileUrl = '/kkfile/onlinePreview?url=' + btoa(url);
+        // 'http://192.168.1.107:18082/kkfile/onlinePreview?url=' + btoa(url);
+      }
+    }
+  }
+};
+</script>
+<style scoped lang="scss">
+</style>

+ 175 - 0
src/components/addDoc/doc_template.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="ele-body" style="height:60vh;overflow: auto;">
+    <el-card shadow="never" v-loading="loading">
+      <ele-split-layout
+        width="210px"
+        allow-collapse
+        :right-style="{ overflow: 'hidden' }"
+      >
+        <div>
+          <!-- 操作按钮 -->
+          <ele-toolbar class="ele-toolbar-actions">
+            <div style="margin: 5px 0"> </div>
+          </ele-toolbar>
+          <div class="ele-border-lighter sys-organization-list">
+            <el-tree
+              ref="tree"
+              :data="data"
+              highlight-current
+              :draggable="true"
+              node-key="id"
+              :props="{ label: 'name', children: 'sonDirectoryList' }"
+              :expand-on-click-node="false"
+              :default-expand-all="true"
+              @node-click="onNodeClick"
+            >
+              <span class="custom-tree-node" slot-scope="{ node, data }">
+                <ElementTreeLine
+                  :node="node"
+                  :showLabelLine="true"
+                  :indent="20"
+                >
+                  <img src="../../assets/wjj.png" />
+
+                  <span>{{ node.label }}</span>
+                </ElementTreeLine>
+              </span>
+            </el-tree>
+          </div>
+        </div>
+        <template v-slot:content>
+          <FileTableList
+            ref="tableRef"
+            :parentData="current"
+            :disabledTableList="disabledTableList"
+          />
+        </template>
+      </ele-split-layout>
+    </el-card>
+
+    <!-- {{current?.id}} -->
+  </div>
+</template>
+
+<script>
+//
+import FileTableList from './file-table-listTemplate.vue';
+import { getDocTreeListAPI } from './api';
+import { mapGetters } from 'vuex';
+
+import ElementTreeLine from 'element-tree-line';
+// css
+import 'element-tree-line/dist/style.scss';
+export default {
+  components: { FileTableList, ElementTreeLine },
+
+  data() {
+    return {
+      loading: true,
+      // 列表数据
+      data: [],
+      fileType:0,
+      // 选中数据
+      current: {}
+    };
+  },
+  props: {
+    lcyStatus: '', //1:文档工作区 2:文档归档区 3:文档发布区 4:文档废止区
+
+    disabledTableList: {
+      //已选择列表
+      default: () => []
+    }
+  },
+  computed: {
+    ...mapGetters(['user'])
+  },
+  created() {
+    this.query();
+  },
+
+  methods: {
+    /* 查询 */
+    async query() {
+      this.loading = true;
+      let query = {
+        type: this.fileType,
+        currentUserId: this.user.info.userId
+      };
+      this.data = await getDocTreeListAPI(query);
+
+      this.current = null;
+      this.$nextTick(() => {
+        this.$refs.tree.setCurrentKey(this.data[0].id);
+
+        this.onNodeClick(this.data[0]);
+      });
+      this.loading = false;
+    },
+    /* 选择数据 */
+    onNodeClick(row) {
+      if (row) {
+        this.current = row;
+        this.$nextTick(() => {
+          this.$refs.tableRef.reload();
+        });
+      } else {
+        this.current = null;
+      }
+    },
+
+    getTableList() {
+      return this.$refs.tableRef.getTableList();
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.sys-organization-list {
+  height: calc(100vh - 180px);
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  overflow: auto;
+}
+
+.sys-organization-list :deep(.el-tree-node__content) {
+  height: 30px;
+
+  & > .el-tree-node__expand-icon {
+    margin-left: 10px;
+  }
+}
+.custom-tree-node {
+  display: flex;
+  align-items: center;
+}
+:deep(.el-popover) {
+  min-width: 50px;
+  position: fixed;
+}
+:deep(.el-link--inner) {
+  padding: 3px 0;
+}
+// :deep(.element-tree-node-line-hor) {
+//   border-bottom: 1px solid #dcdfe6;
+// }
+// :deep(.element-tree-node-line-ver) {
+//   border-left: 1px solid #dcdfe6;
+// }
+</style>
+<style lang="scss">
+.el-tree
+  > .el-tree-node
+  > .el-tree-node__content:nth-of-type(1)
+  .element-tree-node-line-hor {
+  border: none;
+}
+.el-tree
+  > .el-tree-node
+  > .el-tree-node__content:nth-of-type(1)
+  .element-tree-node-line-ver {
+  border: none;
+}
+</style>

+ 233 - 0
src/components/addDoc/file-edit.vue

@@ -0,0 +1,233 @@
+<!-- 用户编辑弹窗 -->
+<template>
+  <ele-modal
+    width="500px"
+    :visible.sync="showEditFlag"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    append-to-body
+    @close="cancel"
+    :title="title"
+    ref="Emodal"
+  >
+    <el-form ref="form" :model="form" :rules="rules" label-width="82px">
+      <el-row :gutter="15">
+        <el-col :span="24">
+          <el-form-item label="编码" prop="code">
+            <el-input v-model="form.code" placeholder="请申请编码" disabled>
+              <template slot="append">
+                <el-link :underline="false" @click.native="getCodeOpen"
+                  >申请编码
+                </el-link></template
+              >
+            </el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="文档类型" prop="type">
+            <DictSelection
+              dictName="文档类型"
+              v-model="form.type"
+            ></DictSelection>
+          </el-form-item>
+        </el-col>
+        <!-- <el-col :span="24">
+          <el-form-item label="上传方式" prop="SCFS">
+            <el-radio-group v-model="SCFS">
+              <el-radio :label="1">手动上传</el-radio>
+              <el-radio :label="2">选择模板</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col> -->
+        <el-col :span="24">
+          <el-form-item label="文档名称" prop="name">
+            <el-input
+              v-model="form.name"
+              placeholder="请输入文档名称"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="文档" prop="storagePath">
+            <div style="display: flex; align-items: center">
+              <fileUpload
+                v-model="form.storagePath"
+                module="main"
+                :limit="1"
+                @fileChange="fileChange"
+              >
+              </fileUpload>
+            </div>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="文档位置" prop="directoryId">
+            <el-cascader
+              style="width: 100%"
+              v-model="form.directoryId"
+              :options="folderList"
+              :props="{
+                value: 'id',
+                label: 'name',
+                children: 'sonDirectoryList',
+                emitPath: false,
+                checkStrictly: true
+              }"
+            ></el-cascader>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注" prop="remark">
+            <el-input
+              v-model="form.remark"
+              type="textarea"
+              placeholder="请输入"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <template v-slot:footer>
+      <el-button @click="cancel">取消</el-button>
+      <el-button type="primary" :loading="loading" @click="save">
+        确认
+      </el-button>
+    </template>
+    <getCode ref="getCode" @success="success"></getCode>
+  </ele-modal>
+</template>
+
+<script>
+import { fileSaveAPI,getDocTreeListAPI } from './api';
+import FileUpload from './fileUpload.vue';
+import { setFolderList } from './util.js';
+import getCode from './getCode.vue';
+import { mapGetters } from 'vuex';
+
+export default {
+  components: { FileUpload, getCode },
+
+  data() {
+    const defaultForm = {
+      name: '', //名称
+      type: '', //类型
+      sizeUnit: '', //大小,
+      unit: '', //单位
+      remark: '', //备注
+      status: '', //状态
+      storagePathId: '',
+      directoryId: '',
+      storagePath: [],
+      id: '',
+      lcyStatus: 1,
+      fileType:0
+    };
+    return {
+      rules: {
+        name: [{ required: true, message: '请输入', trigger: 'blur' }],
+        code: [{ required: true, message: '请输入', trigger: 'blur' }],
+        directoryId: [{ required: true, message: '请选择', trigger: 'blur' }],
+        storagePath: [{ required: true, message: '请选择', trigger: 'blur' }]
+      },
+      templateVisible: false,
+      folderList: [],
+      defaultForm,
+      code: '',
+      // 表单数据
+      form: { ...defaultForm },
+
+      // 提交状态
+      loading: false,
+      showEditFlag: false,
+      title: '新建附件'
+    };
+  },
+  computed: {
+    // 是否开启响应式布局
+    styleResponsive() {
+      return this.$store.state.theme.styleResponsive;
+    },
+    ...mapGetters(['user'])
+  },
+  async created() {
+    let query = {
+      type: 0,
+      currentUserId: this.user.info.userId
+    };
+    this.folderList = await getDocTreeListAPI(query);
+    setFolderList(this.folderList); //权限过滤
+  },
+  methods: {
+    async open() {
+      this.showEditFlag = true;
+    },
+    getCodeOpen() {
+      this.$refs.getCode.open();
+    },
+    fileChange(file) {
+      this.form.name = file.name.replace(/\.[^/.]+$/, '');
+    },
+    success(code) {
+      this.code = code;
+      this.$nextTick(() => {
+        this.$set(this.form, 'code', code);
+      });
+    },
+    /* 保存编辑 */
+    save() {
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) {
+          return false;
+        }
+
+        const data = {
+          ...this.form,
+        };
+
+        this.loading = true;
+        fileSaveAPI(data)
+          .then((msg) => {
+            this.loading = false;
+
+            this.cancel();
+            this.$emit('done',msg);
+          })
+          .catch((e) => {
+            this.loading = false;
+          });
+      });
+    },
+
+    cancel() {
+      this.form = { ...this.defaultForm };
+      this.$refs.form.clearValidate();
+      this.showEditFlag = false;
+    }
+  }
+};
+</script>
+<style scoped lang="scss">
+.aaa {
+  width: 100%;
+
+  ::v-deep .upload-demo {
+    width: 100%;
+
+    .el-upload--text {
+      width: 100%;
+
+      button {
+        width: 100%;
+        background: #ffffff;
+        border: 1px solid #dbdbdb;
+        border-radius: 5px;
+      }
+    }
+
+    .el-upload-list {
+      transform: translate(10px, -39px);
+      position: absolute;
+    }
+  }
+}
+</style>

+ 201 - 0
src/components/addDoc/file-table-listTemplate.vue

@@ -0,0 +1,201 @@
+<template>
+  <div>
+    <!-- 数据表格 -->
+    <ele-pro-table
+      ref="table"
+      :columns="columns"
+      :datasource="datasource"
+      tool-class="ele-toolbar-form"
+      :needPage="false"
+      row-key="id"
+      :selection.sync="selection"
+      :toolbar="false"
+    >
+         <!-- 操作列 -->
+         <template v-slot:action="{ row }">
+        <el-link
+          type="primary"
+          :underline="false"
+          icon="el-icon-edit"
+          @click="browseOpen(row)"
+        >
+          浏览
+        </el-link>
+
+      </template>
+    </ele-pro-table>
+    <browse  ref="browseRef"></browse>
+
+  </div>
+</template>
+
+<script>
+import { filePageAPI } from './api';
+import browse from './browse.vue';
+
+export default {
+  components: { browse },
+  props: {
+    // 上级
+    parentData: {
+      type: Object,
+      default: () => {}
+    },
+   
+    disabledTableList: {
+      //已选择列表
+      default: () => []
+    }
+  },
+
+  data() {
+    return {
+      selection: [],
+      columns: [
+        {
+          width: 45,
+          type: 'selection',
+          columnKey: 'selection',
+          align: 'center',
+          selectable: (row, index) => {
+            return !this.disabledTableList
+              .map((item) => item.id)
+              .includes(row.id);
+          }
+        },
+        {
+          label: '编码',
+          prop: 'code',
+          width: 180,
+          align: 'center',
+          fixed: 'left',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'name',
+          label: '文档名称',
+          align: 'center',
+          slot: 'name',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'storagePath',
+          label: '文件名称',
+          align: 'center',
+
+          showOverflowTooltip: true,
+          minWidth: 200,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue[0]?.name;
+          }
+        },
+        {
+          prop: 'version',
+          label: '版本',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'checkOutUserName',
+          label: '检出人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'checkOutStatus',
+          label: '检出状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue == 1 ? '已检出' : '';
+          }
+        },
+        {
+          prop: 'checkOutTime',
+          label: '检出时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 160
+        },
+        {
+          prop: 'createUserName',
+          label: '创建人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'createTime',
+          label: '创建时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 160,
+          formatter: (_row, _column, cellValue) => {
+            return this.$util.toDateString(cellValue);
+          }
+        },
+        {
+          prop: 'updateUserName',
+          label: '修改人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'updateTime',
+          label: '修改时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 160
+        },
+        {
+          prop: 'sizeUnit',
+          label: '文档大小',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 150,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true,
+          fixed: 'right'
+        }
+      ]
+    };
+  },
+  created() {},
+
+  methods: {
+    /* 表格数据源 */
+    datasource({ page, limit, where, order }) {
+      return filePageAPI({
+        ...where,
+        ...order,
+        pageNum: page,
+        size: limit,
+        directoryId: this.parentData?.id
+      });
+    },
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({ pageNum: 1, where: where });
+    },
+
+    browseOpen(row) {
+      this.$refs.browseRef.open(row);
+    },
+    getTableList() {
+      return JSON.parse(JSON.stringify(this.selection));
+    }
+  }
+};
+</script>

+ 262 - 0
src/components/addDoc/fileUpload.vue

@@ -0,0 +1,262 @@
+<template>
+  <div class="upload-file">
+    <el-upload
+      class="upload-demo"
+      action="#"
+      v-loading="loading"
+      element-loading-text="上传中"
+      :http-request="handlRequest"
+      :before-remove="beforeRemove"
+      :on-remove="handleRemove"
+      :on-preview="handleItem"
+      :multiple="multiple"
+      :before-upload="beforeUpload"
+      :file-list="fileList"
+      :show-file-list="!showLib"
+      :disabled="disabled"
+    >
+      <!-- <slot>
+        <el-button :disabled="disabled" type="primary" icon="el-icon-plus" size="mini">点击上传</el-button>
+      </slot> -->
+      <el-button
+        slot="trigger"
+        :disabled="disabled"
+        type="primary"
+        icon="el-icon-plus"
+        size="mini"
+        >点击上传</el-button
+      >
+      <slot name="templateBtn"> </slot>
+    </el-upload>
+  </div>
+</template>
+
+<script>
+import {
+  getFileList,
+  getFile,
+  removeFile
+} from '@/api/system/file/index.js';
+import {
+  uploadFileNew,
+} from './api';
+import { getImageUrl, getImagePath } from '@/utils/file';
+export default {
+  props: {
+    value: {
+      type: [Array, String],
+      default: () => []
+    },
+    multiple: {
+      type: Boolean,
+      default: false
+    },
+    // 所属模块
+    module: {
+      type: String,
+      required: true
+    },
+    // 文档库
+    showLib: {
+      type: Boolean,
+      default: false
+    },
+    // 限制数量
+    limit: {
+      type: Number,
+      default: -1
+    },
+    // 限制大小 mb
+    size: {
+      type: Number,
+      default: 1000
+    },
+    disabled: {
+      default: false,
+      type: Boolean
+    }
+  },
+  data() {
+    return {
+      documentVisible: false,
+      selectItem: null,
+      loading: false,
+      documentForm: {
+        name: ''
+      },
+      columns: [
+        {
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center'
+        },
+        {
+          label: '文档名称',
+          prop: 'name',
+          minWidth: '180',
+          showOverflowTooltip: true
+        },
+        {
+          label: '文档类型',
+          prop: 'type'
+        },
+        {
+          label: '系统'
+        },
+        {
+          label: '储存路径',
+          prop: 'storePath',
+          minWidth: '180',
+          showOverflowTooltip: true
+        },
+        {
+          label: '模块名',
+          prop: 'module'
+        },
+        {
+          label: '上传时间',
+          prop: 'createTime'
+        }
+      ]
+    };
+  },
+  computed: {
+    fileList: {
+      set(val) {
+        // console.log(val);
+        this.$emit(
+          'input',
+          val.map((item) => ({
+            ...item,
+            url: getImagePath(item.url)
+          }))
+        );
+      },
+      get() {
+        // console.log(this.value, 2);
+        if (!Array.isArray(this.value)) return [];
+        const arr =
+          (this.value &&
+            this.value.map((item) => ({
+              ...item,
+              url: getImageUrl(item.url)
+            }))) ||
+          [];
+        return arr;
+      }
+    }
+  },
+
+  methods: {
+    //点击查看图片
+    handleItem(file) {
+      getFile({ objectName: file.storePath }, file.name);
+    },
+    delFileList() {
+      this.$emit('input', []);
+    },
+    handleOpenLib() {
+      this.documentVisible = true;
+      this.$nextTick(() => {
+        this.reload();
+      });
+    },
+    //图文档勾选
+    submitDocument() {
+      this.$emit('input', [
+        { url: this.selectItem.storePath, ...this.selectItem }
+      ]);
+      this.documentVisible = false;
+    },
+    datasource({ page, limit }) {
+      return getFileList({
+        ...this.documentForm,
+        pageNum: page,
+        size: limit
+      });
+    },
+    reload() {
+      this.$refs.table.reload();
+    },
+    beforeRemove(file) {
+      if (file.id) {
+        return removeFile({
+          fileId: file.id
+        }).then(() => {
+          return true;
+        });
+        return true;
+      } else {
+        return true;
+      }
+    },
+    handleRemove(file, fileList) {
+      this.fileList = fileList;
+    },
+    beforeUpload(file) {
+      // if (file.size / 1024 / 1024 > this.size) {
+      //   this.$message.error(`大小不能超过 ${this.size}MB`);
+      //   return false;
+      // }
+
+      if (this.limit > 0 && this.fileList.length === this.limit) {
+        this.$message.error(`最多上传 ${this.limit}个文件`);
+        return false;
+      }
+      this.loading = true;
+      return uploadFileNew({
+        module: this.module,
+        multiPartFile: file
+      })
+        .then((res) => {
+          if (res.data) {
+            this.$emit('input', [
+              ...(this.value || []),
+              { ...file, url: res.data.storePath, ...res.data }
+            ]);
+          }
+          this.$emit('fileChange', res.data);
+          return res.data;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    handlRequest() {
+      return Promise.resolve();
+    }
+    // onSuccess(response, file, fileList){
+    //   alert(1)
+    //    this.$emit('fileChange',file)
+    // },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.upload-file {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+
+  .lib {
+    margin-left: 12px;
+  }
+
+  .imgs-box {
+    margin-left: 10px;
+    flex: 1;
+  }
+  .imgs-box .imgs-p {
+    height: 30px;
+    background: #f0f3f3;
+    line-height: 30px;
+    min-width: 480px;
+    margin-bottom: 5px;
+    padding: 0 10px;
+    display: flex;
+    justify-content: space-between;
+  }
+}
+</style>

+ 176 - 0
src/components/addDoc/getCode.vue

@@ -0,0 +1,176 @@
+<!-- 用户编辑弹窗 -->
+<template>
+  <ele-modal
+    width="500px"
+    :visible.sync="showEditFlag"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    append-to-body
+    @close="cancel"
+    title="申请编码"
+  >
+    <el-form ref="form" :model="form" :rules="rules" label-width="82px">
+      <el-row :gutter="15">
+        <el-col :span="24">
+          <el-form-item label="编码分类" prop="type">
+            <ele-tree-select
+              clearable
+              :data="list"
+              v-model="form.type"
+              placeholder="请选择"
+              default-expand-all
+              labelKey="name"
+              childrenKey="sonDirectoryList"
+              valueKey="id"
+              @change="typeChange"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="编码方案" prop="type1">
+            <el-select
+              v-model="form.type1"
+              placeholder="请选择"
+              style="width: 100%"
+              @change="type1Change"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="编码预览" prop="code">
+            <el-input v-model="form.code" disabled></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <headerTitle title="编码码段"></headerTitle>
+    <template v-slot:footer>
+      <el-button @click="cancel">取消</el-button>
+      <el-button type="primary" @click="save"> 确认 </el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script>
+import {
+  selectTreeList,
+  listParentId,
+  getCode
+} from './api';
+import headerTitle from '@/components/header-title/index.vue';
+
+export default {
+  data() {
+    return {
+      rules: {
+        type: [{ required: true, message: '请选择', trigger: 'blur' }],
+        type1: [{ required: true, message: '请选择', trigger: 'blur' }],
+        code: [{ required: true, message: '请申请', trigger: 'blur' }]
+      },
+      list: [],
+      options: [],
+      // 表单数据
+      form: {
+        type: '',
+        code: '',
+        type1: ''
+      },
+
+      showEditFlag: false
+    };
+  },
+  computed: {
+    // 是否开启响应式布局
+    styleResponsive() {
+      return this.$store.state.theme.styleResponsive;
+    }
+  },
+  components: {
+    headerTitle
+  },
+  created() {},
+  methods: {
+    async open() {
+      this.list = await selectTreeList();
+      this.setTree(this.list);
+      this.showEditFlag = true;
+    },
+    setTree(data) {
+      data.forEach((item) => {
+        item.sonDirectoryList = item.sonDirectoryList.filter(
+          (item) => item.type == 1
+        );
+        if (item.sonDirectoryList.length > 0) {
+          this.setTree(item.sonDirectoryList);
+        }
+      });
+    },
+    async typeChange(val) {
+      let data = await listParentId({
+        pageNum: 1,
+        size: 100,
+        parentId: val
+      });
+      this.options = data.list.filter((item) => item.type == 2);
+      this.form.type1 = '';
+    },
+    async type1Change(val) {
+      this.form.code = await getCode(val);
+      // let data = await pageSegment({
+      //   pageNum: 1,
+      //   size: 100,
+      //   businessCodeCategoryId: val
+      // });
+      // data.list.map((item) =>{
+      //   console.log(item,'dsds')
+      // });
+      // console.log(code, 'ds');
+      // this.options = data.list.map((item) => item.type == 2);
+    },
+    /* 保存编辑 */
+    save() {
+      this.$emit('success', this.form.code);
+      this.cancel();
+    },
+
+    cancel() {
+      this.form.type = '';
+      this.form.code = '';
+      this.showEditFlag = false;
+    }
+  }
+};
+</script>
+<style scoped lang="scss">
+.aaa {
+  width: 100%;
+
+  ::v-deep .upload-demo {
+    width: 100%;
+
+    .el-upload--text {
+      width: 100%;
+
+      button {
+        width: 100%;
+        background: #ffffff;
+        border: 1px solid #dbdbdb;
+        border-radius: 5px;
+      }
+    }
+
+    .el-upload-list {
+      transform: translate(10px, -39px);
+      position: absolute;
+    }
+  }
+}
+</style>

+ 209 - 0
src/components/addDoc/main.vue

@@ -0,0 +1,209 @@
+<template>
+  <ele-modal
+    width="60%"
+    :visible.sync="showEditFlag"
+    :close-on-click-modal="false"
+    custom-class="ele-dialog-form"
+    append-to-body
+    ref="Emodal"
+  >
+    <!-- 数据表格 -->
+    <ele-pro-table
+      ref="table"
+      :columns="columns"
+      :datasource="tableList"
+      tool-class="ele-toolbar-form"
+      :needPage="false"
+      row-key="id"
+    >
+      <template v-slot:toolbar   v-if="type != 'view'">
+        <el-button type="primary" @click="fileEditOpen">本地上传</el-button>
+        <el-button type="primary" @click="fileShow = true">
+          关联文档库
+        </el-button>
+      </template>
+      <!-- 操作列 -->
+      <template v-slot:action="{ row }">
+        <el-link
+          type="primary"
+          :underline="false"
+          icon="el-icon-edit"
+          @click="browseOpen(row)"
+        >
+          浏览
+        </el-link>
+
+        <el-popconfirm
+          v-if="type != 'view'"
+          class="ele-action"
+          title="确定要删除吗?"
+          @confirm="remove(row)"
+        >
+          <template v-slot:reference>
+            <el-link type="danger" :underline="false" icon="el-icon-delete">
+              删除
+            </el-link>
+          </template>
+        </el-popconfirm>
+      </template>
+    </ele-pro-table>
+    <template v-slot:footer>
+      <el-button @click="showEditFlag = false">取消</el-button>
+      <el-button type="primary" @click="addFile" v-if="type != 'view'"> 确认 </el-button>
+    </template>
+    <fileEdit ref="fileEditRef" @done="done"></fileEdit>
+    <ele-modal
+      width="80%"
+      :visible.sync="fileShow"
+      :close-on-click-modal="false"
+      custom-class="ele-dialog-form"
+      append-to-body
+    >
+      <doc_template
+        :disabledTableList="tableList"
+        ref="doc_templateRef"
+      ></doc_template>
+      <template v-slot:footer>
+        <el-button @click="fileShow = false">取消</el-button>
+        <el-button type="primary" @click="addTemplate"> 确认 </el-button>
+      </template>
+    </ele-modal>
+    <browse ref="browseRef"></browse>
+  </ele-modal>
+</template>
+
+<script>
+import doc_template from './doc_template.vue';
+import fileEdit from './file-edit.vue';
+import browse from './browse.vue';
+import { queryIds } from './api';
+
+export default {
+  components: { doc_template, fileEdit, browse },
+
+  data() {
+    return {
+      fileId: [],
+      fileShow: false,
+      showEditFlag: false,
+      tableList: [],
+      type: 'add',
+      columns: [
+        {
+          label: '编码',
+          prop: 'code',
+          width: 180,
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'name',
+          label: '文档名称',
+          align: 'center',
+          slot: 'name',
+          showOverflowTooltip: true,
+          minWidth: 200
+        },
+        {
+          prop: 'storagePath',
+          label: '文件名称',
+          align: 'center',
+
+          showOverflowTooltip: true,
+          minWidth: 200,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue && cellValue[0]?.name;
+          }
+        },
+        {
+          prop: 'version',
+          label: '版本',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+
+        {
+          prop: 'createUserName',
+          label: '创建人',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'createTime',
+          label: '创建时间',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 160
+        },
+
+        {
+          prop: 'sizeUnit',
+          label: '文档大小',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 200,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          showOverflowTooltip: true
+        }
+      ]
+    };
+  },
+  created() {},
+
+  methods: {
+    open(fileId, type) {
+      this.showEditFlag = true;
+      this.fileId = fileId || [];
+      if (type) {
+        this.type = type;
+      }
+      this.init();
+    },
+    fileEditOpen() {
+      this.$refs.fileEditRef.open();
+    },
+    remove(row) {
+      this.tableList = this.tableList.filter((item) => item.code != row.code);
+      this.fileId = this.tableList.map((item) => item.id);
+    },
+    async init() {
+      if (this.fileId.length > 0) {
+        this.tableList = await queryIds({ ids: "'" + this.fileId + "'" });
+      }
+    },
+    done(id) {
+      this.fileId.push(id);
+      this.init();
+    },
+    browseOpen(row) {
+      this.$refs.browseRef.open(row);
+    },
+    addFile() {
+      this.$emit(
+        'success',
+        this.tableList.map((item) => item.id)
+      );
+      this.showEditFlag = false;
+    },
+    addTemplate() {
+      let list = this.$refs.doc_templateRef.getTableList();
+      this.fileShow = false;
+      if (list.length == 0) {
+        this.$message.error('请选择一条数据');
+        return;
+      }
+      this.tableList.push(...list);
+    }
+  }
+};
+</script>

+ 65 - 0
src/components/addDoc/util.js

@@ -0,0 +1,65 @@
+import store from '@/store';
+const userId = store.state.user.info.userId
+const userName = store.state.user.info.name
+export function isPower(data = {}, power, selection = []) {
+
+    if (power == 'download') {
+        console.log(!data?.id && selection.length == 0)
+    }
+    if (!data?.id && selection.length == 0) {
+        return false
+
+    }
+    if (power == 'checkEnter' && data?.checkOutUserId != userId) { //检入特殊处理
+        return false
+    }
+    if (selection.length > 0) { //多选情况处理
+        let isPower = true
+        let userAuthorityS = []
+        let createUserIdS = selection.map(item => item.createUserId).filter(createUserId => createUserId == userId)
+        if (createUserIdS.length == selection.length || userName == 'admin') {
+            return true
+        }
+        selection.forEach(val => {
+            const powerObj = val.userAuthority.find(item => item.id == userId)
+            if (powerObj) {
+                userAuthorityS.push(powerObj)
+            }
+        })
+
+        if (userAuthorityS.length == 0) {
+            isPower = false
+        }
+        userAuthorityS.forEach(item => {
+            if (item[power] != '1') {
+                isPower = false
+            }
+        })
+        return isPower
+    }
+
+    if (data.createUserId == userId || userName == 'admin') { //创建人/admin所有权限
+        return true
+    }
+    if (!power) {
+        return false
+    }
+    const powerObj = data.userAuthority.find(item => item.id == userId)
+    if (powerObj) {
+
+        return powerObj[power] == '1'
+    }
+}
+
+export function setFolderList(data) { //递归过滤文件夹权限
+    data.forEach((item) => {
+        item['disabled'] = !isPower(item, 'add');
+        if (item.sonDirectoryList && item.sonDirectoryList.length > 0) {
+            setFolderList(item.sonDirectoryList);
+        }
+    });
+}
+//新迪预览工具支持的文件格式
+export function getFileType() {
+    return ['par', 'asm', 'psm', 'dft', 'sldprt', 'sldasm', 'ipt', 'iam', 'prt', '3dxml', 'CATPart', 'CATProduct', 'cgr', 'model', 'exp', 'session', 'x_t', 'xmt_txt', 'x_b', 'xmp_bin', 'xmp_txt', 'sat', 'sab', 'igs', 'iges', 'stp', 'step', 'jt', 'xcgm', '3dm', 'stl', 'obj', '3mf', 'fbx', 'vda', 'dxf', 'dwg', 'pdf', 'idf', 'idb', 'emn', 'brd']
+}

+ 127 - 112
src/views/bpm/handleTask/components/contractBook/addDialog.vue

@@ -57,7 +57,6 @@
             </el-select>
           </el-form-item>
 
-
           <el-form-item
             label="核价单"
             prop="sourceName"
@@ -111,7 +110,6 @@
             />
           </el-form-item>
 
-
           <el-form-item
             label="合同名称"
             prop="contractName"
@@ -135,12 +133,9 @@
             />
           </el-form-item>
           <el-form-item prop="contractFile" label="合同附件">
-            <fileUpload
-              v-model="form.contractFile"
-              module="main"
-              :showLib="false"
-              :limit="10"
-            />
+            <el-badge :value="form.fileId.length" class="item">
+              <el-button type="primary" @click="fileOpen">附件上传</el-button>
+            </el-badge>
           </el-form-item>
         </el-col>
         <el-col :span="12">
@@ -226,12 +221,15 @@
             prop="pricingWay"
             style="margin-bottom: 22px"
           >
-            <el-radio-group v-model="form.pricingWay" @change="changePricingWay">
-              <el-radio v-for="item in pricingWayList" :label="item.id">{{ item.name }}</el-radio>
+            <el-radio-group
+              v-model="form.pricingWay"
+              @change="changePricingWay"
+            >
+              <el-radio v-for="item in pricingWayList" :label="item.id">{{
+                item.name
+              }}</el-radio>
             </el-radio-group>
           </el-form-item>
-
-
         </el-col>
       </el-row>
       <headerTitle title="基本信息"></headerTitle>
@@ -333,7 +331,7 @@
             prop="partaFax"
             style="margin-bottom: 22px"
           >
-            <el-input clearable v-model="form.partaFax" placeholder="请输入"/>
+            <el-input clearable v-model="form.partaFax" placeholder="请输入" />
           </el-form-item>
           <el-form-item
             label="	甲方Email"
@@ -447,10 +445,10 @@
             </template>
           </el-form-item>
           <el-form-item prop="partbTel" label="乙方联系电话">
-            <el-input clearable v-model="form.partbTel" placeholder="请输入"/>
+            <el-input clearable v-model="form.partbTel" placeholder="请输入" />
           </el-form-item>
           <el-form-item prop="partbFax" label="乙方传真">
-            <el-input clearable v-model="form.partbFax" placeholder="请输入"/>
+            <el-input clearable v-model="form.partbFax" placeholder="请输入" />
           </el-form-item>
 
           <el-form-item
@@ -486,13 +484,13 @@
         :isCustomerMark="false"
         :isDiscountTotalPrice="true"
         :contractBookType="form.type"
-        :pricingWay='form.pricingWay'
+        :pricingWay="form.pricingWay"
       ></inventoryTable>
       <headerTitle
         :title="form.type == '2' ? '付款方式' : '收款方式'"
         style="margin-top: 30px"
       ></headerTitle>
-      <paymentList ref="paymentListTable"/>
+      <paymentList ref="paymentListTable" />
     </el-form>
 
     <parentList ref="parentRef" @changeParent="changeParent"></parentList>
@@ -515,13 +513,18 @@
     ></supplierList>
     <head-list ref="headRef" @changeParent="changePersonel"></head-list>
     <!-- 商机   -->
-    <opportunity-dialog :opportunityDialogFlag.sync="opportunityDialogFlag" v-if="opportunityDialogFlag"
-                        ref="opportunityDialogRef" @changeParent="getOpportunityDetail"></opportunity-dialog>
+    <opportunity-dialog
+      :opportunityDialogFlag.sync="opportunityDialogFlag"
+      v-if="opportunityDialogFlag"
+      ref="opportunityDialogRef"
+      @changeParent="getOpportunityDetail"
+    ></opportunity-dialog>
+    <fileMain ref="fileMainRef" @success="fileSuccess"></fileMain>
   </div>
 </template>
 
 <script>
-import {emailReg, numberReg} from 'ele-admin';
+import { emailReg, numberReg } from 'ele-admin';
 import inventoryTable from './inventoryTable.vue';
 import fileUpload from '@/components/upload/fileUpload';
 import dictMixins from '@/mixins/dictMixins';
@@ -533,18 +536,19 @@ import {
   getDetail,
   enterprisePage
 } from '@/api/bpm/components/contractManage/contractBook';
-import {getcontactlink} from '@/api/bpm/components/saleManage/businessOpportunity.js';
-import {getDetail as getOpportunityInfo} from '@/api/bpm/components/saleManage/businessOpportunity';
+import { getcontactlink } from '@/api/bpm/components/saleManage/businessOpportunity.js';
+import { getDetail as getOpportunityInfo } from '@/api/bpm/components/saleManage/businessOpportunity';
 import paymentList from './paymentList.vue';
-import {copyObj} from '@/utils/util';
-import {contactTypeTree} from '@/api/bpm/components/saleManage/contact';
-import InquiryManageList from "@/views/bpm/handleTask/components/inquiryManage/inquiryManage-list.vue";
-import InquiryList from "@/views/bpm/handleTask/components/contractBook/inquiryList.vue";
-import QuotationList from "@/views/bpm/handleTask/components/contractBook/quotationList.vue";
-import OpportunityDialog
-  from "@/views/bpm/handleTask/components/financialManage/components/opportunityDialog.vue";
-import {getplanDetail} from "@/api/bpm/components/purchasingManage/purchasePlanManage";
-import {contactDetail} from '@/api/bpm/components/saleManage/contact';
+import { copyObj } from '@/utils/util';
+import fileMain from '@/components/addDoc/main';
+
+import { contactTypeTree } from '@/api/bpm/components/saleManage/contact';
+import InquiryManageList from '@/views/bpm/handleTask/components/inquiryManage/inquiryManage-list.vue';
+import InquiryList from '@/views/bpm/handleTask/components/contractBook/inquiryList.vue';
+import QuotationList from '@/views/bpm/handleTask/components/contractBook/quotationList.vue';
+import OpportunityDialog from '@/views/bpm/handleTask/components/financialManage/components/opportunityDialog.vue';
+import { getplanDetail } from '@/api/bpm/components/purchasingManage/purchasePlanManage';
+import { contactDetail } from '@/api/bpm/components/saleManage/contact';
 export default {
   mixins: [dictMixins],
   components: {
@@ -557,7 +561,8 @@ export default {
     inventoryTable,
     supplierList,
     parentList,
-    headList
+    headList,
+    fileMain
   },
   props: {
     businessId: {
@@ -601,42 +606,43 @@ export default {
       pricingWay: 1,
       totalPrice: null,
       type: '', //1=销售合同  2=采购合同
-      typeName: ''
+      typeName: '',
+      fileId: [] //附件集合
     };
 
     return {
       payWayOptions: [],
       delDetailIds: [],
       paymentTypeOptions: [
-        {id: 1, name: '固定'},
-        {id: 2, name: '分期'}
+        { id: 1, name: '固定' },
+        { id: 2, name: '分期' }
       ],
       pricingWayList: [
-        {id: 1, name: '按数量计价'},
-        {id: 2, name: '按重量计价'}
+        { id: 1, name: '按数量计价' },
+        { id: 2, name: '按重量计价' }
       ],
       contractBookTypeList: [],
       sourceTypeList: [
         {
           code: 1,
           name: '报价单',
-          parentId: '1',
+          parentId: '1'
         },
         {
           code: 2,
           name: '核价单',
-          parentId: '2',
+          parentId: '2'
         },
         {
           code: 3,
           name: '采购计划',
-          parentId: '2',
+          parentId: '2'
         },
         {
           code: 4,
           name: '商机',
-          parentId: '1',
-        },
+          parentId: '1'
+        }
       ],
       categoryList: [],
       linkNameOptions: [],
@@ -654,28 +660,28 @@ export default {
 
       rules: {
         type: [
-          {required: true, message: '请选择合同类型', trigger: 'change'}
+          { required: true, message: '请选择合同类型', trigger: 'change' }
         ],
         settlementMode: [
-          {required: true, message: '请选择结算方式', trigger: 'change'}
+          { required: true, message: '请选择结算方式', trigger: 'change' }
         ],
         categoryId: [
-          {required: true, message: '请选择合同分类', trigger: 'change'}
+          { required: true, message: '请选择合同分类', trigger: 'change' }
         ],
         contractNumber: [
-          {required: true, message: '请输入自带编号', trigger: 'change'}
+          { required: true, message: '请输入自带编号', trigger: 'change' }
         ],
         contractName: [
-          {required: true, message: '请输入合同名称', trigger: 'blur'}
+          { required: true, message: '请输入合同名称', trigger: 'blur' }
         ],
         partaName: [
-          {required: true, message: '请选择甲方名称', trigger: 'change'}
+          { required: true, message: '请选择甲方名称', trigger: 'change' }
         ],
         partaLinkName: [
-          {required: true, message: '请选择甲方联系人', trigger: 'change'}
+          { required: true, message: '请选择甲方联系人', trigger: 'change' }
         ],
         acceptUnpack: [
-          {required: true, message: '请选择是否接受', trigger: 'change'}
+          { required: true, message: '请选择是否接受', trigger: 'change' }
         ],
         partaTel: [
           {
@@ -686,14 +692,14 @@ export default {
           }
         ],
         deliveryDate: [
-          {required: true, message: '请选择交货日期', trigger: 'change'}
+          { required: true, message: '请选择交货日期', trigger: 'change' }
         ],
 
         partbName: [
-          {required: true, message: '请输入乙方名称', trigger: 'change'}
+          { required: true, message: '请输入乙方名称', trigger: 'change' }
         ],
         partbLinkName: [
-          {required: true, message: '请输入乙方联系人', trigger: 'change'}
+          { required: true, message: '请输入乙方联系人', trigger: 'change' }
         ],
         partbTel: [
           {
@@ -704,14 +710,12 @@ export default {
           }
         ],
         partaEmail: [
-          {pattern: emailReg, message: '邮箱格式不正确', trigger: 'blur'}
+          { pattern: emailReg, message: '邮箱格式不正确', trigger: 'blur' }
         ],
         contractStartDate: [
-          {required: true, message: '请选择签订日期', trigger: 'change'}
+          { required: true, message: '请选择签订日期', trigger: 'change' }
         ],
-        contractEndDate: [
-          {validator: this.validateEndDate, trigger: 'blur'}
-        ]
+        contractEndDate: [{ validator: this.validateEndDate, trigger: 'blur' }]
       },
       enterprise: {
         address: '',
@@ -730,7 +734,7 @@ export default {
     };
   },
   async created() {
-    await contactTypeTree({type: 20}).then((res) => {
+    await contactTypeTree({ type: 20 }).then((res) => {
       this.treeList = res.data;
     });
     await enterprisePage({
@@ -767,7 +771,14 @@ export default {
         callback();
       }
     },
-
+ //文件上传
+ fileOpen() {
+      this.$refs.fileMainRef.open(this.form.fileId);
+    },
+    //文件列表回调
+    fileSuccess(list) {
+      this.form.fileId = list;
+    },
     //选择供应商
     changeSupplier(obj) {
       this.form = Object.assign({}, this.form, {
@@ -789,15 +800,16 @@ export default {
       this.loading = false;
       if (data) {
         this.$nextTick(() => {
-          let {contractVO} = data;
+          let { contractVO } = data;
           this.dictChange(contractVO.type, 'init');
           this.form = contractVO;
+          if (this.form.fileId) {
+            this.form.fileId = JSON.parse(this.form.fileId);
+          }
           this.$refs.inventoryTable &&
-          this.$refs.inventoryTable.putTableValue(data);
+            this.$refs.inventoryTable.putTableValue(data);
           this.$refs.paymentListTable &&
-          this.$refs.paymentListTable.putTableValue(
-            data.receiptPaymentList
-          );
+            this.$refs.paymentListTable.putTableValue(data.receiptPaymentList);
           this.getLinkInfo(
             contractVO.type == '2' ? contractVO.partbId : contractVO.partaId
           );
@@ -811,7 +823,7 @@ export default {
 
     //更新联系人数据
     async getLinkInfo(contactId) {
-      const data = await getcontactlink({contactId});
+      const data = await getcontactlink({ contactId });
       if (data && data?.length) {
         this.linkNameOptions = data;
       }
@@ -882,7 +894,7 @@ export default {
         partbName: '',
         partbTel: '',
         partaUnifiedSocialCreditCode: '',
-        partbUnifiedSocialCreditCode: '',
+        partbUnifiedSocialCreditCode: ''
         // categoryName: '',
         // categoryId: ''
       });
@@ -1019,9 +1031,9 @@ export default {
     //     this.getDetailData(row.id);
     //   }
     // },
-//切换计价方式重新算费用
+    //切换计价方式重新算费用
     changePricingWay() {
-      this.$refs.inventoryTable.getTotalPrice()
+      this.$refs.inventoryTable.getTotalPrice();
     },
     salesmanChange(val, info) {
       this.otherForm.salesmanName = info.name;
@@ -1036,51 +1048,52 @@ export default {
       }
     },
     handInquiry(e) {
-      if (e.target.nodeName == "I") {
+      if (e.target.nodeName == 'I') {
         this.$set(this.form, 'sourceName', '');
         this.$set(this.form, 'sourceId', '');
-        return
+        return;
       }
       this.$refs.inquiryListRef.open();
     },
     handQuotation(e) {
-      if (e.target.nodeName == "I") {
+      if (e.target.nodeName == 'I') {
         this.$set(this.form, 'sourceName', '');
         this.$set(this.form, 'sourceId', '');
-        return
+        return;
       }
       this.$refs.quotationListRef.open();
     },
 
-    async changeInquiryList({data, sourceCode}) {
+    async changeInquiryList({ data, sourceCode }) {
       this.setValue(data);
       this.$set(this.form, 'sourceName', sourceCode);
       this.$set(this.form, 'sourceId', data.id);
 
-      let contactId = this.form.type == 2 ? data.contractVO.partbId : data.contractVO.partaId
-      let {base} = await contactDetail(contactId)
+      let contactId =
+        this.form.type == 2 ? data.contractVO.partbId : data.contractVO.partaId;
+      let { base } = await contactDetail(contactId);
       this.$set(this.form, 'contractName', base.simpleName);
     },
     //选择采购计划
     handPlan(e) {
-      if (e.target.nodeName == "I") {
+      if (e.target.nodeName == 'I') {
         this.$set(this.form, 'sourceName', '');
         this.$set(this.form, 'sourceId', '');
-        return
+        return;
       }
       this.$refs.inquiryManageRef.open();
     },
     //选择采购计划回调
     async changeInquiryManageList(data) {
-      let info = await this.getPlanInfo(data.id)
-      let cusInfo = {}
+      let info = await this.getPlanInfo(data.id);
+      let cusInfo = {};
       // if (info.detailList.length) cusInfo = await this.getCusInfo(info.detailList[0]?.supplierId ?? '');
       this.$set(this.form, 'sourceName', data.planName);
       this.$set(this.form, 'sourceId', data.id);
       // this.$set(this.form, 'contractName', cusInfo?.base?.simpleName);
       let form = {
         contractVO: {
-          ...this.form,
+          ...this.form
           // partbName: cusInfo.base.name,
           // partbId: cusInfo.base.id,
           // partbUnifiedSocialCreditCode: cusInfo.base.unifiedSocialCreditCode,
@@ -1090,34 +1103,33 @@ export default {
           // partbTel: cusInfo.linkList[0]?.mobilePhone,
         },
         productList: info.detailList || []
-      }
+      };
       this.setValue(form);
       // await this.getLinkInfo(cusInfo.base.id)
-
     },
     //获取计划详情
     async getPlanInfo(id) {
-      return Promise.resolve(await getplanDetail(id))
+      return Promise.resolve(await getplanDetail(id));
     },
     //获取客户详情
     async getCusInfo(id = '') {
-      if (!id) return
-      return Promise.resolve(await contactDetail(id))
+      if (!id) return;
+      return Promise.resolve(await contactDetail(id));
     },
     //选择商机
     handOpportunity(e) {
-      if (e.target.nodeName == "I") {
+      if (e.target.nodeName == 'I') {
         this.$set(this.form, 'sourceName', '');
         this.$set(this.form, 'sourceId', '');
-        return
+        return;
       }
-      this.opportunityDialogFlag = true
+      this.opportunityDialogFlag = true;
       this.$nextTick(() => {
         let item = {
           id: this.form.sourceId
-        }
-        this.$refs.opportunityDialogRef.init(item)
-      })
+        };
+        this.$refs.opportunityDialogRef.init(item);
+      });
     },
     //获取商机信息
     async getOpportunityDetail(row) {
@@ -1125,17 +1137,17 @@ export default {
       this.$set(this.form, 'sourceId', row.id);
       let cusInfo = await this.getCusInfo(row?.contactId ?? '');
       let info = await this.getOpportunityDetailData(row?.id ?? '');
-      await this.getLinkInfo(cusInfo.base.id)
+      await this.getLinkInfo(cusInfo.base.id);
       let totalPrice = info.productList.reduce((num, cur) => {
         return num + Number(cur.totalPrice);
-      }, 0)
+      }, 0);
       info.productList.forEach((item) => {
-        item.discountSinglePrice = item.discountSinglePrice || item.singlePrice
-        item.discountTotalPrice = item.discountTotalPrice || item.totalPrice
-      })
+        item.discountSinglePrice = item.discountSinglePrice || item.singlePrice;
+        item.discountTotalPrice = item.discountTotalPrice || item.totalPrice;
+      });
       let discountTotalPrice = info.productList.reduce((num, cur) => {
         return num + Number(cur.discountTotalPrice);
-      }, 0)
+      }, 0);
       let form = {
         contractVO: {
           ...this.form,
@@ -1147,34 +1159,33 @@ export default {
           partaLinkId: cusInfo.linkList[0]?.id,
           partaTel: cusInfo.linkList[0]?.mobilePhone,
           totalPrice: totalPrice,
-          discountTotalPrice: discountTotalPrice,
+          discountTotalPrice: discountTotalPrice
         },
         productList: info.productList || []
-      }
+      };
       this.setValue(form);
-
     },
     //获取商机详情
     async getOpportunityDetailData(id) {
-      return Promise.resolve(await getOpportunityInfo(id))
+      return Promise.resolve(await getOpportunityInfo(id));
     },
     //赋值
     setValue(row) {
-      let {contractVO} = row;
+      let { contractVO } = row;
       contractVO = {
         ...contractVO,
         categoryId: contractVO.categoryId || this.form.categoryId,
         categoryName: contractVO.categoryName || this.form.categoryName,
-        contractStartDate: contractVO.contractStartDate || this.form.contractStartDate,
-        contractEndDate: contractVO.contractEndDate || this.form.contractEndDate,
-        pricingWay: 1,
-
-      }
+        contractStartDate:
+          contractVO.contractStartDate || this.form.contractStartDate,
+        contractEndDate:
+          contractVO.contractEndDate || this.form.contractEndDate,
+        pricingWay: 1
+      };
       this.form = contractVO;
-      this.$refs.inventoryTable &&
-      this.$refs.inventoryTable.putTableValue(row);
+      this.$refs.inventoryTable && this.$refs.inventoryTable.putTableValue(row);
       this.$refs.paymentListTable &&
-      this.$refs.paymentListTable.putTableValue(row.receiptPaymentList);
+        this.$refs.paymentListTable.putTableValue(row.receiptPaymentList);
 
       this.getEnterprise();
       this.getLinkInfo(
@@ -1217,7 +1228,8 @@ export default {
         await this.getValidate();
         // 表单验证通过,执行保存操作
         this.loading = true;
-        let [totalPrice, discountTotalPrice] = this.$refs.inventoryTable.getPrice();
+        let [totalPrice, discountTotalPrice] =
+          this.$refs.inventoryTable.getPrice();
         this.form.totalPrice = totalPrice;
         this.form.discountTotalPrice = discountTotalPrice;
         if (this.form.categoryId) {
@@ -1230,6 +1242,9 @@ export default {
           '结算方式',
           this.form.settlementMode
         );
+        if (this.form.fileId) {
+          this.form.fileId = JSON.stringify(this.form.fileId);
+        }
         let commitData = Object.assign(
           {},
           {

+ 267 - 267
src/views/bpm/handleTask/components/contractBook/detailDialog.vue

@@ -17,7 +17,7 @@
             style="margin-bottom: 22px"
             v-if="form.sourceType == 2"
           >
-            {{form.sourceName}}
+            {{ form.sourceName }}
           </el-form-item>
           <el-form-item
             label="报价单:"
@@ -25,7 +25,7 @@
             style="margin-bottom: 22px"
             v-if="form.sourceType == 1"
           >
-            {{form.sourceName}}
+            {{ form.sourceName }}
           </el-form-item>
           <el-form-item
             label="计划名称:"
@@ -33,7 +33,7 @@
             style="margin-bottom: 22px"
             v-if="form.sourceType == 3"
           >
-            {{form.sourceName}}
+            {{ form.sourceName }}
           </el-form-item>
           <el-form-item
             label="商机名称:"
@@ -41,7 +41,7 @@
             style="margin-bottom: 22px"
             v-if="form.sourceType == 4"
           >
-            {{form.sourceName}}
+            {{ form.sourceName }}
           </el-form-item>
           <el-form-item
             label="合同名称:"
@@ -85,7 +85,7 @@
             prop="payWay"
             style="margin-bottom: 16px"
           >
-            {{ form.pricingWay==1?'按数量计费':'按重量计费' }}
+            {{ form.pricingWay == 1 ? '按数量计费' : '按重量计费' }}
           </el-form-item>
           <el-form-item
             label="结算方式:"
@@ -95,17 +95,9 @@
             {{ form.settlementModeName }}
           </el-form-item>
           <el-form-item prop="contractFile" label="合同附件:">
-            <div v-if="form.contractFile && form.contractFile?.length">
-              <el-link
-                v-for="link in form.contractFile"
-                :key="link.id"
-                type="primary"
-                :underline="false"
-                @click="downloadFile(link)"
-              >
-                {{ link.name }}</el-link
-              >
-            </div>
+            <el-badge :value="form.fileId.length" class="item">
+              <el-button type="primary" @click="fileOpen">查看附件</el-button>
+            </el-badge>
           </el-form-item>
         </el-col>
       </el-row>
@@ -187,7 +179,6 @@
             label="乙方统一社会信用代码:"
             prop="partaName"
             label-width="180px"
-
             style="margin-bottom: 16px"
           >
             {{ form.partbUnifiedSocialCreditCode }}
@@ -258,273 +249,282 @@
       row-key="id"
     >
     </ele-pro-table>
+    <fileMain ref="fileMainRef"></fileMain>
   </div>
 </template>
 
 <script>
-  import { getDetail } from '@/api/bpm/components/contractManage/contractBook';
-  import { getFile } from '@/api/system/file';
-  import dictMixins from '@/mixins/dictMixins';
-  import { copyObj } from '@/utils/util';
-  import inventoryTabledetail from './inventoryTabledetail.vue';
+import { getDetail } from '@/api/bpm/components/contractManage/contractBook';
+import { getFile } from '@/api/system/file';
+import dictMixins from '@/mixins/dictMixins';
+import { copyObj } from '@/utils/util';
+import inventoryTabledetail from './inventoryTabledetail.vue';
+import fileMain from '@/components/addDoc/main';
 
-  export default {
-    mixins: [dictMixins],
-    components: {
-      inventoryTabledetail
-    },
-    props: {
-      businessId: {
-        default: ''
-      }
-    },
-    data() {
-      return {
-        visible: false,
-        detailId: '',
-        title: '详情',
-        row: {},
-        activeName: 'base',
-        form: {},
-        rules: {},
-        detailData: {},
-        receiptPaymentListcolumns: [
-          {
-            width: 45,
-            type: 'index',
-            columnKey: 'index',
-            align: 'center',
-            fixed: 'left'
-          },
-          {
-            width: 200,
-            prop: 'moneyName',
-            label: '款项名称',
-            slot: 'moneyName'
-          },
-          {
-            width: 100,
-            prop: 'price',
-            label: '金额',
-            slot: 'price',
-            formatter: (_row, _column, cellValue) => {
-              return _row.price + '元';
-            }
-          },
-          {
-            width: 100,
-            prop: 'ratio',
-            label: '比例',
-            slot: 'ratio',
-            formatter: (_row, _column, cellValue) => {
-              return _row.ratio + '%';
-            }
-          },
-          {
-            width: 160,
-            prop: 'deadLine',
-            label: '截止日期',
-            slot: 'deadLine'
-          },
-          {
-            prop: 'remark',
-            label: '	说明',
-            slot: 'remark'
+export default {
+  mixins: [dictMixins],
+  components: {
+    inventoryTabledetail,
+    fileMain
+  },
+  props: {
+    businessId: {
+      default: ''
+    }
+  },
+  data() {
+    return {
+      visible: false,
+      detailId: '',
+      title: '详情',
+      row: {},
+      activeName: 'base',
+      form: {},
+      rules: {},
+      detailData: {},
+      receiptPaymentListcolumns: [
+        {
+          width: 45,
+          type: 'index',
+          columnKey: 'index',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          width: 200,
+          prop: 'moneyName',
+          label: '款项名称',
+          slot: 'moneyName'
+        },
+        {
+          width: 100,
+          prop: 'price',
+          label: '金额',
+          slot: 'price',
+          formatter: (_row, _column, cellValue) => {
+            return _row.price + '元';
           }
-        ],
-        competAnalysisListcolumns: [
-          {
-            width: 45,
-            type: 'index',
-            columnKey: 'index',
-            align: 'center',
-            fixed: 'left'
-          },
-          {
-            width: 200,
-            prop: 'productName',
-            label: '名称',
-            slot: 'productName'
-          },
-          {
-            width: 120,
-            prop: 'productCode',
-            label: '编码',
-            slot: 'productCode'
-          },
-          {
-            width: 200,
-            prop: 'productCategoryName',
-            label: '类型',
-            slot: 'productCategoryName'
-          },
-          {
-            width: 160,
-            prop: 'productBrand',
-            label: '牌号',
-            slot: 'productBrand'
-          },
-          {
-            width: 120,
-            prop: 'modelType',
-            label: '型号',
-            slot: 'modelType'
-          },
-          {
-            width: 120,
-            prop: 'specification',
-            label: '规格',
-            slot: 'specification'
-          },
+        },
+        {
+          width: 100,
+          prop: 'ratio',
+          label: '比例',
+          slot: 'ratio',
+          formatter: (_row, _column, cellValue) => {
+            return _row.ratio + '%';
+          }
+        },
+        {
+          width: 160,
+          prop: 'deadLine',
+          label: '截止日期',
+          slot: 'deadLine'
+        },
+        {
+          prop: 'remark',
+          label: '	说明',
+          slot: 'remark'
+        }
+      ],
+      competAnalysisListcolumns: [
+        {
+          width: 45,
+          type: 'index',
+          columnKey: 'index',
+          align: 'center',
+          fixed: 'left'
+        },
+        {
+          width: 200,
+          prop: 'productName',
+          label: '名称',
+          slot: 'productName'
+        },
+        {
+          width: 120,
+          prop: 'productCode',
+          label: '编码',
+          slot: 'productCode'
+        },
+        {
+          width: 200,
+          prop: 'productCategoryName',
+          label: '类型',
+          slot: 'productCategoryName'
+        },
+        {
+          width: 160,
+          prop: 'productBrand',
+          label: '牌号',
+          slot: 'productBrand'
+        },
+        {
+          width: 120,
+          prop: 'modelType',
+          label: '型号',
+          slot: 'modelType'
+        },
+        {
+          width: 120,
+          prop: 'specification',
+          label: '规格',
+          slot: 'specification'
+        },
 
-          {
-            width: 160,
-            prop: 'singlePrice',
-            label: '单价',
-            slot: 'singlePrice'
-          },
-          {
-            width: 120,
-            prop: 'totalCount',
-            label: '数量',
-            slot: 'totalCount'
-          },
-          {
-            width: 120,
-            prop: 'totalPrice',
-            label: '销售总金额',
-            slot: 'totalPrice',
-            formatter: (_row, _column, cellValue) => {
-              return _row.totalPrice + '元';
-            }
-          },
-          {
-            width: 120,
-            prop: 'measuringUnit',
-            label: '计量单位',
-            slot: 'measuringUnit'
-          },
-          {
-            width: 120,
-            prop: 'deliveryDays',
-            label: '交期(天)',
-            slot: 'deliveryDays'
-          },
-          {
-            width: 200,
-            prop: 'guaranteePeriod',
-            label: '质保期',
-            slot: 'guaranteePeriod',
-            formatter: (_row, _column, cellValue) => {
-              return (_row.guaranteePeriod||'') + _row.guaranteePeriodUnitName;
-            }
-          },
-          // {
-          //   width: 120,
-          //   prop: 'guaranteePeriodUnitCode',
-          //   label: '',
-          //   slot: 'guaranteePeriodUnitCode'
-          // },
-          {
-            width: 240,
-            prop: 'customerReqFiles',
-            label: '技术图纸',
-            slot: 'customerReqFiles'
-          },
+        {
+          width: 160,
+          prop: 'singlePrice',
+          label: '单价',
+          slot: 'singlePrice'
+        },
+        {
+          width: 120,
+          prop: 'totalCount',
+          label: '数量',
+          slot: 'totalCount'
+        },
+        {
+          width: 120,
+          prop: 'totalPrice',
+          label: '销售总金额',
+          slot: 'totalPrice',
+          formatter: (_row, _column, cellValue) => {
+            return _row.totalPrice + '元';
+          }
+        },
+        {
+          width: 120,
+          prop: 'measuringUnit',
+          label: '计量单位',
+          slot: 'measuringUnit'
+        },
+        {
+          width: 120,
+          prop: 'deliveryDays',
+          label: '交期(天)',
+          slot: 'deliveryDays'
+        },
+        {
+          width: 200,
+          prop: 'guaranteePeriod',
+          label: '质保期',
+          slot: 'guaranteePeriod',
+          formatter: (_row, _column, cellValue) => {
+            return (_row.guaranteePeriod || '') + _row.guaranteePeriodUnitName;
+          }
+        },
+        // {
+        //   width: 120,
+        //   prop: 'guaranteePeriodUnitCode',
+        //   label: '',
+        //   slot: 'guaranteePeriodUnitCode'
+        // },
+        {
+          width: 240,
+          prop: 'customerReqFiles',
+          label: '技术图纸',
+          slot: 'customerReqFiles'
+        },
 
-          {
-            width: 120,
-            prop: 'technicalAnswerName',
-            label: '技术答疑人',
-            slot: 'technicalAnswerName'
-          },
-          {
-            width: 220,
-            prop: 'technicalParams',
-            label: '技术参数',
-            slot: 'technicalParams'
-          },
-          {
-            width: 240,
-            prop: 'technicalDrawings',
-            label: '技术图纸',
-            slot: 'technicalDrawings',
-            formatter: (_row, _column, cellValue) => {
-              return (_row.guaranteePeriod||'') + _row.guaranteePeriodUnitName;
-            }
-          },
-          {
-            width: 220,
-            prop: 'remark',
-            label: '备注',
-            slot: 'remark'
+        {
+          width: 120,
+          prop: 'technicalAnswerName',
+          label: '技术答疑人',
+          slot: 'technicalAnswerName'
+        },
+        {
+          width: 220,
+          prop: 'technicalParams',
+          label: '技术参数',
+          slot: 'technicalParams'
+        },
+        {
+          width: 240,
+          prop: 'technicalDrawings',
+          label: '技术图纸',
+          slot: 'technicalDrawings',
+          formatter: (_row, _column, cellValue) => {
+            return (_row.guaranteePeriod || '') + _row.guaranteePeriodUnitName;
           }
-        ]
-      };
+        },
+        {
+          width: 220,
+          prop: 'remark',
+          label: '备注',
+          slot: 'remark'
+        }
+      ]
+    };
+  },
+  created() {
+    this.getDetailData(this.businessId);
+  },
+  methods: {
+    //导出
+    // async exportTable() {
+    //   this.loading = true;
+    //   const response = await getExport(this.detailId);
+    // },
+    // async open(row) {
+    //   this.form = row;
+    //   this.visible = true;
+    //   this.getDetailData(row.id);
+    //   this.detailId = row.id;
+    // },
+    //文件上传
+    fileOpen() {
+      this.$refs.fileMainRef.open(this.form.fileId, 'view');
     },
-    created() {
-      this.getDetailData(this.businessId);
+    cancel() {
+      this.$nextTick(() => {
+        // 关闭后,销毁所有的表单数据
+        (this.form = copyObj(this.formDef)),
+          (this.otherForm = copyObj(this.otherFormDef)),
+          (this.tableBankData = []);
+        this.tableLinkData = [];
+        this.visible = false;
+      });
     },
-    methods: {
-      //导出
-      // async exportTable() {
-      //   this.loading = true;
-      //   const response = await getExport(this.detailId);
-      // },
-      // async open(row) {
-      //   this.form = row;
-      //   this.visible = true;
-      //   this.getDetailData(row.id);
-      //   this.detailId = row.id;
-      // },
-
-      cancel() {
-        this.$nextTick(() => {
-          // 关闭后,销毁所有的表单数据
-          (this.form = copyObj(this.formDef)),
-            (this.otherForm = copyObj(this.otherFormDef)),
-            (this.tableBankData = []);
-          this.tableLinkData = [];
-          this.visible = false;
-        });
-      },
-      downloadFile(file) {
-        getFile({ objectName: file.storePath }, file.name);
-      },
-      async getDetailData(id) {
-        this.loading = true;
-        const data = await getDetail(id);
-        this.loading = false;
-        if (data) {
-          this.detailData = data;
-          this.form = data.contractVO;
-          this.$refs.inventoryTabledetailRef &&
-            this.$refs.inventoryTabledetailRef.putTableValue({
-              ...data,
-              ...data.contractVO
-            });
-          console.log(this.form.type);
-        }
+    downloadFile(file) {
+      getFile({ objectName: file.storePath }, file.name);
+    },
+    async getDetailData(id) {
+      this.loading = true;
+      const data = await getDetail(id);
+      this.loading = false;
+      if (data) {
+        this.detailData = data;
+        this.form = data.contractVO;
+        if (this.form.fileId) {
+            this.form.fileId = JSON.parse(this.form.fileId);
+          }
+        this.$refs.inventoryTabledetailRef &&
+          this.$refs.inventoryTabledetailRef.putTableValue({
+            ...data,
+            ...data.contractVO
+          });
+        console.log(this.form.type);
       }
     }
-  };
+  }
+};
 </script>
 
 <style scoped lang="scss">
-  .ele-dialog-form {
-    .el-form-item {
-      margin-bottom: 10px;
-    }
+.ele-dialog-form {
+  .el-form-item {
+    margin-bottom: 10px;
   }
+}
 
-  .headbox {
-    display: flex;
-    justify-content: flex-start;
-    align-items: center;
-    .amount {
-      font-size: 14px;
-      font-weight: bold;
-      margin-right: 20px;
-    }
+.headbox {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  .amount {
+    font-size: 14px;
+    font-weight: bold;
+    margin-right: 20px;
   }
+}
 </style>