| | |
| | | <template> |
| | | <view class="content"> |
| | | <image class="logo" src="@/static/logo.png"></image> |
| | | <view class="text-area"> |
| | | <text class="title">Hello RuoYi</text> |
| | | <view class="home-container"> |
| | | <!-- 顶部用户信息区域 --> |
| | | <view class="user-info-section"> |
| | | <view class="user-info-content"> |
| | | <view class="user-details"> |
| | | <view class="user-name">{{ userName || '未登录' }}</view> |
| | | <view class="vehicle-info"> |
| | | <text v-if="boundVehicle">关联车牌号:{{ boundVehicle }}</text> |
| | | <text v-else>未绑定车牌号</text> |
| | | </view> |
| | | </view> |
| | | <button |
| | | class="bind-vehicle-btn" |
| | | @click="goToBindVehicle" |
| | | > |
| | | {{ boundVehicle ? '更换车辆' : '绑定车辆' }} |
| | | </button> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 消息入口 --> |
| | | <view class="message-entry" @click="goToMessages"> |
| | | <view class="message-icon"> |
| | | <uni-icons type="chat" size="24" color="#007AFF"></uni-icons> |
| | | </view> |
| | | <view class="message-text">消息中心</view> |
| | | <view class="unread-dot" v-if="unreadMessageCount > 0">{{ unreadMessageCount }}</view> |
| | | <view class="arrow"> |
| | | <uni-icons type="arrowright" size="16" color="#999"></uni-icons> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 正在运行的任务标题 --> |
| | | <view class="running-tasks-header"> |
| | | <text class="header-title">正在运行的任务</text> |
| | | </view> |
| | | |
| | | <!-- 正在运行的任务列表 --> |
| | | <scroll-view class="running-tasks-section" scroll-y="true"> |
| | | <view class="task-list"> |
| | | <view class="task-item" v-for="task in runningTasks" :key="task.id"> |
| | | <view class="task-main" @click="viewTaskDetail(task)"> |
| | | <view class="task-title">{{ getTaskTypeText(task.type) }} - {{ task.vehicle }}</view> |
| | | <view class="task-info"> |
| | | <view class="info-row"> |
| | | <view class="info-item"> |
| | | <view class="label">任务编号:</view> |
| | | <view class="value">{{ task.taskNo }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">任务状态:</view> |
| | | <view class="value">{{ getStatusText(task.status) }}</view> |
| | | </view> |
| | | </view> |
| | | <view class="info-row"> |
| | | <view class="info-item"> |
| | | <view class="label">出发地:</view> |
| | | <view class="value">{{ task.startLocation }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">目的地:</view> |
| | | <view class="value">{{ task.endLocation }}</view> |
| | | </view> |
| | | </view> |
| | | <view class="info-row"> |
| | | <view class="info-item"> |
| | | <view class="label">出发时间:</view> |
| | | <view class="value">{{ task.startTime }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">执行人员:</view> |
| | | <view class="value">{{ task.assignee }}</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="task-actions"> |
| | | <button |
| | | class="action-btn" |
| | | :class="{ disabled: isActionDisabled(task, 'depart') }" |
| | | @click="handleTaskAction(task, 'depart')" |
| | | v-if="task.status !== 'completed'" |
| | | > |
| | | 出发 |
| | | </button> |
| | | <button |
| | | class="action-btn" |
| | | :class="{ disabled: isActionDisabled(task, 'arrive') }" |
| | | @click="handleTaskAction(task, 'arrive')" |
| | | v-if="task.status !== 'completed'" |
| | | > |
| | | 已到达 |
| | | </button> |
| | | <button |
| | | class="action-btn" |
| | | :class="{ disabled: isActionDisabled(task, 'return') }" |
| | | @click="handleTaskAction(task, 'return')" |
| | | v-if="task.status !== 'completed'" |
| | | > |
| | | 返程 |
| | | </button> |
| | | <button |
| | | class="action-btn" |
| | | :class="{ disabled: isActionDisabled(task, 'settle') }" |
| | | @click="handleTaskAction(task, 'settle')" |
| | | v-if="task.status !== 'completed'" |
| | | > |
| | | 结算 |
| | | </button> |
| | | <button |
| | | class="action-btn primary" |
| | | :class="{ disabled: isActionDisabled(task, 'complete') }" |
| | | @click="handleTaskAction(task, 'complete')" |
| | | v-if="task.status !== 'completed'" |
| | | > |
| | | 已完成 |
| | | </button> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="no-data" v-if="runningTasks.length === 0"> |
| | | <uni-icons type="info" size="40" color="#ccc"></uni-icons> |
| | | <text>暂无正在运行的任务</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | |
| | | export default { |
| | | onLoad: function() { |
| | | data() { |
| | | return { |
| | | // 模拟用户绑定的车辆信息 |
| | | boundVehicle: '粤A12345', // 模拟已绑定车辆 |
| | | |
| | | // 模拟消息数据 |
| | | messages: [ |
| | | { |
| | | id: 1, |
| | | type: 'create', // 创建成功 |
| | | content: 'TD 1011 广州天河->广州东站,时间:13:20 任务创建成功', |
| | | time: '2023-05-15 13:20', |
| | | read: false, |
| | | taskId: 1 |
| | | }, |
| | | { |
| | | id: 2, |
| | | type: 'push', // 任务推送 |
| | | content: 'TD1021 广州天河->广州东站,时间:13:20 出发,请及时处理', |
| | | time: '2023-05-15 13:25', |
| | | read: false, |
| | | taskId: 2 |
| | | }, |
| | | { |
| | | id: 3, |
| | | type: 'status', // 任务状态变更 |
| | | content: 'TD1021 广州天河->广州东站,时间:13:20,任务正在转运中', |
| | | time: '2023-05-15 14:30', |
| | | read: true, |
| | | taskId: 2 |
| | | }, |
| | | { |
| | | id: 4, |
| | | type: 'create', // 创建成功 |
| | | content: 'TD 1022 深圳南山->深圳福田,时间:15:10 任务创建成功', |
| | | time: '2023-05-15 15:10', |
| | | read: false, |
| | | taskId: 3 |
| | | }, |
| | | { |
| | | id: 5, |
| | | type: 'push', // 任务推送 |
| | | content: 'TD1023 深圳南山->深圳福田,时间:16:00 出发,请及时处理', |
| | | time: '2023-05-15 16:00', |
| | | read: true, |
| | | taskId: 4 |
| | | } |
| | | ], |
| | | |
| | | // 模拟正在运行的任务列表 |
| | | taskList: [ |
| | | { |
| | | id: 1, |
| | | title: '紧急维修任务', |
| | | type: 'maintenance', // 维修保养 |
| | | startLocation: '广州市天河区XX路123号', |
| | | endLocation: '广州市白云区YY路456号', |
| | | startTime: '2023-05-15 15:00', |
| | | assignee: '张三', |
| | | status: 'pending', |
| | | vehicle: '粤A12345', |
| | | taskNo: 'RW20230515001' |
| | | }, |
| | | { |
| | | id: 2, |
| | | title: '定期保养任务', |
| | | type: 'maintenance', // 维修保养 |
| | | startLocation: '深圳市南山区XX路789号', |
| | | endLocation: '深圳市福田区YY路999号', |
| | | startTime: '2023-05-14 10:00', |
| | | assignee: '李四', |
| | | status: 'processing', |
| | | vehicle: '粤B67890', |
| | | taskNo: 'RW20230514002' |
| | | }, |
| | | { |
| | | id: 5, |
| | | title: '急救转运任务', |
| | | type: 'emergency', // 急救转运 |
| | | startLocation: '广州市越秀区医院路1号', |
| | | endLocation: '广州市海珠区医院路2号', |
| | | startTime: '2023-05-16 14:00', |
| | | assignee: '张医生,李护士', |
| | | status: 'pending', |
| | | vehicle: '粤E33333', |
| | | taskNo: 'RW20230516005' |
| | | }, |
| | | { |
| | | id: 6, |
| | | title: '福祉车任务', |
| | | type: 'welfare', // 福祉车 |
| | | startLocation: '广州市荔湾区社区路10号', |
| | | endLocation: '广州市天河区养老院路20号', |
| | | startTime: '2023-05-17 08:00', |
| | | assignee: '王司机', |
| | | status: 'processing', |
| | | vehicle: '粤F44444', |
| | | taskNo: 'RW20230517006' |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapState({ |
| | | userName: state => state.user.name |
| | | }), |
| | | |
| | | // 正在运行的任务(待处理和处理中的任务) |
| | | runningTasks() { |
| | | return this.taskList.filter(task => |
| | | task.status === 'pending' || task.status === 'processing' |
| | | ); |
| | | }, |
| | | |
| | | // 未读消息数量 |
| | | unreadMessageCount() { |
| | | return this.messages.filter(message => !message.read).length; |
| | | } |
| | | }, |
| | | methods: { |
| | | // 跳转到绑定车辆页面 |
| | | goToBindVehicle() { |
| | | // 跳转到绑定车辆的页面 |
| | | this.$tab.navigateTo('/pages/bind-vehicle'); |
| | | }, |
| | | |
| | | // 跳转到消息页面 |
| | | goToMessages() { |
| | | this.$tab.switchTab('/pages/message/index'); |
| | | }, |
| | | |
| | | // 查看任务详情 |
| | | viewTaskDetail(task) { |
| | | // 跳转到任务详情页面 |
| | | this.$tab.navigateTo(`/pages/task/detail?id=${task.id}`); |
| | | }, |
| | | |
| | | // 判断操作按钮是否禁用 |
| | | isActionDisabled(task, action) { |
| | | // 根据任务状态和操作类型判断是否禁用 |
| | | switch (action) { |
| | | case 'depart': |
| | | return task.status !== 'pending'; |
| | | case 'arrive': |
| | | return task.status !== 'processing'; |
| | | case 'return': |
| | | return task.status !== 'processing'; |
| | | case 'settle': |
| | | return task.status !== 'processing'; |
| | | case 'complete': |
| | | return task.status !== 'processing'; |
| | | default: |
| | | return false; |
| | | } |
| | | }, |
| | | |
| | | // 处理任务操作 |
| | | handleTaskAction(task, action) { |
| | | if (this.isActionDisabled(task, action)) { |
| | | return; |
| | | } |
| | | |
| | | switch (action) { |
| | | case 'depart': |
| | | // 出发操作,根据任务类型显示不同的确认信息 |
| | | let departMessage = '确定要标记为已出发吗?'; |
| | | if (task.type !== 'maintenance' && task.type !== 'refuel' && task.type !== 'inspection') { |
| | | departMessage = '发出去目的地,确认?'; |
| | | } |
| | | this.$modal.confirm(departMessage).then(() => { |
| | | task.status = 'processing'; |
| | | this.$modal.showToast('已出发'); |
| | | // 这里可以调用API更新任务状态 |
| | | }).catch(() => {}); |
| | | break; |
| | | case 'arrive': |
| | | // 已到达操作 |
| | | this.$modal.confirm('已经到达目的地,确认?').then(() => { |
| | | this.$modal.showToast('已到达'); |
| | | // 这里可以调用API更新任务状态 |
| | | }).catch(() => {}); |
| | | break; |
| | | case 'return': |
| | | // 返程操作 |
| | | this.$modal.confirm('现在已经返程中,确认?').then(() => { |
| | | this.$modal.showToast('返程中'); |
| | | // 这里可以调用API更新任务状态 |
| | | }).catch(() => {}); |
| | | break; |
| | | case 'settle': |
| | | // 结算操作,跳转到结算页面 |
| | | this.$tab.navigateTo(`/pages/task/settlement?id=${task.id}`); |
| | | break; |
| | | case 'complete': |
| | | // 已完成操作 |
| | | this.$modal.confirm('任务是否已经全部完成,确认?').then(() => { |
| | | task.status = 'completed'; |
| | | this.$modal.showToast('任务已完成'); |
| | | // 这里可以调用API更新任务状态 |
| | | }).catch(() => {}); |
| | | break; |
| | | } |
| | | }, |
| | | |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | 'pending': '待处理', |
| | | 'processing': '处理中', |
| | | 'completed': '已完成' |
| | | } |
| | | return statusMap[status] || '未知' |
| | | }, |
| | | |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | 'maintenance': '维修保养', |
| | | 'refuel': '加油', |
| | | 'inspection': '巡检', |
| | | 'emergency': '急救转运', |
| | | 'welfare': '福祉车' |
| | | } |
| | | return typeMap[type] || '未知类型' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .content { |
| | | <style lang="scss"> |
| | | .home-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | height: 100vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | } |
| | | |
| | | .logo { |
| | | height: 200rpx; |
| | | width: 200rpx; |
| | | margin-top: 200rpx; |
| | | margin-left: auto; |
| | | margin-right: auto; |
| | | margin-bottom: 50rpx; |
| | | |
| | | // 用户信息区域 |
| | | .user-info-section { |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .user-info-content { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .user-details { |
| | | .user-name { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 10rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .vehicle-info { |
| | | font-size: 28rpx; |
| | | color: #666; |
| | | } |
| | | } |
| | | |
| | | .bind-vehicle-btn { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | border-radius: 10rpx; |
| | | padding: 15rpx 30rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .text-area { |
| | | |
| | | // 消息入口 |
| | | .message-entry { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | position: relative; |
| | | |
| | | .message-icon { |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .message-text { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .unread-dot { |
| | | position: absolute; |
| | | top: 15rpx; |
| | | right: 60rpx; |
| | | background-color: #ff4d4f; |
| | | color: white; |
| | | border-radius: 50%; |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | font-size: 20rpx; |
| | | } |
| | | |
| | | .arrow { |
| | | margin-left: 20rpx; |
| | | } |
| | | } |
| | | |
| | | .title { |
| | | font-size: 36rpx; |
| | | color: #8f8f94; |
| | | |
| | | // 正在运行的任务标题 |
| | | .running-tasks-header { |
| | | margin-bottom: 20rpx; |
| | | flex-shrink: 0; // 防止收缩 |
| | | |
| | | .header-title { |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | } |
| | | </style> |
| | | |
| | | // 正在运行的任务列表 |
| | | .running-tasks-section { |
| | | flex: 1; |
| | | background-color: white; |
| | | border-radius: 15rpx; |
| | | padding: 30rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | // 隐藏滚动条但保持滚动功能 |
| | | ::-webkit-scrollbar { |
| | | display: none; |
| | | width: 0 !important; |
| | | height: 0 !important; |
| | | background: transparent; |
| | | } |
| | | |
| | | // Firefox滚动条隐藏 |
| | | * { |
| | | scrollbar-width: none; /* Firefox */ |
| | | } |
| | | |
| | | // IE/Edge滚动条隐藏 |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | |
| | | .task-list { |
| | | .task-item { |
| | | background-color: #fafafa; |
| | | border-radius: 15rpx; |
| | | margin-bottom: 30rpx; |
| | | overflow: hidden; |
| | | |
| | | .task-main { |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | |
| | | .task-title { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .task-info { |
| | | .info-row { |
| | | display: flex; |
| | | margin-bottom: 15rpx; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .info-item { |
| | | flex: 1; |
| | | display: flex; |
| | | |
| | | .label { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | margin-right: 10rpx; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .value { |
| | | font-size: 26rpx; |
| | | flex: 1; |
| | | word-break: break-all; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .task-actions { |
| | | display: flex; |
| | | padding: 20rpx; |
| | | |
| | | .action-btn { |
| | | flex: 1; |
| | | height: 70rpx; |
| | | border-radius: 10rpx; |
| | | font-size: 26rpx; |
| | | margin: 0 5rpx; |
| | | background-color: #f0f0f0; |
| | | color: #333; |
| | | |
| | | &.primary { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | } |
| | | |
| | | &.disabled { |
| | | opacity: 0.5; |
| | | } |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .no-data { |
| | | text-align: center; |
| | | padding: 100rpx 0; |
| | | color: #999; |
| | | |
| | | text { |
| | | display: block; |
| | | margin-top: 20rpx; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |