Commit 2764b83e602b3746156e41ee9b4d4c5e222f0fc8

Authored by 刘淇
1 parent ff65dc6c

分配养护员

common/utils/common.js
  1 +export const nextStepMap = {
  2 + ylTeamLeader: '养护组长分配', //
  3 + ylWorker:'养护员待实施'
  4 +
  5 +}
0 \ No newline at end of file 6 \ No newline at end of file
pages-sub/problem/work-order-manage/add-maintain-order.vue 0 → 100644
  1 +<template>
  2 + <view class="page-container">
  3 + <view class="work-order-form-content commonPageLRpadding">
  4 + <up-form
  5 + label-position="left"
  6 + :model="workOrderForm"
  7 + ref="workOrderFormRef"
  8 + labelWidth="190rpx"
  9 + >
  10 + <!-- 1. 工单编号(新增:从URL获取,只读展示) -->
  11 + <up-form-item
  12 + label="工单编号"
  13 + border-bottom
  14 + >
  15 + <up-input
  16 + v-model="workOrderForm.orderNo"
  17 + border="none"
  18 + readonly
  19 + placeholder="暂无工单编号"
  20 + ></up-input>
  21 + </up-form-item>
  22 +
  23 + <!-- 2. 共同处理人(新增:非必选,下拉框) -->
  24 + <up-form-item
  25 + label="共同处理人"
  26 + prop="coProcessorName"
  27 + border-bottom
  28 + @click="handleActionSheetOpen('coProcessor'); hideKeyboard()"
  29 + >
  30 + <up-input
  31 + v-model="workOrderForm.coProcessorName"
  32 + disabled
  33 + disabled-color="#ffffff"
  34 + placeholder="请选择共同处理人(可选)"
  35 + border="none"
  36 + ></up-input>
  37 + <template #right>
  38 + <up-icon name="arrow-right" size="16"></up-icon>
  39 + </template>
  40 + </up-form-item>
  41 +
  42 + <!-- 3. 处理建议(新增:必传,文本域) -->
  43 + <up-form-item
  44 + label="处理建议"
  45 + prop="reason"
  46 + required
  47 + >
  48 + <up-textarea
  49 + placeholder="请输入处理建议(必填,最多200字)"
  50 + v-model.trim="workOrderForm.reason"
  51 + count
  52 + maxlength="200"
  53 + rows="4"
  54 + border="none"
  55 + @blur="() => workOrderFormRef.validateField('reason')"
  56 + ></up-textarea>
  57 + </up-form-item>
  58 +
  59 + <!-- 原有:工单位置(地图选择) -->
  60 + <up-form-item
  61 + label="工单位置"
  62 + prop="workLocation"
  63 + border-bottom
  64 + required
  65 + @click="chooseWorkLocation(); hideKeyboard()"
  66 + >
  67 + <up-input
  68 + v-model="workOrderForm.workLocation"
  69 + border="none"
  70 + readonly
  71 + suffix-icon="map-fill"
  72 + placeholder="点击选择工单位置"
  73 + ></up-input>
  74 + </up-form-item>
  75 +
  76 + <!-- 原有:道路名称(下拉框) -->
  77 + <up-form-item
  78 + label="道路名称"
  79 + prop="roadName"
  80 + border-bottom
  81 + required
  82 + @click="handleActionSheetOpen('roadName'); hideKeyboard()"
  83 + >
  84 + <up-input
  85 + v-model="workOrderForm.roadName"
  86 + readonly
  87 + disabled-color="#ffffff"
  88 + placeholder="请先选择工单位置"
  89 + border="none"
  90 + ></up-input>
  91 + <template #right>
  92 + <up-icon name="arrow-right" size="16"></up-icon>
  93 + </template>
  94 + </up-form-item>
  95 +
  96 + <!-- 原有:工单名称(下拉框) -->
  97 + <up-form-item
  98 + label="工单名称"
  99 + prop="orderName"
  100 + border-bottom
  101 + required
  102 + @click="handleActionSheetOpen('orderName'); hideKeyboard()"
  103 + >
  104 + <up-input
  105 + v-model="workOrderForm.orderName"
  106 + disabled
  107 + disabled-color="#ffffff"
  108 + placeholder="请选择工单名称"
  109 + border="none"
  110 + ></up-input>
  111 + <template #right>
  112 + <up-icon name="arrow-right" size="16"></up-icon>
  113 + </template>
  114 + </up-form-item>
  115 +
  116 + <!-- 原有:紧急程度选择 -->
  117 + <up-form-item
  118 + label="紧急程度"
  119 + prop="pressingTypeName"
  120 + border-bottom
  121 + required
  122 + @click="handleActionSheetOpen('pressingType'); hideKeyboard()"
  123 + >
  124 + <up-input
  125 + v-model="workOrderForm.pressingTypeName"
  126 + disabled
  127 + disabled-color="#ffffff"
  128 + placeholder="请选择紧急程度"
  129 + border="none"
  130 + ></up-input>
  131 + <template #right>
  132 + <up-icon name="arrow-right" size="16"></up-icon>
  133 + </template>
  134 + </up-form-item>
  135 +
  136 + <!-- 原有:情况描述(文本域) -->
  137 + <up-form-item
  138 + label="情况描述"
  139 + prop="problemDesc"
  140 + required
  141 + >
  142 + <up-textarea
  143 + placeholder="请输入情况描述(最多200字)"
  144 + v-model.trim="workOrderForm.problemDesc"
  145 + count
  146 + maxlength="200"
  147 + rows="4"
  148 + @blur="() => workOrderFormRef.validateField('problemDesc')"
  149 + ></up-textarea>
  150 + </up-form-item>
  151 +
  152 + <!-- 原有:问题照片 -->
  153 + <up-form-item label="问题照片" prop="problemImgs" required>
  154 + <up-upload
  155 + :file-list="problemImgs.imgList"
  156 + @after-read="problemImgs.uploadImgs"
  157 + @delete="problemImgs.deleteImg"
  158 + multiple
  159 + :max-count="problemImgs.uploadConfig.maxCount"
  160 + :upload-text="problemImgs.uploadConfig.uploadText"
  161 + :size-type="problemImgs.uploadConfig.sizeType"
  162 + ></up-upload>
  163 + </up-form-item>
  164 +
  165 + <!-- 原有:完成时间 -->
  166 + <up-form-item
  167 + label="希望完成时间"
  168 + prop="finishDate"
  169 + @click="show=true;hideKeyboard()"
  170 + >
  171 + <up-input
  172 + v-model="workOrderForm.finishDate"
  173 + border="none"
  174 + readonly
  175 + placeholder="点击选择时间"
  176 + ></up-input>
  177 + <template #right>
  178 + <up-icon name="arrow-right" size="16"></up-icon>
  179 + </template>
  180 + </up-form-item>
  181 + </up-form>
  182 +
  183 + <!-- 4. Tabs标签栏(新增:开始、进行中、结束、人员、材料) -->
  184 + <view class="tabs-wrap commonPageLRpadding" style="margin-top: 30rpx;">
  185 + <up-tabs
  186 + v-model="activeTab"
  187 + :list="tabList"
  188 + line-width="40rpx"
  189 + active-color="#1989fa"
  190 + inactive-color="#666666"
  191 + ></up-tabs>
  192 + <!-- Tab对应内容容器(可根据需求填充具体内容) -->
  193 + <view class="tab-content" style="padding-top: 20rpx;">
  194 + <view v-if="activeTab === 0">开始阶段相关内容</view>
  195 + <view v-if="activeTab === 1">进行中阶段相关内容</view>
  196 + <view v-if="activeTab === 2">结束阶段相关内容</view>
  197 + <view v-if="activeTab === 3">人员配置相关内容</view>
  198 + <view v-if="activeTab === 4">材料使用相关内容</view>
  199 + </view>
  200 + </view>
  201 + </view>
  202 +
  203 + <!-- 底部提交按钮 -->
  204 + <view class="fixed-bottom-btn-wrap">
  205 + <up-button
  206 + type="primary"
  207 + text="提交工单"
  208 + @click="submitWorkOrder"
  209 + ></up-button>
  210 + </view>
  211 +
  212 + <!-- 合并后的通用下拉弹窗(新增共同处理人配置) -->
  213 + <up-action-sheet
  214 + :show="showActionSheet"
  215 + :actions="currentActionSheetData.list"
  216 + :title="currentActionSheetData.title"
  217 + @close="handleActionSheetClose"
  218 + @select="handleActionSheetSelect"
  219 + ></up-action-sheet>
  220 +
  221 + <!-- 完成时间选择器 -->
  222 + <up-datetime-picker
  223 + :show="show"
  224 + v-model="finishDate"
  225 + mode="datetime"
  226 + :min-date="new Date()"
  227 + @cancel="show = false"
  228 + @confirm="finishDateConfirm"
  229 + ></up-datetime-picker>
  230 + </view>
  231 +</template>
  232 +
  233 +<script setup>
  234 +import { ref, reactive, watch, onLoad } from 'vue'
  235 +import { onReady, onShow } from '@dcloudio/uni-app';
  236 +import { useUploadImgs } from '@/common/utils/useUploadImgs'
  237 +import { getRoadListByLatLng } from '@/api/common'
  238 +import { workorderCreate, getYlWorkersPage, ylTeamLeaderAssignWOrder, ylWorkerExcuteWOrder } from '@/api/work-order-manage/work-order-manage'
  239 +import { timeFormat } from '@/uni_modules/uview-plus'
  240 +
  241 +// ========== 表单Ref ==========
  242 +const workOrderFormRef = ref(null)
  243 +
  244 +// ========== 公共上传逻辑复用 ==========
  245 +const problemImgs = useUploadImgs({
  246 + maxCount: 3,
  247 + uploadText: '选择问题照片',
  248 + sizeType: ['compressed'],
  249 + formRef: workOrderFormRef,
  250 + fieldName: 'problemImgs'
  251 +})
  252 +
  253 +// 核心修复:监听响应式数组变化,同步更新纯数组
  254 +watch(() => problemImgs.rawImgList.value, (newVal) => {
  255 + problemImgs.imgList = newVal
  256 +}, { deep: true })
  257 +
  258 +// ========== 页面状态 ==========
  259 +const showActionSheet = ref(false)
  260 +const currentActionSheetData = reactive({
  261 + type: '',
  262 + list: [],
  263 + title: ''
  264 +})
  265 +const show = ref(false)
  266 +const finishDate = ref(Date.now())
  267 +
  268 +// 新增:Tabs配置
  269 +const activeTab = ref(0) // 默认选中第一个标签
  270 +const tabList = ref([
  271 + { name: '开始' },
  272 + { name: '进行中' },
  273 + { name: '结束' },
  274 + { name: '人员' },
  275 + { name: '材料' }
  276 +])
  277 +
  278 +// ========== 下拉列表数据 ==========
  279 +const roadNameList = ref([])
  280 +const orderNameList = ref([])
  281 +const pressingTypeList = ref([])
  282 +const coProcessorList = ref([]) // 新增:共同处理人列表(来自getYlWorkersPage)
  283 +
  284 +// ========== 工单表单数据(新增字段) ==========
  285 +const workOrderForm = reactive({
  286 + orderNo: '', // 新增:工单编号(URL获取)
  287 + coProcessorId: '', // 新增:共同处理人ID(非必选,提交接口用)
  288 + coProcessorName: '', // 新增:共同处理人名称(显示用)
  289 + reason: '', // 新增:处理建议(必填)
  290 + roadId: 0,
  291 + roadName: '',
  292 + workLocation: '',
  293 + orderName: '',
  294 + pressingType: '',
  295 + pressingTypeName: '',
  296 + problemDesc: '',
  297 + lat: 0,
  298 + lon: 0,
  299 + finishDate: '',
  300 +})
  301 +
  302 +// ========== 表单校验规则(更新:新增处理建议必填、共同处理人非必填) ==========
  303 +const workOrderFormRules = reactive({
  304 + orderNo: [ // 工单编号仅展示,无校验
  305 + { type: 'string', trigger: ['change'] }
  306 + ],
  307 + coProcessorName: [ // 共同处理人非必填,仅长度兜底
  308 + { type: 'string', max: 50, message: '共同处理人名称过长', trigger: ['change'] }
  309 + ],
  310 + reason: [ // 处理建议必填+长度限制
  311 + { type: 'string', required: true, message: '请输入处理建议', trigger: ['change', 'blur'] },
  312 + { type: 'string', max: 200, message: '处理建议最多200字', trigger: ['change', 'blur'] }
  313 + ],
  314 + workLocation: [
  315 + { type: 'string', required: true, message: '请选择工单位置', trigger: ['change', 'blur'] }
  316 + ],
  317 + roadName: [
  318 + { type: 'string', required: true, message: '请选择道路名称', trigger: ['change', 'blur'] }
  319 + ],
  320 + orderName: [
  321 + { type: 'string', required: true, message: '请选择工单名称', trigger: ['change', 'blur'] }
  322 + ],
  323 + pressingTypeName: [
  324 + { type: 'string', required: true, message: '请选择紧急程度', trigger: ['change'] }
  325 + ],
  326 + problemDesc: [
  327 + { type: 'string', required: true, message: '请输入情况描述', trigger: ['change', 'blur'] },
  328 + { type: 'string', min: 3, max: 200, message: '情况描述需3-200字', trigger: ['change', 'blur'] }
  329 + ],
  330 + problemImgs: [problemImgs.imgValidateRule]
  331 +})
  332 +
  333 +// ========== 生命周期 ==========
  334 +// 新增:onLoad - 从URL获取工单编号
  335 +onLoad((options) => {
  336 + if (options && options.orderNo) {
  337 + workOrderForm.orderNo = options.orderNo
  338 + }
  339 + console.log('从URL获取工单编号:', workOrderForm.orderNo)
  340 +})
  341 +
  342 +onReady(() => {
  343 + if (workOrderFormRef.value) {
  344 + workOrderFormRef.value.setRules(workOrderFormRules)
  345 + }
  346 + console.log('工单表单规则初始化完成')
  347 +})
  348 +
  349 +onShow(async () => {
  350 + console.log(uni.$dict.getDictLabel('ai_image_status', 20))
  351 + console.log(uni.$dict.getDictSimpleList('work_name'))
  352 +
  353 + // 初始化工单名称列表
  354 + orderNameList.value = uni.$dict.transformLabelValueToNameValue(uni.$dict.getDictSimpleList('work_name'))
  355 + console.log('工单名称列表:', orderNameList.value)
  356 +
  357 + // 初始化紧急程度列表
  358 + pressingTypeList.value = uni.$dict.transformLabelValueToNameValue(uni.$dict.getDictSimpleList('workorder_pressing_type'))
  359 + console.log('紧急程度列表:', pressingTypeList.value)
  360 +
  361 + // 新增:加载共同处理人列表(来自getYlWorkersPage)
  362 + await loadCoProcessorList()
  363 +})
  364 +
  365 +// ========== 新增:加载共同处理人列表 ==========
  366 +const loadCoProcessorList = async () => {
  367 + try {
  368 + uni.showLoading({ title: '获取处理人列表中...' })
  369 + // 构造查询参数(可根据接口需求调整)
  370 + const queryData = {
  371 + roleCode: 'team_leader_yl',
  372 + busiLine: 'yl',
  373 + pageNo: 1,
  374 + pageSize: 100
  375 + }
  376 + const res = await getYlWorkersPage(queryData)
  377 + uni.hideLoading()
  378 +
  379 + // 适配接口返回格式(兼容res.data.list或res.records)
  380 + let listData = []
  381 + if (res && res.code === 0 && res.data && res.data.list) {
  382 + listData = res.data.list
  383 + } else if (res && res.records) {
  384 + listData = res.records
  385 + }
  386 +
  387 + if (Array.isArray(listData) && listData.length > 0) {
  388 + // 格式化共同处理人列表(映射name和value)
  389 + coProcessorList.value = listData.map(item => ({
  390 + name: item.nickname || item.realName || item.userName || '未知处理人',
  391 + value: item.id || item.workerId || '',
  392 + id: item.id || item.workerId || ''
  393 + }))
  394 + } else {
  395 + coProcessorList.value = []
  396 + uni.showToast({ title: '未查询到处理人数据', icon: 'none' })
  397 + }
  398 + } catch (err) {
  399 + uni.hideLoading()
  400 + console.error('获取共同处理人列表失败:', err)
  401 + uni.showToast({ title: '获取处理人失败,请重试', icon: 'none' })
  402 + coProcessorList.value = []
  403 + }
  404 +}
  405 +
  406 +// ========== 方法定义 ==========
  407 +/**
  408 + * 打开通用下拉弹窗(新增共同处理人配置)
  409 + */
  410 +const handleActionSheetOpen = (type) => {
  411 + // 道路名称需先校验工单位置是否选择
  412 + if (type === 'roadName' && !workOrderForm.workLocation) {
  413 + uni.showToast({ title: '请先选择工单位置', icon: 'none' })
  414 + return
  415 + }
  416 +
  417 + // 共同处理人列表为空提示
  418 + if (type === 'coProcessor' && coProcessorList.value.length === 0) {
  419 + uni.showToast({ title: '暂无处理人数据可选', icon: 'none' })
  420 + return
  421 + }
  422 +
  423 + // 配置当前弹窗参数(新增coProcessor)
  424 + const configMap = {
  425 + coProcessor: {
  426 + title: '请选择共同处理人',
  427 + list: coProcessorList.value
  428 + },
  429 + roadName: {
  430 + title: '请选择道路名称',
  431 + list: roadNameList.value
  432 + },
  433 + orderName: {
  434 + title: '请选择工单名称',
  435 + list: orderNameList.value
  436 + },
  437 + pressingType: {
  438 + title: '请选择紧急程度',
  439 + list: pressingTypeList.value
  440 + }
  441 + }
  442 +
  443 + currentActionSheetData.type = type
  444 + currentActionSheetData.title = configMap[type].title
  445 + currentActionSheetData.list = configMap[type].list
  446 + showActionSheet.value = true
  447 +}
  448 +
  449 +/**
  450 + * 关闭通用下拉弹窗
  451 + */
  452 +const handleActionSheetClose = () => {
  453 + showActionSheet.value = false
  454 + currentActionSheetData.type = ''
  455 + currentActionSheetData.list = []
  456 + currentActionSheetData.title = ''
  457 +}
  458 +
  459 +/**
  460 + * 通用下拉弹窗选择事件(新增共同处理人逻辑)
  461 + */
  462 +const handleActionSheetSelect = (e) => {
  463 + const { type } = currentActionSheetData
  464 + switch (type) {
  465 + case 'coProcessor': // 新增:共同处理人选择
  466 + workOrderForm.coProcessorName = e.name
  467 + workOrderForm.coProcessorId = e.value
  468 + workOrderFormRef.value?.validateField('coProcessorName')
  469 + break
  470 + case 'roadName':
  471 + workOrderForm.roadName = e.name
  472 + workOrderForm.roadId = e.code
  473 + workOrderFormRef.value?.validateField('roadName')
  474 + break
  475 + case 'orderName':
  476 + workOrderForm.orderName = e.name
  477 + workOrderFormRef.value?.validateField('orderName')
  478 + break
  479 + case 'pressingType':
  480 + workOrderForm.pressingType = e.value
  481 + workOrderForm.pressingTypeName = e.name
  482 + workOrderFormRef.value?.validateField('pressingType')
  483 + break
  484 + }
  485 + showActionSheet.value = false
  486 +}
  487 +
  488 +/**
  489 + * 返回上一页
  490 + */
  491 +const navigateBack = () => {
  492 + uni.navigateBack()
  493 +}
  494 +
  495 +/**
  496 + * 选择工单位置
  497 + */
  498 +const chooseWorkLocation = () => {
  499 + uni.chooseLocation({
  500 + success: async (res) => {
  501 + workOrderForm.roadName = ''
  502 + workOrderForm.roadId = 0
  503 + roadNameList.value = []
  504 +
  505 + workOrderForm.workLocation = res.name
  506 + workOrderForm.lat = res.latitude
  507 + workOrderForm.lon = res.longitude
  508 +
  509 + workOrderFormRef.value?.validateField('workLocation')
  510 + workOrderFormRef.value?.validateField('roadName')
  511 +
  512 + try {
  513 + uni.showLoading({ title: '获取道路名称中...' })
  514 + const roadRes = await getRoadListByLatLng({
  515 + companyCode: 'sls',
  516 + latitude: res.latitude,
  517 + longitude: res.longitude
  518 + })
  519 + uni.hideLoading()
  520 +
  521 + if (Array.isArray(roadRes)) {
  522 + roadNameList.value = roadRes.map((item) => ({
  523 + name: item.roadName || '',
  524 + code: item.roadCode || '',
  525 + id: item.roadId || 0
  526 + }))
  527 + } else {
  528 + roadNameList.value = [{ name: '未查询到道路名称', code: '', id: 0 }]
  529 + uni.showToast({ title: '未查询到该位置的道路信息', icon: 'none' })
  530 + }
  531 + } catch (err) {
  532 + uni.hideLoading()
  533 + console.error('获取道路名称失败:', err)
  534 + uni.showToast({ title: '获取道路名称失败,请重试', icon: 'none' })
  535 + roadNameList.value = [{ name: '获取失败,请重新选择位置', code: '', id: 0 }]
  536 + }
  537 + },
  538 + fail: (err) => {
  539 + console.error('选择位置失败:', err)
  540 + uni.showToast({ title: '选择位置失败:' + err.errMsg, icon: 'none' })
  541 + }
  542 + })
  543 +}
  544 +
  545 +/**
  546 + * 完成时间确认
  547 + */
  548 +const finishDateConfirm = (e) => {
  549 + console.log('选择的完成时间:', e)
  550 + workOrderForm.finishDate = timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')
  551 + show.value = false
  552 +}
  553 +
  554 +/**
  555 + * 隐藏键盘
  556 + */
  557 +const hideKeyboard = () => {
  558 + uni.hideKeyboard()
  559 +}
  560 +
  561 +/**
  562 + * 提交工单(改造:使用ylWorkerExcuteWOrder接口,传递新增参数)
  563 + */
  564 +const submitWorkOrder = async () => {
  565 + try {
  566 + // 表单校验
  567 + await workOrderFormRef.value.validate()
  568 +
  569 + // 构造提交参数(包含原有参数+新增字段)
  570 + const submitData = {
  571 + id: workOrderForm.orderNo, // 工单编号(对应接口id)
  572 + reason: workOrderForm.reason.trim(), // 处理建议(必填)
  573 + coProcessorId: workOrderForm.coProcessorId, // 共同处理人ID(非必选)
  574 + roadId: workOrderForm.roadId,
  575 + roadName: workOrderForm.roadName,
  576 + imgs: problemImgs.getSuccessImgUrls(),
  577 + remark: workOrderForm.problemDesc.trim(),
  578 + latLonType: 2,
  579 + lat: workOrderForm.lat,
  580 + lon: workOrderForm.lon,
  581 + lonLatAddress: workOrderForm.workLocation,
  582 + pressingType: workOrderForm.pressingType,
  583 + orderName: workOrderForm.orderName,
  584 + finishDate: workOrderForm.finishDate,
  585 + sourceId: 1,
  586 + sourceName: '园林',
  587 + busiLine: 'yl'
  588 + }
  589 +
  590 + // 显示加载中
  591 + uni.showLoading({ title: '提交中...' })
  592 +
  593 + // 替换为指定接口:ylWorkerExcuteWOrder
  594 + const res = await ylWorkerExcuteWOrder(submitData)
  595 +
  596 + uni.hideLoading()
  597 + uni.showToast({
  598 + title: '工单提交成功',
  599 + icon: 'success',
  600 + duration: 1000
  601 + })
  602 +
  603 + // 延迟跳转
  604 + setTimeout(() => {
  605 + uni.redirectTo({
  606 + url: '/pages-sub/problem/work-order-manage/index'
  607 + })
  608 + }, 1000)
  609 + } catch (error) {
  610 + uni.hideLoading()
  611 +
  612 + // 区分表单校验失败和接口调用失败
  613 + if (!Array.isArray(error)) {
  614 + console.error('工单提交失败:', error)
  615 + uni.showToast({
  616 + title: '提交失败,请重试',
  617 + icon: 'none',
  618 + duration: 2000
  619 + })
  620 + }
  621 + }
  622 +}
  623 +</script>
  624 +
  625 +<style lang="scss" scoped>
  626 +// 全局页面样式
  627 +.page-container {
  628 + min-height: 100vh;
  629 + padding-bottom: 100rpx; // 给底部按钮留空间
  630 + background-color: #f5f5f5;
  631 +}
  632 +
  633 +// 工单表单内容容器
  634 +.work-order-form-content {
  635 + background: #fff;
  636 + padding-bottom: 30rpx;
  637 +}
  638 +
  639 +// Tabs容器样式
  640 +.tabs-wrap {
  641 + background: #fff;
  642 +}
  643 +
  644 +
  645 +</style>
