Jelajahi Sumber

refactor(bpm): 重构协同办公列表摘要显示与表格列逻辑

将表单字段列改为统一的摘要列,通过解析 makingJson 动态渲染字段数据,并新增 getDeptUserName 和 getGroupUserTree 支持部门用户树形名称解析。清理已注释的旧表格列逻辑,优化代码格式。
yusheng 1 Minggu lalu
induk
melakukan
c2c99e5db1
1 mengubah file dengan 181 tambahan dan 85 penghapusan
  1. 181 85
      src/views/bpm/collaborative/index.vue

+ 181 - 85
src/views/bpm/collaborative/index.vue

@@ -53,10 +53,7 @@
         <!-- 表格 -->
         <template v-slot:content>
           <div class="tab-box el-form-box">
-            <el-tabs
-              @tab-click="tabClick"
-              v-model="activeName"
-            >
+            <el-tabs @tab-click="tabClick" v-model="activeName">
               <el-tab-pane
                 v-for="tab in tabOptions"
                 :key="tab.name"
@@ -73,13 +70,13 @@
                 @keyup.enter.native="handleSearch"
                 @submit.native.prevent
               >
-                <el-row
-                  :gutter="15"
-                  style="display: flex; align-items: center"
-                >
+                <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" @change="changeDictTypeChange">
+                      <el-select
+                        v-model="params.dictType"
+                        @change="changeDictTypeChange"
+                      >
                         <el-option
                           v-for="(item, index) in dictList[
                             'collaborative_type'
@@ -93,11 +90,12 @@
                   </el-col>
                   <el-col v-bind="{ span: 4 }">
                     <el-form-item label="单据:" label-width="60px">
-                      <el-select v-model="params.formId" @change="changeFormIdChange">
+                      <el-select
+                        v-model="params.formId"
+                        @change="changeFormIdChange"
+                      >
                         <el-option
-                          v-for="(item, index) in templateList[
-                                params.dictType
-                              ]"
+                          v-for="(item, index) in templateList[params.dictType]"
                           :key="index"
                           :value="item.id"
                           :label="item.name"
@@ -125,9 +123,7 @@
                       prop="startUserName"
                       label-width="70px"
                     >
-                      <el-input
-                        v-model="params.startUserName"
-                      ></el-input>
+                      <el-input v-model="params.startUserName"></el-input>
                     </el-form-item>
                   </el-col>
                   <el-col v-bind="{ span: 6 }">
@@ -184,7 +180,12 @@
             >
               <!-- 表头工具栏 -->
               <template v-slot:toolbar>
-                <el-button type="primary" class="el-icon-printer" size="small" @click="handlePrint">
+                <el-button
+                  type="primary"
+                  class="el-icon-printer"
+                  size="small"
+                  @click="handlePrint"
+                >
                   打印
                 </el-button>
               </template>
@@ -224,45 +225,80 @@
                   {{ 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)"
+              <template v-slot:remark="{ row }">
+                <div
+                  style="
+                    max-height: 180px;
+                    overflow: hidden;
+                    padding: 5px;
+                    overflow-y: auto;
+                  "
+                >
+                  <template
+                    v-if="row?.formJson?.makingJson"
+                    v-for="(item, index) in JSON.parse(
+                      row?.formJson?.makingJson
+                    )?.list.filter(
+                      (val) =>
+                        !['grid', 'blank', 'report', 'component','card','collapse','tabs','inline','divider','alert','table','subform','dialog'].includes(
+                          val.type
+                        )
+                    )"
                   >
-                  </el-image>
-                </div>
-                <div v-else-if="item.type == 'fileupload'">
-                  <fileMain
-                    v-if="row[item.model]?.length"
-                    type="view"
-                    v-model="row[item.model]"
-                  ></fileMain>
-                </div>
+                    <div style="display: flex">
+                      <div>{{ item.name }}:</div>
+                      <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'">
+                        <fileMain
+                          v-if="row[item.model]?.length"
+                          type="view"
+                          v-model="row[item.model]"
+                        ></fileMain>
+                      </div>
 
