diff --git a/api/common.js b/api/common.js index a919cc8..26f822a 100644 --- a/api/common.js +++ b/api/common.js @@ -57,6 +57,16 @@ export const getByType = (params) => { }; /** + * 拉取「已配置填报项」的作业类型 + * 填报页进入时若该业务线只配了一个作业类型,直接选中并加载动态字段,避免用户不知道要先选作业类型。 + * @param {Object} params {`businessType`、`bizType`} + * @returns {Promise} List<{workTypeId, workTypeName}> + */ +export const getConfiguredWorkTypes = (params) => { + return get('/app-api/app/garden/work-field-config/work-types', params); +}; + +/** * 拉取选项 用于 fieldType 3(枚举)/6(多选)/9(关联记录) 且 field.options 为空(即非静态来源)时获取可选项。 * @param {Object} params {} * @returns {Promise} diff --git a/common/config/env.js b/common/config/env.js index 5ec8714..9f3e623 100644 --- a/common/config/env.js +++ b/common/config/env.js @@ -2,12 +2,12 @@ const env = { // 开发环境 development: { - baseUrl: 'https://test.jichengshanshui.com.cn:28302', + baseUrl: 'http://192.168.1.55:48081', // https://test.jichengshanshui.com.cn:28302 // baseUrl: 'http://192.168.1.111:48081', - uploadUrl: 'https://test.jichengshanshui.com.cn:28302', + uploadUrl: 'http://192.168.1.55:48081', // baseApi:'admin-api', // appApi:'app-api' }, diff --git a/common/utils/common.js b/common/utils/common.js index ee33750..702c4fb 100644 --- a/common/utils/common.js +++ b/common/utils/common.js @@ -286,6 +286,9 @@ export const translateRoles = (roles = []) => { .join(','); } +/** 配置了工单(biz_type=1)动态字段的业务线;其他业务线走统一动作弹窗 */ +const WORKER_IMPLEMENT_BIZ_LINES = ['yl', 'hj']; + /** * 跳转「作业填报」页(养护员实施) * @@ -293,11 +296,20 @@ export const translateRoles = (roles = []) => { * 上传开始/进行中/结束/人员/材料五组照片,统一动作弹窗只有原因+单个附件,承载不了, * 因此实施动作固定进「作业填报」页。 * + * 只有养护(yl)、环卫(hj)配置了工单动态字段,秩序(zx)/市政(sz)/物业(wy)没有配置, + * 这类工单仍走统一动作弹窗,保持原有处理流程。 + * * 工单数据存本地缓存,URL 只带临时 key,避免参数过长。 * @param {Object} item 待办行数据,需包含 id(工单ID)与 taskId(流程任务ID) - * @returns {Boolean} 是否成功跳转 + * @param {String} from 来源列表页标识:work-order / regional / ai,提交后回到对应列表 + * @returns {Boolean} 是否已跳转;返回 false 时由调用方继续走统一动作弹窗 */ -export const toWorkerImplementPage = (item) => { +export const toWorkerImplementPage = (item, from = 'work-order') => { + // 业务线可能多选(逗号分隔),任一命中即视为养护类工单 + const bizLines = String(item?.busiLine || '').split(',').map(v => v.trim()).filter(Boolean); + if (!bizLines.some(v => WORKER_IMPLEMENT_BIZ_LINES.includes(v))) { + return false; + } if (!item || !item.id || !item.taskId) { uni.showToast({ title: '工单信息异常,无法实施', icon: 'none' }); return false; @@ -311,7 +323,7 @@ export const toWorkerImplementPage = (item) => { return false; } uni.navigateTo({ - url: `/pages-sub/problem/work-order-manage/add-maintain-order?tempKey=${tempKey}` + url: `/pages-sub/problem/work-order-manage/add-maintain-order?tempKey=${tempKey}&from=${from}` }); return true; } \ No newline at end of file diff --git a/pages-sub/problem/ai-manage/index.vue b/pages-sub/problem/ai-manage/index.vue index a0a908a..fe9f017 100644 --- a/pages-sub/problem/ai-manage/index.vue +++ b/pages-sub/problem/ai-manage/index.vue @@ -517,9 +517,9 @@ const handleUnifiedProcess = async (item, action = null) => { : await queryUnifiedActions(item) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'ai')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 diff --git a/pages-sub/problem/regional-order-manage/index.vue b/pages-sub/problem/regional-order-manage/index.vue index cc9792e..9eecc81 100644 --- a/pages-sub/problem/regional-order-manage/index.vue +++ b/pages-sub/problem/regional-order-manage/index.vue @@ -498,9 +498,9 @@ const handleUnifiedProcess = async (item, action = null) => { : await queryUnifiedActions(item) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 diff --git a/pages-sub/problem/regional-order-manage/list-detail.vue b/pages-sub/problem/regional-order-manage/list-detail.vue index de878f4..39a82a1 100644 --- a/pages-sub/problem/regional-order-manage/list-detail.vue +++ b/pages-sub/problem/regional-order-manage/list-detail.vue @@ -553,9 +553,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { : await queryUnifiedActions(item?.taskId) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 diff --git a/pages-sub/problem/regional-order-manage/order-detail.vue b/pages-sub/problem/regional-order-manage/order-detail.vue index 851dfc6..43c3a15 100644 --- a/pages-sub/problem/regional-order-manage/order-detail.vue +++ b/pages-sub/problem/regional-order-manage/order-detail.vue @@ -623,9 +623,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { : await queryUnifiedActions(item?.taskId) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 diff --git a/pages-sub/problem/work-order-manage/add-maintain-order.vue b/pages-sub/problem/work-order-manage/add-maintain-order.vue index dc6919e..7ad82bd 100644 --- a/pages-sub/problem/work-order-manage/add-maintain-order.vue +++ b/pages-sub/problem/work-order-manage/add-maintain-order.vue @@ -221,7 +221,7 @@ import { ref, reactive, watch } from 'vue' import { onLoad, onReady, onShow } from '@dcloudio/uni-app'; import { useUploadImgs } from '@/common/utils/useUploadImgs' import { getYlWorkersPage, universalApproval } from '@/api/work-order-manage/work-order-manage' -import { workRecordSubmit } from '@/api/common' +import { workRecordSubmit, getConfiguredWorkTypes } from '@/api/common' import { nextStepMap } from '@/common/utils/common' import { useUserStore } from '@/pinia/user'; const userStore = useUserStore(); @@ -243,6 +243,15 @@ const dynamicFieldCount = ref(0) // 动态字段提交幂等流水号:同一页面生命周期内保持不变,网络重试只落一条记录 let workRecordClientSeq = '' +// 来源列表页标识(work-order/regional/ai),提交后回到用户进入时的列表 +let fromPage = 'work-order' +// 来源标识 -> 列表页路径 +const BACK_URL_MAP = { + 'work-order': '/pages-sub/problem/work-order-manage/index', + 'regional': '/pages-sub/problem/regional-order-manage/index', + 'ai': '/pages-sub/problem/ai-manage/index' +} + // 页面状态 const showActionSheet = ref(false) const currentActionSheetData = reactive({ @@ -372,6 +381,8 @@ onLoad((options) => { } const { tempKey } = options; + // 来源列表页:养护员实施可能从工单管理、区域工单、AI 工单进入,提交后回原列表 + fromPage = options.from || 'work-order'; let orderItem = {}; // 2. 读取缓存并校验缓存数据是否有效 orderItem = uni.getStorageSync(tempKey) || {}; @@ -425,6 +436,9 @@ onLoad((options) => { if (orderItem.workTypeId) { workOrderForm.workTypeId = orderItem.workTypeId workOrderForm.workTypeName = uni.$dict.getDictLabel('maintain_type', orderItem.workTypeId) || '' + } else { + // 该业务线只配了一个作业类型的字段时自动选中,进页即可看到填报项 + loadDefaultWorkType() } // 共同处理人(如有数据则回显,转换为数组格式) if (orderItem.coHandlers && orderItem.coHandlersName) { @@ -728,6 +742,34 @@ const onDynamicFieldsLoaded = (count) => { dynamicFieldCount.value = count || 0 } +/** + * 自动带出作业类型:该业务线下只有一个作业类型配置了填报项时直接选中, + * 动态字段块随之渲染(v-if 绑在 workTypeId 上),用户不用先猜该选哪个作业类型。 + * 配了多个时不自动选,交给用户手选。 + */ +const loadDefaultWorkType = async () => { + if (!workOrderForm.businessType) { + return + } + try { + const list = await getConfiguredWorkTypes({ + businessType: workOrderForm.businessType, + bizType: 1 + }) + if (!Array.isArray(list) || list.length !== 1) { + return + } + const only = list[0] + workOrderForm.workTypeId = only.workTypeId + workOrderForm.workTypeName = only.workTypeName + || uni.$dict.getDictLabel('maintain_type', only.workTypeId) + || '' + dynamicFieldCount.value = 0 + } catch (error) { + console.warn('获取已配置填报项的作业类型失败:', error) + } +} + // 动态字段提交幂等流水号(后端按 userId+clientSeq 去重) const genClientSeq = () => `${Date.now()}-${Math.random().toString(16).slice(2, 10)}` @@ -916,10 +958,10 @@ const submitWorkOrder = async () => { duration: 1000 }) - // 延迟跳转 + // 延迟跳转:来源列表页在 onShow 中不做刷新,用 reLaunch 重建页面保证待办数据最新 setTimeout(() => { uni.reLaunch({ - url: '/pages-sub/problem/work-order-manage/index' + url: BACK_URL_MAP[fromPage] || BACK_URL_MAP['work-order'] }) }, 1000) } catch (error) { diff --git a/pages-sub/problem/work-order-manage/index.vue b/pages-sub/problem/work-order-manage/index.vue index 9a32a79..2f0d772 100644 --- a/pages-sub/problem/work-order-manage/index.vue +++ b/pages-sub/problem/work-order-manage/index.vue @@ -557,9 +557,9 @@ const handleUnifiedProcess = async (item, action = null) => { : await queryUnifiedActions(item) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'work-order')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 @@ -595,7 +595,7 @@ const handleUnifiedSuccess = () => { // 待办-处理工单 const handleProcess = async (item) => { - console.log(nextStepMap[item.taskKey].name) + console.log(nextStepMap[item.taskKey]?.name) try { if (nextStepMap[item.taskKey]?.name == '养护组长分配') { uni.navigateTo({ diff --git a/pages-sub/problem/work-order-manage/order-detail.vue b/pages-sub/problem/work-order-manage/order-detail.vue index e96919e..e3a91cc 100644 --- a/pages-sub/problem/work-order-manage/order-detail.vue +++ b/pages-sub/problem/work-order-manage/order-detail.vue @@ -854,9 +854,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { : await queryUnifiedActions(item) if (actions) { const target = action || actions[0] - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 - if (target?.code === 'HANDLE') { - toWorkerImplementPage(item) + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'work-order')) { return } // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择