0 \ No newline at end of file 646 \ No newline at end of file
pages-sub/problem/work-order-manage/add-order.vue
@@ -7,77 +7,32 @@ @@ -7,77 +7,32 @@
7 ref="workOrderFormRef" 7 ref="workOrderFormRef"
8 labelWidth="190rpx" 8 labelWidth="190rpx"
9 > 9 >
10 - <!-- 1. 工单位置(地图选择) --> 10 + <!-- 1. 工单编号(从URL获取展示) -->
11 <up-form-item 11 <up-form-item
12 - label="工单位置"  
13 - prop="workLocation" 12 + label="工单编号"
14 border-bottom 13 border-bottom
15 - required  
16 - @click="chooseWorkLocation(); hideKeyboard()"  
17 > 14 >
18 <up-input 15 <up-input
19 - v-model="workOrderForm.workLocation" 16 + v-model="workOrderForm.orderNo"
20 border="none" 17 border="none"
21 readonly 18 readonly
22 - suffix-icon="map-fill"  
23 - placeholder="点击选择工单位置"  
24 - ></up-input>  
25 - </up-form-item>  
26 -  
27 - <!-- 2. 道路名称(下拉框) -->  
28 - <up-form-item  
29 - label="道路名称"  
30 - prop="roadName"  
31 - border-bottom  
32 - required  
33 - @click="handleActionSheetOpen('roadName'); hideKeyboard()"  
34 - >  
35 - <up-input  
36 - v-model="workOrderForm.roadName"  
37 - readonly  
38 - disabled-color="#ffffff"  
39 - placeholder="请先选择工单位置"  
40 - border="none"  
41 -  
42 - ></up-input>  
43 - <template #right>  
44 - <up-icon name="arrow-right" size="16" ></up-icon>  
45 - </template>  
46 - </up-form-item>  
47 -  
48 - <!-- 3. 工单名称(下拉框) -->  
49 - <up-form-item  
50 - label="工单名称"  
51 - prop="orderName"  
52 - border-bottom  
53 - required  
54 - @click="handleActionSheetOpen('orderName'); hideKeyboard()"  
55 - >  
56 - <up-input  
57 - v-model="workOrderForm.orderName"  
58 - disabled  
59 - disabled-color="#ffffff"  
60 - placeholder="请选择工单名称"  
61 - border="none" 19 + placeholder="暂无工单编号"
62 ></up-input> 20 ></up-input>
63 - <template #right>  
64 - <up-icon name="arrow-right" size="16"></up-icon>  
65 - </template>  
66 </up-form-item> 21 </up-form-item>
67 22
68 - <!-- 新增:紧急程度选择 --> 23 + <!-- 2. 养护员选择(必选,下拉框) -->
69 <up-form-item 24 <up-form-item
70 - label="紧急程度"  
71 - prop="pressingTypeName" 25 + label="养护员"
  26 + prop="assigneeName"
