HD_wangm пре 4 месеци
родитељ
комит
11c5843594
8 измењених фајлова са 905 додато и 93 уклоњено
  1. 11 0
      api/order/detail.uts
  2. 2 2
      api/workbench/list.uts
  3. 10 3
      pages.json
  4. 741 0
      pages/order/detail/acceptIndex.uvue
  5. 74 18
      pages/order/detail/index.uvue
  6. 64 68
      pages/order/index.uvue
  7. 3 1
      types/order.uts
  8. 0 1
      types/user.uts

+ 11 - 0
api/order/detail.uts

@@ -2,6 +2,7 @@
  * 工作台详情接口
  */
 import { request } from '../../utils/request'
+import type { orderInfo } from '../../types/order'
 
 /**
  * 根据 ID 获取维保工单详情
@@ -25,3 +26,13 @@ export const getRepairOrderInfoById = (id: string): Promise<any> => {
     })
 }
 
+// 接单(支持一次性选择处理人员和检修人员)
+export const acceptOrder = (gxtWorkOrder: orderInfo | null): Promise<any> => {
+	const plainObject = gxtWorkOrder != null ? JSON.parse(JSON.stringify(gxtWorkOrder)) : null;
+	const data: UTSJSONObject | null = plainObject as UTSJSONObject;
+	return request({
+		url: `/mobile/order/accept`,
+		method: 'PUT',
+		data: data
+	})
+}

+ 2 - 2
api/workbench/list.uts

@@ -11,7 +11,7 @@ export const getWorkList = (params: WorkListParams): Promise<PageResult<WorkItem
     return request<PageResult<WorkItem>>({
         url: '/api/workbench/list',
         method: 'GET',
-        data: params as UTSJSONObject
+        data: params as any as UTSJSONObject
     })
 }
 
@@ -48,4 +48,4 @@ export const getOrderList = (page: number, rows: number, workOrderProjectNo: str
         url: url,
         method: 'GET'
     })
-}
+}

+ 10 - 3
pages.json

@@ -21,7 +21,7 @@
 				"navigationStyle": "custom"
 			}
 		},
-		
+
 		{
 			"path": "pages/workbench/list/index",
 			"style": {
@@ -34,7 +34,7 @@
 			"path": "pages/order/detail/index",
 			"style": {
 				"navigationBarTitleText": "详情",
-				"navigationBarBackgroundColor": "#D5E9FE"
+				"navigationStyle": "#custom"
 			}
 		},
 		{
@@ -92,6 +92,13 @@
 				"navigationBarTitleText": "通知",
 				"navigationBarBackgroundColor": "#D5E9FE"
 			}
+		},
+		{
+			"path": "pages/order/detail/acceptIndex",
+			"style": {
+				"navigationBarTitleText": "接单",
+				"navigationStyle": "#custom"
+			}
 		}
 	],
 	"globalStyle": {
@@ -101,4 +108,4 @@
 		"backgroundColor": "#F8F8F8"
 	},
 	"uniIdRouter": {}
-}
+}

+ 741 - 0
pages/order/detail/acceptIndex.uvue

@@ -0,0 +1,741 @@
+<template>
+    <view class="detail-page">
+        <scroll-view class="detail-content" :scroll-y="true">
+            <!-- 工单信息 -->
+            <view class="info-section">
+                <view class="section-title">
+                    <text class="section-title-text">工单信息</text>
+                </view>
+                <view class="info-card">
+                    <view class="info-item">
+                        <text class="info-label">工单编号</text>
+                        <text class="info-value">{{ detailData.workOrderProjectNo ?? '' }}</text>
+                    </view>
+                    <view class="info-item">
+                        <text class="info-label">工单类型</text>
+                        <text class="info-value">{{ detailData.orderType == 1 ? '维修工单' : '维保工单' }}</text>
+                    </view>
+                    <view class="info-item">
+                        <text class="info-label">风机编号</text>
+                        <text class="info-value">{{ detailData.pcsDeviceName ?? '' }}</text>
+                    </view>
+                    <view class="info-item">
+                        <text class="info-label">场站</text>
+                        <text class="info-value">{{ detailData.pcsStationName ?? '' }}</text>
+                    </view>
+                    <view class="info-item">
+                        <text class="info-label">机型</text>
+                        <text class="info-value">{{ detailData.brand ?? '' }} {{ detailData.model ?? '' }}</text>
+                    </view>
+					<view class="info-item">
+					    <text class="info-label">创建时间</text>
+					    <text class="info-value">{{ detailData.createTime ?? '' }}</text>
+					</view>
+
+                </view>
+            </view>
+			<!-- <view class="info-section">
+				<view class="section-title">
+					<text class="section-title-text">工作负责人</text>
+				</view>
+				<view class="info-card">
+					<view class="info-item">
+						<input class="input" type="text" placeholder="请输入工作负责人" v-model="teamLeaderName" />
+					</view>
+				</view>
+			</view> -->
+			<!-- 工作负责人选择 -->
+			<view class="info-section">
+			    <view class="section-title">
+			        <text class="section-title-text">工作负责人</text>
+			    </view>
+			    <view class="info-card">
+			        <view class="form-item">
+			            <text class="form-label required">工作负责人</text>
+			            <view class="form-picker" @click="showLeaderPicker = true">
+			                <view class="picker-display">
+			                    <text v-if="selectedTeamLeaderName" class="selected-value">{{ selectedTeamLeaderName }}</text>
+			                    <text v-else class="placeholder">请选择工作负责人</text>
+			                    <text class="arrow">▼</text>
+			                </view>
+			            </view>
+			        </view>
+			    </view>
+			</view>
+
+			<!-- 自定义选择器弹窗 -->
+			<view v-if="showLeaderPicker" class="picker-modal">
+			    <view class="modal-mask" @click="showLeaderPicker = false"></view>
+			    <view class="modal-content">
+			        <view class="modal-header">
+			            <text class="modal-title">选择负责人</text>
+			            <text class="modal-close" @click="showLeaderPicker = false">取消</text>
+			        </view>
+			        <scroll-view class="modal-body" scroll-y="true">
+			            <view
+			                v-for="(option, index) in teamLeaderNameOptions"
+			                :key="index"
+			                class="picker-option"
+			                :class="{ 'selected': index === selectedTeamLeaderIndex }"
+			                @click="selectLeaderManually(index)"
+			            >
+			                <text class="option-text">{{ option.label }}</text>
+			                <text v-if="index === selectedTeamLeaderIndex" class="option-check">✓</text>
+			            </view>
+			        </scroll-view>
+			    </view>
+			</view>
+
+            <!-- 工单流转 -->
+            <!-- <view class="info-section">
+                <view class="section-title">
+                    <text class="section-title-text">工单流转</text>
+                </view>
+                <view class="info-card" v-if="detailData.workOrderFlowList != null && detailData.workOrderFlowList.length > 0">
+                    <view class="flow-item" v-for="(flow, index) in detailData.workOrderFlowList" :key="index">
+                        <view class="flow-header">
+                            <text class="flow-operator">{{ flow.operatorName ?? '未知操作人' }}</text>
+                            <text class="flow-time">{{ flow.actionTime ?? '' }}</text>
+                        </view>
+                        <view class="flow-content">
+                            <text class="flow-action">{{ getActionTypeName(flow.actionType) }}</text>
+                            <text class="flow-remark" v-if="flow.actionRemark">{{ flow.actionRemark }}</text>
+                        </view>
+                    </view>
+                </view>
+                <view class="info-card" v-else>
+                    <view class="no-data">暂无流转记录</view>
+                </view>
+            </view> -->
+        </scroll-view>
+
+        <!-- 接单按钮 -->
+        <view class="accept-button-container">
+            <button class="accept-button" @click="handleAcceptOrder">接单</button>
+        </view>
+
+        <!-- 加载中状态 -->
+        <view v-if="loading" class="loading-mask">
+            <text class="loading-text">加载中...</text>
+        </view>
+    </view>
+</template>
+
+<script setup lang="uts">
+    import { ref } from 'vue'
+    import type { orderInfo } from '../../../types/order'
+    import type { WorkOrderFlow } from '../../../types/flow'
+    import { getOrderInfoById, getRepairOrderInfoById, acceptOrder } from '../../../api/order/detail'
+	import type { SysDictData } from '../../../types/dict'
+	import { getDictDataByType } from '../../../api/dict/index'
+	import { getUserList } from '../../../api/user/list'
+	import type { UserInfo } from '../../../types/user'
+
+	const teamLeaderName = ref<string>("")
+	const statusDictList = ref<SysDictData[]>([]) // 工单状态字典列表
+	// 添加字典加载状态
+	const dictLoaded = ref<boolean>(false)
+
+	// 详情数据
+	const detailData = ref<orderInfo>({
+		orderType: 0,
+		id: 0,
+		teamLeaderId: 0,
+		acceptUserId: 0,
+		teamLeaderName: null,
+		acceptUserName: null,
+		acceptTime: null,
+		assignTime:  null,
+		assignUserName: null,
+		status: 0,
+		workOrderProjectNo: null,
+		workOrderStatus: null,
+		gxtCenterId: 0,
+		gxtCenter: null,
+		pcsStationId:  0,
+		pcsStationName: null,
+		pcsDeviceId: 0,
+		pcsDeviceName: null,
+		brand: null,
+		model: null,
+		createTime: null,
+		workOrderFlowList: null
+	})
+
+	// 选择器选项类型
+	type PickerOption = {
+	    label: string
+	    value: string
+	}
+
+	// 选中的负责人信息
+	const selectedTeamLeaderId = ref<string>('')
+	const selectedTeamLeaderName = ref<string>('')
+	const selectedTeamLeaderIndex = ref<number>(-1)
+	const teamLeaderNameOptions = ref<PickerOption[]>([])
+	const showLeaderPicker = ref<boolean>(false)
+
+	// 获取负责人列表(使用用户列表接口)
+	const loadTeamLeaderList = async (): Promise<void> => {
+	    try {
+			const deptId = detailData.value.gxtCenterId
+	        const result = await getUserList(deptId)
+	        const resultObj = result as UTSJSONObject
+
+	        if (resultObj['code'] == 200) {
+	            const data = resultObj['data'] as any[]
+	            const leaders: UserInfo[] = []
+				const options: PickerOption[] = []
+
+	            if (data.length > 0) {
+	                for (let i = 0; i < data.length; i++) {
+	                    const item = data[i] as UTSJSONObject
+	                    let leader: UserInfo = {
+							userName: item['userName'] as string,
+							nickName: item['nickName'] as string,
+							userId: new Int32Array([item['userId'] != null ? (item['userId'] as number) : 0]),
+							phone: item['phonenumber'] as string,
+							deptName : item['deptName'] != null ? (item['deptName'] as string) : ''
+	                    }
+	                    leaders.push(leader)
+
+						// 构建选择器选项(只使用用户名)
+						options.push({
+						    label: leader.nickName,
+						    value: leader.userId.toString()
+						})
+	                }
+	            }
+
+	            // teamLeaderList.value = leaders
+				teamLeaderNameOptions.value = options
+	        }
+	    } catch (e: any) {
+	        console.error('获取负责人列表失败:', e.message)
+	    }
+	}
+
+	// 手动选择负责人
+	const selectLeaderManually = (index: number): void => {
+	    selectedTeamLeaderIndex.value = index
+	    if (index >= 0 && index < teamLeaderNameOptions.value.length) {
+	        const selectedOption = teamLeaderNameOptions.value[index]
+	        selectedTeamLeaderName.value = selectedOption.label
+	        selectedTeamLeaderId.value = selectedOption.value
+			const leaderId = (selectedOption.value != null && selectedOption.value.length > 0) ? parseInt(selectedOption.value) : 0
+			detailData.value.teamLeaderId = leaderId
+			detailData.value.teamLeaderName = selectedOption.label
+			console.log("=======",detailData.value.teamLeaderName)
+	    }
+	    showLeaderPicker.value = false
+	}
+
+	// 获取工单状态字典列表
+	const loadStatusDictList = async (): Promise<void> => {
+	    try {
+	        const result = await getDictDataByType('gxt_repair_order_flow_action_type')
+	        const resultObj = result as UTSJSONObject
+
+	        if (resultObj['code'] == 200) {
+	            const data = resultObj['data'] as any[]
+	            const dictData: SysDictData[] = []
+
+	            if (data.length > 0) {
+	                for (let i = 0; i < data.length; i++) {
+	                    const item = data[i] as UTSJSONObject
+	                    // 只提取需要的字段
+	                    const dictItem: SysDictData = {
+							dictValue: item['dictValue'] as string | null,
+							dictLabel: item['dictLabel'] as string | null,
+							dictCode: null,
+							dictSort: null,
+							dictType: null,
+							cssClass: null,
+							listClass: null,
+							isDefault: null,
+							status: null,
+							default: null,
+							createTime: null,
+							remark: null
+						}
+	                    dictData.push(dictItem)
+	                }
+	            }
+
+	            statusDictList.value = dictData
+	            dictLoaded.value = true
+	        }
+	    } catch (e: any) {
+	        console.error('获取工单状态字典失败:', e.message)
+	        dictLoaded.value = true
+	    }
+	}
+
+	// 处理接单操作
+	const handleAcceptOrder = async (): Promise<void> => {
+		if (selectedTeamLeaderName.value == null || selectedTeamLeaderName.value.trim() === '') {
+			uni.showToast({
+				title: '请选择工作负责人',
+				icon: 'none'
+			})
+			return
+		}
+
+		// const subOrder = {
+		// 	id: detailData.value.id,
+		// 	orderType: detailData.value.orderType,
+		// 	teamLeaderId: (selectedTeamLeaderId.value != null && selectedTeamLeaderId.value.length > 0) ? parseInt(selectedTeamLeaderId.value) : 0,
+		// 	teamLeaderName: selectedTeamLeaderName.value,
+		// 	workOrderProjectNo: detailData.value.workOrderProjectNo,
+		// 	// gxtRepairOrder:
+		// } as UTSJSONObject
+		detailData.value.workOrderStatus = 'to_finish'
+			try {
+				const result = await acceptOrder(detailData.value)
+				const resultObj = result as UTSJSONObject
+				const code = resultObj['code'] as number
+				if (code == 200) {
+					uni.showToast({
+						title: '接单成功',
+						icon: 'success'
+					})
+
+				// 使用事件总线通知列表页面刷新
+				uni.$emit('refreshOrderList', {})
+				// 接单成功后返回上一页
+				setTimeout(() => {
+					uni.navigateBack()
+				}, 1000)
+			}
+		} catch (error) {
+		  console.error('请求失败:', error);
+		}
+
+	}
+
+
+
+    const loading = ref<boolean>(false)
+
+	// 获取操作类型名称
+	const getActionTypeName = (item: string | null): string | null => {
+	    if (item == null) return ''
+	    // const orderInfoItem = item as orderInfo
+	    const rawStatus = item
+
+	    if (rawStatus==null) return ''
+
+		// 如果字典尚未加载,返回原始值
+		if (!dictLoaded.value) {
+			return rawStatus
+		}
+
+	    // 查找字典中对应的标签
+	    const dictItem = statusDictList.value.find(dict => dict.dictValue == rawStatus)
+	    return dictItem!=null ? dictItem.dictLabel : rawStatus
+	}
+
+    // 加载详情数据
+    const loadDetail = async (id: string, orderType?: number): Promise<void> => {
+        try {
+            loading.value = true
+
+            let result: any;
+
+            // 根据orderType决定调用哪个API
+            if (orderType == 1) {
+                // 维修工单
+                result = await getRepairOrderInfoById(id)
+            } else {
+                // 维保工单
+                result = await getOrderInfoById(id)
+            }
+
+            // 提取响应数据
+            const resultObj = result as UTSJSONObject
+			const code = resultObj['code'] as number
+            const data = resultObj['data'] as UTSJSONObject | null
+
+            if (code == 200 && data != null) {
+                // 处理工单流转列表
+                let workOrderFlowList: WorkOrderFlow[] | null = null
+				let flowList: UTSJSONObject[] = []
+				if (orderType == 1) {
+				    // 维修工单
+				    flowList = data['repairOrderFlowList'] as UTSJSONObject[]
+				} else {
+				    // 维保工单
+				    flowList = data['workOrderFlowList'] as UTSJSONObject[]
+				}
+                if (flowList != null) {
+                    workOrderFlowList = []
+                    for (let i = 0; i < flowList.length; i++) {
+                        const flowItem = flowList[i]
+                        const flow: WorkOrderFlow = {
+                            id: flowItem['id'] as Number,
+                            orderId: flowItem['orderId'] as Number,
+                            orderCode: flowItem['orderCode'] as string,
+                            actionType: flowItem['actionType'] as string,
+                            fromStatus: flowItem['fromStatus'] as string | null,
+                            toStatus: flowItem['toStatus'] as string,
+                            operatorId: flowItem['operatorId'] as Number | null,
+                            operatorName: flowItem['operatorName'] as string | null,
+                            actionTime: flowItem['actionTime'] as string,
+                            actionRemark: flowItem['actionRemark'] as string | null,
+                            createBy: flowItem['createBy'] as string | null,
+                            createTime: flowItem['createTime'] as string | null
+                        }
+                        workOrderFlowList.push(flow)
+                    }
+                }
+
+                // 转换数据
+                const orderDtail: orderInfo = {
+                    orderType: data['orderType'] as Number,
+                    id: data['id'] as Number,
+  					teamLeaderId: data['teamLeaderId'] != null ? (data['teamLeaderId'] as Number) : 0,
+  					acceptUserId: data['acceptUserId'] != null ? (data['acceptUserId'] as Number) : 0,
+                    teamLeaderName: data['teamLeaderName'] as string | null,
+                    acceptUserName: data['acceptUserName'] as string | null,
+                    acceptTime: data['acceptTime'] as string | null,
+                    assignTime: data['assignTime'] as string | null,
+                    assignUserName: data['assignUserName'] as string | null,
+                    status: (data['status']==null)?0:data['status'] as Number,
+                    workOrderProjectNo: data['workOrderProjectNo'] as string | null,
+                    workOrderStatus: data['workOrderStatus'] as string | null,
+                    gxtCenterId: data['gxtCenterId'] as Number | 0,
+                    gxtCenter: data['gxtCenter'] as string | null,
+                    pcsStationId: data['pcsStationId'] as Number | 0,
+                    pcsStationName: data['pcsStationName'] as string | null,
+                    pcsDeviceId: data['pcsDeviceId'] as Number | 0,
+                    pcsDeviceName: data['pcsDeviceName'] as string | null,
+                    brand: data['brand'] as string | null,
+                    model: data['model'] as string | null,
+                    createTime: data['createTime'] as string | null,
+                    workOrderFlowList: workOrderFlowList
+                }
+                detailData.value = orderDtail
+
+				// 如果工单数据中已有负责人信息,设置到输入框中
+				if (orderDtail.teamLeaderName != null && orderDtail.teamLeaderName.length > 0) {
+					teamLeaderName.value = orderDtail.teamLeaderName as string
+				}
+				loadTeamLeaderList()
+            } else {
+                const msg = resultObj['msg'] as string | null
+                uni.showToast({
+                    title: msg ?? '加载失败',
+                    icon: 'none'
+                })
+            }
+
+        } catch (e: any) {
+            uni.showToast({
+                title: e.message ?? '加载失败',
+                icon: 'none'
+            })
+        } finally {
+            loading.value = false
+        }
+    }
+
+    // 页面加载
+    onLoad((options: any) => {
+        const params = options as UTSJSONObject
+        const id = params['id'] as string | null
+		const orderTypeParam = params['orderType'] as string | null
+        if (id != null && orderTypeParam != null) {
+            // 先尝试从参数中获取orderType
+            const orderTypeNumber = parseInt(orderTypeParam)
+            loadDetail(id, orderTypeNumber)
+        }
+    })
+	// 初始化
+	onMounted(() => {
+	    loadStatusDictList()
+	})
+</script>
+
+<style lang="scss">
+    .detail-page {
+        flex: 1;
+        background-color: #e8f0f9;
+    }
+
+    .detail-content {
+        flex: 1;
+        padding: 20rpx 0;
+    }
+
+    .info-section {
+        margin: 0 30rpx 24rpx;
+
+        .section-title {
+            position: relative;
+            padding-left: 20rpx;
+            margin-bottom: 20rpx;
+
+            &::before {
+                // content: '';
+                position: absolute;
+                left: 0;
+                top: 50%;
+                transform: translateY(-50%);
+                width: 8rpx;
+                height: 32rpx;
+                background-color: #007aff;
+                border-radius: 4rpx;
+            }
+
+            &-text {
+                font-size: 32rpx;
+                font-weight: bold;
+                color: #333333;
+            }
+        }
+
+        .info-card {
+            background-color: #ffffff;
+            border-radius: 16rpx;
+            padding: 30rpx;
+
+            .info-item {
+                flex-direction: row;
+                padding: 20rpx 0;
+                border-bottom: 1rpx solid #f0f0f0;
+
+                &:last-child {
+                    border-bottom: none;
+                }
+
+                &.full-width {
+                    flex-direction: column;
+
+                    .info-label {
+                        margin-bottom: 12rpx;
+                    }
+
+                    .info-value {
+                        line-height: 44rpx;
+                    }
+                }
+
+                .info-label {
+                    width: 240rpx;
+                    font-size: 28rpx;
+                    color: #666666;
+                    white-space: nowrap;
+                }
+
+                .info-value {
+                    flex: 1;
+                    font-size: 28rpx;
+                    color: #333333;
+                    text-align: right;
+
+                    &.highlight {
+                        color: #007aff;
+                        font-weight: bold;
+                    }
+
+                    &.input {
+                        text-align: left;
+                        border: 1rpx solid #e0e0e0;
+                        border-radius: 8rpx;
+                        padding: 10rpx;
+                    }
+                }
+            }
+
+            .flow-item {
+                padding: 20rpx 0;
+                border-bottom: 1rpx solid #f0f0f0;
+
+                &:last-child {
+                    border-bottom: none;
+                }
+
+                .flow-header {
+                    flex-direction: row;
+                    justify-content: space-between;
+                    margin-bottom: 10rpx;
+
+                    .flow-operator {
+                        font-size: 28rpx;
+                        color: #333333;
+                        font-weight: bold;
+                    }
+
+                    .flow-time {
+                        font-size: 24rpx;
+                        color: #999999;
+                    }
+                }
+
+                .flow-content {
+                    flex-direction: column;
+
+                    .flow-action {
+                        font-size: 26rpx;
+                        color: #666666;
+                        margin-bottom: 8rpx;
+                    }
+
+                    .flow-remark {
+                        font-size: 24rpx;
+                        color: #999999;
+                        background-color: #f5f5f5;
+                        padding: 10rpx;
+                        border-radius: 8rpx;
+                    }
+                }
+            }
+
+            .no-data {
+                text-align: center;
+                padding: 40rpx 0;
+                font-size: 28rpx;
+                color: #999999;
+            }
+        }
+    }
+
+    .accept-button-container {
+        padding: 20rpx 30rpx;
+        background-color: #ffffff;
+
+        .accept-button {
+            width: 100%;
+            height: 80rpx;
+            background-color: #007aff;
+            color: #ffffff;
+            font-size: 32rpx;
+            border-radius: 16rpx;
+            border: none;
+
+            &:active {
+                background-color: #0062cc;
+            }
+        }
+    }
+
+    .loading-mask {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        justify-content: center;
+        align-items: center;
+        background-color: rgba(0, 0, 0, 0.3);
+
+        .loading-text {
+            padding: 30rpx 60rpx;
+            background-color: rgba(0, 0, 0, 0.7);
+            color: #ffffff;
+            font-size: 28rpx;
+            border-radius: 12rpx;
+        }
+    }
+	.picker-modal {
+	    position: fixed;
+	    top: 0;
+	    left: 0;
+	    right: 0;
+	    bottom: 0;
+	    z-index: 1000;
+	}
+
+	.modal-mask {
+	    position: absolute;
+	    top: 0;
+	    left: 0;
+	    right: 0;
+	    bottom: 0;
+	    background-color: rgba(0, 0, 0, 0.5);
+	}
+
+	.modal-content {
+	    position: absolute;
+	    bottom: 0;
+	    left: 0;
+	    right: 0;
+	    background-color: #ffffff;
+	    border-top-left-radius: 16rpx;
+	    border-top-right-radius: 16rpx;
+	    max-height: 700rpx;
+	}
+
+	.modal-header {
+	    flex-direction: row;
+	    justify-content: space-between;
+	    align-items: center;
+	    padding: 30rpx;
+	    border-bottom: 1rpx solid #f0f0f0;
+	}
+
+	.modal-title {
+	    font-size: 32rpx;
+	    font-weight: bold;
+	    color: #333333;
+	}
+
+	.modal-close {
+	    font-size: 28rpx;
+	    color: #007aff;
+	}
+
+	.modal-body {
+	    max-height: 600rpx;
+	}
+
+	.picker-option {
+	    flex-direction: row;
+	    justify-content: space-between;
+	    align-items: center;
+	    padding: 24rpx 30rpx;
+	    border-bottom: 1rpx solid #f0f0f0;
+	}
+
+	.picker-option.selected {
+	    background-color: #f8f9fa;
+	}
+
+	.option-text {
+	    font-size: 28rpx;
+	    color: #333333;
+	}
+
+	.option-check {
+	    font-size: 28rpx;
+	    color: #007aff;
+	}
+
+	.form-picker {
+	    flex: 1;
+	}
+
+	.picker-display {
+	    flex-direction: row;
+	    justify-content: space-between;
+	    align-items: center;
+	    min-height: 40rpx;
+	}
+
+	.selected-value {
+	    font-size: 28rpx;
+	    color: #333333;
+	}
+
+	.placeholder {
+	    font-size: 28rpx;
+	    color: #999999;
+	}
+
+	.arrow {
+	    font-size: 24rpx;
+	    color: #999999;
+	    margin-left: 12rpx;
+	}
+</style>
+

+ 74 - 18
pages/order/detail/index.uvue

@@ -69,11 +69,59 @@
     import type { orderInfo } from '../../../types/order'
     import type { WorkOrderFlow } from '../../../types/flow'
     import { getOrderInfoById, getRepairOrderInfoById } from '../../../api/order/detail'
-
+	import type { SysDictData } from '../../../types/dict'
+	import { getDictDataByType } from '../../../api/dict/index'
+
+
+	const statusDictList = ref<SysDictData[]>([]) // 工单状态字典列表
+	// 添加字典加载状态
+	const dictLoaded = ref<boolean>(false)
+	// 获取工单状态字典列表
+	const loadStatusDictList = async (): Promise<void> => {
+	    try {
+	        const result = await getDictDataByType('gxt_repair_order_flow_action_type')
+	        const resultObj = result as UTSJSONObject
+
+	        if (resultObj['code'] == 200) {
+	            const data = resultObj['data'] as any[]
+	            const dictData: SysDictData[] = []
+
+	            if (data.length > 0) {
+	                for (let i = 0; i < data.length; i++) {
+	                    const item = data[i] as UTSJSONObject
+	                    // 只提取需要的字段
+	                    const dictItem: SysDictData = {
+							dictValue: item['dictValue'] as string | null,
+							dictLabel: item['dictLabel'] as string | null,
+							dictCode: null,
+							dictSort: null,
+							dictType: null,
+							cssClass: null,
+							listClass: null,
+							isDefault: null,
+							status: null,
+							default: null,
+							createTime: null,
+							remark: null
+						}
+	                    dictData.push(dictItem)
+	                }
+	            }
+
+	            statusDictList.value = dictData
+	            dictLoaded.value = true
+	        }
+	    } catch (e: any) {
+	        console.error('获取工单状态字典失败:', e.message)
+	        dictLoaded.value = true
+	    }
+	}
     // 详情数据
     const detailData = ref<orderInfo>({
 		orderType: 0,
 		id: 0,
+		teamLeaderId: 0,
+		acceptUserId: 0,
 		teamLeaderName: null,
 		acceptUserName: null,
 		acceptTime: null,
@@ -96,21 +144,23 @@
 
     const loading = ref<boolean>(false)
 
-    // 获取操作类型名称
-    const getActionTypeName = (actionType: string): string => {
-        const actionTypeMap = new Map<string, string>()
-        actionTypeMap.set('create', '创建')
-        actionTypeMap.set('assign', '派单')
-        actionTypeMap.set('accept', '接单')
-        actionTypeMap.set('process', '处理')
-        actionTypeMap.set('pause', '暂停')
-        actionTypeMap.set('suspend', '挂起')
-        actionTypeMap.set('restart', '重启')
-        actionTypeMap.set('approve', '审批')
-        actionTypeMap.set('complete', '完成')
-        const name = actionTypeMap.get(actionType)
-        return (name != null) ? name : actionType
-    }
+	// 获取操作类型名称
+	const getActionTypeName = (item: string | null): string | null => {
+	    if (item == null) return ''
+	    // const orderInfoItem = item as orderInfo
+	    const rawStatus = item
+
+	    if (rawStatus==null) return ''
+
+		// 如果字典尚未加载,返回原始值
+		if (!dictLoaded.value) {
+			return rawStatus
+		}
+
+	    // 查找字典中对应的标签
+	    const dictItem = statusDictList.value.find(dict => dict.dictValue == rawStatus)
+	    return dictItem!=null ? dictItem.dictLabel : rawStatus
+	}
 
     // 加载详情数据
     const loadDetail = async (id: string, orderType?: number): Promise<void> => {
@@ -118,7 +168,7 @@
             loading.value = true
 
             let result: any;
-            
+
             // 根据orderType决定调用哪个API
             if (orderType == 1) {
                 // 维修工单
@@ -170,6 +220,8 @@
                 const orderDtail: orderInfo = {
                     orderType: data['orderType'] as Number,
                     id: data['id'] as Number,
+					teamLeaderId: data['teamLeaderId'] != null ? (data['teamLeaderId'] as Number) : 0,
+					acceptUserId: data['acceptUserId'] != null ? (data['acceptUserId'] as Number) : 0,
                     teamLeaderName: data['teamLeaderName'] as string | null,
                     acceptUserName: data['acceptUserName'] as string | null,
                     acceptTime: data['acceptTime'] as string | null,
@@ -214,11 +266,15 @@
         const id = params['id'] as string | null
 		const orderTypeParam = params['orderType'] as string | null
         if (id != null && orderTypeParam != null) {
-            // 先尝试从参数中获取orderType 
+            // 先尝试从参数中获取orderType
             const orderTypeNumber = parseInt(orderTypeParam)
             loadDetail(id, orderTypeNumber)
         }
     })
+	// 初始化
+	onMounted(() => {
+	    loadStatusDictList()
+	})
 </script>
 
 <style lang="scss">

+ 64 - 68
pages/order/index.uvue

@@ -5,7 +5,7 @@
         <view class="search-bar">
             <view class="search-box">
                 <image class="search-icon" src="/static/images/workbench/list/1.png" mode="aspectFit"></image>
-                <input class="search-input" type="text" placeholder="搜索工单编号、风机编号" v-model="keyword" @confirm="handleSearch" @blur="handleSearchOnBlur" />
+                <input class="search-input" type="text" placeholder="搜索工单编号、风机编号" v-model="keyword" @confirm="handleSearch" @blur="handleSearch" />
                 <text v-if="keyword.length > 0" class="clear-icon" @click="clearSearch">✕</text>
             </view>
         </view>
@@ -39,28 +39,39 @@
 							<text class="item-title">{{ getWorkOrderProjectNo(item) }}-{{ getPcsDeviceName(item) }}{{ getOrderType(item) }}</text>
 							<text class="info-value">{{ getWorkOrderStatus(item) }}</text>
                         </view>
-						<view class="info-row"></view>
 						<!-- <view class="flex justify-between items-center"> -->
-						<!-- <view class="info-card"> -->
-							<view class="info-row">
-								<view class="info-label">
-									<text class="text-xs text-gray-500">{{ getDisplayTime(item) }}</text>
-								</view>
-								<view class="info-value">
-									<button
-										v-if="currentStatus === 'assigned'"
-										class="btn-primary"
-										@click="acceptOrder(item)">
-										接单
-									</button>
-									<button
-										v-else-if="currentStatus === 'to_approve'"
-										class="btn-primary"
-										@click="approveOrder(item)">
-										审批
-									</button>
-								</view>
+						<view class="info-card">
+						<!-- <view class="info-item"> -->
+							<view class="info-item">
+								<text class="info-label">{{ getDisplayTime(item) }}</text>
+								<button
+									v-if="currentStatus === 'assigned'"
+									class="info-value btn-primary"
+									@click.stop="acceptOrder(item)">
+									接单
+								</button>
+								<button
+									v-else-if="currentStatus === 'to_approve'"
+									class="info-value btn-primary"
+									@click="approveOrder(item)">
+									审批
+								</button>
 							</view>
+							<!-- <view class="info-value">
+								<button
+									v-if="currentStatus === 'assigned'"
+									class="btn-primary"
+									@click="acceptOrder(item)">
+									接单
+								</button>
+								<button
+									v-else-if="currentStatus === 'to_approve'"
+									class="btn-primary"
+									@click="approveOrder(item)">
+									审批
+								</button>
+							</view> -->
+						</view>
 						<!-- </view> -->
 						<!-- </view> -->
 
@@ -94,19 +105,16 @@
     </view>
 </template>
 
-<script lang="uts">
+<script setup lang="uts">
 import { ref, onBeforeUnmount, onMounted } from 'vue'
 import type { orderInfo } from '../../types/order'
 import type { SysDictData, DictDataResponse } from '../../types/dict'
 import { getOrderList } from '../../api/order/list'
 import { getDictDataByType } from '../../api/dict/index'
 
-export default {
-	setup() {
-
     // 列表数据
     const dataList = ref<orderInfo[]>([])
-    const keyword = ref<string>("")
+    let keyword = ref<string>("")
     const page = ref<number>(1)
     const pageSize: number = 10
     const hasMore = ref<boolean>(true)
@@ -177,7 +185,7 @@ export default {
             if (shouldRefresh) {
                 page.value = 1
             }
-			console.log("searchKeyword===" + keyword)
+			console.log("searchKeyword===" + keyword.value)
             // 调用 API,传递关键字参数
             const searchKeyword = keyword.value.length > 0 ? keyword.value : null
 
@@ -197,6 +205,8 @@ export default {
                     const orderItem: orderInfo = {
 						orderType: item['orderType'] as Number,
                         id: item['id'] as Number,
+						teamLeaderId: item['teamLeaderId'] != null ? (item['teamLeaderId'] as Number) : 0,
+						acceptUserId: item['acceptUserId'] != null ? (item['acceptUserId'] as Number) : 0,
                         teamLeaderName: item['teamLeaderName'] as string | null,
                         acceptUserName: item['acceptUserName'] as string | null,
                         acceptTime: item['acceptTime'] as string | null,
@@ -367,13 +377,10 @@ export default {
     // 搜索
     const handleSearch = (): void => {
         page.value = 1
-		console.log("======搜索=====")
+		console.log("======搜索=====" + keyword.value)
         loadData(true as boolean | null)
     }
 
-	// 添加防抖处理,避免频繁搜索
-	let searchTimer: number | null = null
-
 	const handleSearchOnBlur = (): void => {
 		handleSearch()
 	}
@@ -383,10 +390,18 @@ export default {
     const handleItemClick = (item: any | null, index: number): void => {
         if (item == null) return
         const orderItem = item as orderInfo
-        // 传递orderType参数以便详情页决定调用哪个API
-        uni.navigateTo({
-            url: `/pages/order/detail/index?id=${orderItem.id}&orderType=${orderItem.orderType}`
-        })
+		if(currentStatus.value === '' || currentStatus.value === 'to_finish' || currentStatus.value === 'completed') {
+			// 传递orderType参数以便详情页决定调用哪个API
+			uni.navigateTo({
+			    url: `/pages/order/detail/index?id=${orderItem.id}&orderType=${orderItem.orderType}`
+			})
+		// } else if(currentStatus.value === 'assigned') {
+		// 	// 跳转到接单页面
+		// 	uni.navigateTo({
+		// 	    url: `/pages/order/detail/acceptIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
+		// 	})
+		}
+
     }
 
     // 接单操作
@@ -394,10 +409,9 @@ export default {
         if (item == null) return
         const orderItem = item as orderInfo
         console.log('接单操作:', orderItem.id)
-        // 这里可以添加实际的接单逻辑
-        uni.showToast({
-            title: '接单成功',
-            icon: 'success'
+        // 跳转到接单页面
+        uni.navigateTo({
+            url: `/pages/order/detail/acceptIndex?id=${orderItem.id}&orderType=${orderItem.orderType}`
         })
     }
 
@@ -433,42 +447,24 @@ export default {
 	onMounted(() => {
 	    loadStatusDictList()
 	    loadData(true as boolean | null)
+
+		// 监听接单成功的事件,刷新列表
+		uni.$on('refreshOrderList', () => {
+			page.value = 1
+			loadData(true)
+		})
 	})
-    // 组件卸载前清理
+
+    // 组件卸载前清理事件监听
     onBeforeUnmount(() => {
         refreshing.value = false
         loading.value = false
+
+		// 移除事件监听
+		uni.$off('refreshOrderList',{})
     })
 
 
-    // 返回模板可直接使用的变量/方法
-    return {
-        dataList,
-        keyword,
-        currentStatus,
-        loading,
-        refreshing,
-        hasMore,
-        getOrderType,
-        getWorkOrderProjectNo,
-        getWorkOrderStatus,
-        getPcsStationName,
-        getPcsDeviceName,
-        getAssignTime,
-        getAcceptTime,
-        getCreateTime,
-        getDisplayTime,
-        switchStatus,
-        handleRefresh,
-        loadMore,
-        handleSearch,
-        handleItemClick,
-        acceptOrder,
-        approveOrder,
-        clearSearch,
-		handleSearchOnBlur
-    }
-}}
 </script>
 
 <style lang="scss">

+ 3 - 1
types/order.uts

@@ -4,7 +4,9 @@ import type { WorkOrderFlowList } from './flow'
 export type orderInfo = {
 	orderType: Number
     id: Number
+	teamLeaderId: Number | 0
     teamLeaderName: string | null
+	acceptUserId: Number | 0
     acceptUserName: string | null
     acceptTime: string | null
     assignTime: string | null
@@ -38,4 +40,4 @@ export type orderListResponse = {
     msg: string | null
     total: number
     rows: orderInfo[]
-}
+}

+ 0 - 1
types/user.uts

@@ -37,4 +37,3 @@ export type UserInfo = {
 	phone: string
 	deptName : string
 }
-