Browse Source

办件中心页面接口对接

songxy 11 months ago
parent
commit
9e7035f984

+ 118 - 87
client/src/api/oa/workflow/index.ts

@@ -1,9 +1,48 @@
 import request from '@/config/axios'
 
+export type InullyApplyFormType = {
+  id: string
+  nickname?: string
+  nullyApplyUserId: string
+  flowInstanceId: string
+  voidFlowInstanceId: string
+  iNullied: string
+  voidFlowCode: string
+  voidFlowDesc: string
+  voidFlowName: string
+  nullyApplyTime: string
+  nullyReason: string
+}
+export type CallbackFormType = {
+  flowInsId: string
+  currentActInsId: string
+  currentActTempId: string
+  participantId: string
+  position: string
+  callbackRemark: string
+  iBranchReturn?: string
+}
+
+const jsonToFormData = (json: Object) => {
+  const formData = new FormData()
+  const keys = Object.keys(json)
+  keys.forEach((key) => {
+    if (json[key] instanceof Object) {
+      formData.append(key, JSON.stringify(json[key]))
+    } else {
+      formData.append(key, json[key])
+    }
+  })
+  return formData
+}
 // 获取办件中心列表
 export const getHandlerCaseCenterList = async (data) => {
   return await request.postOriginal(
-    { url: '/HandlerCaseCenter/list', data: data, headersType: 'application/form-data' },
+    {
+      url: '/HandlerCaseCenter/list',
+      data: jsonToFormData(data),
+      headersType: 'application/form-data'
+    },
     '/workflow'
   )
 }