72 border-bottom 27 border-bottom
73 required 28 required
74 - @click="handleActionSheetOpen('pressingType'); hideKeyboard()" 29 + @click="handleActionSheetOpen('assignee'); hideKeyboard()"
75 > 30 >
76 <up-input 31 <up-input
77 - v-model="workOrderForm.pressingTypeName" 32 + v-model="workOrderForm.assigneeName"
78 disabled 33 disabled
79 disabled-color="#ffffff" 34 disabled-color="#ffffff"
80 - placeholder="请选择紧急程度" 35 + placeholder="请选择养护员"
81 border="none" 36 border="none"
82 ></up-input> 37 ></up-input>
83 <template #right> 38 <template #right>
@@ -85,51 +40,19 @@ @@ -85,51 +40,19 @@
85 </template> 40 </template>
86 </up-form-item> 41 </up-form-item>
87 42
88 - <!-- 4. 情况描述(文本域) --> 43 + <!-- 3. 处理意见(非必填,文本域) -->
89 <up-form-item 44 <up-form-item
90 - label="情况描述"  
91 - prop="problemDesc"  
92 - required 45 + label="处理意见"
  46 + prop="reason"
93 > 47 >
94 <up-textarea 48 <up-textarea
95 - placeholder="请输入情况描述(最多200字)"  
96 - v-model.trim="workOrderForm.problemDesc" 49 + placeholder="请输入处理意见(可选,最多200字)"
  50 + v-model.trim="workOrderForm.reason"
