소스 검색

Merge branch 'feat-contractReview' into dev

liujt 8 달 전
부모
커밋
0e01e54f93

+ 86 - 0
src/api/bpm/model.js

@@ -0,0 +1,86 @@
+import request from '@/utils/request'
+
+export async function getModelPage(query) {
+  const res = await request({
+    url: '/bpm/model/page',
+    method: 'get',
+    params: query
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function getModel(id) {
+  const res = await request({
+    url: '/bpm/model/get?id=' + id,
+    method: 'get'
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function updateModel(data) {
+  const res = await request({
+    url: '/bpm/model/update',
+    method: 'PUT',
+    data: data
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 任务状态修改
+export async function updateModelState(id, state) {
+  const res = await request({
+    url: '/bpm/model/update-state',
+    method: 'put',
+    data: {
+      id,
+      state
+    }
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function createModel(data) {
+  const res = await request({
+    url: '/bpm/model/create',
+    method: 'POST',
+    data: data
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function deleteModel(id) {
+  const res = await request({
+    url: '/bpm/model/delete?id=' + id,
+    method: 'DELETE'
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function deployModel(id) {
+  const res = await request({
+    url: '/bpm/model/deploy?id=' + id,
+    method: 'POST'
+  })
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 361 - 0
src/api/bpm/task.js

@@ -0,0 +1,361 @@
+import request from '@/utils/request';
+import store from '@/store';
+import Vue from 'vue';
+
+export async function getTodoTaskPage(query) {
+  const res = await request({
+    url: '/bpm/task/todo-page',
+    method: 'post',
+    data: query
+  });
+  if (res.data.code == 0) {
+    store.dispatch('user/setMenuBadge', {
+      path: '/todo',
+      value: res.data.data.count || 0,
+      color: 'danger'
+    });
+    // console.log('-----getTodoTaskPage---user--------');
+    // console.log(store.state.user);
+    // if (store.state.user.menus?.length) {
+    //   for (const p of store.state.user.menus) {
+    //     console.log('getTodoTaskPage----------------------');
+    //     console.log(p);
+    //     if (p.path === '/todo') {
+    //       console.log('进来了2~~~');
+
+    //       break;
+    //     }
+    //   }
+    // } else {
+    //   const unwatch = Vue.prototype.$watch(
+    //     '$store.state.user.menus',
+    //     () => {
+    //       console.log('-----getTodoTaskPage---user--------');
+    //       console.log(store.state.user);
+    //       if (store.state.user.menus?.length) {
+    //         for (const p of store.state.user.menus) {
+    //           console.log('getTodoTaskPage----------------------');
+    //           console.log(p);
+    //           if (p.path === '/todo') {
+    //             console.log('进来了2~~~');
+    //             store.dispatch('user/setMenuBadge', {
+    //               path: '/todo',
+    //               value: res.data.data.count || 0,
+    //               color: 'danger'
+    //             });
+    //             break;
+    //           }
+    //         }
+    //         unwatch();
+    //       }
+    //     },
+    //     {
+    //       immediate: true
+    //     }
+    //   );
+    // }
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function getDoneTaskPage(query) {
+  const res = await request({
+    url: '/bpm/task/done-page',
+    method: 'post',
+    data: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export function completeTask(data) {
+  return request({
+    url: '/bpm/task/complete',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export async function approveTask(data) {
+  const res = await request({
+    url: '/bpm/task/approve',
+    method: 'PUT',
+    data: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export function rejectTask(data) {
+  return request({
+    url: '/bpm/task/reject',
+    method: 'PUT',
+    data: data
+  });
+}
+export function cancelTask(data) {
+  return request({
+    url: '/bpm/process-instance/cancel',
+    method: 'post',
+    data: data
+  });
+}
+
+export function backTask(data) {
+  return request({
+    url: '/bpm/task/back',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export function updateTaskAssignee(data) {
+  return request({
+    url: '/bpm/task/update-assignee',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export async function getTaskListByProcessInstanceId(processInstanceId) {
+  const res = await request({
+    url:
+      '/bpm/task/list-by-process-instance-id?processInstanceId=' +
+      processInstanceId,
+    method: 'get'
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export function getReturnList(taskId) {
+  return request({
+    url: '/bpm/task/return-list?taskId=' + taskId,
+    method: 'get'
+  });
+}
+
+export function returnTask(data) {
+  return request({
+    url: '/bpm/task/return',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export function delegateTask(data) {
+  return request({
+    url: '/bpm/task/delegate',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export function approveTaskWithVariables(data) {
+  return request({
+    url: '/bpm/task/approveTaskWithVariables',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export function approveTaskWithVariablesOther(data) {
+  return request({
+    url: '/bpm/inwarehouse/assign',
+    method: 'post',
+    data: data
+  });
+}
+
+export function outApproveNotPass(data) {
+  return request({
+    url: '/bpm/outApprove/notPass',
+    method: 'PUT',
+    data: data
+  });
+}
+
+export function outinApproveNotPass(data) {
+  return request({
+    url: '/bpm/outinApprove/notPass',
+    method: 'PUT',
+    data: data
+  });
+}
+
+// 我的消息分页
+export async function notifyMessagePageAPI(data) {
+  const res = await request({
+    url: `/sys/notifymessage/page`,
+    method: 'post',
+    data: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 更新已读-指定消息ID
+ */
+export async function updateNotifyMessageReadByIdAPI(data) {
+  const res = await request({
+    url: `/sys/notifymessage/updateNotifyMessageRead`,
+    method: 'post',
+    data: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//工作流自定义表单集合
+export async function getBpmCustomFormPage(query) {
+  const res = await request({
+    url: '/flowable/bpmcustomform/page',
+    method: 'get',
+    params: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//工作流自定义权限过滤表单集合
+export async function getBpmCustomFormList(query) {
+  const res = await request({
+    url: '/flowable/bpmcustomform/list',
+    method: 'get',
+    params: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//工作流自定义表单保存
+export async function bpmCustomFormSave(data) {
+  const res = await request({
+    url: '/flowable/bpmcustomform/save',
+    method: 'post',
+    data
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//工作流自定义表单修改
+export async function bpmCustomFormUpdate(data) {
+  const res = await request({
+    url: '/flowable/bpmcustomform/update',
+    method: 'put',
+    data
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//工作流自定义表单修改
+export async function bpmCustomFormDelete(data) {
+  const res = await request({
+    url: '/flowable/bpmcustomform/delete',
+    method: 'delete',
+    data
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function getProcessInstancePage(query) {
+  const res = await request({
+    url: '/bpm/process-instance/my-page',
+    method: 'post',
+    data: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getProcessInstanceDeptPage(query) {
+  const res = await request({
+    url: '/bpm/process-instance/my-dept-page',
+    method: 'post',
+    data: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getProcessInstanceNoticePage(query) {
+  const res = await request({
+    url: '/bpm/process-instance/my-notice-page',
+    method: 'post',
+    data: query
+  });
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 我的抄送分页
+export async function ccPage(data) {
+  console.log(data);
+
+  const res = await request({
+    url: `/bpm/task/cc-page`,
+    method: 'post',
+    data
+  });
+
+  const res1 = await request({
+    url: `/bpm/task/cc-page`,
+    method: 'post',
+    data: {
+      pageNum: 1,
+      size: -1
+    }
+  });
+
+  if (res1.data.code == 0) {
+    const num = res1.data.data.list.filter(
+      (item) => item.processResult == 1
+    ).length;
+
+    store.dispatch('user/setMenuBadge', {
+      path: '/carbonCopy',
+      value: num || 0,
+      color: 'danger'
+    });
+  }
+
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 12 - 0
src/api/main/index.js

@@ -78,3 +78,15 @@ export async function getProduceTreeByCode(code) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+//h获取部门用户
+export async function getGroupUserTree(params) {
+  const res = await request.get(
+    `/main/group/getGroupUserTree`,
+    params
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 402 - 0
src/views/contractManage/contractReview/components/addDialog.vue

@@ -0,0 +1,402 @@
+<template>
+  <ele-modal
+    custom-class="ele-dialog-form long-dialog-form"
+    :centered="true"
+    :visible="addFlag"
+    :title="title"
+    append-to-body
+    :close-on-click-modal="false"
+    width="1100px"
+    :before-close="cancel"
+    :maxable="true"
+    :resizable="true"
+  >
+    <div style="height: 100%;">
+      <div>
+        <el-form
+          class="ele-form-search"
+        >
+          <el-row
+            :gutter="15"
+            style="display: flex; align-items: center"
+          >
+            <el-col v-bind="{ span: 10 }">
+              <el-form-item label="单据:" label-width="60px">
+                <el-select v-model="formId"
+                    @change="init"
+                >
+                  <el-option
+                    v-for="(item, index) in list"
+                    :key="index"
+                    :value="item.id"
+                    :label="item.name"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <div class="form-box">
+        <fm-generate-form
+          :preview="true"
+          class="el-form-box"
+          v-if="Object.keys(form?.formJson || {}).length !== 0"
+          :data="jsonData"
+          :value="form.valueJson"
+          ref="generateForm"
+        >
+          <!-- 客户名称 -->
+          <template v-slot:eom_contact="scope">
+            <div class="eom_contact">
+              <el-input
+                  v-model="scope.model.eom_contact.name"
+                  style="width: 100%"
+                  @click.native="addContact('eom_contact')"
+                ></el-input>
+            </div>
+          </template>
+        </fm-generate-form>
+      </div>
+    </div>
+
+    <div slot="footer">
+      <el-form :model="form">
+        <el-form-item label="通知人:">
+          <el-button
+            style="float: left; margin-top: 5px"
+            icon="el-icon-circle-plus-outline"
+            round
+            @click="handleEditDataScope"
+          ></el-button>
+          <div style="display: flex; flex-direction: row; flex-wrap: wrap">
+            <el-tag
+              style="float: left; margin: 5px 5px 0 5px"
+              v-for="(item, index) in form.noticeScope"
+              :key="item.name"
+              effect="plain"
+              closable
+              :title="item.name"
+              @close="handleCloseTag(index)"
+            >
+              {{
+                item.name.length > 3
+                  ? item.name[0] + item.name[1] + item.name[2] + '...'
+                  : item.name
+              }}
+            </el-tag>
+          </div>
+        </el-form-item>
+      </el-form>
+      <el-button type="primary" size="small" @click="submit">提交</el-button>
+      <el-button size="small" @click="cancel">关闭</el-button>
+      <staffSelection
+        ref="staffSelection"
+        @confirm="getTreeList"
+      ></staffSelection>
+    </div>
+    <parentList
+      ref="parentRef"
+      @changeParent="handleConcatConfirm"
+    ></parentList>
+  </ele-modal>
+</template>
+<script>
+  import {
+    getModelPage,
+    processInstanceCreateAPI
+  } from './api';
+  import { listRoles } from '@/api/system/role';
+  import dictMixins from '@/mixins/dictMixins';
+  import { getModel } from '@/api/bpm/model';
+  import { getToken } from '@/utils/token-util';
+  import { mapGetters } from 'vuex';
+  import staffSelection from '@/components/staffSelection/staffSelection.vue';
+  import dayjs from 'dayjs';
+  import parentList from '@/views/saleManage/contact/components/parentList.vue';
+  export default {
+    name: 'processSubmitDialog',
+    components: { staffSelection, parentList },
+    mixins: [dictMixins],
+    props: {
+      addFlag: {
+        type: Boolean,
+        default: false
+      },
+      list: {
+        type: Array,
+        default: () => []
+      },
+    },
+    watch: {
+      filterText(val) {
+        this.$refs.tree.filter(val);
+      }
+    },
+    data() {
+      return {
+        jsonData: {},
+        form: {
+          LCFL: '',
+          FQLC: '',
+          processDefinitionId: '',
+          name: '',
+          businessId: '',
+          noticeScope: [],
+          formJson: {},
+          valueJson: {},
+          businessKey: ''
+        },
+        formId: '',
+        title: '',
+        active: 0,
+        filterText: null,
+        treeList: [],
+        treeData: [],
+        defaultProps: {
+          children: 'children',
+          label: 'name'
+        },
+        processList: [],
+        datasource: [],
+        roleOptions: [],
+        editForm: {
+          start: '',
+          end: '',
+          days: ''
+        },
+      };
+    },
+    computed: {
+      ...mapGetters(['user']),
+    },
+    async created() {
+      // 获得角色列表
+      this.roleOptions = [];
+      listRoles({
+        current: 1,
+        size: 9999
+      }).then((data) => {
+        this.roleOptions.push(...data.list);
+      });
+
+    },
+    mounted() {
+    },
+    methods: {
+      async addContact(type) {
+        console.log(type);
+        let data = await this.$refs.generateForm.getData(false);
+        console.log('data', data);
+        data[type] = {
+          id: '',
+          name: ''
+        };
+        this.$refs.generateForm.setData({
+          type: data[type]
+        });
+        let item = {
+          id: data[type].id
+        };
+        this.$refs.parentRef.open(item);
+      },
+
+      async handleConcatConfirm(item) {
+        console.log('选择的客户', item);
+
+        let data = await this.$refs.generateForm.getData(false);
+        data['eom_contact'] = {
+          id: item.id,
+          name: item.name
+        }
+        this.$refs.generateForm.setData({
+          'eom_contact': data['eom_contact']
+        });
+        console.log('data~~~~', data);
+      },
+      async init(id) {
+        const row = this.list.find(item => item.id === id) || {};
+        console.log('row', row);
+        this.title = row.name; //'新建' + row.name + '单';
+        this.form = _.cloneDeep(row);
+        this.form.formId = row.id;
+        this.$set(this.form, 'noticeScope', []);
+        this.$set(this.form, 'LCFL', '');
+        this.$set(this.form, 'FQLC', '');
+        this.$set(this.form, 'name', '');
+        this.$set(this.form, 'key', '');
+        this.$set(this.form, 'valueJson', {});
+        this.jsonData = JSON.parse(this.form.formJson.makingJson);
+        console.log('jsonData', this.jsonData);
+
+        this.jsonData.config.dataSource &&
+          this.jsonData.config.dataSource.forEach((item) => {
+            item.headers = {
+              Authorization: getToken()
+            };
+            // item.url = item.url && item.url.replace('/api', this.APIUrl);
+          });
+        this.jsonData.list.forEach((item) => {
+          if (item.type == 'deptAndUserCascader') {
+          }
+          if (item.type == 'deptCascader') {
+            if (item.options.isDefaultLoginUser) {
+              this.form.valueJson[item.model] = this.user.info.groupIdList;
+            }
+          }
+          if (item.type == 'userSelect') {
+            if (item.options.isDefaultLoginUser) {
+              this.form.valueJson[item.model] = this.user.info.userId;
+            }
+          }
+          if (item.type == 'imgupload') {
+            // this.form.valueJson[item.model].length &&
+            //   this.form.valueJson[item.model].forEach((item) => {
+            //     //item.objectUrl = this.APIUrl +'/kd-aiot' + item.storePath
+            //     // item.objectUrl = item.url;
+            //     // console.log(item);
+            //   });
+          }
+        });
+        await this.getDefaultInfo(row.processModelId);
+      },
+      async getDefaultInfo(businessKey) {
+        let info = await getModel(businessKey);
+        this.form.LCFL = info?.category;
+        this.form.FQLC = info?.id;
+        this.form.name = this.title;
+        this.form.key = info?.key;
+        if (this.form.LCFL) await this.getProcessList(this.form.LCFL);
+      },
+      async getProcessList(val) {
+        let params = {
+          pageNo: 1,
+          pageSize: 999,
+          processTypeId: val
+        };
+        const { list } = await getModelPage(params);
+        this.processList = list.filter((item) => item.processDefinition);
+      },
+      handleEditDataScope() {
+        this.$refs.staffSelection.open(this.form.noticeScope);
+      },
+      getTreeList(list) {
+        list.forEach((item) => {
+          item.type = 1;
+        });
+        this.form.noticeScope = list;
+      },
+      handleCloseTag(index) {
+        this.form.noticeScope.splice(index, 1);
+      },
+
+
+      generateFormValid(validate = true) {
+        return this.$refs.generateForm.getData(validate).then((data) => {
+          return data;
+        });
+      },
+
+      async submit() {
+
+        let data = await this.$refs.generateForm.getData(false);
+        
+        this.form.valueJson = await this.generateFormValid()
+        this.form.processType = '1';
+        console.log('formformformform', this.form);
+        await processInstanceCreateAPI({
+          ...this.form,
+          variables: { ...this.form.valueJson }
+        });
+        this.$message('提交审核成功');
+        this.$emit('reload');
+        this.cancel();
+      },
+      cancel() {
+        this.$emit('update:addFlag', false);
+      },
+      getDays(start, end) {
+        const startDay = dayjs(start);
+        const endDay = dayjs(end);
+        const diffInMilliseconds = endDay.diff(startDay);
+
+        // 计算天数
+        const days = Math.floor(diffInMilliseconds / (1000 * 60 * 60 * 24));
+        // 计算剩余小时数
+        const hours = Math.floor(
+          (diffInMilliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)
+        );
+        // 计算剩余分钟数
+        const minutes = Math.floor(
+          (diffInMilliseconds % (1000 * 60 * 60)) / (1000 * 60)
+        );
+        // 计算剩余秒数
+        const seconds = Math.floor((diffInMilliseconds % (1000 * 60)) / 1000);
+
+        let result = '';
+        if (days > 0) result += `${days} 天 `;
+        if (hours > 0) result += `${hours} 小时 `;
+        if (minutes > 0) result += `${minutes} 分钟 `;
+        if (seconds > 0) result += `${seconds} 秒`;
+        return result.trim();
+      }
+    }
+  };
+</script>
+<style scoped lang="scss">
+  .box {
+    display: flex;
+    height: 450px;
+
+    .left-box {
+      width: 55%;
+      border-right: 1px solid #e2e4e7;
+      padding-right: 15px;
+      height: 100%;
+
+      .el-tree {
+        height: 85%;
+        overflow-y: auto;
+      }
+    }
+
+    .right-box {
+      flex: 1;
+      padding-left: 20px;
+      height: 100%;
+
+      .right-box-item {
+        margin-top: 5px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+      }
+    }
+  }
+
+  .form-box {
+    // max-height: 500px;
+    min-width: 400px;
+    overflow: auto;
+    background: #4298fd0d;
+  }
+  ::v-deep .el-dialog {
+    min-width: 400px;
+    .el-dialog__header {
+      background: #1890ffd6;
+    }
+    .el-dialog__title,
+    .el-dialog__close {
+      color: #ffffff;
+    }
+  }
+  .blank_adopzrdd {
+    display: flex;
+    align-items: center;
+    > span {
+      display: inline-block;
+      width: 80px;
+    }
+    margin-bottom: 10px;
+  }
+</style>

+ 89 - 0
src/views/contractManage/contractReview/components/api.js

@@ -0,0 +1,89 @@
+import request from '@/utils/request';
+
+export async function getProcessDefinitionBpmnXML(id) {
+  const res = await request({
+    url: '/bpm/process-definition/get-bpmn-xml?id=' + id,
+    method: 'get'
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getTaskAssignRuleList(query) {
+  const res = await request({
+    url: '/bpm/task-assign-rule/list',
+    method: 'get',
+    params: query
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function processInstanceCreateAPI(data) {
+  const res = await request(
+    {
+      url: '/bpm/process-instance/create',
+      method: 'post',
+      data
+    },
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getModelPage(query) {
+  const res = await request({
+    url: '/bpm/model/page',
+    method: 'get',
+    params: query
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function getProcessDefinitionInfo(params) {
+  const res = await request({
+    url: `/bpm/process-definition/get`,
+    method: 'get',
+    params
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+export async function listAllUserBind() {
+  const res = await request.get('/main/user/listAllUserBind');
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取用户组精简信息列表
+export async function listSimpleUserGroups() {
+  const res = await request({
+    url: '/bpm/user-group/list-all-simple',
+    method: 'get'
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 获取客户信息列表
+ */
+export async function contactPageUsages(params) {
+  const res = await request.get(`/eom/contact/page2Usages`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+

+ 487 - 0
src/views/contractManage/contractReview/index.vue

@@ -0,0 +1,487 @@
+<template>
+  <div class="ele-body">
+    <el-card
+      shadow="never"
+    >
+      <div class="filter-container">
+        <el-form
+          class="ele-form-search"
+          @keyup.enter.native="reload"
+          @submit.native.prevent
+        >
+          <el-row
+            :gutter="15"
+            style="display: flex; align-items: center"
+          >
+            <!-- <el-col v-bind="{ span: 4 }">
+              <el-form-item label="分类:" label-width="60px">
+                <el-select v-model="params.dictType">
+                  <el-option
+                    v-for="(item, index) in dictList[
+                      'collaborative_type'
+                    ]"
+                    :key="index"
+                    :value="item.value"
+                    :label="item.label"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col> -->
+            <el-col v-bind="{ span: 6 }">
+              <el-form-item label="单据:" label-width="60px">
+                <el-select v-model="params.formId">
+                  <el-option
+                    v-for="(item, index) in templateList"
+                    :key="index"
+                    :value="item.id"
+                    :label="item.name"
+                  ></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col v-bind="{ span: 6 }">
+              <el-form-item
+                label="结果:"
+                prop="result"
+                label-width="60px"
+              >
+                <DictSelection
+                  dictName="流程实例的结果"
+                  clearable
+                  v-model="params.result"
+                >
+                </DictSelection>
+              </el-form-item>
+            </el-col>
+            <el-col v-bind="{ span: 6 }">
+              <el-form-item
+                label="创建时间:"
+                prop="createTime1"
+                label-width="90px"
+              >
+                <el-date-picker
+                  v-model="createTime1"
+                  style="width: 100%"
+                  value-format="yyyy-MM-dd HH:mm:ss"
+                  type="daterange"
+                  range-separator="-"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                  :default-time="['00:00:00', '23:59:59']"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col v-bind="{ span: 6 }">
+              <el-form-item>
+                <el-button
+                  type="primary"
+                  icon="el-icon-search"
+                  class="ele-btn-icon"
+                  @click="reload"
+                >
+                  查询
+                </el-button>
+                <el-button @click="reset">重置</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <ele-pro-table
+        ref="table"
+        height="calc(100vh - 350px)"
+        :columns="columns"
+        :datasource="datasource"
+        :init-load="false"
+        @columns-change="handleColumnChange"
+        :cache-key="cacheKeyUrl"
+        :page-size="20"
+      >
+        <template v-slot:toolbar="{ row }">
+          <el-button
+            type="primary"
+            icon="el-icon-search"
+            class="ele-btn-icon"
+            @click="handleStartProcess"
+          >
+            新建
+          </el-button>
+        </template>
+        <template v-slot:result="{ row }">
+          <el-tag
+            size="medium"
+            :type="
+              getTimelineItemType(
+                getDictValue('流程实例的结果', row.result)
+              )
+            "
+          >
+            {{ getDictValue('流程实例的结果', row.result) }}
+          </el-tag>
+        </template>
+        <template v-slot:dictType="{ row }">
+          {{ getDictV('collaborative_type', row.dictType) }}
+        </template>
+        <template v-slot:durationInMillis="{ row }">
+          {{ getDateTime(row.durationInMillis) }}
+        </template>
+        <template v-slot:name="{ row }">
+          <el-link
+            type="primary"
+            :underline="false"
+            @click="handleDetail(row)"
+          >
+            {{ row.name }}
+          </el-link>
+        </template>
+        <template
+          v-if="formColumnList.length"
+          v-for="(item, index) in formColumnList"
+          v-slot:[item.model]="{ row }"
+        >
+          <div v-if="item.type == 'imgupload'">
+            <el-image
+              v-if="row[item.model].length"
+              style="width: 100px; height: 100px"
+              :src="row[item.model][0].url"
+              :preview-src-list="row[item.model].map((i) => i.url)"
+            >
+            </el-image>
+          </div>
+          <div v-else-if="item.type == 'fileupload'">
+            <el-button
+              type="text"
+              v-if="row[item.model]?.length"
+              @click="getFiles(row[item.model])"
+              >下载
+            </el-button>
+          </div>
+
+          <div v-else-if="item.type == 'userSelect'">
+            {{ getUserName(row[item.model]) }}
+          </div>
+          <div v-else-if="item.type == 'deptAndUserCascader'">
+            {{ getDeptAndUserName(row[item.model]) }}
+          </div>
+          <div v-else-if="item.type == 'deptCascader'">
+            {{ getDeptName(row[item.model]) }}
+          </div>
+          <div v-else>
+            {{ row[item.model] }}
+          </div>
+        </template>
+        <!-- 操作列 -->
+        <!-- <template v-slot:action="{ row }">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-edit"
+            @click="handleAudit(row)"
+            >详情
+          </el-button>
+        </template> -->
+      </ele-pro-table>
+    </el-card>
+    <add-dialog
+      :add-flag.sync="addFlag"
+      v-if="addFlag"
+      :list="templateList"
+      ref="addDialogRef"
+      @reload="reload"
+    ></add-dialog>
+  </div>
+</template>
+<script>
+  import {
+    getBpmCustomFormList,
+    getProcessInstancePage
+  } from '@/api/bpm/task';
+  import { getDate } from '@/utils/dateUtils';
+  import dictMixins from '@/mixins/dictMixins';
+  // import detail from '@/views/bpm/processInstance/detail.vue';
+  // import formDetail from './detail.vue';
+  import { getByCode } from '@/api/system/dictionary-data';
+  import { getFile } from '@/api/system/file';
+  import { getUserPage } from '@/api/system/organization';
+  import { listOrganizations } from '@/api/system/organization';
+  import tabMixins from '@/mixins/tableColumnsMixin';
+  import addDialog from './components/addDialog.vue';
+
+  // 默认表单数据
+  const defaultParams = {
+    dictType: '5',
+    status: '',
+    name: '',
+    formId: ''
+  };
+  export default {
+    name: 'index',
+    components: {
+      addDialog
+      // detail,
+      // formDetail
+    },
+    mixins: [dictMixins, tabMixins],
+    data() {
+      return {
+        cacheKeyUrl: 'wt-eaf1548b-collaborative',
+        addFlag: false,
+        formDetailDialogFlag: false,
+        templateList: {},
+        dictList: {},
+        defaultTemplateList: [],
+        userList: [],
+        deptList: [],
+        params: { ...defaultParams },
+        statusList: [],
+        formColumnList: [],
+        createTime1: [],
+      };
+    },
+    computed: {
+      // 是否开启响应式布局
+      styleResponsive() {
+        return this.$store.state.theme.styleResponsive;
+      },
+      columns() {
+        let list = this.formColumnList.map((item) => {
+          return {
+            prop: item.model,
+            label: item.name,
+            align: 'center',
+            slot: item.model,
+            showOverflowTooltip: true,
+            minWidth: 120
+          };
+        });
+        return [
+          {
+            columnKey: 'index',
+            label: '序号',
+            type: 'index',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+          {
+            prop: 'dictType',
+            label: '分类',
+            align: 'center',
+            slot: 'dictType',
+            showOverflowTooltip: true,
+            minWidth: 70
+          },
+          {
+            prop: 'formName',
+            label: '单据',
+            align: 'center',
+            slot: 'formName',
+            showOverflowTooltip: true,
+            minWidth: 70
+          },
+          {
+            prop: 'name',
+            label: '名称',
+            align: 'center',
+            slot: 'name',
+            showOverflowTooltip: true,
+            minWidth: 80
+          },
+          ...list,
+          {
+            prop: 'result',
+            slot: 'result',
+            label: '结果',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 80
+          },
+          {
+            prop: 'endTime',
+            label: '审批时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 120
+          },
+          {
+            prop: 'createTime',
+            label: '创建时间',
+            align: 'center',
+            showOverflowTooltip: true,
+            minWidth: 120
+          },
+          {
+            columnKey: 'action',
+            label: '操作',
+            width: 100,
+            align: 'center',
+            resizable: false,
+            slot: 'action',
+            showOverflowTooltip: true,
+            fixed: 'right'
+          }
+        ];
+      },
+      getUserName() {
+        return (id) => {
+          if (!id) return '';
+          let find = this.userList.find((item) => item.id == id) || {};
+          return find.name;
+        };
+      },
+      getDeptAndUserName() {
+        return (id = []) => {
+          if (!id.length) return '';
+          id = Array.isArray(id) ? id : [id];
+          let find =
+            this.userList.find((item) => item.id == id[id.length - 1]) || {};
+          return find.name;
+        };
+      },
+      getDeptName() {
+        return (id = []) => {
+          if (!id.length) return '';
+          id = Array.isArray(id) ? id : [id];
+          let find =
+            this.deptList.find((item) => item.id == id[id.length - 1]) || {};
+          return find.name;
+        };
+      }
+    },
+    watch: {
+      'params.formId': {
+        handler(val) {
+          this.reload();
+        }
+      },
+    },
+    async mounted() {
+      await this.getDictList('collaborative_type');
+      await this.getTemplateList();
+      await this.getUserList();
+      await this.getDeptList();
+    },
+    methods: {
+      getDictV(code, val) {
+        if (!this.dictList[code]) return '';
+        return this.dictList[code].find((item) => item.value == val)?.label;
+      },
+      async getDictList(code) {
+        let { data: res } = await getByCode(code);
+        this.dictList[code] = res.map((item) => {
+          let values = Object.keys(item);
+          return {
+            value: values[0],
+            label: item[values[0]]
+          };
+        });
+      },
+      //获取人员数据
+      async getUserList() {
+        let params = { pageNum: 1, size: -1 };
+        let { list } = await getUserPage(params);
+        this.userList = list;
+      },
+      //获取部门数据
+      async getDeptList() {
+        this.deptList = await listOrganizations();
+      },
+      getFiles(row = []) {
+        row.forEach((item) => {
+          getFile({ objectName: item.storePath }, item.name);
+        });
+      },
+      async getTemplateList() {
+        this.defaultTemplateList = await getBpmCustomFormList({ status: 1 });
+        this.templateList = _.groupBy(this.defaultTemplateList, 'dictType')['5'];
+        // this.params.dictType = this.dictList['collaborative_type'][0].value;
+        this.params.formId = this.templateList[0]?.id;
+        let makingJson =
+          JSON.parse(this.defaultTemplateList[0].formJson.makingJson) || {};
+        this.formColumnList = makingJson.list;
+        console.log(this.formColumnList);
+      },
+      handleStartProcess() {
+        this.addFlag = true;
+        // this.$nextTick(() => {
+        //   this.$refs.addDialogRef.init();
+        // });
+      },
+      /* 表格数据源 */
+      async datasource({ page, limit, where, order }) {
+        let [createTimeBegin, createTimeEnd] = this.createTime1 || [];
+
+        let data = await getProcessInstancePage({
+          pageNo: page,
+          pageSize: limit,
+          ...this.params,
+          processType: '1',
+          createTimeBegin,
+          createTimeEnd
+        });
+        data = data.list.map((item) => {
+          return {
+            ...item,
+            ...item.valueJson
+          };
+        });
+        return data;
+      },
+      /* 刷新表格 */
+      reload(where) {
+        let find =
+          this.defaultTemplateList.find(
+            (item) => item.id == this.params.formId
+          ) || {};
+        let makingJson = JSON.parse(find.formJson.makingJson) || {};
+        this.formColumnList = makingJson.list;
+        this.$refs.table.reload({ page: 1, where });
+        this.$refs.table.reRenderTable();
+      },
+
+      /*  重置 */
+      reset() {
+        this.params = { ...defaultParams };
+        this.createTime1 = [];
+        this.params.dictType = this.dictList['collaborative_type'][0].value;
+        this.params.formId = this.templateList[this.params.dictType][0]?.id;
+
+        this.reload();
+      },
+      /**  */
+      handleAudit(row) {
+        this.$refs.detailRef.open(row.id);
+      },
+      /**  */
+      handleDetail(row) {
+        this.formDetailDialogFlag = true;
+        this.$nextTick(() => {
+          this.$refs.formDetailDialogRef.open(row);
+        });
+      },
+      getTimelineItemType(result) {
+        if (result === '通过') {
+          return 'success';
+        }
+        if (result === '不通过') {
+          return 'danger';
+        }
+        if (result === '取消') {
+          return 'info';
+        }
+        if (result === '处理中') {
+          return 'warning';
+        }
+
+        return '';
+      },
+      getDateTime(ms) {
+        return getDate(ms);
+      },
+    }
+  };
+</script>
+<style scoped lang="scss">
+
+</style>