ソースを参照

review:【bpm】审批详情的操作们

YunaiV 3 ヶ月 前
コミット
9260346aaa

+ 2 - 0
src/api/bpm/task/index.ts

@@ -11,10 +11,12 @@ export interface TaskUser {
   deptName?: string
 }
 
+/** 操作按钮设置 */
 export interface OperationButtonSetting {
   displayName: string // 按钮名称
   enable: boolean // 是否启用
 }
+
 /** 流程任务 */
 export interface Task {
   id: string

+ 9 - 8
src/pages-bpm/processInstance/detail/add-sign/index.vue

@@ -85,13 +85,10 @@ const taskId = computed(() => props.taskId)
 const processInstanceId = computed(() => props.processInstanceId)
 const toast = useToast()
 const submitting = ref(false)
-const formRef = ref<FormInstance>()
-
 const formData = reactive({
   userIds: [] as number[],
   reason: '',
 })
-
 const formRules = {
   userIds: [
     { required: true, message: '加签处理人不能为空', validator: (value: number[]) => value.length > 0 },
@@ -100,12 +97,14 @@ const formRules = {
     { required: true, message: '审批意见不能为空' },
   ],
 }
+const formRef = ref<FormInstance>()
 
 /** 返回上一页 */
 function handleBack() {
   navigateBackPlus(`/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`)
 }
 
+// TODO @jason:最好放在 onMounted 里?或者其他地方,有个入口方法。
 /** 初始化校验 */
 if (!props.taskId || !props.processInstanceId) {
   toast.show('参数错误')
@@ -113,23 +112,24 @@ if (!props.taskId || !props.processInstanceId) {
 
 /** 提交操作 */
 async function handleSubmit(type: 'before' | 'after') {
-  if (submitting.value)
+  if (submitting.value) {
     return
-
-  // 使用 wd-form 的校验方法
+  }
   const { valid } = await formRef.value!.validate()
   if (!valid) {
     return
   }
+
+  // TODO @jason:submitting 改成 formLoading 哇?统一代码风格哈;
   submitting.value = true
   try {
+    // TODO @jason:这里是不是不用判断 result 哈?
     const result = await signCreateTask({
       id: taskId.value as string,
       type,
       userIds: formData.userIds,
       reason: formData.reason,
     })
-
     if (result) {
       const actionText = type === 'before' ? '向前加签' : '向后加签'
       toast.success(`${actionText}成功`)
@@ -137,9 +137,10 @@ async function handleSubmit(type: 'before' | 'after') {
         uni.redirectTo({
           url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`,
         })
-      }, 1500)
+      }, 500)
     }
   } catch (error) {
+    // TODO @jason:可以不用这里的 catch 哈?
     const actionText = type === 'before' ? '向前加签' : '向后加签'
     console.error(`[add-sign] ${actionText}失败:`, error)
     toast.error(`${actionText}失败`)

+ 7 - 5
src/pages-bpm/processInstance/detail/audit/index.vue

@@ -1,6 +1,6 @@
 <template>
   <view class="yd-page-container">
-    <!-- TODO @芋艿:还有一些细节,在审批通过没搞完! -->
+    <!-- TODO @jason:还有一些细节,在审批通过没搞完!1)签名;2)选择审批人;3)其它等等 -->
     <!-- 顶部导航栏 -->
     <wd-navbar
       :title="isApprove ? '审批同意' : '审批拒绝'"
@@ -93,14 +93,18 @@ function validateForm() {
 /** 提交审批 */
 async function handleSubmit() {
   // TODO @jason:看看是不是要用原生的校验
-  if (submitting.value)
+  if (submitting.value) {
     return
-  if (!validateForm())
+  }
+  if (!validateForm()) {
     return
+  }
 
+  // TODO @jason:要不换成 formLoading?保持项目统一;
   submitting.value = true
   try {
     const api = isApprove.value ? approveTask : rejectTask
+    // TODO @jason:这里看看不用 result
     const result = await api({
       id: taskId.value as string,
       reason: formData.reason,
@@ -111,8 +115,6 @@ async function handleSubmit() {
         handleBack()
       }, 1500)
     }
-  } catch (error) {
-    console.error('[audit] 审批失败:', error)
   } finally {
     submitting.value = false
   }

+ 7 - 4
src/pages-bpm/processInstance/detail/components/operation-button.vue

@@ -16,7 +16,7 @@
       <!-- 更多操作 ActionSheet -->
       <wd-action-sheet v-if="moreOperations.length > 0" v-model="showMoreActions" :actions="moreOperations" title="请选择操作" @select="handleMoreAction" />
 
-      <!-- 右侧按钮,TODO 是否一定要保留两个按钮 -->
+      <!-- 右侧按钮,TODO @jason:是否一定要保留两个按钮(需要的哈) -->
       <view class="flex flex-1 gap-16rpx">
         <wd-button
           v-for="(action, idx) in rightOperations"
@@ -33,7 +33,7 @@
       </view>
     </view>
   </view>
-  <!--  无待审批的任务 仅显示取消按钮。TODO 看看还需要显示 -->
+  <!--  无待审批的任务 仅显示取消按钮。TODO @jason:看看还需要显示(这个微信交流下) -->
   <view v-if="!runningTask && isShowProcessStartCancel()" class="yd-detail-footer">
     <wd-button
       plain
@@ -90,6 +90,7 @@ const operationIconsMap: Record<number, string> = {
 }
 
 const userStore = useUserStore()
+// TODO @jason:字段注释,使用尾注释哈;
 /** 左侧操作按钮 【最多两个】{转办, 委派, 退回, 加签, 抄送等} */
 const leftOperations = ref<LeftOperationType[]>([])
 
@@ -98,7 +99,6 @@ const rightOperationTypes = []
 const rightOperations = ref<RightOperationType[]>([])
 /** 更多操作 */
 const moreOperations = ref<MoreOperationType[]>([])
-const toast = useToast()
 const runningTask = ref<Task>()
 const processInstance = ref<ProcessInstance>()
 const reasonRequire = ref<boolean>(false)
@@ -109,6 +109,7 @@ function init(theProcessInstance: ProcessInstance, task: Task) {
   runningTask.value = task
   if (task) {
     reasonRequire.value = task.reasonRequire ?? false
+    // TODO @jason:这里的判断,是否可以简化哈?就是默认计算出按钮,然后根据数量,去渲染具体的按钮。
     // 右侧按钮
     if (isHandleTaskStatus() && isShowButton(BpmTaskOperationButtonTypeEnum.REJECT)) {
       rightOperationTypes.push(BpmTaskOperationButtonTypeEnum.REJECT)
@@ -148,7 +149,8 @@ function init(theProcessInstance: ProcessInstance, task: Task) {
         }
       }
     })
-    /** 减签操作的显示 */
+
+    // 减签操作的显示
     if (isShowDeleteSign()) {
       if (leftOperations.value.length >= 2) {
         moreOperations.value.push({
@@ -191,6 +193,7 @@ function init(theProcessInstance: ProcessInstance, task: Task) {
     }
   }
 }
+
 /** 跳转到相应的操作页面 */
 function handleOperation(operationType: number) {
   switch (operationType) {

+ 11 - 11
src/pages-bpm/processInstance/detail/delete-sign/index.vue

@@ -76,14 +76,11 @@ const taskId = computed(() => props.taskId)
 const processInstanceId = computed(() => props.processInstanceId)
 const toast = useToast()
 const submitting = ref(false)
-const formRef = ref<FormInstance>()
 const taskOptions = ref<any[]>([])
-
 const formData = reactive({
   deleteSignTaskId: '',
   reason: '',
 })
-
 const formRules = {
   deleteSignTaskId: [
     { required: true, message: '减签人员不能为空' },
@@ -92,6 +89,7 @@ const formRules = {
     { required: true, message: '审批意见不能为空' },
   ],
 }
+const formRef = ref<FormInstance>()
 
 /** 返回上一页 */
 function handleBack() {
@@ -99,6 +97,7 @@ function handleBack() {
 }
 
 /** 初始化校验 */
+// TODO @jason:最好放在 onMounted 里?或者其他地方,有个入口方法。
 if (!props.taskId || !props.processInstanceId) {
   toast.show('参数错误')
 }
@@ -114,7 +113,7 @@ function getDeleteSignUserLabel(task: any): string {
 async function loadDeleteSignTaskList() {
   try {
     let childTasks = []
-
+    // TODO @jason:这里应该是从 props 里获取?
     // 从 URL 参数中获取子任务数据
     if (props.children) {
       try {
@@ -123,7 +122,6 @@ async function loadDeleteSignTaskList() {
         console.error('[delete-sign] 解析子任务数据失败:', parseError)
       }
     }
-
     // 提示没有子任务数据
     if (childTasks.length === 0) {
       toast.show('没有可减签的任务')
@@ -135,6 +133,7 @@ async function loadDeleteSignTaskList() {
       label: getDeleteSignUserLabel(task),
     }))
   } catch (error) {
+    // TODO @jason:这里不用 try catch 哈
     console.error('[delete-sign] 获取可减签任务失败:', error)
     toast.error('获取可减签任务失败')
   }
@@ -142,31 +141,32 @@ async function loadDeleteSignTaskList() {
 
 /** 提交操作 */
 async function handleSubmit() {
-  if (submitting.value)
+  if (submitting.value) {
     return
-
-  // 使用 wd-form 的校验方法
+  }
   const { valid } = await formRef.value!.validate()
   if (!valid) {
     return
   }
 
+  // TODO @jason:submitting 改成 formLoading 哇?统一代码风格哈;
   submitting.value = true
   try {
+    // TODO @jason:这里是不是不用判断 result 哈?
     const result = await signDeleteTask({
       id: formData.deleteSignTaskId,
       reason: formData.reason,
     })
-
     if (result) {
       toast.success('减签成功')
       setTimeout(() => {
         uni.redirectTo({
           url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`,
         })
-      }, 1500)
+      }, 500)
     }
   } catch (error) {
+    // TODO @jason:可以不用这里的 catch 哈?
     console.error('[delete-sign] 减签失败:', error)
     toast.error('减签失败')
   } finally {
@@ -174,7 +174,7 @@ async function handleSubmit() {
   }
 }
 
-/** 页面加载时获取可减签任务列表 */
+/** 页面加载时获取可减签任务列表 */
 onMounted(() => {
   loadDeleteSignTaskList()
 })

+ 4 - 6
src/pages-bpm/processInstance/detail/index.vue

@@ -117,19 +117,18 @@ definePage({
   },
 })
 
-const userStore = useUserStore()
 const toast = useToast()
 const processInstance = ref<ProcessInstance>()
 const processDefinition = ref<ProcessDefinition>()
 const tasks = ref<Task[]>([])
 const orderAsc = ref(true)
 
-// 操作按钮组件 ref
-const operationButtonRef = ref()
+const operationButtonRef = ref() // 操作按钮组件 ref
 
 /** 排序后的任务列表 */
 const sortedTasks = computed(() => {
   const list = [...tasks.value].filter(t => t.status !== 4) // 过滤已取消
+  // TODO @jason:这里有红色报错,看看 fix 下哇?或者这块排序逻辑去掉,貌似没啥用。
   list.sort((a, b) => {
     if (a.endTime && b.endTime) {
       return orderAsc.value ? a.endTime - b.endTime : b.endTime - a.endTime
@@ -227,11 +226,10 @@ function getStatusTextClass(status: number) {
 
 /** 加载流程实例 */
 async function loadProcessInstance() {
-  const param = {
+  const data = await getApprovalDetail({
     processInstanceId: props.id,
     taskId: props.taskId,
-  }
-  const data = await getApprovalDetail(param)
+  })
   if (!data || !data.processInstance) {
     toast.show('查询不到审批详情信息')
     return

+ 7 - 8
src/pages-bpm/processInstance/detail/process-cancel/index.vue

@@ -72,17 +72,15 @@ const processInstanceId = computed(() => props.processInstanceId)
 const taskId = computed(() => props.taskId)
 const toast = useToast()
 const submitting = ref(false)
-const formRef = ref<FormInstance>()
-
 const formData = reactive({
   cancelReason: '',
 })
-
 const formRules = {
   cancelReason: [
     { required: true, message: '取消理由不能为空' },
   ],
 }
+const formRef = ref<FormInstance>()
 
 /** 返回上一页 */
 function handleBack() {
@@ -99,31 +97,32 @@ if (!props.processInstanceId) {
 
 /** 提交操作 */
 async function handleSubmit() {
-  if (submitting.value)
+  if (submitting.value) {
     return
-
-  // 使用 wd-form 的校验方法
+  }
   const { valid } = await formRef.value!.validate()
   if (!valid) {
     return
   }
 
+  // TODO @jason:最好放在 onMounted 里?或者其他地方,有个入口方法。
   submitting.value = true
   try {
+    // TODO @jason:不判断 result 可以哇?
     const result = await cancelProcessInstanceByStartUser(
       processInstanceId.value,
       formData.cancelReason,
     )
-
     if (result) {
       toast.success('流程取消成功')
       setTimeout(() => {
         uni.redirectTo({
           url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}`,
         })
-      }, 1500)
+      }, 500)
     }
   } catch (error) {
+    // TODO @jason:错误处理,这里可以去掉哈。
     console.error('[process-cancel] 取消流程失败:', error)
     toast.error('取消流程失败')
   } finally {

+ 9 - 12
src/pages-bpm/processInstance/detail/reassign/index.vue

@@ -76,13 +76,10 @@ const operationType = computed(() => props.type || 'transfer') // 默认转办
 const isDelegate = computed(() => operationType.value === 'delegate')
 const toast = useToast()
 const submitting = ref(false)
-const formRef = ref<FormInstance>()
-
 const formData = reactive({
   userId: undefined as number | undefined,
   reason: '',
 })
-
 const formRules = {
   userId: [
     { required: true, message: `请选择${isDelegate.value ? '接收人' : '新审批人'}` },
@@ -91,6 +88,7 @@ const formRules = {
     { required: true, message: '审批意见不能为空' },
   ],
 }
+const formRef = ref<FormInstance>()
 
 /** 返回上一页 */
 function handleBack() {
@@ -98,52 +96,51 @@ function handleBack() {
 }
 
 /** 初始化校验 */
+// TODO @jason:最好放在 onMounted 里?或者其他地方,有个入口方法。
 if (!props.taskId || !props.processInstanceId) {
   toast.show('参数错误')
 }
 
 /** 提交操作 */
 async function handleSubmit() {
-  if (submitting.value)
+  if (submitting.value) {
     return
-
-  // 使用 wd-form 的校验方法
+  }
   const { valid } = await formRef.value!.validate()
   if (!valid) {
     return
   }
 
+  // TODO @jason:submitting 改成 formLoading 哇?统一代码风格哈;
   submitting.value = true
   try {
     const data = {
       id: taskId.value as string,
       reason: formData.reason,
     }
-
-    let result
+    // todo @jason:这里是不是不用判断 result 哈?
+    let result: boolean
     if (isDelegate.value) {
-      // 委派
       result = await delegateTask({
         ...data,
         delegateUserId: String(formData.userId),
       })
     } else {
-      // 转办
       result = await transferTask({
         ...data,
         assigneeUserId: String(formData.userId),
       })
     }
-
     if (result) {
       toast.success(`${isDelegate.value ? '委派' : '转办'}成功`)
       setTimeout(() => {
         uni.redirectTo({
           url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`,
         })
-      }, 1500)
+      }, 500)
     }
   } catch (error) {
+    // TODO @jason:可以不用这里的 catch 哈?
     console.error(`[reassign] ${isDelegate.value ? '委派' : '转办'}失败:`, error)
     toast.error(`${isDelegate.value ? '委派' : '转办'}失败`)
   } finally {

+ 10 - 8
src/pages-bpm/processInstance/detail/return/index.vue

@@ -74,14 +74,11 @@ const taskId = computed(() => props.taskId)
 const processInstanceId = computed(() => props.processInstanceId)
 const toast = useToast()
 const submitting = ref(false)
-const formRef = ref<FormInstance>()
 const activityOptions = ref<any[]>([])
-
 const formData = reactive({
   targetActivityId: '',
   reason: '',
 })
-
 const formRules = {
   targetActivityId: [
     { required: true, message: '退回节点不能为空' },
@@ -90,6 +87,7 @@ const formRules = {
     { required: true, message: '退回原因不能为空' },
   ],
 }
+const formRef = ref<FormInstance>()
 
 /** 返回上一页 */
 function handleBack() {
@@ -97,6 +95,7 @@ function handleBack() {
 }
 
 /** 初始化校验 */
+// TODO @jason:最好放在 onMounted 里?或者其他地方,有个入口方法。
 if (!props.taskId || !props.processInstanceId) {
   toast.show('参数错误')
 }
@@ -105,10 +104,12 @@ if (!props.taskId || !props.processInstanceId) {
 async function loadReturnTaskList() {
   try {
     const result = await getTaskListByReturn(taskId.value)
+    // TODO @jason:这个判断可以考虑去掉哈。
     if (result && Array.isArray(result)) {
       activityOptions.value = result
     }
   } catch (error) {
+    // TODO @jason:错误处理,这里可以去掉哈。
     console.error('[return] 获取可退回节点失败:', error)
     toast.error('获取可退回节点失败')
   }
@@ -116,32 +117,33 @@ async function loadReturnTaskList() {
 
 /** 提交操作 */
 async function handleSubmit() {
-  if (submitting.value)
+  if (submitting.value) {
     return
-
-  // 使用 wd-form 的校验方法
+  }
   const { valid } = await formRef.value!.validate()
   if (!valid) {
     return
   }
 
+  // TODO @jason:submitting 改成 formLoading 哇?统一代码风格哈;
   submitting.value = true
   try {
+    // TODO @jason:这里是不是不用判断 result 哈?
     const result = await returnTask({
       id: taskId.value as string,
       targetTaskDefinitionKey: formData.targetActivityId,
       reason: formData.reason,
     })
-
     if (result) {
       toast.success('退回成功')
       setTimeout(() => {
         uni.redirectTo({
           url: `/pages-bpm/processInstance/detail/index?id=${processInstanceId.value}&taskId=${taskId.value}`,
         })
-      }, 1500)
+      }, 500)
     }
   } catch (error) {
+    // TODO @jason:可以不用这里的 catch 哈?
     console.error('[return] 退回失败:', error)
     toast.error('退回失败')
   } finally {

+ 1 - 1
src/store/user.ts

@@ -63,7 +63,7 @@ export const useUserStore = defineStore(
     /** 获取用户信息 */
     const fetchUserInfo = async () => {
       const res = await getAuthPermissionInfo()
-      // 后端返回的用户 Id 字段为 id.
+      // 兼容:后端返回的用户 id 字段为 id
       res.user.userId = res.user.id
       setUserInfo(res)
       return res