97 count 51 count
98 maxlength="200" 52 maxlength="200"
99 rows="4" 53 rows="4"
100 - @blur="() => workOrderFormRef.validateField('problemDesc')"  
101 ></up-textarea> 54 ></up-textarea>
102 </up-form-item> 55 </up-form-item>
103 -  
104 - <!-- 问题照片(核心修复:绑定纯数组) -->  
105 - <up-form-item label="问题照片" prop="problemImgs" required>  
106 - <up-upload  
107 - :file-list="problemImgs.imgList"  
108 - @after-read="problemImgs.uploadImgs"  
109 - @delete="problemImgs.deleteImg"  
110 - multiple  
111 - :max-count="problemImgs.uploadConfig.maxCount"  
112 - :upload-text="problemImgs.uploadConfig.uploadText"  
113 - :size-type="problemImgs.uploadConfig.sizeType"  
114 - ></up-upload>  
115 - </up-form-item>  
116 -  
117 - <!-- 完成时间 -->  
118 - <up-form-item  
119 - label="希望完成时间"  
120 - prop="finishDate"  
121 - @click="show=true;hideKeyboard()"  
122 - >  
123 - <up-input  
124 - v-model="workOrderForm.finishDate"  
125 - border="none"  
126 - readonly  
127 - placeholder="点击选择时间"  
128 - ></up-input>  
129 - <template #right>  
130 - <up-icon name="arrow-right" size="16"></up-icon>  
131 - </template>  
132 - </up-form-item>  
133 </up-form> 56 </up-form>
134 </view> 57 </view>
135 58
@@ -137,12 +60,12 @@ @@ -137,12 +60,12 @@
137 <view class="fixed-bottom-btn-wrap"> 60 <view class="fixed-bottom-btn-wrap">
138 <up-button 61 <up-button
139 type="primary" 62 type="primary"
140 - text="提交工单" 63 + text="提交"
141 @click="submitWorkOrder" 64 @click="submitWorkOrder"
142 ></up-button> 65 ></up-button>
143 </view> 66 </view>
144 67
145 - <!-- 合并后的通用下拉弹窗 --> 68 + <!-- 养护员下拉弹窗 -->
146 <up-action-sheet 69 <up-action-sheet
147 :show="showActionSheet" 70 :show="showActionSheet"
148 :actions="currentActionSheetData.list" 71 :actions="currentActionSheetData.list"
@@ -150,315 +73,188 @@ @@ -150,315 +73,188 @@
150 @close="handleActionSheetClose" 73 @close="handleActionSheetClose"
151 @select="handleActionSheetSelect" 74 @select="handleActionSheetSelect"
152 ></up-action-sheet> 75 ></up-action-sheet>
153 -  
154 - <!-- 完成时间选择器 -->  
155 - <up-datetime-picker  
156 - :show="show"  
157 - v-model="finishDate"  
158 - mode="datetime"  
159 - :min-date="new Date()"  
160 - @cancel="show = false"  
161 - @confirm="finishDateConfirm"  
162 - ></up-datetime-picker>  
163 </view> 76 </view>
164 </template> 77 </template>
165 78
166 <script setup> 79 <script setup>
167 -import { ref, reactive, watch } from 'vue'  
168 -import { onReady, onShow } from '@dcloudio/uni-app';  
169 -import { useUploadImgs } from '@/common/utils/useUploadImgs' // 引入改造后的上传逻辑  
170 -import { getRoadListByLatLng } from '@/api/common'  
171 -import { workorderCreate } from '@/api/work-order-manage/work-order-manage'  
172 -import { timeFormat } from '@/uni_modules/uview-plus'  
173 - 80 +import { ref, reactive } from 'vue'
  81 +import { onLoad, onReady, onShow } from '@dcloudio/uni-app';
  82 +import { getYlWorkersPage, ylTeamLeaderAssignWOrder } from '@/api/work-order-manage/work-order-manage'
  83 +import { useUserStore } from '@/pinia/user';
  84 +const userStore = useUserStore();
