Commit 28e3b4f3d4f5db106f43e22235fce841d8e71c6f
1 parent
98689726
业务线 小程序不用写死,从后端接口获取
Showing
10 changed files
with
91 additions
and
27 deletions
api/common.js
| ... | ... | @@ -57,6 +57,16 @@ export const getByType = (params) => { |
| 57 | 57 | }; |
| 58 | 58 | |
| 59 | 59 | /** |
| 60 | + * 拉取「已配置填报项」的作业类型 | |
| 61 | + * 填报页进入时若该业务线只配了一个作业类型,直接选中并加载动态字段,避免用户不知道要先选作业类型。 | |
| 62 | + * @param {Object} params {`businessType`、`bizType`} | |
| 63 | + * @returns {Promise} List<{workTypeId, workTypeName}> | |
| 64 | + */ | |
| 65 | +export const getConfiguredWorkTypes = (params) => { | |
| 66 | + return get('/app-api/app/garden/work-field-config/work-types', params); | |
| 67 | +}; | |
| 68 | + | |
| 69 | +/** | |
| 60 | 70 | * 拉取选项 用于 fieldType 3(枚举)/6(多选)/9(关联记录) 且 field.options 为空(即非静态来源)时获取可选项。 |
| 61 | 71 | * @param {Object} params {} |
| 62 | 72 | * @returns {Promise} | ... | ... |
common/config/env.js
| ... | ... | @@ -2,12 +2,12 @@ |
| 2 | 2 | const env = { |
| 3 | 3 | // 开发环境 |
| 4 | 4 | development: { |
| 5 | - baseUrl: 'https://test.jichengshanshui.com.cn:28302', | |
| 5 | + baseUrl: 'http://192.168.1.55:48081', | |
| 6 | 6 | // https://test.jichengshanshui.com.cn:28302 |
| 7 | 7 | |
| 8 | 8 | // baseUrl: 'http://192.168.1.111:48081', |
| 9 | 9 | |
| 10 | - uploadUrl: 'https://test.jichengshanshui.com.cn:28302', | |
| 10 | + uploadUrl: 'http://192.168.1.55:48081', | |
| 11 | 11 | // baseApi:'admin-api', |
| 12 | 12 | // appApi:'app-api' |
| 13 | 13 | }, | ... | ... |
common/utils/common.js
| ... | ... | @@ -286,6 +286,9 @@ export const translateRoles = (roles = []) => { |
| 286 | 286 | .join(','); |
| 287 | 287 | } |
| 288 | 288 | |
| 289 | +/** 配置了工单(biz_type=1)动态字段的业务线;其他业务线走统一动作弹窗 */ | |
| 290 | +const WORKER_IMPLEMENT_BIZ_LINES = ['yl', 'hj']; | |
| 291 | + | |
| 289 | 292 | /** |
| 290 | 293 | * 跳转「作业填报」页(养护员实施) |
| 291 | 294 | * |
| ... | ... | @@ -293,11 +296,20 @@ export const translateRoles = (roles = []) => { |
| 293 | 296 | * 上传开始/进行中/结束/人员/材料五组照片,统一动作弹窗只有原因+单个附件,承载不了, |
| 294 | 297 | * 因此实施动作固定进「作业填报」页。 |
| 295 | 298 | * |
| 299 | + * 只有养护(yl)、环卫(hj)配置了工单动态字段,秩序(zx)/市政(sz)/物业(wy)没有配置, | |
| 300 | + * 这类工单仍走统一动作弹窗,保持原有处理流程。 | |
| 301 | + * | |
| 296 | 302 | * 工单数据存本地缓存,URL 只带临时 key,避免参数过长。 |
| 297 | 303 | * @param {Object} item 待办行数据,需包含 id(工单ID)与 taskId(流程任务ID) |
| 298 | - * @returns {Boolean} 是否成功跳转 | |
| 304 | + * @param {String} from 来源列表页标识:work-order / regional / ai,提交后回到对应列表 | |
| 305 | + * @returns {Boolean} 是否已跳转;返回 false 时由调用方继续走统一动作弹窗 | |
| 299 | 306 | */ |
| 300 | -export const toWorkerImplementPage = (item) => { | |
| 307 | +export const toWorkerImplementPage = (item, from = 'work-order') => { | |
| 308 | + // 业务线可能多选(逗号分隔),任一命中即视为养护类工单 | |
| 309 | + const bizLines = String(item?.busiLine || '').split(',').map(v => v.trim()).filter(Boolean); | |
| 310 | + if (!bizLines.some(v => WORKER_IMPLEMENT_BIZ_LINES.includes(v))) { | |
| 311 | + return false; | |
| 312 | + } | |
| 301 | 313 | if (!item || !item.id || !item.taskId) { |
| 302 | 314 | uni.showToast({ title: '工单信息异常,无法实施', icon: 'none' }); |
| 303 | 315 | return false; |
| ... | ... | @@ -311,7 +323,7 @@ export const toWorkerImplementPage = (item) => { |
| 311 | 323 | return false; |
| 312 | 324 | } |
| 313 | 325 | uni.navigateTo({ |
| 314 | - url: `/pages-sub/problem/work-order-manage/add-maintain-order?tempKey=${tempKey}` | |
| 326 | + url: `/pages-sub/problem/work-order-manage/add-maintain-order?tempKey=${tempKey}&from=${from}` | |
| 315 | 327 | }); |
| 316 | 328 | return true; |
| 317 | 329 | } |
| 318 | 330 | \ No newline at end of file | ... | ... |
pages-sub/problem/ai-manage/index.vue
| ... | ... | @@ -517,9 +517,9 @@ const handleUnifiedProcess = async (item, action = null) => { |
| 517 | 517 | : await queryUnifiedActions(item) |
| 518 | 518 | if (actions) { |
| 519 | 519 | const target = action || actions[0] |
| 520 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 521 | - if (target?.code === 'HANDLE') { | |
| 522 | - toWorkerImplementPage(item) | |
| 520 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 521 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 522 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'ai')) { | |
| 523 | 523 | return |
| 524 | 524 | } |
| 525 | 525 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 | ... | ... |
pages-sub/problem/regional-order-manage/index.vue
| ... | ... | @@ -498,9 +498,9 @@ const handleUnifiedProcess = async (item, action = null) => { |
| 498 | 498 | : await queryUnifiedActions(item) |
| 499 | 499 | if (actions) { |
| 500 | 500 | const target = action || actions[0] |
| 501 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 502 | - if (target?.code === 'HANDLE') { | |
| 503 | - toWorkerImplementPage(item) | |
| 501 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 502 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 503 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { | |
| 504 | 504 | return |
| 505 | 505 | } |
| 506 | 506 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 | ... | ... |
pages-sub/problem/regional-order-manage/list-detail.vue
| ... | ... | @@ -553,9 +553,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { |
| 553 | 553 | : await queryUnifiedActions(item?.taskId) |
| 554 | 554 | if (actions) { |
| 555 | 555 | const target = action || actions[0] |
| 556 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 557 | - if (target?.code === 'HANDLE') { | |
| 558 | - toWorkerImplementPage(item) | |
| 556 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 557 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 558 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { | |
| 559 | 559 | return |
| 560 | 560 | } |
| 561 | 561 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 | ... | ... |
pages-sub/problem/regional-order-manage/order-detail.vue
| ... | ... | @@ -623,9 +623,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { |
| 623 | 623 | : await queryUnifiedActions(item?.taskId) |
| 624 | 624 | if (actions) { |
| 625 | 625 | const target = action || actions[0] |
| 626 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 627 | - if (target?.code === 'HANDLE') { | |
| 628 | - toWorkerImplementPage(item) | |
| 626 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 627 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 628 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'regional')) { | |
| 629 | 629 | return |
| 630 | 630 | } |
| 631 | 631 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 | ... | ... |
pages-sub/problem/work-order-manage/add-maintain-order.vue
| ... | ... | @@ -221,7 +221,7 @@ import { ref, reactive, watch } from 'vue' |
| 221 | 221 | import { onLoad, onReady, onShow } from '@dcloudio/uni-app'; |
| 222 | 222 | import { useUploadImgs } from '@/common/utils/useUploadImgs' |
| 223 | 223 | import { getYlWorkersPage, universalApproval } from '@/api/work-order-manage/work-order-manage' |
| 224 | -import { workRecordSubmit } from '@/api/common' | |
| 224 | +import { workRecordSubmit, getConfiguredWorkTypes } from '@/api/common' | |
| 225 | 225 | import { nextStepMap } from '@/common/utils/common' |
| 226 | 226 | import { useUserStore } from '@/pinia/user'; |
| 227 | 227 | const userStore = useUserStore(); |
| ... | ... | @@ -243,6 +243,15 @@ const dynamicFieldCount = ref(0) |
| 243 | 243 | // 动态字段提交幂等流水号:同一页面生命周期内保持不变,网络重试只落一条记录 |
| 244 | 244 | let workRecordClientSeq = '' |
| 245 | 245 | |
| 246 | +// 来源列表页标识(work-order/regional/ai),提交后回到用户进入时的列表 | |
| 247 | +let fromPage = 'work-order' | |
| 248 | +// 来源标识 -> 列表页路径 | |
| 249 | +const BACK_URL_MAP = { | |
| 250 | + 'work-order': '/pages-sub/problem/work-order-manage/index', | |
| 251 | + 'regional': '/pages-sub/problem/regional-order-manage/index', | |
| 252 | + 'ai': '/pages-sub/problem/ai-manage/index' | |
| 253 | +} | |
| 254 | + | |
| 246 | 255 | // 页面状态 |
| 247 | 256 | const showActionSheet = ref(false) |
| 248 | 257 | const currentActionSheetData = reactive({ |
| ... | ... | @@ -372,6 +381,8 @@ onLoad((options) => { |
| 372 | 381 | } |
| 373 | 382 | |
| 374 | 383 | const { tempKey } = options; |
| 384 | + // 来源列表页:养护员实施可能从工单管理、区域工单、AI 工单进入,提交后回原列表 | |
| 385 | + fromPage = options.from || 'work-order'; | |
| 375 | 386 | let orderItem = {}; |
| 376 | 387 | // 2. 读取缓存并校验缓存数据是否有效 |
| 377 | 388 | orderItem = uni.getStorageSync(tempKey) || {}; |
| ... | ... | @@ -425,6 +436,9 @@ onLoad((options) => { |
| 425 | 436 | if (orderItem.workTypeId) { |
| 426 | 437 | workOrderForm.workTypeId = orderItem.workTypeId |
| 427 | 438 | workOrderForm.workTypeName = uni.$dict.getDictLabel('maintain_type', orderItem.workTypeId) || '' |
| 439 | + } else { | |
| 440 | + // 该业务线只配了一个作业类型的字段时自动选中,进页即可看到填报项 | |
| 441 | + loadDefaultWorkType() | |
| 428 | 442 | } |
| 429 | 443 | // 共同处理人(如有数据则回显,转换为数组格式) |
| 430 | 444 | if (orderItem.coHandlers && orderItem.coHandlersName) { |
| ... | ... | @@ -728,6 +742,34 @@ const onDynamicFieldsLoaded = (count) => { |
| 728 | 742 | dynamicFieldCount.value = count || 0 |
| 729 | 743 | } |
| 730 | 744 | |
| 745 | +/** | |
| 746 | + * 自动带出作业类型:该业务线下只有一个作业类型配置了填报项时直接选中, | |
| 747 | + * 动态字段块随之渲染(v-if 绑在 workTypeId 上),用户不用先猜该选哪个作业类型。 | |
| 748 | + * 配了多个时不自动选,交给用户手选。 | |
| 749 | + */ | |
| 750 | +const loadDefaultWorkType = async () => { | |
| 751 | + if (!workOrderForm.businessType) { | |
| 752 | + return | |
| 753 | + } | |
| 754 | + try { | |
| 755 | + const list = await getConfiguredWorkTypes({ | |
| 756 | + businessType: workOrderForm.businessType, | |
| 757 | + bizType: 1 | |
| 758 | + }) | |
| 759 | + if (!Array.isArray(list) || list.length !== 1) { | |
| 760 | + return | |
| 761 | + } | |
| 762 | + const only = list[0] | |
| 763 | + workOrderForm.workTypeId = only.workTypeId | |
| 764 | + workOrderForm.workTypeName = only.workTypeName | |
| 765 | + || uni.$dict.getDictLabel('maintain_type', only.workTypeId) | |
| 766 | + || '' | |
| 767 | + dynamicFieldCount.value = 0 | |
| 768 | + } catch (error) { | |
| 769 | + console.warn('获取已配置填报项的作业类型失败:', error) | |
| 770 | + } | |
| 771 | +} | |
| 772 | + | |
| 731 | 773 | // 动态字段提交幂等流水号(后端按 userId+clientSeq 去重) |
| 732 | 774 | const genClientSeq = () => `${Date.now()}-${Math.random().toString(16).slice(2, 10)}` |
| 733 | 775 | |
| ... | ... | @@ -916,10 +958,10 @@ const submitWorkOrder = async () => { |
| 916 | 958 | duration: 1000 |
| 917 | 959 | }) |
| 918 | 960 | |
| 919 | - // 延迟跳转 | |
| 961 | + // 延迟跳转:来源列表页在 onShow 中不做刷新,用 reLaunch 重建页面保证待办数据最新 | |
| 920 | 962 | setTimeout(() => { |
| 921 | 963 | uni.reLaunch({ |
| 922 | - url: '/pages-sub/problem/work-order-manage/index' | |
| 964 | + url: BACK_URL_MAP[fromPage] || BACK_URL_MAP['work-order'] | |
| 923 | 965 | }) |
| 924 | 966 | }, 1000) |
| 925 | 967 | } catch (error) { | ... | ... |
pages-sub/problem/work-order-manage/index.vue
| ... | ... | @@ -557,9 +557,9 @@ const handleUnifiedProcess = async (item, action = null) => { |
| 557 | 557 | : await queryUnifiedActions(item) |
| 558 | 558 | if (actions) { |
| 559 | 559 | const target = action || actions[0] |
| 560 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 561 | - if (target?.code === 'HANDLE') { | |
| 562 | - toWorkerImplementPage(item) | |
| 560 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 561 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 562 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'work-order')) { | |
| 563 | 563 | return |
| 564 | 564 | } |
| 565 | 565 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 |
| ... | ... | @@ -595,7 +595,7 @@ const handleUnifiedSuccess = () => { |
| 595 | 595 | |
| 596 | 596 | // 待办-处理工单 |
| 597 | 597 | const handleProcess = async (item) => { |
| 598 | - console.log(nextStepMap[item.taskKey].name) | |
| 598 | + console.log(nextStepMap[item.taskKey]?.name) | |
| 599 | 599 | try { |
| 600 | 600 | if (nextStepMap[item.taskKey]?.name == '养护组长分配') { |
| 601 | 601 | uni.navigateTo({ | ... | ... |
pages-sub/problem/work-order-manage/order-detail.vue
| ... | ... | @@ -854,9 +854,9 @@ const handleUnifiedProcess = async (item: any, action: any = null) => { |
| 854 | 854 | : await queryUnifiedActions(item) |
| 855 | 855 | if (actions) { |
| 856 | 856 | const target = action || actions[0] |
| 857 | - // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页 | |
| 858 | - if (target?.code === 'HANDLE') { | |
| 859 | - toWorkerImplementPage(item) | |
| 857 | + // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; | |
| 858 | + // 该业务线未配置工单动态字段时返回 false,继续走统一动作弹窗 | |
| 859 | + if (target?.code === 'HANDLE' && toWorkerImplementPage(item, 'work-order')) { | |
| 860 | 860 | return |
| 861 | 861 | } |
| 862 | 862 | // 传入的动作即用户点击的配置按钮,直接执行该动作,不再弹「请选择操作」二次选择 | ... | ... |