-                <div v-else-if="item.type == 'userSelect'">
-                  <el-link
-                    type="primary"
-                    :underline="false"
-                    @click="handleDetail(row)"
-                  >
-                    {{ getUserName(row[item.model]) }}
-                  </el-link>
-                </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>
-                  {{ formatValue(row[item.model]) }}
+                      <div
+                        v-else-if="
+                          [
+                            'deptCascader',
+                            'deptAndUserCascader',
+                            'userSelect'
+                          ].includes(item.type)
+                        "
+                      >
+                        <div
+                          style="white-space: initial"
+                          v-if="
+                            item.options.remoteDataSource == 'getGroupUserTree'
+                          "
+                        >
+                          {{ getDeptUserName(row[item.model]) }}
+                        </div>
+                        <div
+                          style="white-space: initial"
+                          v-else-if="
+                            item.options.remoteDataSource == 'getUserPage'
+                          "
+                        >
+                          {{ getUserName(row[item.model]) }}
+                        </div>
+                        <div style="white-space: initial" v-else>
+                          {{ getDeptName(row[item.model]) }}</div
+                        >
+                      </div>
+
+                      <div v-else>
+                        {{ formatValue(row[item.model]) }}
+                      </div>
+                    </div>
+                  </template>
                 </div>
               </template>
             </ele-pro-table>
@@ -305,6 +341,7 @@
   import { getUserPage } from '@/api/tickets';
   import { listOrganizations } from '@/api/system/organization';
   import tabMixins from '@/mixins/tableColumnsMixin';
+  import { getGroupUserTree } from '@/api/main';
 
   // 默认表单数据
   const defaultParams = {
@@ -333,6 +370,7 @@
         defaultTemplateList: [],
         userList: [],
         deptList: [],
+        groupUserTree: [],
         params: { ...defaultParams },
         statusList: [],
         formColumnList: [],
@@ -375,16 +413,18 @@
         return this.$store.state.theme.styleResponsive;
       },
       columns() {
-        let list = this.formColumnList.filter(item => item.name && item.name != '自定义区域').map((item) => {
-          return {
-            prop: item.model,
-            label: item.name,
-            align: 'center',
-            slot: item.model,
-            showOverflowTooltip: true,
-            minWidth: 120
-          };
-        });
+        // let list = this.formColumnList
+        //   .filter((item) => item.name && item.name != '自定义区域')
+        //   .map((item) => {
+        //     return {
+        //       prop: item.model,
+        //       label: item.name,
+        //       align: 'center',
+        //       slot: item.model,
+        //       showOverflowTooltip: true,
+        //       minWidth: 120
+        //     };
+        //   });
         return [
           {
             width: 45,
@@ -417,6 +457,14 @@
             showOverflowTooltip: true,
             minWidth: 70
           },
+          {
+            prop: 'remark',
+            label: '摘要',
+            align: 'center',
+            slot: 'remark',
+            showOverflowTooltip: true,
+            minWidth: 300
+          },
           {
             prop: 'name',
             label: '名称',
@@ -454,7 +502,7 @@
             align: 'center',
             showOverflowTooltip: true,
             minWidth: 120
-          },
+          }
 
           // {
           //   prop: 'durationInMillis',
@@ -477,16 +525,18 @@
         ];
       },
       deptColumns() {
-        let list = this.formColumnList.filter(item => item.name && item.name != '自定义区域').map((item) => {
-          return {
-            prop: item.model,
-            label: item.name,
-            align: 'center',
-            slot: item.model,
-            showOverflowTooltip: true,
-            minWidth: 120
-          };
-        });
+        // let list = this.formColumnList
+        //   .filter((item) => item.name && item.name != '自定义区域')
+        //   .map((item) => {
+        //     return {
+        //       prop: item.model,
+        //       label: item.name,
+        //       align: 'center',
+        //       slot: item.model,
+        //       showOverflowTooltip: true,
+        //       minWidth: 120
+        //     };
+        //   });
         return [
           {
             columnKey: 'index',
@@ -588,9 +638,24 @@
           return find.name;
         };
       },
+      getDeptUserName() {
+        return (id = []) => {
+          if (!id.length) return '';
+          return id
+            .map((pathArr) => {
+              const names = this.getNodeNamesByPath(
+                this.groupUserTree,
+                pathArr
+              );
+              return names.join('/');
+            })
+            .join(',');
+        };
+      },
       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]) || {};