174 // ========== 表单Ref ========== 85 // ========== 表单Ref ==========
175 const workOrderFormRef = ref(null) 86 const workOrderFormRef = ref(null)
176 -  
177 -// ========== 公共上传逻辑复用 ==========  
178 -const problemImgs = useUploadImgs({  
179 - maxCount: 3,  
180 - uploadText: '选择问题照片',  
181 - sizeType: ['compressed'],  
182 - formRef: workOrderFormRef,  
183 - fieldName: 'problemImgs'  
184 -})  
185 -  
186 -// 核心修复:监听响应式数组变化,同步更新纯数组(解决u-upload不刷新问题)  
187 -watch(() => problemImgs.rawImgList.value, (newVal) => {  
188 - problemImgs.imgList = newVal  
189 -}, { deep: true })  
190 -  
191 // ========== 页面状态 ========== 87 // ========== 页面状态 ==========
192 -// 通用弹窗控制  
193 const showActionSheet = ref(false) 88 const showActionSheet = ref(false)
194 -// 当前弹窗配置  
195 const currentActionSheetData = reactive({ 89 const currentActionSheetData = reactive({
196 type: '', 90 type: '',
197 list: [], 91 list: [],
198 title: '' 92 title: ''
199 }) 93 })
200 -// 完成时间选择器控制  
201 -const show = ref(false)  
202 -const finishDate = ref(Date.now())  
203 -  
204 // ========== 下拉列表数据 ========== 94 // ========== 下拉列表数据 ==========
205 -const roadNameList = ref([])  
206 -const orderNameList = ref([])  
207 -const pressingTypeList = ref([])  
208 -  
209 -// ========== 工单表单数据 ========== 95 +const assigneeList = ref([]) // 养护员列表
  96 +// ========== 工单表单数据(仅保留所需字段) ==========
210 const workOrderForm = reactive({ 97 const workOrderForm = reactive({
211 - roadId: 0, // 道路ID  
212 - roadName: '', // 道路名称  
213 - workLocation: '', // 工单位置  
214 - orderName: '', // 工单名称  
215 - pressingType: '', // 紧急程度值(提交接口用)  
216 - pressingTypeName: '', // 紧急程度名称(显示用)  
217 - problemDesc: '', // 情况描述  
218 - lat: 0, // 纬度  
219 - lon: 0, // 经度  
220 - finishDate: '', // 完成时间 98 + taskId:'',
  99 + orderNo: '', // 工单编号(对应接口参数id)
  100 + assigneeId: '', // 养护员ID(对应接口参数nextAssignee)
  101 + assigneeName: '', // 养护员名称(显示用)
  102 + reason: '' // 处理意见(对应接口参数reason)
221 }) 103 })
222 -  
223 -// ========== 表单校验规则 ========== 104 +// ========== 表单校验规则(仅保留养护员必选校验) ==========
224 const workOrderFormRules = reactive({ 105 const workOrderFormRules = reactive({
225 - workLocation: [  
226 - { type: 'string', required: true, message: '请选择工单位置', trigger: ['change', 'blur'] } 106 + assigneeName: [
  107 + {type: 'string', required: true, message: '请选择养护员', trigger: ['change']}
227 ], 108 ],
228 - roadName: [  
229 - { type: 'string', required: true, message: '请选择道路名称', trigger: ['change', 'blur'] }  
230 - ],  
231 - orderName: [  
232 - { type: 'string', required: true, message: '请选择工单名称', trigger: ['change', 'blur'] }  
233 - ],  
234 - pressingTypeName: [  
235 - { type: 'string', required: true, message: '请选择紧急程度', trigger: ['change'] }  
236 - ],  
237 - problemDesc: [  
238 - { type: 'string', required: true, message: '请输入情况描述', trigger: ['change', 'blur'] },  
239 - { type: 'string', min: 3, max: 200, message: '情况描述需3-200字', trigger: ['change', 'blur'] }  
240 - ],  
241 - problemImgs: [problemImgs.imgValidateRule] // 复用上传校验规则 109 + reason: [
  110 + {type: 'string', max: 200, message: '处理意见最多200字', trigger: ['change', 'blur']}
  111 + ]
242 }) 112 })
243 -  
244 // ========== 生命周期 ========== 113 // ========== 生命周期 ==========
  114 +// onLoad - 获取URL中的工单编号
  115 +onLoad((options) => {
  116 + // 从URL参数中获取工单编号(参数名orderNo可根据实际修改)
  117 + if (options && options.orderNo) {
  118 + workOrderForm.orderNo = options.orderNo
  119 + workOrderForm.taskId = options.taskId
  120 +
  121 + }
  122 + console.log('从URL获取工单编号:', workOrderForm.orderNo)
  123 +})