@@ -62,15 +101,10 @@ export const recoverActivity = async (data: {
   activityInstanceId: string
   participantId: string
 }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/HandlerCaseCenter/recoverActivity',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
@@ -79,15 +113,10 @@ export const recoverActivity = async (data: {
 
 //办件中心“解挂”操作
 export const addIHangUp = async (data: { activityInstanceId: string; isRecover: number }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/IHangUp/add',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
@@ -99,15 +128,10 @@ export const addINullyApply = async (data: {
   voidFlowInstanceId: string
   isRecover: number
 }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/INullyApply/add',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
@@ -115,29 +139,21 @@ export const addINullyApply = async (data: {
 }
 //办件中心“彻底作废”操作
 export const completelyVoidINullyApply = async (data: { flowInstanceId: string }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/INullyApply/completelyVoid',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
   )
 }
-//办件中心“退回”操作
-export const getCalBackActivity = async (data: {
-  activityInstanceId: string
-  flowInsId: string
-}) => {
-  // {"activityInstanceId": rowObj.ACTIVITYINSID, "flowInsId": rowObj.flowInsId}
+//办件中心“挂起”操作
+export const isHangUp = async (data: { activityInstanceId: string }) => {
+  // {"activityInstanceId": rowObj.ACTIVITYINSID}
   return await request.postOriginal(
     {
-      url: '/HandlerCaseCenter/getCalBackActivity',
+      url: '/Transfer/isHangUp',
       data: data,
       headersType: 'application/form-data'
     },
@@ -145,89 +161,109 @@ export const getCalBackActivity = async (data: {
   )
 }
 
-//办件中心“挂起”操作
-export const isHangUp = async (data: { activityInstanceId: string }) => {
-  // {"activityInstanceId": rowObj.ACTIVITYINSID}
+//效验该流程是否已经作废
+export const isFlowVoid = async (data: { flowInstanceId: string }) => {
   return await request.postOriginal(
     {
-      url: '/Transfer/isHangUp',
-      data: data,
+      url: '/Transfer/isVoid',
+      data: jsonToFormData(data),
+      headersType: 'application/form-data'
+    },
+    '/workflow'
+  )
+}
+//获取提交作废的参数
+export const getINullyApplyExample = async (data: {
+  voidFlowInstanceId: string
+  isRecover: number
+}) => {
+  return await request.postOriginal(
+    {
+      url: '/INullyApply/getExample',
+      data: jsonToFormData(data),
+      headersType: 'application/form-data'
+    },
+    '/workflow'
+  )
+}
+//办件中心“作废”操作
+export const saveINullyApply = async (data: { nullyApply: InullyApplyFormType }) => {
+  return await request.postOriginal(
+    {
+      url: '/INullyApply/save',
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
   )
 }
 
-//效验该流程是否已经作废
-export const isFlowVoid = async (data: { flowInstanceId: string }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    if (data[key] instanceof Object) {
-      formData.append(key, JSON.stringify(data[key]))
-    } else {
-      formData.append(key, data[key])
-    }
-  })
+//获取退回所在流程信息
+export const getCalBackActivityNew = async (data: {
+  activityInstanceId: string
+  flowInsId: string
+}) => {
   return await request.postOriginal(
     {
-      url: '/Transfer/isVoid',
-      data: formData,
+      url: '/HandlerCaseCenter/getCalBackActivityNew',
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
   )
 }
 
-//办件中心“作废”操作
-export const saveINullyApply = async (data: {
-  nullyApply: {
-    id: string
-    nullyApplyUserId: string
-    flowInstanceId: string
-    voidFlowInstanceId: string
-    iNullied: string
-    voidFlowCode: string
-    voidFlowDesc: string
-    voidFlowName: string
-    nullyApplyTime: string
-    nullyReason: string
+//检查退件
+export const checkReturnMethod = async (data: {
+  paramMap: {
+    flowInsId: string
+    currentActInsId: string
+    currentActTempId: string
+    participantId: string
+    position: string
+    callbackRemark: string
   }
+  backToActivitys: {
+    callbackActTempId: string
+    callbackActInsId: string
+  }[]
 }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    if (data[key] instanceof Object) {
-      formData.append(key, JSON.stringify(data[key]))
-    } else {
-      formData.append(key, data[key])
-    }
-  })
   return await request.postOriginal(
     {
-      url: '/INullyApply/save',
-      data: data,
+      url: '/HandlerCaseCenter/checkReturnMethod',
+      data: jsonToFormData(data),
+      headersType: 'application/form-data'
+    },
+    '/workflow'
+  )
+}
+//发起退回操作
+export const callbackActivitySure = async (data: {
+  paramMap: CallbackFormType
+  backToActivitys: {
+    callbackActTempId: string
+    callbackActInsId: string
+  }[]
+}) => {
+  return await request.postOriginal(
+    {
+      url: '/HandlerCaseCenter/callbackActivity',
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
   )
 }
-
 //公共待办件提示
 export const openOfficeTip = async (data: {
   activityInsId: string
   particiPantId: string
   isView: boolean
 }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/HandlerCaseCenter/openOfficeTip',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'
@@ -243,15 +279,10 @@ export const saveAndGetUrl = async (data: {
   userId: string | null
   isView: boolean
 }) => {
-  const keys = Object.keys(data)
-  const formData = new FormData()
-  keys.forEach((key) => {
-    formData.append(key, data[key])
-  })
   return await request.postOriginal(
     {
       url: '/HandlerCaseCenter/saveAndGetUrl',
-      data: formData,
+      data: jsonToFormData(data),
       headersType: 'application/form-data'
     },
     '/workflow'

+ 17 - 0
client/src/utils/tool.ts

@@ -47,3 +47,20 @@ export const getUserInfo = () => {
   const userInfo = wsCache.get(CACHE_KEY.USER)
   return userInfo.user ?? {}
 }
+
+/**
+ * 获取当前日期
+ */
+export const getCurrentDate = (isSecond: boolean = false) => {
+  const dateObj = new Date()
+  const year = dateObj.getFullYear()
+  const month = dateObj.getMonth() + 1
+  const day = dateObj.getDate()
+  if (!isSecond) return `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`
+  const hours = dateObj.getHours()
+  const min = dateObj.getMinutes()
+  const second = dateObj.getSeconds()
+  return `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day} ${
+    hours > 9 ? hours : '0' + hours
+  }:${min > 9 ? min : '0' + min}:${second > 9 ? second : '0' + second}`
+}

+ 115 - 0
client/src/views/OaSystem/officeCenter/mainOfficeCenter/callback.ts

@@ -0,0 +1,115 @@
+import type { CallbackFormType } from '@/api/oa/workflow'
+import { getCalBackActivityNew, checkReturnMethod, callbackActivitySure } from '@/api/oa/workflow'
+
+export type CallbackOptionType = {
+  success?: (msg: string) => void
+}
+const useCallback = (option: CallbackOptionType) => {
+  /**
+   * 退回
+   */
+  const callbackVisible = ref<boolean>(false)
+  const callbackTitle = ref<string>('退回至当前流程环节')
+  const callbacks = ref<any[]>([])
+  const callbackForm = reactive<CallbackFormType>({
+    flowInsId: '',
+    currentActInsId: '',
+    currentActTempId: '',
+    participantId: '',
+    position: '',
+    callbackRemark: '',
+    iBranchReturn: ''
+  })
+  const initCallbackFormData = (item: any) => {
+    callbackForm.flowInsId = item['flowInstanceId']
+    callbackForm.currentActInsId = item['currentActInsId']
+    callbackForm.currentActTempId = item['currentActTempId']
+    callbackForm.participantId = ''
+    callbackForm.position = ''
+    callbackForm.callbackRemark = ''
+  }
+  const callbackActivity = (item: any) => {
+    getCalBackActivityNew({
+      activityInstanceId: item['ACTIVITYINSID'],
+      flowInsId: item['FLOWINSID']
+    }).then((result: any) => {
+      callbackVisible.value = true
+      initCallbackFormData(result)
+      if (result.callbackParentNode.length > 0) {
+        callbackTitle.value = '退回至父流程环节'
+        callbacks.value = result.callbackParentNode
+      } else if (result.callbackNode.length > 0) {
+        callbackTitle.value = '退回至当前流程环节'
+        callbacks.value = result.callbackNode
+      }
+    })
+  }
+  const callbackSumbit = () => {
+    const backToActivitys = callbacks.value.map((item) => {
+      return {
+        callbackActTempId: item['activityTemplateId'],
+        callbackActInsId: item['id']
+      }
+    })
+    checkReturnMethod({
+      paramMap: callbackForm,
+      backToActivitys
+    }).then((res: any) => {
+      if (res && !res.msg) {
+        callbackForm['iBranchReturn'] = res.isReturnAllSameLevelNode ? 'false' : 'true'
+        if (
+          res.isReturnAllSameLevelNode ||
+          res.isChildToParent == 1 ||
+          res.isBackToChild == 1 ||
+          res.isHaveChild == 1
+        ) {
+          let confirmTip = '此退件将退回所有同级办理环节,是否确认退件?'
+          if (res.isChildToParent == 1) {
+            confirmTip = '此退件将退回至父流程,是否确认退件?'
+          } else if (res.isBackToChild == 1) {
+            confirmTip = '此退件将退回至子流程,是否确认退件?'
+          } else if (res.isHaveChild == 1) {
+            confirmTip = '此退件包含子流程退回,是否确认退件?'
+          } else if (res.isSameReturn == 1) {
+            confirmTip = '是否确认同级退件?'
+          }
+          ElMessageBox.confirm(confirmTip, 'Warning', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+            callbackActivitySure({
+              paramMap: callbackForm,
+              backToActivitys
+            }).then((res: any) => {
+              if (res) {
+                callbackVisible.value = false
+                option.success && option.success(res)
+              }
+            })
+          })
+        } else {
+          callbackActivitySure({
+            paramMap: callbackForm,
+            backToActivitys
+          }).then((res: any) => {
+            if (res) {
+              callbackVisible.value = false
+              option.success && option.success(res)
+            }
+          })
+        }
+      }
+    })
+  }
+  return {
+    callbackVisible,
+    callbackTitle,
+    callbacks,
+    callbackForm,
+    callbackActivity,
+    callbackSumbit
+  }
+}
+
+export default useCallback

+ 26 - 1
client/src/views/OaSystem/officeCenter/mainOfficeCenter/index.scss

@@ -75,7 +75,7 @@
             height: 2px;
             bottom: -1px;
             background-color: #fff;
-            z-index: 9999999;
+            z-index: 999;
           }
         }
       }
@@ -99,4 +99,29 @@
       justify-content: flex-end;
     }
   }
+}
+.callback_header {
+  margin-bottom: 20px;
+  >.title {
+    display: block;
+    margin-bottom: 10px;
+  }
+  >.callback_process {
+    font-size: 16px;
+    display: flex;
+    >li {
+      display: flex;
+      align-items: center;
+      border: 1px solid #409eff;
+      color: #409eff;
+      padding: 5px 12px;
+      font-size: 14px;
+      border-radius: 4px;
+      margin-right: 10px;
+      &.active {
+      background-color: #409eff;
+      color: #fff;
+      }
+    }
+  }
 }

+ 158 - 173
client/src/views/OaSystem/officeCenter/mainOfficeCenter/index.vue

@@ -43,17 +43,22 @@
         <el-form :inline="true" :model="searchForm" class="demo-form-inline">
           <el-form-item label="流程名称">
             <el-tree-select
-              v-model="value"
-              :data="flowTemplateNameTree"
+              :data="flowTemplates"
+              :props="defaultProps"
               :render-after-expand="false"
-              show-checkbox
-              default-expand-all
-              :props="{ label: 'name', value: 'id', children: 'children' }"
+              ref="treeRef"
               style="width: 240px"
+              default-expand-all
+              show-checkbox
             />
           </el-form-item>
           <el-form-item label="">
-            <el-input type="text" />
+            <el-input
+              type="text"
+              style="width: 280px"
+              v-model="sendData['searchVal']"
+              placeholder="业务编号/流程描述/流程名称"
+            />
           </el-form-item>
           <el-form-item>
             <el-button type="primary" @click="searchHandle">查询</el-button>
@@ -72,7 +77,7 @@
             color: '#233755',
             height: '50px'
           }"
-          @row-dblclick="dblclickHandle"
+          @row-dblclick="(item) => openFlowHandle(item)"
         >
           <el-table-column
             v-for="(item, index) in currentColumn"
@@ -92,7 +97,11 @@
                   split-button
                   type="primary"
                   @click="flowApplyHandle(scope.row)"
-                  @command="commandHandle"
+                  @command="
+                    (name) => {
+                      commandHandle(name, scope.row)
+                    }
+                  "
                 >
                   办理
                   <template #dropdown>
@@ -109,7 +118,7 @@
                 </el-dropdown>
               </template>
               <template v-else-if="currentTab === '90'">
-                <el-button type="primary" icon="Search" @click="lookHandle(scope.row)">
+                <el-button type="primary" icon="Search" @click="openFlowHandle(scope.row)">
                   查看
                 </el-button>
                 <el-popconfirm title="是否确定追回?" @confirm="recoverActivityHandle(scope.row)">
@@ -119,12 +128,12 @@
                 </el-popconfirm>
               </template>
               <template v-else-if="currentTab === '40'">
-                <el-button type="primary" icon="Search" @click="lookHandle(scope.row)">
+                <el-button type="primary" icon="Search" @click="openFlowHandle(scope.row)">
                   查看
                 </el-button>
               </template>
               <template v-else-if="currentTab === '20'">
-                <el-button type="primary" icon="Search" @click="lookHandle(scope.row)">
+                <el-button type="primary" icon="Search" @click="openFlowHandle(scope.row)">
                   查看
                 </el-button>
                 <el-popconfirm title="是否确定解挂?" @confirm="addIHangUpHandle(scope.row)">
@@ -134,14 +143,16 @@
                 </el-popconfirm>
               </template>
               <template v-else-if="currentTab === '160'">
-                <el-button type="primary" icon="Search" @click="lookHandle(scope.row)">
+                <el-button type="primary" icon="Search" @click="openFlowHandle(scope.row, '160')">
                   查看
                 </el-button>
-                <el-popconfirm title="是否确定恢复?" @confirm="addINullyApplyHandle(scope.row)">
-                  <template #reference>
-                    <el-button type="warning" icon="RefreshRight"> 恢复 </el-button>
-                  </template>
-                </el-popconfirm>
+                <el-button
+                  type="warning"
+                  icon="RefreshRight"
+                  @click="recoverINullyApplyHandle(scope.row)"
+                >
+                  恢复
+                </el-button>
                 <el-popconfirm
                   title="是否确定彻底作废?"
                   @confirm="completelyVoidINullyApplyHandle(scope.row)"
@@ -166,30 +177,97 @@
         />
       </div>
     </div>
+    <!-- 作废表单Dialog -->
+    <el-dialog v-model="nullyApplyVisible" :title="nullyApplyTitle" width="40%">
+      <el-form v-model="inullyApplyForm" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="申请人:">
+              <el-input v-model="inullyApplyForm.nickname" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="申请时间:">
+              <el-input v-model="inullyApplyForm.nullyApplyTime" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="申请原因:">
+              <el-input
+                type="textarea"
+                rows="5"
+                style="width: 100%"
+                v-model="inullyApplyForm.nullyReason"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="nullyApplyVisible = false">关闭</el-button>
+          <el-button type="primary" @click="nullyApplySubmit">提交</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 退回表单Dialog -->
+    <el-dialog v-model="callbackVisible" title="退回" width="40%">
+      <el-form v-model="callbackForm" label-width="100px">
+        <div class="callback_header">
+          <span class="title">{{ callbackTitle }}</span>
+          <ul class="callback_process">
+            <li
+              v-for="(item, index) in callbacks"
+              :key="index"
+              :class="{ active: index === 0 }"
+              :icon="Edit"
+            >
+              <el-icon style="margin-right: 2px">
+                <DArrowRight />
+              </el-icon>
+              <span>{{ item['name'] }}</span>
+            </li>
+          </ul>
+        </div>
+        <div class="callback_header">
+          <span class="title">请填写退回原因</span>
+          <el-input
+            type="textarea"
+            rows="5"
+            style="width: 100%"
+            v-model="callbackForm.callbackRemark"
+          />
+        </div>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="callbackVisible = false">关闭</el-button>
+          <el-button type="primary" @click="callbackSumbit">提交</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup lang="ts">
-import { listToTree } from '@/utils/tree'
-import { openFlow } from '@/utils/flow'
+import { Edit } from '@element-plus/icons-vue'
+import { defaultProps, handleTree } from '@/utils/tree'
 import {
   getHandlerCaseCenterList,
   getHandlerCaseCenterCount,
   getFlowTemplateTreeDataByUser,
   getFlowTemplateTree,
-  addTProcessEngine,
   recoverActivity,
-  addIHangUp,
-  addINullyApply,
-  completelyVoidINullyApply,
-  isFlowVoid,
-  saveINullyApply,
-  openOfficeTip,
-  saveAndGetUrl
+  addIHangUp
 } from '@/api/oa/workflow'
 import { TabColumns } from './common'
+import { InullyApplyEnum, InullyApplyEnumType } from './inullyApply'
+import useLookAndApplyFlow from './lookAndApplyFlow'
+import useInullyApply from './inullyApply'
+import useCallback from './callback'
 
-const router = useRouter()
 const message = useMessage()
 const currentTab = ref<string>('1')
 const currentColumn = ref<any[]>(TabColumns[currentTab.value])
@@ -202,7 +280,7 @@ const pageParam = reactive<{
   pageNo: 1,
   pageSize: 10
 })
-const sendData = {
+const sendData = reactive({
   _search: false,
   status: 1,
   flowTemIds: [],
@@ -210,20 +288,17 @@ const sendData = {
   isMobile: false,
   queryMethod: 0,
   toSystemId: '',
-  excludedSystemId: ''
-}
+  excludedSystemId: '',
+  page: 1,
+  rows: 10
+})
 /**
  * 初始化流程列表
  */
 const queryHandlerCaseCenterList = () => {
   sendData['page'] = pageParam['pageNo']
   sendData['rows'] = pageParam['pageSize']
-  const formData = new FormData()
-  const keys = Object.keys(sendData)
-  for (let key of keys) {
-    formData.set(key, sendData[key])
-  }
-  getHandlerCaseCenterList(formData).then((result: any) => {
+  getHandlerCaseCenterList(sendData).then((result: any) => {
     if (result.rows && result.rows.length > 0) {
       result.rows.forEach((item) => {
         item['btnArrJson'] = item['btnArrJson'] ? JSON.parse(item['btnArrJson']) : []
@@ -314,26 +389,10 @@ const initFlowTemplateTree = () => {
 }
 initFlowTemplateTree()
 
-/**
- * 通过流程模板发起流程
- */
-const addTProcessHandle = (item) => {
-  addTProcessEngine(item['id']).then((result) => {
-    router.push({
-      path: '/processContainer',
-      query: {
-        iframe: '1',
-        iFrameId: item['id'],
-        url: result,
-        title: item['name']
-      }
-    })
-  })
-}
 /**
  * 初始化搜索条件中流程名称Tree结构数据
  */
-const flowTemplateNameTree = ref<any>()
+const flowTemplates = ref<any[]>([])
 const queryFlowTemplateTreeDataByUser = (officeStatus = '1') => {
   const formData = new FormData()
   formData.append('isRight', '0')
@@ -341,115 +400,67 @@ const queryFlowTemplateTreeDataByUser = (officeStatus = '1') => {
   formData.append('excludedSystemId', '') //后台获取
   formData.append('officeStatus', officeStatus)
   getFlowTemplateTreeDataByUser(formData).then((result: any) => {
-    flowTemplateNameTree.value = listToTree(result)
+    flowTemplates.value = handleTree(result, 'id', 'pid')
   })
 }
 queryFlowTemplateTreeDataByUser()
 const searchForm = ref({
   name: ''
 })
+const treeRef = ref()
 const searchHandle = () => {
+  sendData.flowTemIds = treeRef.value.getCheckedNodes(false).map((item) => item['id'])
   handleCurrentChange(1)
 }
-/**
- * 流程办理
- */
-const flowApplyHandle = (item) => {
-  const saveAndGetUrlReqParam = {
-    activityInsId: item['ACTIVITYINSID'],
-    flowInsId: item['FLOWINSID'],
-    particiPantId: item['PARTICIPANTID'],
-    status: item['STATUS'],
-    userId: '',
-    isView: false
+const { addTProcessHandle, openFlowHandle, flowApplyHandle } = useLookAndApplyFlow()
+
+const commandHandle = (name, item) => {
+  if (name === '作废') {
+    cancelFlow(item)
+  } else if (name === '退回') {
+    callbackActivity(item)
   }
-  openOfficeTip({
-    activityInsId: item['ACTIVITYINSID'],
-    particiPantId: item['PARTICIPANTID'],
-    isView: false
-  }).then((res: any) => {
-    saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
-      const officeUrl = result.officeUrl
-      openFlow(router, officeUrl, '流程办理')
-    })
-  })
-}
-const commandHandle = (item) => {
-  console.log(item)
   return
-  saveINullyApply({
-    id: '',
-    nullyApplyUserId: '91507848-736f-4327-887e-22aec122d5c7',
-    flowInstanceId: '0191021ed6a800011ab09091724c091b',
-    voidFlowInstanceId: '0191020bbc9c00011ab09091724c0912',
-    iNullied: '10',
-    voidFlowCode: 'LX2024070011',
-    voidFlowDesc: '',
-    voidFlowName: '立项申请',
-    nullyApplyTime: '2024-07-30',
-    nullyReason: ''
-  })
 }
 /**
- * 待办组合操作:退回、挂起、作废
+ * 初始化作废Hook
  */
-const flowOperateGroup = () => {}
-/***
- * 双击查看流程详情
- */
-const dblclickHandle = (item) => {
-  lookHandle(item)
-}
-const isEmpty = (content) => {
-  if (!content || content.replace(/\s*/g, '') == '') {
-    return true
-  } else {
-    return false
-  }
-}
-const lookHandle = (item: any) => {
-  const saveAndGetUrlReqParam = {
-    activityInsId: item['ACTIVITYINSID'],
-    flowInsId: item['FLOWINSID'],
-    particiPantId: item['PARTICIPANTID'],
-    status: item['STATUS'],
-    userId: '',
-    isView: true
+const {
+  nullyApplyTitle,
+  nullyApplyVisible,
+  inullyApplyForm,
+  cancelFlow,
+  nullyApplySubmit,
+  recoverINullyApplyHandle,
+  completelyVoidINullyApplyHandle
+} = useInullyApply({
+  success: (type: InullyApplyEnumType) => {
+    message.success(
+      type === InullyApplyEnum.Recover
+        ? '恢复作废成功!'
+        : type === InullyApplyEnum.Nully
+        ? '作废成功!'
+        : '彻底作废成功!'
+    )
+    initHandleCaseCenterData()
   }
-  //非待办件、委托直接打开
-  if (item['STATUS'] !== '1' && item['STATUS'] !== '2') {
-    saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
-      const officeUrl = result.officeUrl
-      openFlow(router, officeUrl, '流程查看')
-    })
-  } else {
-    openOfficeTip({
-      activityInsId: item['ACTIVITYINSID'],
-      particiPantId: item['PARTICIPANTID'],
-      isView: true
-    }).then((res: any) => {
-      if (!res.msg && res.isTip && !isEmpty(res.tipMsg)) {
-        ElMessageBox.confirm(res.tipMsg, 'Warning', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        })
-          .then(() => {
-            saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
-              const officeUrl = result.officeUrl
-              openFlow(router, officeUrl, '流程查看')
-            })
-          })
-          .catch(() => {})
-      } else {
-        saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
-          const officeUrl = result.officeUrl
-          openFlow(router, officeUrl, '流程查看')
-        })
-      }
-    })
+})
+/**
+ * 初始化退回Hook
+ */
+const {
+  callbackVisible,
+  callbackTitle,
+  callbacks,
+  callbackForm,
+  callbackActivity,
+  callbackSumbit
+} = useCallback({
+  success: (msg: string) => {
+    message.success(msg)
+    initHandleCaseCenterData()
   }
-}
+})
 /***
  * 追回
  */
@@ -478,32 +489,6 @@ const addIHangUpHandle = (item: any) => {
     }
   })
 }
-/***
- * 恢复作废
- */
-const addINullyApplyHandle = (item: any) => {
-  addINullyApply({
-    activityInstanceId: item['ACTIVITYINSID'],
-    voidFlowInstanceId: item['FLOWINSID'],
-    isRecover: 1
-  }).then((res) => {
-    if (res) {
-      message.success('解挂成功!')
-    }
-  })
-}
-/***
- * 彻底作废
- */
-const completelyVoidINullyApplyHandle = (item: any) => {
-  completelyVoidINullyApply({
-    flowInstanceId: item['FLOWINSID']
-  }).then((res) => {
-    if (res) {
-      message.success('解挂成功!')
-    }
-  })
-}
 const tableRef: any = ref(null)
 const tableHeight: any = ref(0)
 onMounted(() => {

+ 110 - 0
client/src/views/OaSystem/officeCenter/mainOfficeCenter/inullyApply.ts

@@ -0,0 +1,110 @@
+import { getUserInfo, getCurrentDate } from '@/utils/tool'
+import { generateUUID } from '@/utils'
+import type { InullyApplyFormType } from '@/api/oa/workflow'
+import {
+  isFlowVoid,
+  saveINullyApply,
+  getINullyApplyExample,
+  completelyVoidINullyApply
+} from '@/api/oa/workflow'
+/**
+ * 作废业务逻辑
+ * 包含作废、恢复、彻底作废
+ */
+export enum InullyApplyEnum {
+  Nully, //作废
+  Recover, //恢复
+  Nullify //彻底作废
+}
+export type InullyApplyEnumType = InullyApplyEnum
+export type InullyApplyOptionType = {
+  success?: (type: InullyApplyEnum) => void
+}
+const useInullyApply = (option: InullyApplyOptionType) => {
+  const nullyApplyTitle = ref<string>('申请作废')
+  const nullyApplyVisible = ref<boolean>(false)
+  const inullyApplyForm = reactive<InullyApplyFormType>({
+    id: '',
+    nullyApplyUserId: '',
+    flowInstanceId: '',
+    voidFlowInstanceId: '',
+    iNullied: '',
+    voidFlowCode: '',
+    voidFlowDesc: '',
+    voidFlowName: '',
+    nullyApplyTime: '',
+    nullyReason: ''
+  })
+  const initInullyApplyFormData = (row, iNullied: string = '10', id: string = '') => {
+    const userInfo = getUserInfo()
+    inullyApplyForm.id = id ?? ''
+    inullyApplyForm.nullyApplyUserId = userInfo?.id ?? ''
+    inullyApplyForm.nickname = userInfo?.nickname
+    inullyApplyForm.nullyApplyTime = getCurrentDate()
+    inullyApplyForm.iNullied = iNullied
+    inullyApplyForm.flowInstanceId = generateUUID()
+    inullyApplyForm.voidFlowInstanceId = row?.FLOWINSID ?? ''
+    inullyApplyForm.voidFlowCode = row?.CODE ?? ''
+    inullyApplyForm.voidFlowDesc = row?.DESCRIBTION ?? ''
+    inullyApplyForm.voidFlowName = row?.ACTIVITYNAME ?? ''
+    inullyApplyForm.nullyReason = ''
+  }
+  const cancelFlow = (row) => {
+    initInullyApplyFormData(row)
+    isFlowVoid({
+      flowInstanceId: row['FLOWINSID']
+    }).then((result: any) => {
+      if (result === 'ok') {
+        nullyApplyVisible.value = true
+      }
+    })
+  }
+  const nullyApplySubmit = async () => {
+    return await saveINullyApply({
+      nullyApply: inullyApplyForm
+    }).then((result: any) => {
+      if (result === 'ok') {
+        nullyApplyVisible.value = false
+        option?.success &&
+          option.success(inullyApplyForm.id ? InullyApplyEnum.Recover : InullyApplyEnum.Nully)
+      }
+    })
+  }
+  /***
+   * 恢复作废
+   */
+  const recoverINullyApplyHandle = (item: any) => {
+    getINullyApplyExample({
+      voidFlowInstanceId: item['FLOWINSID'],
+      isRecover: 1
+    }).then((result: any) => {
+      if (result) {
+        nullyApplyVisible.value = true
+        initInullyApplyFormData(item, '30', result)
+      }
+    })
+  }
+  /***
+   * 彻底作废
+   */
+  const completelyVoidINullyApplyHandle = (item: any) => {
+    completelyVoidINullyApply({
+      flowInstanceId: item['FLOWINSID']
+    }).then((res: any) => {
+      if (res === 'ok') {
+        option?.success && option.success(InullyApplyEnum.Nullify)
+      }
+    })
+  }
+  return {
+    nullyApplyTitle,
+    nullyApplyVisible,
+    inullyApplyForm,
+    cancelFlow,
+    nullyApplySubmit,
+    recoverINullyApplyHandle,
+    completelyVoidINullyApplyHandle
+  }
+}
+
+export default useInullyApply

+ 107 - 0
client/src/views/OaSystem/officeCenter/mainOfficeCenter/lookAndApplyFlow.ts

@@ -0,0 +1,107 @@
+import { openFlow } from '@/utils/flow'
+import { openOfficeTip, addTProcessEngine, saveAndGetUrl } from '@/api/oa/workflow'
+
+const isEmpty = (content) => {
+  if (!content || content.replace(/\s*/g, '') == '') {
+    return true
+  } else {
+    return false
+  }
+}
+
+/**
+ * 查看流程和办理流程业务逻辑
+ */
+const useLookAndApplyFlow = () => {
+  const router = useRouter()
+  /**
+   * 通过流程模板发起流程
+   */
+  const addTProcessHandle = (item) => {
+    addTProcessEngine(item['id']).then((result: any) => {
+      router.push({
+        path: '/processContainer',
+        query: {
+          iframe: '1',
+          iFrameId: item['id'],
+          url: result,
+          title: item['name']
+        }
+      })
+    })
+  }
+  /**
+   * 查看流程详情
+   */
+  const openFlowHandle = (item: any, status?: string) => {
+    const saveAndGetUrlReqParam = {
+      activityInsId: item['ACTIVITYINSID'] || '',
+      flowInsId: item['FLOWINSID'] || '',
+      particiPantId: item['PARTICIPANTID'] || '',
+      status: item['STATUS'] || status,
+      userId: '',
+      isView: true
+    }
+    //非待办件、委托直接打开
+    if (item['STATUS'] !== '1' && item['STATUS'] !== '2') {
+      saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
+        const officeUrl = result.officeUrl
+        openFlow(router, officeUrl, '流程查看')
+      })
+    } else {
+      openOfficeTip({
+        activityInsId: item['ACTIVITYINSID'],
+        particiPantId: item['PARTICIPANTID'],
+        isView: true
+      }).then((res: any) => {
+        if (!res.msg && res.isTip && !isEmpty(res.tipMsg)) {
+          ElMessageBox.confirm(res.tipMsg, 'Warning', {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+            saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
+              const officeUrl = result.officeUrl
+              openFlow(router, officeUrl, '流程查看')
+            })
+          })
+        } else {
+          saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
+            const officeUrl = result.officeUrl
+            openFlow(router, officeUrl, '流程查看')
+          })
+        }
+      })
+    }
+  }
+  /**
+   * 流程办理
+   */
+  const flowApplyHandle = (item) => {
+    const saveAndGetUrlReqParam = {
+      activityInsId: item['ACTIVITYINSID'],
+      flowInsId: item['FLOWINSID'],
+      particiPantId: item['PARTICIPANTID'],
+      status: item['STATUS'],
+      userId: '',
+      isView: false
+    }
+    openOfficeTip({
+      activityInsId: item['ACTIVITYINSID'],
+      particiPantId: item['PARTICIPANTID'],
+      isView: false
+    }).then((res: any) => {
+      saveAndGetUrl(saveAndGetUrlReqParam).then((result: any) => {
+        const officeUrl = result.officeUrl
+        openFlow(router, officeUrl, '流程办理')
+      })
+    })
+  }
+  return {
+    addTProcessHandle,
+    openFlowHandle,
+    flowApplyHandle
+  }
+}
+
+export default useLookAndApplyFlow

+ 1 - 1
client/src/views/system/role/ProcessDataPermissionForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog v-model="dialogVisible" title="菜单权限" width="800">
+  <Dialog v-model="dialogVisible" title="流程权限" width="800">
     <el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
       <el-form-item label="角色名称">
         <el-tag>{{ formData.name }}</el-tag>

+ 1 - 1
client/src/views/system/role/RoleDataPermissionForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog v-model="dialogVisible" title="菜单权限" width="800">
+  <Dialog v-model="dialogVisible" title="数据权限" width="800">
     <el-form ref="formRef" v-loading="formLoading" :model="formData" label-width="80px">
       <el-form-item label="角色名称">
         <el-tag>{{ formData.name }}</el-tag>