diff --git a/src/pages/integrated/meeting/detail.vue b/src/pages/integrated/meeting/detail.vue index 2d1ec77..b9e144d 100644 --- a/src/pages/integrated/meeting/detail.vue +++ b/src/pages/integrated/meeting/detail.vue @@ -53,7 +53,57 @@ - 发起会议 + 发起会议 + + + + + + 会议预约 + × + + + + + + 是否需要会务服务 + + + {{ option.label }} + + + + + + + 桌子摆放形态 + + + {{ layout.name }} + {{ layout.description }} + + + + + + + 取消 + + {{ isBooking ? '预约中...' : '确认预约' }} + + + + @@ -120,6 +170,19 @@ const selectedTimeText = computed(() => { }) const selectedDuration = computed(() => selectedTime.value.length * 30) +// 弹窗相关数据 +const showModal = ref(false) +const needService = ref('0') // 默认不需要会务服务 +const selectedLayout = ref('') // 选中的桌子摆放形态ID +const deskLayouts = ref([]) // 桌子摆放形态列表 +const isBooking = ref(false) // 预约中状态 + +// 会务服务选项 +const serviceOptions = [ + { value: '0', label: '不需要' }, + { value: '1', label: '需要' } +] + // 获取日期字符串 const getDateString = (index: number) => { const date = new Date() @@ -172,6 +235,24 @@ const fetchTimeSlots = async (date: string) => { } } +// 获取桌子摆放形态数据 +const fetchDeskLayouts = async () => { + try { + const res = await meetingRoomApi.getMeetingDeskLayout('') + console.log('Desk layouts response:', res) + + const response = res as unknown as ApiResponse + if (response.code === 0 && response.data) { + deskLayouts.value = response.data + console.log('Desk layouts data:', deskLayouts.value) + } else { + console.error('Failed to fetch desk layouts:', response) + } + } catch (error) { + console.error('API request failed:', error) + } +} + // 选择时间 function selectTime(index: number) { const slot = timeSlots.value[index] @@ -200,20 +281,52 @@ function selectTime(index: number) { } } -// 预约会议 -async function reserveMeeting() { +// 显示预约弹窗 +function showReserveModal() { if (selectedTime.value.length === 0) { uni.showToast({ title: '请选择时间', icon: 'none' }) return } + showModal.value = true +} +// 隐藏弹窗 +function hideModal() { + showModal.value = false +} + +// 选择会务服务 +function selectService(value: string) { + needService.value = value +} + +// 选择桌子摆放形态 +function selectLayout(layoutId: string) { + selectedLayout.value = layoutId +} + +// 确认预约 +async function confirmReserve() { if (!roomId.value) { uni.showToast({ title: '会议室ID不存在', icon: 'none' }) return } + // 防止重复点击 + if (isBooking.value) { + return + } + + // 设置预约中状态 + isBooking.value = true + + // 显示loading + uni.showLoading({ + title: '预约中...', + mask: true + }) + try { - uni.showLoading({ title: '预约中...', mask: true }) const date = getDateString(activeDate.value) const startSlot = timeSlots.value[selectedTime.value[0]] const endSlot = timeSlots.value[selectedTime.value[selectedTime.value.length - 1]] @@ -224,29 +337,83 @@ async function reserveMeeting() { endTime: endSlot.endTime, title: room.value.name || '会议', description: '', - attendees: [] + attendees: [], + need_service: needService.value, + desk_layout: selectedLayout.value }) - const response = res as unknown as ApiResponse - if (response.code === 0) { - uni.hideLoading() - uni.showToast({ title: '预约成功', icon: 'success' }) - setTimeout(() => { - uni.navigateBack() - }, 1500) + console.log('预约接口响应:', res) + console.log('响应类型:', typeof res) + console.log('响应内容:', JSON.stringify(res)) + + // 处理响应数据 + const responseData = res as any + + // 检查业务错误(HTTP 200 但 code !== 0) + if (responseData && responseData.code !== undefined) { + console.log('检测到响应码:', responseData.code) + console.log('检测到响应消息:', responseData.msg) + + if (responseData.code === 0) { + // 成功:隐藏loading,显示成功提示 + uni.hideLoading() + isBooking.value = false + uni.showToast({ title: '预约成功', icon: 'success' }) + hideModal() + setTimeout(() => { + uni.navigateBack() + }, 1500) + } else { + // 失败:隐藏loading,关闭弹窗,显示错误信息 + uni.hideLoading() + isBooking.value = false + console.log('预约失败,错误信息:', responseData.msg) + + // 先关闭弹窗,再显示错误信息 + hideModal() + + // 延迟显示错误信息,确保弹窗完全关闭 + setTimeout(() => { + uni.showToast({ + title: responseData.msg || '预约失败', + icon: 'none', + duration: 3000 + }) + }, 300) + } } else { + // 响应格式异常:隐藏loading,显示错误信息 uni.hideLoading() + isBooking.value = false + console.log('响应格式异常:', responseData) uni.showToast({ - title: response.msg || '预约失败', - icon: 'none' + title: '预约失败,响应格式异常', + icon: 'none', + duration: 3000 }) } } catch (error) { + // 确保在异常情况下也隐藏loading uni.hideLoading() - uni.showToast({ - title: '预约失败', - icon: 'none' - }) + isBooking.value = false + console.error('预约失败:', error) + + // 处理HTTP错误(如500错误) + const errorData = error as any + if (errorData?.data?.msg) { + console.log('HTTP错误信息:', errorData.data.msg) + uni.showToast({ + title: errorData.data.msg, + icon: 'none', + duration: 3000 + }) + } else { + uni.showToast({ + title: '预约失败,请重试', + icon: 'none', + duration: 3000 + }) + } } } @@ -284,6 +451,9 @@ onMounted(() => { console.log('Fetching time slots for date:', today) fetchTimeSlots(today) + // 获取桌子摆放形态数据 + fetchDeskLayouts() + // 从 localStorage 获取用户信息 try { const userInfoString = localStorage.getItem('user_info') @@ -489,4 +659,160 @@ const goBack = () => { padding: 24rpx 0; font-weight: 600; } + +/* 弹窗样式 */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal-content { + width: 90%; + max-width: 600rpx; + background: #fff; + border-radius: 16rpx; + overflow: hidden; +} + +.modal-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 32rpx; + border-bottom: 1px solid #f0f0f0; +} + +.modal-title { + font-size: 32rpx; + font-weight: 600; + color: #222; +} + +.modal-close { + font-size: 40rpx; + color: #999; + width: 60rpx; + height: 60rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-body { + padding: 32rpx; +} + +.form-item { + margin-bottom: 32rpx; +} + +.form-label { + display: block; + font-size: 28rpx; + color: #333; + margin-bottom: 16rpx; + font-weight: 500; +} + +.service-options { + display: flex; + gap: 16rpx; +} + +.service-option { + flex: 1; + padding: 20rpx; + border: 2rpx solid #e0e0e0; + border-radius: 8rpx; + text-align: center; + background: #fff; + transition: all 0.3s; +} + +.service-option.active { + border-color: #1777FF; + background: #e6f0ff; + color: #1777FF; +} + +.option-text { + font-size: 26rpx; +} + +.layout-options { + display: flex; + flex-direction: column; + gap: 12rpx; +} + +.layout-option { + padding: 20rpx; + border: 2rpx solid #e0e0e0; + border-radius: 8rpx; + background: #fff; + transition: all 0.3s; +} + +.layout-option.active { + border-color: #1777FF; + background: #e6f0ff; +} + +.layout-name { + display: block; + font-size: 26rpx; + color: #333; + font-weight: 500; + margin-bottom: 4rpx; +} + +.layout-option.active .layout-name { + color: #1777FF; +} + +.layout-desc { + display: block; + font-size: 22rpx; + color: #666; +} + +.layout-option.active .layout-desc { + color: #1777FF; +} + +.modal-footer { + display: flex; + border-top: 1px solid #f0f0f0; +} + +.modal-btn { + flex: 1; + padding: 24rpx; + text-align: center; + font-size: 28rpx; + font-weight: 500; +} + +.cancel-btn { + color: #666; + border-right: 1px solid #f0f0f0; +} + +.confirm-btn { + color: #1777FF; + font-weight: 600; +} + +.modal-btn.disabled { + opacity: 0.5; + pointer-events: none; +} \ No newline at end of file diff --git a/src/pages/integrated/todo/index.vue b/src/pages/integrated/todo/index.vue index 174e854..5278d5e 100644 --- a/src/pages/integrated/todo/index.vue +++ b/src/pages/integrated/todo/index.vue @@ -4,10 +4,10 @@ - 工作待办 + 我的待办 - 工作待办 + 我的待办 我的已办 @@ -34,8 +34,8 @@ - 拒绝 - 同意 + 开始处理 + 查看 @@ -43,6 +43,335 @@ 没有更多了 + + + + + + 提交审核 + × + + + + + 审核意见 + + {{ approvalComment.length }}/100 + + + + + 取消 + 确定 + + + + + + + + + 选择转办人员 + × + + + + + + + + + + + + + {{ item.name }} + > + + + + + + + + 部门 + + + ✓ + + 🏢 + + {{ dept.name }} + 部门 + + 下级 + + + + 员工 + + + ✓ + + + + {{ employee.name.charAt(0) }} + + + {{ employee.name }} + 员工 + + + + + + + 取消 + 确定 + + + + + + + + + 转办确认 + × + + + + + + 转办给: + {{ selectedUser?.name }} + + + + + 审核意见 * + + {{ delegateComment.length }}/100 + + + + + 取消 + 确定 + + + + + + + + + 审批处理 + × + + + + + + + {{ field.name }}{{ field.required ? ' *' : '' }} + + {{ field.props?.value || '' }} + + + {{ field.props?.value || field.placeholder || '未知' }} + + {{ field.props?.value || '未知' }} + + + + + + + + 流水号 + {{ currentTask.serialNumber || '未知流水号' }} + + + + + * 会议室 + {{ currentTask.roomName || '未知会议室' }} + + + + + * 预约人 + {{ currentTask.applicantName || '未知申请人' }} + + + + + * 预约时间 + {{ currentTask.meetingTime || '未知时间' }} + + + + + + + + + + {{ flow.status === 2 ? '✓' : '⟲' }} + + + {{ flow.name }}{{ flow.placeholder ? ` [${flow.placeholder}]` : '' }} + + + + + {{ user.name?.charAt(0) || '?' }} + + {{ user.name || '未知用户' }} + + + + + 待分配 + + + + + + + + + + ✓ + + 发起人 + + + {{ currentTask.applicantName || '未知申请人' }} + + + + + + ⟲ + + 审批人 + + + 当前用户 + + + + + + + + + + + × + 关闭 + + + + + + ✕ + 拒绝 + + + ✓ + 同意 + + + ↗ + 转办 + + + + + + + + + + + 转办 + + + + + + + + + + 选择转办人员 + * + + + + {{ selectedUser.name }} + × + + + + + + + {{ userSelectError }} + + + + + + 审核意见 + * + + + + {{ delegateFormComment.length }}/100 + + {{ commentError }} + + + + + + 取消 + + + 确定 + + + + @@ -50,6 +379,7 @@ import { ref, onMounted } from 'vue' import { onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app' import integratedApi from '@/sheep/api/integrated' +import taskApi from '@/sheep/api/task' const todoList = ref([]) const current = ref(1) @@ -59,6 +389,39 @@ const loading = ref(false) const finished = ref(false) const activeTab = ref(0) +// 审批弹窗相关 +const showApprovalModal = ref(false) +const currentTask = ref({}) +const isProcessing = ref(false) + +// 审核意见弹窗相关 +const showCommentModal = ref(false) +const approvalComment = ref('') +const pendingApproval = ref(null) // true: 同意, false: 拒绝 + +// 转办相关 +const showDelegateModal = ref(false) +const showDelegateConfirmModal = ref(false) +const selectedUser = ref(null) +const delegateComment = ref('') +const searchKeyword = ref('') + +// 用户选择数据 +const userSelectionData = ref({}) +const filteredDepartments = ref([]) +const filteredEmployees = ref([]) + +// 转办表单弹窗 +const showDelegateFormModal = ref(false) +const delegateFormComment = ref('') + +// 面包屑导航 +const breadcrumbPath = ref([]) + +// 表单验证错误提示 +const userSelectError = ref('') +const commentError = ref('') + function fetchTodoList(isRefresh = false) { if (loading.value) return loading.value = true @@ -109,6 +472,603 @@ onReachBottom(() => { current.value += 1 fetchTodoList() }) + +// 查看已办任务 +async function viewProcess(item: any) { + if (isProcessing.value) return + + isProcessing.value = true + uni.showLoading({ title: '加载中...', mask: true }) + + try { + // 调用第一个接口:查询任务详情 (view=true) + const taskRes = await taskApi.queryTask(item.taskId, true) + console.log('任务详情(view=true):', taskRes) + + // 调用第二个接口:格式化开始节点显示 + const formatData = { + flowId: item.flowId, + processInstanceId: item.processInstanceId, + paramMap: { + mcmxfktv1b0zg: null, + roomName: item.roomName, + applicantName: item.applicantName, + meetingTime: item.meetingTime + }, + taskId: item.taskId + } + + console.log('发送给formatStartNodeShow的数据:', formatData) + + const formatRes = await taskApi.formatStartNodeShow(formatData) + console.log('格式化显示:', formatRes) + + // 从接口返回的数据中提取动态字段和审批流程 + const taskData = taskRes as any + const formatData_result = formatRes as any + + let formItems = [] + let approvalFlow = [] + + if (taskData.code === 0 && taskData.data) { + // 从 queryTask 接口获取表单字段 + formItems = taskData.data.formItems || [] + } + + if (formatData_result.code === 0 && formatData_result.data) { + // 从 formatStartNodeShow 接口获取审批流程 + approvalFlow = formatData_result.data || [] + } + + // 设置当前任务数据 - 使用实际的任务数据和接口返回的动态数据 + currentTask.value = { + ...item, + serialNumber: item.serialNumber || item.taskId?.substring(0, 13) || '未知流水号', + roomName: item.roomName || '未知会议室', + applicantName: item.applicantName || item.rootUserName || '未知申请人', + meetingTime: item.meetingTime || item.startTime || '未知时间', + flowId: item.flowId, + processInstanceId: item.processInstanceId, + taskId: item.taskId, + // 添加动态数据 + formItems: formItems, + approvalFlow: approvalFlow, + // 标记为查看模式 + isViewMode: true + } + + console.log('设置的任务数据(查看模式):', currentTask.value) + + // 显示审批弹窗 + showApprovalModal.value = true + + } catch (error) { + console.error('加载查看信息失败:', error) + uni.showToast({ + title: '加载失败,请重试', + icon: 'none' + }) + } finally { + uni.hideLoading() + isProcessing.value = false + } +} + +// 开始处理审批 +async function startProcess(item: any) { + if (isProcessing.value) return + + isProcessing.value = true + uni.showLoading({ title: '加载中...', mask: true }) + + try { + // 调用第一个接口:查询任务详情 + const taskRes = await taskApi.queryTask(item.taskId, false) + console.log('任务详情:', taskRes) + + // 调用第二个接口:格式化开始节点显示 + const formatData = { + flowId: item.flowId, + processInstanceId: item.processInstanceId, + paramMap: { + mcmxfktv1b0zg: null, + roomName: item.roomName, + applicantName: item.applicantName, + meetingTime: item.meetingTime + }, + taskId: item.taskId + } + + console.log('发送给formatStartNodeShow的数据:', formatData) + + const formatRes = await taskApi.formatStartNodeShow(formatData) + console.log('格式化显示:', formatRes) + + // 从接口返回的数据中提取动态字段和审批流程 + const taskData = taskRes as any + const formatData_result = formatRes as any + + let formItems = [] + let approvalFlow = [] + + if (taskData.code === 0 && taskData.data) { + // 从 queryTask 接口获取表单字段 + formItems = taskData.data.formItems || [] + } + + if (formatData_result.code === 0 && formatData_result.data) { + // 从 formatStartNodeShow 接口获取审批流程 + approvalFlow = formatData_result.data || [] + } + + // 设置当前任务数据 - 使用实际的任务数据和接口返回的动态数据 + currentTask.value = { + ...item, + serialNumber: item.serialNumber || item.taskId?.substring(0, 13) || '未知流水号', + roomName: item.roomName || '未知会议室', + applicantName: item.applicantName || item.rootUserName || '未知申请人', + meetingTime: item.meetingTime || item.startTime || '未知时间', + flowId: item.flowId, + processInstanceId: item.processInstanceId, + taskId: item.taskId, + // 添加动态数据 + formItems: formItems, + approvalFlow: approvalFlow + } + + console.log('设置的任务数据:', currentTask.value) + + // 显示审批弹窗 + showApprovalModal.value = true + + } catch (error) { + console.error('加载审批信息失败:', error) + uni.showToast({ + title: '加载失败,请重试', + icon: 'none' + }) + } finally { + uni.hideLoading() + isProcessing.value = false + } +} + +// 隐藏审批弹窗 +function hideApprovalModal() { + showApprovalModal.value = false + currentTask.value = {} +} + +// 处理拒绝 +function handleReject() { + console.log('handleReject - 设置 pendingApproval.value = false') + pendingApproval.value = false + approvalComment.value = '' + showCommentModal.value = true +} + +// 处理提交(同意) +function handleSubmit() { + console.log('handleSubmit - 设置 pendingApproval.value = true') + pendingApproval.value = true + approvalComment.value = '' + showCommentModal.value = true +} + +// 处理转办 +async function handleTransfer() { + // 先显示转办表单弹窗 + delegateFormComment.value = '' + selectedUser.value = null + showDelegateFormModal.value = true +} + +// 提交审批结果 +async function submitApproval(approved: boolean) { + console.log('submitApproval 被调用,参数 approved:', approved, '类型:', typeof approved) + + if (isProcessing.value) return + + isProcessing.value = true + uni.showLoading({ + title: approved ? '提交中...' : '拒绝中...', + mask: true + }) + + try { + // 检查任务数据 + console.log('当前任务数据:', currentTask.value) + console.log('审核意见:', approvalComment.value) + + if (!currentTask.value.taskId) { + throw new Error('任务ID不存在') + } + + // 构建审批参数 + const paramMap = { + mcmxfktv1b0zg: null, + roomName: currentTask.value.roomName, + applicantName: currentTask.value.applicantName, + meetingTime: currentTask.value.meetingTime, + mcmxoxqvzau0u_approve_condition: approved + } + + console.log('approved 值:', approved) + console.log('mcmxoxqvzau0u_approve_condition 值:', paramMap.mcmxoxqvzau0u_approve_condition) + + const taskLocalParamMap = { + approveDesc: approvalComment.value || (approved ? '同意申请' : '拒绝申请') + } + + const requestData = { + taskId: currentTask.value.taskId, + paramMap: paramMap, + taskLocalParamMap: taskLocalParamMap + } + + console.log('构建的paramMap:', paramMap) + console.log('构建的taskLocalParamMap:', taskLocalParamMap) + console.log('审批请求参数:', requestData) + + const res = await taskApi.completeTask(requestData) + + console.log('审批结果:', res) + + uni.showToast({ + title: approved ? '提交成功' : '拒绝成功', + icon: 'success' + }) + + // 关闭弹窗并刷新列表 + hideApprovalModal() + setTimeout(() => { + fetchTodoList(true) + }, 1000) + + } catch (error) { + console.error('审批失败:', error) + uni.showToast({ + title: '操作失败,请重试', + icon: 'none' + }) + } finally { + uni.hideLoading() + isProcessing.value = false + } +} + +// 审核意见弹窗相关方法 +function hideCommentModal() { + showCommentModal.value = false + approvalComment.value = '' + pendingApproval.value = null +} + +function confirmApproval() { + if (!approvalComment.value.trim()) { + uni.showToast({ + title: '请输入审核意见', + icon: 'none' + }) + return + } + + console.log('confirmApproval - pendingApproval.value:', pendingApproval.value) + console.log('confirmApproval - approvalComment.value:', approvalComment.value) + + // 先保存 pendingApproval 的值,因为 hideCommentModal 会重置它 + const approvalValue = pendingApproval.value + + hideCommentModal() + submitApproval(approvalValue!) +} + +// 转办表单弹窗相关方法 +function hideDelegateFormModal() { + showDelegateFormModal.value = false + delegateFormComment.value = '' + selectedUser.value = null +} + +async function showUserSelection() { + try { + // 获取用户选择列表 - 使用抽取的API + const res = await taskApi.getDeptOrgUsers(0) + console.log('用户选择列表:', res) + + const responseData = res as any + if (responseData.code === 0 && responseData.data) { + // 处理接口返回的数据结构 + const apiData = responseData.data + userSelectionData.value = { + titleDepartments: apiData.titleDepartments || [], + employees: apiData.employees || [], + childDepartments: apiData.childDepartments || [] + } + filteredDepartments.value = apiData.childDepartments || [] + filteredEmployees.value = apiData.employees || [] + searchKeyword.value = '' + // 初始化面包屑导航 + breadcrumbPath.value = [{ id: 0, name: '全部', type: 'root' }] + showDelegateModal.value = true + } else { + uni.showToast({ + title: '获取用户列表失败', + icon: 'none' + }) + } + } catch (error) { + console.error('获取用户列表失败:', error) + uni.showToast({ + title: '获取用户列表失败', + icon: 'none' + }) + } +} + +function removeSelectedUser() { + selectedUser.value = null +} + +function confirmDelegateForm() { + console.log('confirmDelegateForm 被调用') + console.log('selectedUser.value:', selectedUser.value) + console.log('delegateFormComment.value:', delegateFormComment.value) + + // 清除之前的错误提示 + userSelectError.value = '' + commentError.value = '' + + let hasError = false + + // 验证表单 + if (!selectedUser.value) { + console.log('验证失败:未选择转办人员') + userSelectError.value = '请选择转办人员' + hasError = true + } + + if (!delegateFormComment.value || delegateFormComment.value.length < 2) { + console.log('验证失败:审核意见太短') + commentError.value = '请输入审核意见(至少2字)' + hasError = true + } else if (delegateFormComment.value.length > 100) { + console.log('验证失败:审核意见太长') + commentError.value = '审核意见不能超过100字' + hasError = true + } + + if (hasError) { + return + } + + console.log('验证通过,准备提交转办') + // 设置转办数据并提交 + delegateComment.value = delegateFormComment.value + // 先提交转办,再关闭弹窗 + submitDelegate() +} + +// 转办相关方法 +function hideDelegateModal() { + showDelegateModal.value = false + // 不要清空 selectedUser,因为用户可能已经选择了 + searchKeyword.value = '' +} + +function hideDelegateConfirmModal() { + showDelegateConfirmModal.value = false + delegateComment.value = '' +} + +async function selectUser(user: any) { + // 如果是部门类型,请求下级数据 + if (user.type === 'dept') { + try { + uni.showLoading({ title: '加载中...', mask: true }) + + const res = await taskApi.getDeptOrgUsers(user.id) + console.log('下级部门数据:', res) + + const responseData = res as any + if (responseData.code === 0 && responseData.data) { + const apiData = responseData.data + + // 更新数据,显示下级部门和员工 + userSelectionData.value = { + titleDepartments: [...(userSelectionData.value.titleDepartments || []), user], + employees: apiData.employees || [], + childDepartments: apiData.childDepartments || [] + } + filteredDepartments.value = apiData.childDepartments || [] + filteredEmployees.value = apiData.employees || [] + searchKeyword.value = '' + + // 更新面包屑导航 + breadcrumbPath.value.push(user) + } else { + uni.showToast({ + title: '获取下级数据失败', + icon: 'none' + }) + } + } catch (error) { + console.error('获取下级数据失败:', error) + uni.showToast({ + title: '获取下级数据失败', + icon: 'none' + }) + } finally { + uni.hideLoading() + } + } else { + // 如果是员工,直接选择并关闭弹窗 + console.log('选择员工:', user) + selectedUser.value = user + console.log('selectedUser.value:', selectedUser.value) + hideDelegateModal() + // 返回到转办表单弹窗 + showDelegateFormModal.value = true + } +} + +function confirmDelegateUser() { + if (!selectedUser.value) { + uni.showToast({ + title: '请选择转办人员', + icon: 'none' + }) + return + } + + hideDelegateModal() + // 返回到转办表单弹窗 + showDelegateFormModal.value = true +} + +// 面包屑导航点击 +async function navigateToBreadcrumb(index: number) { + if (index === breadcrumbPath.value.length - 1) { + // 点击当前层级,不执行任何操作 + return + } + + try { + uni.showLoading({ title: '加载中...', mask: true }) + + // 截取面包屑路径到指定层级 + breadcrumbPath.value = breadcrumbPath.value.slice(0, index + 1) + + // 获取目标层级的数据 + const targetItem = breadcrumbPath.value[index] + const res = await taskApi.getDeptOrgUsers(targetItem.id) + + const responseData = res as any + if (responseData.code === 0 && responseData.data) { + const apiData = responseData.data + + // 更新数据 + filteredDepartments.value = apiData.childDepartments || [] + filteredEmployees.value = apiData.employees || [] + searchKeyword.value = '' + } else { + uni.showToast({ + title: '获取数据失败', + icon: 'none' + }) + } + } catch (error) { + console.error('获取数据失败:', error) + uni.showToast({ + title: '获取数据失败', + icon: 'none' + }) + } finally { + uni.hideLoading() + } +} + +function confirmDelegate() { + if (!delegateComment.value.trim()) { + uni.showToast({ + title: '请输入审核意见', + icon: 'none' + }) + return + } + + if (delegateComment.value.length < 2) { + uni.showToast({ + title: '审核意见至少2个字符', + icon: 'none' + }) + return + } + + submitDelegate() +} + +async function submitDelegate() { + console.log('submitDelegate 被调用') + console.log('isProcessing.value:', isProcessing.value) + + if (isProcessing.value) { + console.log('正在处理中,跳过') + return + } + + isProcessing.value = true + uni.showLoading({ title: '转办中...', mask: true }) + + try { + // 使用抽取的转办接口 + const res = await taskApi.setAssignee({ + paramMap: { + mcmxfktv1b0zg: null, + roomName: currentTask.value.roomName, + applicantName: currentTask.value.applicantName, + meetingTime: currentTask.value.meetingTime, + mcmxoxqvzau0u_approve_condition: true + }, + taskId: currentTask.value.taskId, + targetUserIdList: [selectedUser.value.id], + taskLocalParamMap: { + approveDesc: delegateComment.value + } + }) + + console.log('转办结果:', res) + + const responseData = res as any + if (responseData.code === 0) { + uni.showToast({ + title: '转办成功', + icon: 'success' + }) + + // 关闭弹窗并刷新列表 + hideDelegateFormModal() + hideApprovalModal() + setTimeout(() => { + fetchTodoList(true) + }, 1000) + } else { + uni.showToast({ + title: responseData.msg || '转办失败', + icon: 'none' + }) + } + + } catch (error) { + console.error('转办失败:', error) + uni.showToast({ + title: '转办失败,请重试', + icon: 'none' + }) + } finally { + uni.hideLoading() + isProcessing.value = false + } +} + +// 搜索过滤 +function filterUsers() { + const keyword = searchKeyword.value.toLowerCase() + + if (!keyword) { + filteredDepartments.value = userSelectionData.value.childDepartments || [] + filteredEmployees.value = userSelectionData.value.employees || [] + return + } + + filteredDepartments.value = (userSelectionData.value.childDepartments || []).filter((dept: any) => + dept.name.toLowerCase().includes(keyword) + ) + + filteredEmployees.value = (userSelectionData.value.employees || []).filter((emp: any) => + emp.name.toLowerCase().includes(keyword) + ) +} diff --git a/src/pages/tabbar/integrated.vue b/src/pages/tabbar/integrated.vue index 3cde773..49c8280 100644 --- a/src/pages/tabbar/integrated.vue +++ b/src/pages/tabbar/integrated.vue @@ -7,7 +7,10 @@ - + + + {{ todoCount > 99 ? '99+' : todoCount }} + {{ item.label }} @@ -18,6 +21,10 @@