245 onReady(() => { 124 onReady(() => {
246 // 设置表单校验规则 125 // 设置表单校验规则
247 if (workOrderFormRef.value) { 126 if (workOrderFormRef.value) {
248 workOrderFormRef.value.setRules(workOrderFormRules) 127 workOrderFormRef.value.setRules(workOrderFormRules)
249 } 128 }
250 - console.log('工单表单规则初始化完成')  
251 }) 129 })
252 -  
253 onShow(() => { 130 onShow(() => {
254 - console.log(uni.$dict.getDictLabel('ai_image_status', 20))  
255 - console.log(uni.$dict.getDictSimpleList('work_name'))  
256 -  
257 - // 初始化工单名称列表  
258 - orderNameList.value = uni.$dict.transformLabelValueToNameValue(uni.$dict.getDictSimpleList('work_name'))  
259 - console.log('工单名称列表:', orderNameList.value)  
260 -  
261 - // 初始化紧急程度列表  
262 - pressingTypeList.value = uni.$dict.transformLabelValueToNameValue(uni.$dict.getDictSimpleList('workorder_pressing_type'))  
263 - console.log('紧急程度列表:', pressingTypeList.value) 131 + // 加载养护员列表
  132 + loadAssigneeList()
264 }) 133 })
265 - 134 +// ========== 加载养护员列表 ==========
  135 +const loadAssigneeList = async () => {
  136 + try {
  137 + uni.showLoading({title: '获取养护员中...'})
  138 + // 调用getYlWorkersPage接口(可根据接口要求传递参数,此处默认空对象)
  139 + console.log(userStore.userInfo.user.busiLine)
  140 + let queryData = {
  141 + // roleCode:userStore.userInfo.roles,
  142 + roleCode: 'yl_worker',
  143 + busiLine: userStore.userInfo.user.busiLine,
  144 + pageNo: 1,
  145 + pageSize: 100
  146 + }
  147 + const res = await getYlWorkersPage(queryData)
  148 + uni.hideLoading()
  149 + if (res.list.length > 0) {
  150 + assigneeList.value = res.list.map(item => ({
  151 + name: item.nickname,
  152 + value: item.id,
  153 + id: item.id
  154 + }))
  155 + console.log(currentActionSheetData.list)
  156 + } else {
  157 + uni.showToast({title: '所在班组暂无养护员,请先配置养护员', icon: 'none'})
  158 + }
  159 + console.log(currentActionSheetData.list)
  160 + } catch (err) {
  161 + uni.hideLoading()
  162 + console.error('获取养护员列表失败:', err)
  163 + uni.showToast({title: '获取养护员失败,请重试', icon: 'none'})
  164 + assigneeList.value = []
  165 + }
  166 +}