@@ -625,6 +690,7 @@
       await this.getTemplateList();
       await this.getUserList();
       await this.getDeptList();
+      await this.getGroupUserTree();
       // 默认进入页面显示个人记录并加载其数据
       this.activeName = 'user';
       this.handleSearch();
@@ -667,6 +733,24 @@
       async getDeptList() {
         this.deptList = await listOrganizations();
       },
+      async getGroupUserTree() {
+        this.groupUserTree = await getGroupUserTree();
+      },
+      // 根据路径数组从树形结构中递归获取节点名称
+      getNodeNamesByPath(tree, pathArr) {
+        const names = [];
+        let nodes = tree;
+        for (const id of pathArr) {
+          const node = nodes.find((item) => item.id == id);
+          if (node) {
+            names.push(node.name);
+            nodes = node.children || [];
+          } else {
+            break;
+          }
+        }
+        return names;
+      },
       getFiles(row = []) {
         row.forEach((item) => {
           getFile({ objectName: item.storePath }, item.name);
@@ -681,9 +765,12 @@
         // this.params.formId = this.templateList[this.currentDictType][0]?.id;
         let makingJson =
           JSON.parse(this.defaultTemplateList?.[0]?.formJson?.makingJson) || {};
-          console.log('makingJson~~~', makingJson);
+        console.log('makingJson~~~', makingJson);
         this.formColumnList = makingJson.list;
-        console.log(this.formColumnList, this.templateList[this.currentDictType]);
+        console.log(
+          this.formColumnList,
+          this.templateList[this.currentDictType]
+        );
       },
       handleStartProcess(i) {
         this.processSubmitDialogFlag = true;
@@ -695,7 +782,13 @@
       async datasource({ page, limit, where, order }) {
         let [createTimeBegin, createTimeEnd] = this.createTime1 || [];
         let apiName = this.apiMap[this.activeName] || 'getProcessInstancePage';
-        let data = await this.callApi(apiName, page, limit, createTimeBegin, createTimeEnd);
+        let data = await this.callApi(
+          apiName,
+          page,
+          limit,
+          createTimeBegin,
+          createTimeEnd
+        );
         return {
           count: data.count,
           list: data.list.map((item) => {
@@ -725,12 +818,15 @@
       },
       /* 刷新表格:根据当前选中的 tab 刷新 */
       handleSearch(where) {
-        // let find =
-        //   this.defaultTemplateList.find(
-        //     (item) => item.id == this.currentFormId
-        //   ) || {};
-        // let makingJson = find.formJson?.makingJson ? JSON.parse(find.formJson.makingJson) || {} : {};
-        // this.formColumnList = makingJson.list;
+        let find =
+          this.defaultTemplateList.find(
+            (item) => item.id == this.currentFormId
+          ) || {};
+        let makingJson = find.formJson?.makingJson
+          ? JSON.parse(find.formJson.makingJson) || {}
+          : {};
+        console.log(makingJson, 'makingJson');
+        this.formColumnList = makingJson.list;
         this.$nextTick(() => {
           this.$refs.table.reload({ page: 1, where });
         });
@@ -801,7 +897,7 @@
       changeFormIdChange(v) {
         // this.currentFormId = v;
         this.handleSearch();
-      },
+      }
     }
   };
 </script>