Browse Source

流程转件功能优化

songxy 1 năm trước cách đây
mục cha
commit
3110ddefc6

+ 1 - 2
client_h5/.env.dev

@@ -1,5 +1,4 @@
-# VITE_BASE_URL='http://10.10.10.7:18080'
-VITE_BASE_URL='http://oa.zjugis.com:28080/'
+VITE_BASE_URL='http://10.10.10.7:18080'
 # VITE_BASE_URL='http://localhost:6090/'
 
 

+ 285 - 0
client_h5/src/components/flowForm copy.vue

@@ -0,0 +1,285 @@
+<template>
+  <div class="flow_form_box">
+    <div class="flow_container">
+      <template v-if="isShowTab">
+        <van-tabs v-model:active="currentActive" :sticky="true">
+          <van-tab title="基础信息">
+            <slot></slot>
+          </van-tab>
+          <van-tab title="审批意见">
+            <div class="flowOpinionBox">
+              <template v-if="templateOpinion.length > 0">
+                <div v-for="(item,index) in templateOpinion" :key="index" :class="{'flowOpinionItem': true, 'disabled': !item['isEditor']}">
+                  <h4>{{ item['opinionName'] }}</h4>
+                  <div class="content">
+                    <template v-if="item['isEditor']">
+                      <van-field
+                      v-model="currentOpinion.opinionContent"
+                      rows="3"
+                      autosize
+                      label=""
+                      type="textarea"
+                      maxlength="50"
+                      placeholder="请输入留言"
+                    />
+                  </template>
+                  <template v-else>
+                      <van-field
+                      v-model="item.opinionContent"
+                      rows="3"
+                      autosize
+                      label=""
+                      type="textarea"
+                      :disabled="true"
+                      maxlength="50"
+                      placeholder="请输入留言"
+                    />
+                  </template>
+                  </div>
+                  <div class="footer">
+                    <p>
+                      <span>办理人:</span>
+                      <span v-if="item['isEditor']">
+                        <template v-if="currentOpinion['sign'] && currentOpinion['sign'].indexOf('http') !== -1">
+                          <img class="signImg" :src="currentOpinion['sign']" />
+                        </template>
+                        <template v-else>
+                          {{ currentOpinion['sign'] }}
+                        </template>
+                      </span>
+                      <span v-else>
+                        <template v-if="item['sign'] && item['sign'].indexOf('http') !== -1">
+                          <img class="signImg" :src="item['sign']" />
+                        </template>
+                        <template v-else>
+                          {{ item['sign'] }}
+                        </template>
+                      </span>
+                    </p>
+                    <p>
+                      <span>办理时间:</span>
+                      <span>{{ item['isEditor'] ? currentOpinion['opinionTime'] : item['opinionTime']}}</span>
+                    </p>
+                  </div>
+                </div>
+              </template>
+            </div>
+          </van-tab>
+        </van-tabs>
+      </template>
+      <template v-else>
+        <slot></slot>
+      </template>
+    </div>
+    <div class="fixed-btn" v-if="isSubmitVisabled">
+      <van-button :disabled="isSubmitDisabled" round block type="primary" @click="submitHandle">
+          转件
+      </van-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { showNotify } from 'vant';
+import { closePage } from 'dingtalk-jsapi';
+import { formatDate, jsonToFormData } from "@/utils/common";
+import { FlowDTO, getNextActivity } from "@/service/flow";
+import { getTemplateOpinionListByFlowInstanceId, getOpinionListByFlowInstanceId } from '@/service/flow';
+
+defineOptions({
+  name: 'FlowForm'
+})
+const isSubmitVisabled = ref<boolean>(true)
+const isSubmitDisabled = ref<boolean>(false)
+const userInfo = JSON.parse(localStorage.getItem('_userInfo') as string);
+const userId: string = userInfo ? userInfo['id'] ?? '' : ''
+const signatureUrl: string = userInfo ? userInfo['signatureUrl'] ?? '' : ''
+const currentUserName: string = userInfo ? userInfo['nickname'] ?? '' : ''
+defineProps<{
+  data: any
+}>();
+const emit = defineEmits<{
+  (e: 'submit', payload?: any):void
+}>()
+const route = useRoute();
+const currentActive = ref<string>('基础信息')
+const { flowInstanceId, activityInstanceId, participant, _o, _top } = route.query as {
+  flowInstanceId: string
+  activityInstanceId: string
+  participant: string
+  _o: string
+  _top: string
+}
+if (_o && _o == 'v') {
+  isSubmitVisabled.value = false
+}
+const currentOpinion = ref({
+  id: '',
+  opinionContent: '',
+  opinionTime: '',
+  sign: ''
+})
+const isShowTab = ref<boolean>(true)
+const templateOpinion = ref<any[]>([])  //用来缓存展示节点
+getTemplateOpinionListByFlowInstanceId(flowInstanceId).then((tResult) => {
+  let tList = tResult.data ?? []
+  getOpinionListByFlowInstanceId(flowInstanceId).then((oResult) => {
+    const oList = oResult.data ?? []
+    if(oList.length === 0){
+      isShowTab.value = false;
+    }
+    if (oList.length > 0) { 
+      for (let i = 0; i < tList.length; i++) { 
+        const tItem = tList[i];
+        if (tItem['iDisplayOpinion'] === 0) {
+          tList.splice(i, 1)
+          i--;
+          continue;
+        }
+        tItem['opinions'] = []
+        for (let j = 0; j < oList.length; j++) { 
+          const oItem = oList[j]
+          if (oItem['status'] == '40') {
+            oList.splice(j, 1);
+            j--;
+            continue;
+          }
+          if (tItem['id'] === oItem['flowOpinionId']) {
+            if (_o !== 'v' && oItem['activityInstanceId'] === activityInstanceId && oItem['participantId'] === participant) {
+              oItem['isEditor'] = true;
+              currentOpinion.value.id = oItem['id']
+              currentOpinion.value.opinionContent = oItem['opinionContent'] ?? '同意'
+              currentOpinion.value.opinionTime = formatDate(new Date())
+              currentOpinion.value.sign = signatureUrl ? signatureUrl : currentUserName;
+            }
+            oItem['opinionTime'] = oItem['opinionTime'] ? formatDate(new Date(oItem['opinionTime'])) : ''
+            if (tItem['iHideNonFilledComment'] == 1 && !oItem['opinionContent'] && oItem['activityInstanceId'] !== activityInstanceId) continue;
+            templateOpinion.value.push({
+              opinionName: tItem['opinionName'],
+              opinionUserText: tItem['opinionUserText'],
+              opinionTimeText: tItem['opinionTimeText'],
+              ...oItem
+            })
+            continue
+          } 
+        }
+      }
+    }
+  })
+})
+
+const activityData: FlowDTO = {
+  activityInstanceId,
+  participantId: participant,
+  flowOpinion: "",
+};
+const router = useRouter();
+const submitHandle = async (): Promise<any> => {
+  emit('submit', async () => {
+    isSubmitDisabled.value = true;
+    //工作流转件
+    activityData.activityInstanceId = activityInstanceId;
+    activityData.participantId = participant;
+    activityData.flowOpinion = JSON.stringify(currentOpinion.value);
+    const result = await getNextActivity(jsonToFormData(activityData) as FormData);
+    if (result) {
+      //@ts-ignore
+      if (result.error_code) {
+        showNotify({
+          type: 'danger',
+          //@ts-ignore
+          message: result.msg,
+          position: 'top',
+          onClose() {
+            isSubmitDisabled.value = false;
+          }
+        });
+      } else {
+        showNotify({
+          type: 'primary',
+          message: '转件成功',
+          position: 'top',
+          onClose() {
+            isSubmitDisabled.value = false;
+            if (_top == '1') {
+              closePage({})
+            } else {
+              router.back();
+            }
+          }
+        });
+      }
+    }
+    return result;
+  });
+}
+</script>
+
+<style scoped lang="scss">
+.flow_form_box {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  background-color: #f7f8fa;
+  >.flow_container {
+    flex-grow: 1;
+    height: 0px;
+    overflow-y: scroll;
+  }
+  >.fixed-btn {
+    padding: 10px 20px;
+  }
+  .flowOpinionBox {
+    margin: 10px;
+    >.flowOpinionItem {
+      margin-bottom: 15px;
+      background-color: #fff;
+      padding: 10px 0px;
+      &.disabled {
+        >h4 {
+          color: #999;
+        }
+        
+        >.footer {
+          > p {
+            color: #999;
+          }
+        }
+      }
+      >h4 {
+        font-size: 17px;
+        margin: 0px;
+        padding: 0px 16px;
+      }
+      >.content {
+        :deep(.van-field__value) {
+          border: 1px solid #ececec;
+          border-radius: 5px;
+          padding: 10px
+        }
+      }
+      >.footer {
+        display: flex;
+        align-items: center;
+        padding: 0px 16px;
+        >p {
+          margin: 0px;
+          flex: 1;
+          white-space: nowrap;
+          color: #333;
+          >span {
+            display: inline-block;
+            &:first-child {
+              margin-right: 5px;
+            }
+          }
+          .signImg {
+            height: 30px;
+            vertical-align: middle;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 101 - 121
client_h5/src/components/flowForm.vue

@@ -8,88 +8,60 @@
           </van-tab>
           <van-tab title="审批意见">
             <div class="flowOpinionBox">
-              <template  v-for="(tItem,tIndex) in templateOpinions">
-                <template v-if="tItem['opinions'].length > 0">
-                  <div v-for="(item,index) in tItem['opinions']" :key="tIndex-index" :class="{'flowOpinionItem': true, 'disabled': !item['isEditor']}">
-                    <h4>{{ tItem['opinionName'] }}</h4>
-                    <div class="content">
-                      <template v-if="item['isEditor']">
-                        <van-field
-                        v-model="currentOpinion.opinionContent"
-                        rows="3"
-                        autosize
-                        label=""
-                        type="textarea"
-                        maxlength="50"
-                        placeholder="请输入留言"
-                      />
-                    </template>
-                    <template v-else>
-                        <van-field
-                        v-model="item.opinionContent"
-                        rows="3"
-                        autosize
-                        label=""
-                        type="textarea"
-                        :disabled="true"
-                        maxlength="50"
-                        placeholder="请输入留言"
-                      />
-                    </template>
-                    </div>
-                    <div class="footer">
-                      <p>
-                        <span>办理人:</span>
-                        <span v-if="item['isEditor']">
-                          <template v-if="currentOpinion['sign'] && currentOpinion['sign'].indexOf('http') !== -1">
-                            <img class="signImg" :src="currentOpinion['sign']" />
-                          </template>
-                          <template v-else>
-                            {{ currentOpinion['sign'] }}
-                          </template>
-                        </span>
-                        <span v-else>
-                          <template v-if="item['sign'] && item['sign'].indexOf('http') !== -1">
-                            <img class="signImg" :src="item['sign']" />
-                          </template>
-                          <template v-else>
-                            {{ item['sign'] }}
-                          </template>
-                        </span>
-                      </p>
-                      <p>
-                        <span>办理时间:</span>
-                        <span>{{ item['isEditor'] ? currentOpinion['opinionTime'] : item['opinionTime']}}</span>
-                      </p>
-                    </div>
-                  </div>
-                </template>
-                <template v-else>
-                  <div class="flowOpinionItem" :key="tIndex">
-                    <h4>{{ tItem['opinionName'] }}</h4>
-                    <div class="content">
+              <template v-if="templateOpinion.length > 0">
+                <div v-for="(item,index) in templateOpinion" :key="index" :class="{'flowOpinionItem': true, 'disabled': !item['isEditor']}">
+                  <h4>{{ item['opinionName'] }}</h4>
+                  <div class="content">
+                    <template v-if="item['isEditor']">
+                      <van-field
+                      v-model="currentOpinion.opinionContent"
+                      rows="3"
+                      autosize
+                      label=""
+                      type="textarea"
+                      maxlength="50"
+                      placeholder="请输入留言"
+                    />
+                  </template>
+                  <template v-else>
                       <van-field
-                        rows="3"
-                        autosize
-                        label=""
-                        type="textarea"
-                        :disabled="true"
-                        maxlength="50"
-                        placeholder="请输入留言"
-                      />
-                    </div>
-                    <div class="footer">
-                      <p>
-                        <span>办理人:</span>
-                        <span></span>
-                      </p>
-                      <p>
-                        <span>办理时间:</span>
-                        <span></span>
-                      </p>
-                    </div>
+                      v-model="item.opinionContent"
+                      rows="3"
+                      autosize
+                      label=""
+                      type="textarea"
+                      :disabled="true"
+                      maxlength="50"
+                      placeholder="请输入留言"
+                    />
+                  </template>
+                  </div>
+                  <div class="footer">
+                    <p>
+                      <span>办理人:</span>
+                      <span v-if="item['isEditor']">
+                        <template v-if="currentOpinion['sign'] && currentOpinion['sign'].indexOf('http') !== -1">
+                          <img class="signImg" :src="currentOpinion['sign']" />
+                        </template>
+                        <template v-else>
+                          {{ currentOpinion['sign'] ?? currentUserName }}
+                        </template>
+                      </span>
+                      <span v-else>
+                        <template v-if="item['sign'] && item['sign'].indexOf('http') !== -1">
+                          <img class="signImg" :src="item['sign']" />
+                        </template>
+                        <template v-else>
+                          {{ item['sign'] ??  userMap[item['userId'] ]}}
+                        </template>
+                      </span>
+                    </p>
+                    <p>
+                      <span>办理时间:</span>
+                      <span>{{ item['isEditor'] ? currentOpinion['opinionTime'] : item['opinionTime']}}</span>
+                    </p>
                   </div>
-                </template>
+                </div>
               </template>
             </div>
           </van-tab>
@@ -110,6 +82,7 @@
 <script setup lang="ts">
 import { showNotify } from 'vant';
 import { closePage } from 'dingtalk-jsapi';
+import { getSimpleUserMap } from '@/service/user'
 import { formatDate, jsonToFormData } from "@/utils/common";
 import { FlowDTO, getNextActivity } from "@/service/flow";
 import { getTemplateOpinionListByFlowInstanceId, getOpinionListByFlowInstanceId } from '@/service/flow';
@@ -122,6 +95,13 @@ const isSubmitDisabled = ref<boolean>(false)
 const userInfo = JSON.parse(localStorage.getItem('_userInfo') as string);
 const signatureUrl: string = userInfo ? userInfo['signatureUrl'] ?? '' : ''
 const currentUserName: string = userInfo ? userInfo['nickname'] ?? '' : ''
+
+const userMap = ref<any>({})
+async function initSimpleUserMap() {
+  userMap.value = await getSimpleUserMap()
+}
+initSimpleUserMap()
+
 defineProps<{
   data: any
 }>();
@@ -147,52 +127,52 @@ const currentOpinion = ref({
   sign: ''
 })
 const isShowTab = ref<boolean>(true)
-const templateOpinions = ref<any[]>([]);
-getTemplateOpinionListByFlowInstanceId(flowInstanceId).then((tResult) => {
+const templateOpinion = ref<any[]>([])  //用来缓存展示节点
+
+const initTemplateOptinionFunc = async () => {
+  const templateOpinions = [];
+  const tResult = await getTemplateOpinionListByFlowInstanceId(flowInstanceId);
   const tList = tResult.data ?? []
-  getOpinionListByFlowInstanceId(flowInstanceId).then((oResult) => {
-    const oList = oResult.data ?? []
-    if(oList.length === 0){
-      isShowTab.value = false;
+  const oResult = await getOpinionListByFlowInstanceId(flowInstanceId);
+  const oList = oResult.data ?? []
+  if (oList.length === 0) {
+    isShowTab.value = false;
+  }
+  for (let j = 0; j < oList.length; j++) { 
+    const oItem = oList[j]
+    if (oItem['status'] == '40') {
+      oList.splice(j, 1);
+      j--;
+      continue;
     }
-    if (oList.length > 0) { 
-      for (let i = 0; i < tList.length; i++) { 
-        const tItem = tList[i];
-        if (tItem['iDisplayOpinion'] === 0) {
-          tList.splice(i, 1)
-          i--;
-          continue;
-        }
-        tItem['opinions'] = []
-
-        for (let j = 0; j < oList.length; j++) { 
-          const oItem = oList[j]
-          if (tItem['id'] === oItem['flowOpinionId']) {
-            if (_o !== 'v' && oItem['activityInstanceId'] === activityInstanceId) {
-              oItem['isEditor'] = true;
-              currentOpinion.value.id = oItem['id']
-              currentOpinion.value.opinionContent = oItem['opinionContent'] ?? '同意'
-              currentOpinion.value.opinionTime = formatDate(new Date())
-              currentOpinion.value.sign = signatureUrl ? signatureUrl : currentUserName;
-            }
-            oItem['opinionTime'] = oItem['opinionTime'] ? formatDate(new Date(oItem['opinionTime'])) : ''
-            tItem['opinions'].push(oItem);
-            break;
-          } else {
-            if (j === oList.length - 1) {
-              if (tItem['iHideNonFilledComment'] == 1) {
-                tList.splice(i, 1)
-                i--;
-                continue;
-              }
-            }
-          }
-        }
+    const tItems = tList.filter((item: any) => {
+      return item['id'] === oItem['flowOpinionId']
+    })
+    if (tItems.length > 0) {
+      const tItem = tItems[0]
+      if (_o !== 'v' && oItem['activityInstanceId'] === activityInstanceId && oItem['participantId'] === participant) {
+        oItem['isEditor'] = true;
+        currentOpinion.value.id = oItem['id']
+        currentOpinion.value.opinionContent = oItem['opinionContent'] ?? '同意'
+        currentOpinion.value.opinionTime = formatDate(new Date())
+        currentOpinion.value.sign = signatureUrl ? signatureUrl : null;
       }
+      oItem['opinionTime'] = oItem['opinionTime'] ? formatDate(new Date(oItem['opinionTime'])) : ''
+      if (tItem['iHideNonFilledComment'] == 1 && !oItem['opinionContent'] && oItem['activityInstanceId'] !== activityInstanceId) continue;
+      templateOpinions.push({
+        opinionName: tItem['opinionName'],
+        opinionUserText: tItem['opinionUserText'],
+        opinionTimeText: tItem['opinionTimeText'],
+        ...oItem
+      })
     }
-    templateOpinions.value = tList
+  }
+  templateOpinions.sort((a, b) => {
+    return a.isEditor === b.isEditor ? 0 : a.isEditor ? -1 : 1
   })
-})
+  templateOpinion.value = templateOpinions;
+}
+initTemplateOptinionFunc();
 
 const activityData: FlowDTO = {
   activityInstanceId,

+ 17 - 16
client_h5/src/router/index.ts

@@ -15,22 +15,23 @@ const router = createRouter({
 
 // 路由加载前
 router.beforeEach(async (to, from, next) => {
-  getUserInfoPromise(true).then((isLogin) => {
-    next(); 
-    if (!isLogin) {
-      showDialog({
-        message: '很抱歉,用户未登录,请先重新加载!',
-        confirmButtonText: '重新加载',
-        beforeClose: function(action) {
-          if (action === 'confirm') {
-            closeDialog()
-            localStorage.clear();
-            window.location.reload()
-          }
-        },
-      })
-    }
-  })
+  next()
+  // getUserInfoPromise(true).then((isLogin) => {
+  //   next(); 
+  //   if (!isLogin) {
+  //     showDialog({
+  //       message: '很抱歉,用户未登录,请先重新加载!',
+  //       confirmButtonText: '重新加载',
+  //       beforeClose: function(action) {
+  //         if (action === 'confirm') {
+  //           closeDialog()
+  //           localStorage.clear();
+  //           window.location.reload()
+  //         }
+  //       },
+  //     })
+  //   }
+  // })
 })
 const setupRouter = (app: App<Element>): void => {
   app.use(router)