266 // ========== 方法定义 ========== 167 // ========== 方法定义 ==========
267 /** 168 /**
268 - * 打开通用下拉弹窗 169 + * 打开养护员下拉弹窗
269 */ 170 */
270 const handleActionSheetOpen = (type) => { 171 const handleActionSheetOpen = (type) => {
271 - // 道路名称需先校验工单位置是否选择  
272 - if (type === 'roadName' && !workOrderForm.workLocation) {  
273 - uni.showToast({ title: '请先选择工单位置', icon: 'none' }) 172 + // 判断养护员列表是否为空
  173 + if (type === 'assignee' && assigneeList.value.length === 0) {
  174 + uni.showToast({title: '暂无养护员数据可选', icon: 'none'})
274 return 175 return
275 } 176 }
276 -  
277 - // 配置当前弹窗参数 177 + // 配置弹窗参数
278 const configMap = { 178 const configMap = {
279 - roadName: {  
280 - title: '请选择道路名称',  
281 - list: roadNameList.value  
282 - },  
283 - orderName: {  
284 - title: '请选择工单名称',  
285 - list: orderNameList.value  
286 - },  
287 - pressingType: {  
288 - title: '请选择紧急程度',  
289 - list: pressingTypeList.value 179 + assignee: {
  180 + title: '请选择养护员',
  181 + list: assigneeList.value
290 } 182 }
291 } 183 }
292 -  
293 currentActionSheetData.type = type 184 currentActionSheetData.type = type
294 currentActionSheetData.title = configMap[type].title 185 currentActionSheetData.title = configMap[type].title
295 currentActionSheetData.list = configMap[type].list 186 currentActionSheetData.list = configMap[type].list
296 showActionSheet.value = true 187 showActionSheet.value = true
297 } 188 }
298 -  
299 /** 189 /**
300 - * 关闭通用下拉弹窗 190 + * 关闭下拉弹窗
301 */ 191 */
302 const handleActionSheetClose = () => { 192 const handleActionSheetClose = () => {
303 showActionSheet.value = false 193 showActionSheet.value = false
304 - // 重置当前弹窗配置  
305 currentActionSheetData.type = '' 194 currentActionSheetData.type = ''
306 currentActionSheetData.list = [] 195 currentActionSheetData.list = []
307 currentActionSheetData.title = '' 196 currentActionSheetData.title = ''
308 } 197 }
309 -  
310 /** 198 /**
311 - * 通用下拉弹窗选择事件 199 + * 养护员选择事件
312 */ 200 */
313 const handleActionSheetSelect = (e) => { 201 const handleActionSheetSelect = (e) => {
314 - const { type } = currentActionSheetData  
315 - // 根据类型处理不同的选择逻辑  
316 - switch (type) {  
317 - case 'roadName':  
318 - workOrderForm.roadName = e.name  
319 - workOrderForm.roadId = e.code  
320 - workOrderFormRef.value?.validateField('roadName')  
321 - break  
322 - case 'orderName':  
323 - workOrderForm.orderName = e.name  
324 - workOrderFormRef.value?.validateField('orderName')  
325 - break  
326 - case 'pressingType':  
327 - console.log(e)  
328 - workOrderForm.pressingType =e.value  
329 - workOrderForm.pressingTypeName = e.name  
330 - workOrderFormRef.value?.validateField('pressingType')  
331 - break 202 + const {type} = currentActionSheetData
  203 + if (type === 'assignee') {
  204 + workOrderForm.assigneeName = e.name
  205 + workOrderForm.assigneeId = e.value // 绑定养护员ID
  206 + workOrderFormRef.value?.validateField('assigneeName')
332 } 207 }
333 - // 关闭弹窗  
334 showActionSheet.value = false 208 showActionSheet.value = false
335 } 209 }
336 -  
337 -/**  
338 - * 返回上一页  
339 - */  
340 -const navigateBack = () => {  
341 - uni.navigateBack()  
342 -}  
343 -  
344 -/**  
345 - * 选择工单位置  
346 - */  
347 -const chooseWorkLocation = () => {  
348 - uni.chooseLocation({  
349 - success: async (res) => {  
350 - workOrderForm.roadName = ''  
351 - workOrderForm.roadId = 0  
352 - roadNameList.value = []  
353 -  
354 - workOrderForm.workLocation = res.name  
355 - workOrderForm.lat = res.latitude  
356 - workOrderForm.lon = res.longitude  
357 -  
358 - workOrderFormRef.value?.validateField('workLocation')  
359 - workOrderFormRef.value?.validateField('roadName')  
360 -  
361 - try {  
362 - uni.showLoading({ title: '获取道路名称中...' })  
363 - const roadRes = await getRoadListByLatLng({  
364 - companyCode: 'sls',  
365 - latitude: res.latitude,  
366 - longitude: res.longitude  
367 - })  
368 - uni.hideLoading()  
369 -  
370 - if (Array.isArray(roadRes)) {  
371 - roadNameList.value = roadRes.map((item) => ({  
372 - name: item.roadName || '',  
373 - code: item.roadCode || '',  
374 - id: item.roadId || 0  
375 - }))  
376 - } else {  
377 - roadNameList.value = [{ name: '未查询到道路名称', code: '', id: 0 }]  
378 - uni.showToast({ title: '未查询到该位置的道路信息', icon: 'none' })  
379 - }  
380 - } catch (err) {  
381 - uni.hideLoading()  
382 - console.error('获取道路名称失败:', err)  
383 - uni.showToast({ title: '获取道路名称失败,请重试', icon: 'none' })  
384 - roadNameList.value = [{ name: '获取失败,请重新选择位置', code: '', id: 0 }]  
385 - }  
386 - },  
387 - fail: (err) => {  
388 - console.error('选择位置失败:', err)  
389 - uni.showToast({ title: '选择位置失败:' + err.errMsg, icon: 'none' })  
390 - }  
391 - })  
392 -}  
393 -  
394 -/**  
395 - * 完成时间确认  
396 - */  
397 -const finishDateConfirm = (e) => {  
398 - console.log('选择的完成时间:', e)  
399 - workOrderForm.finishDate = timeFormat(e.value, 'yyyy-mm-dd hh:MM:ss')  
400 - show.value = false  
401 -}  
402 -  
403 /** 210 /**
404 * 隐藏键盘 211 * 隐藏键盘
405 */ 212 */
406 const hideKeyboard = () => { 213 const hideKeyboard = () => {
407 uni.hideKeyboard() 214 uni.hideKeyboard()
408 } 215 }
409 -  
410 /** 216 /**
411 - * 提交工单 217 + * 提交数据(使用ylTeamLeaderAssignWOrder接口,传递指定参数)
412 */ 218 */
413 const submitWorkOrder = async () => { 219 const submitWorkOrder = async () => {
414 try { 220 try {
415 - // 先执行表单校验 221 + // 1. 表单校验(先校验养护员必选项)
416 await workOrderFormRef.value.validate() 222 await workOrderFormRef.value.validate()
417 - 223 + // 2. 校验工单编号是否存在(避免无工单编号提交)
  224 + if (!workOrderForm.orderNo) {
  225 + uni.showToast({title: '工单编号不能为空', icon: 'none'})
  226 + return
  227 + }
  228 + // 3. 构造接口所需参数
418 const submitData = { 229 const submitData = {
419 - roadId: workOrderForm.roadId,  
420 - roadName: workOrderForm.roadName,  
421 - imgs: problemImgs.getSuccessImgUrls(), // 复用上传逻辑的URL获取方法  
422 - remark: workOrderForm.problemDesc.trim(),  
423 - latLonType: 2,  
424 - lat: workOrderForm.lat,  
425 - lon: workOrderForm.lon,  
426 - lonLatAddress: workOrderForm.workLocation,  
427 - pressingType: workOrderForm.pressingType,  
428 - orderName: workOrderForm.orderName,  
429 - finishDate: workOrderForm.finishDate,  
430 - sourceId: 1,  
431 - sourceName: '园林',  
432 - busiLine: 'yl' 230 + id: workOrderForm.taskId, // 工单编码(对应接口参数id)
  231 + reason: workOrderForm.reason.trim(), // 处理建议(对应接口参数reason)
  232 + nextAssignee: workOrderForm.assigneeId // 养护员ID(对应接口参数nextAssignee)
433 } 233 }
434 -  
435 - // 显示加载中  
436 - uni.showLoading({ title: '提交中...' })  
437 -  
438 - // 调用提交接口  
439 - const res = await workorderCreate(submitData)  
440 - 234 + console.log('提交参数:', submitData)
  235 + // 4. 显示加载提示
  236 + uni.showLoading({title: '提交中...'})
  237 + // 5. 调用指定接口 ylTeamLeaderAssignWOrder
  238 + const res = await ylTeamLeaderAssignWOrder(submitData)
  239 + // 6. 隐藏加载提示并给出成功反馈
441 uni.hideLoading() 240 uni.hideLoading()
442 uni.showToast({ 241 uni.showToast({
443 - title: '工单提交成功', 242 + title: '提交成功',
444 icon: 'success', 243 icon: 'success',
445 duration: 1000 244 duration: 1000
446 }) 245 })
447 -  
448 - // 延迟跳转 246 + // 7. 提交成功后返回上一页
449 setTimeout(() => { 247 setTimeout(() => {
450 - uni.redirectTo({  
451 - url: '/pages-sub/problem/work-order-manage/index' 248 + uni.navigateTo({
  249 + url: `/pages-sub/problem/work-order-manage/index`
452 }) 250 })
453 }, 1000) 251 }, 1000)
454 } catch (error) { 252 } catch (error) {
455 - // 隐藏加载 253 + // 隐藏加载提示
456 uni.hideLoading() 254 uni.hideLoading()
457 -  
458 - // 区分是表单校验失败还是接口调用失败 255 + // 区分表单校验失败和接口调用失败
459 if (!Array.isArray(error)) { 256 if (!Array.isArray(error)) {
460 - // 接口调用失败  
461 - console.error('工单提交失败:', error) 257 + console.error('提交失败:', error)
462 uni.showToast({ 258 uni.showToast({
463 title: '提交失败,请重试', 259 title: '提交失败,请重试',
464 icon: 'none', 260 icon: 'none',
@@ -472,13 +268,14 @@ const submitWorkOrder = async () =&gt; { @@ -472,13 +268,14 @@ const submitWorkOrder = async () =&gt; {
472 <style lang="scss" scoped> 268 <style lang="scss" scoped>
473 // 全局页面样式 269 // 全局页面样式
474 .page-container { 270 .page-container {
475 - min-height: 100vh;  
476 - padding-bottom: 100rpx; // 给底部按钮留空间 271 +
477 } 272 }
478 273
479 -// 工单表单内容容器 274 +// 表单内容容器
480 .work-order-form-content { 275 .work-order-form-content {
481 background: #fff; 276 background: #fff;
  277 + margin-top: 10rpx;
482 } 278 }
483 279
  280 +
484 </style> 281 </style>
485 \ No newline at end of file 282 \ No newline at end of file
pages-sub/problem/work-order-manage/index.vue
@@ -61,7 +61,7 @@ @@ -61,7 +61,7 @@
61 <view class="common-card-list" style="padding-top: 200rpx;padding-bottom: 30rpx"> 61 <view class="common-card-list" style="padding-top: 200rpx;padding-bottom: 30rpx">
62 <!-- 待办工单卡片 --> 62 <!-- 待办工单卡片 -->
63 <up-card 63 <up-card
64 - v-if="activeTab == 1" 64 + v-if="activeTab == 0"
65 :border="false" 65 :border="false"
66 :foot-border-top="false" 66 :foot-border-top="false"
67 v-for="(item, index) in orderList" 67 v-for="(item, index) in orderList"
@@ -109,7 +109,7 @@ @@ -109,7 +109,7 @@
109 109
110 <!-- 已办工单卡片和我发起的 --> 110 <!-- 已办工单卡片和我发起的 -->
111 <up-card 111 <up-card
112 - v-if="activeTab == 2||activeTab == 0" 112 + v-if="activeTab == 2||activeTab == 1"
113 :border="false" 113 :border="false"
114 :foot-border-top="false" 114 :foot-border-top="false"
115 v-for="(item, index) in orderList" 115 v-for="(item, index) in orderList"
@@ -199,16 +199,15 @@ import { timeFormat } from &#39;@/uni_modules/uview-plus&#39;; @@ -199,16 +199,15 @@ import { timeFormat } from &#39;@/uni_modules/uview-plus&#39;;
199 import { myBuzSimplePage, todoBuzSimplePage, doneBuzSimplePage } from '@/api/work-order-manage/work-order-manage' 199 import { myBuzSimplePage, todoBuzSimplePage, doneBuzSimplePage } from '@/api/work-order-manage/work-order-manage'
200 // 假设从用户store获取角色信息 200 // 假设从用户store获取角色信息
201 import { useUserStore } from '@/pinia/user'; 201 import { useUserStore } from '@/pinia/user';
202 -import { getDictLabel } from "../../../common/utils/dict";  
203 -import EmptyView from "../../../components/empty-view/empty-view.vue"; 202 + import { nextStepMap } from '@/common/utils/common'
204 203
205 // ========== 状态管理 ========== 204 // ========== 状态管理 ==========
206 const userStore = useUserStore(); 205 const userStore = useUserStore();
207 // 标签页切换 206 // 标签页切换
208 -const activeTab = ref(0); // 0-我发起的 1-待办 2-已办 207 +const activeTab = ref(0); // 0-待办 1-我发起的 2-已办
209 const tabList = ref([ 208 const tabList = ref([
210 - { name: '我发起的任务' },  
211 { name: '待办' }, 209 { name: '待办' },
  210 + { name: '我发起的任务' },
212 { name: '已办' } 211 { name: '已办' }
213 ]); 212 ]);
214 // 排序下拉框 213 // 排序下拉框
@@ -252,11 +251,12 @@ const queryList = async (pageNo, pageSize) =&gt; { @@ -252,11 +251,12 @@ const queryList = async (pageNo, pageSize) =&gt; {
252 251
253 let res; 252 let res;
254 if (activeTab.value == 0) { 253 if (activeTab.value == 0) {
255 - // 我发起的任务  
256 - res = await myBuzSimplePage(apiParams);  
257 - } else if(activeTab.value == 1) {  
258 // 待办工单 254 // 待办工单
259 res = await todoBuzSimplePage(apiParams); 255 res = await todoBuzSimplePage(apiParams);
  256 + } else if(activeTab.value == 1) {
  257 + // 我发起的任务
  258 + res = await myBuzSimplePage(apiParams);
  259 +
260 }else { 260 }else {
261 // 已办工单 261 // 已办工单
262 res = await doneBuzSimplePage(apiParams); 262 res = await doneBuzSimplePage(apiParams);
@@ -294,7 +294,7 @@ const handleSearch = (val) =&gt; { @@ -294,7 +294,7 @@ const handleSearch = (val) =&gt; {
294 294
295 // 工单详情 295 // 工单详情
296 const handleDetail = (item) => { 296 const handleDetail = (item) => {
297 - // 0-我发起的 1-待办 2-已办 297 + // 0-待办 1我发起的- 2-已办
298 uni.navigateTo({ 298 uni.navigateTo({
299 url: `/pages-sub/problem/work-order-manage/order-detail?taskId=${item.taskId}&activeTab=${activeTab.value}` 299 url: `/pages-sub/problem/work-order-manage/order-detail?taskId=${item.taskId}&activeTab=${activeTab.value}`
300 }); 300 });
@@ -302,22 +302,19 @@ const handleDetail = (item) =&gt; { @@ -302,22 +302,19 @@ const handleDetail = (item) =&gt; {
302 302
303 // 待办-处理工单 303 // 待办-处理工单
304 const handleProcess = async (item) => { 304 const handleProcess = async (item) => {
  305 + console.log(nextStepMap)
305 try { 306 try {
306 - // 调用处理工单接口,获取跳转标识  
307 - const res = await uni.request({  
308 - url: '/api/order/process',  
309 - method: 'POST',  
310 - data: { orderId: item.id }  
311 - });  
312 307
313 - const { jumpType, jumpUrl } = res.data;  
314 - // 根据返回标识跳转不同页面  
315 - if (jumpType === 1) {  
316 - uni.navigateTo({ url: jumpUrl });  
317 - } else if (jumpType === 2) {  
318 - uni.redirectTo({ url: jumpUrl });  
319 - } else if (jumpType === 3) {  
320 - uni.switchTab({ url: jumpUrl }); 308 + if(nextStepMap[item.taskKey] == '养护组长分配'){
  309 + uni.navigateTo({
  310 + url: `/pages-sub/problem/work-order-manage/add-order?taskId=${item.taskId}&orderNo=${item.orderNo}`
  311 + })
  312 + }
  313 +
  314 + if(nextStepMap[item.taskKey] == '养护员待实施'){
  315 + uni.navigateTo({
  316 + url: `/pages-sub/problem/work-order-manage/add-maintain-order?taskId=${item.taskId}&orderNo=${item.orderNo}`
  317 + })
321 } 318 }
322 } catch (error) { 319 } catch (error) {
323 console.error('处理工单失败:', error); 320 console.error('处理工单失败:', error);
pages-sub/problem/work-order-manage/order-detail.vue
@@ -184,12 +184,18 @@ const getMyTaskDetailQuery = async (taskId) =&gt; { @@ -184,12 +184,18 @@ const getMyTaskDetailQuery = async (taskId) =&gt; {
184 onLoad((options) => { 184 onLoad((options) => {
185 console.log(options) 185 console.log(options)
186 const { taskId, activeTab } = options; 186 const { taskId, activeTab } = options;
187 - // 0-我发起的 1-待办 2-已办 187 + // 0-待办 1我发起的- 2-已办
188 console.log(taskId) 188 console.log(taskId)
189 if(activeTab==0){ 189 if(activeTab==0){
190 - getMyTaskDetailQuery(taskId); 190 + getTodoTaskDetail(taskId);
191 } 191 }
  192 + if(activeTab==1){
  193 + getMyTaskDetailQuery(taskId);
192 194
  195 + }
  196 + if(activeTab==2){
  197 + getDoneTaskDetail(taskId);
  198 + }
193 }); 199 });
194 </script> 200 </script>
195 201
pages.json
@@ -126,13 +126,18 @@ @@ -126,13 +126,18 @@
126 }, 126 },
127 { 127 {
128 "path": "work-order-manage/add-order", 128 "path": "work-order-manage/add-order",
129 - "style": { "navigationBarTitleText": "新增工单" } 129 + "style": { "navigationBarTitleText": "工单提交" }
130 }, 130 },
131 131
132 { 132 {
133 "path": "work-order-manage/order-detail", 133 "path": "work-order-manage/order-detail",
134 "style": { "navigationBarTitleText": "工单详情" } 134 "style": { "navigationBarTitleText": "工单详情" }
135 }, 135 },
  136 + {
  137 + "path": "work-order-manage/add-maintain-order",
  138 + "style": { "navigationBarTitleText": "养护任务" }
  139 + },
  140 +
136 141
137 142
138 { 143 {