| | |
| | | import config from './config' |
| | | import store from '@/store' |
| | | import { getToken } from '@/utils/auth' |
| | | import { getUnreadCount } from '@/api/message' |
| | | |
| | | export default { |
| | | onLaunch: function() { |
| | | this.initApp() |
| | | }, |
| | | onShow: function() { |
| | | // åºç¨æ¾ç¤ºæ¶å·æ°æªè¯»æ¶æ¯æ°é |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | } |
| | | }, |
| | | methods: { |
| | | // åå§ååºç¨ |
| | |
| | | //#ifdef H5 |
| | | this.checkLogin() |
| | | //#endif |
| | | |
| | | // 妿已ç»å½ï¼å¯å¨æªè¯»æ¶æ¯è½®è¯¢ |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | // æ¯30ç§è½®è¯¢ä¸æ¬¡ |
| | | this.startMessagePolling() |
| | | } |
| | | }, |
| | | initConfig() { |
| | | this.globalData.config = config |
| | |
| | | if (!getToken()) { |
| | | this.$tab.reLaunch('/pages/login') |
| | | } |
| | | }, |
| | | |
| | | // æ´æ°æªè¯»æ¶æ¯å¾½æ |
| | | updateUnreadMessageBadge() { |
| | | getUnreadCount().then(response => { |
| | | const count = response.data || 0 |
| | | console.log('æªè¯»æ¶æ¯æ°é:', count) |
| | | |
| | | if (count > 0) { |
| | | // 设置徽æ |
| | | uni.setTabBarBadge({ |
| | | index: 3, // æ¶æ¯é¡µé¢å¨tabBarä¸çç´¢å¼ä½ç½®ï¼0å¼å§ï¼ |
| | | text: count > 99 ? '99+' : count.toString() |
| | | }) |
| | | } else { |
| | | // ç§»é¤å¾½æ |
| | | uni.removeTabBarBadge({ |
| | | index: 3 |
| | | }) |
| | | } |
| | | }).catch(error => { |
| | | console.error('è·åæªè¯»æ¶æ¯æ°é失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // å¯å¨æ¶æ¯è½®è¯¢ |
| | | startMessagePolling() { |
| | | // æ¯30ç§è½®è¯¢ä¸æ¬¡ |
| | | this.messagePollingTimer = setInterval(() => { |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | } else { |
| | | // å¦æç¨æ·å·²ç»åºï¼åæ¢è½®è¯¢ |
| | | this.stopMessagePolling() |
| | | } |
| | | }, 30000) // 30ç§ |
| | | }, |
| | | |
| | | // åæ¢æ¶æ¯è½®è¯¢ |
| | | stopMessagePolling() { |
| | | if (this.messagePollingTimer) { |
| | | clearInterval(this.messagePollingTimer) |
| | | this.messagePollingTimer = null |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | const ENV_CONFIG = { |
| | | // æ¬å°å¼åç¯å¢ |
| | | development: { |
| | | baseUrl: `http://${LOCAL_IP}:8080`, |
| | | baseUrl: `https://dsp.966120.com.cn`, |
| | | description: 'æ¬å°å¼åç¯å¢' |
| | | }, |
| | | // æµè¯ç¯å¢ |
| | | test: { |
| | | baseUrl: 'http://test.yourdomain.com', |
| | | baseUrl: 'https://dsp.966120.com.cn', |
| | | description: 'æµè¯ç¯å¢' |
| | | }, |
| | | // ç产ç¯å¢ |
| | | production: { |
| | | baseUrl: 'https://api.yourdomain.com', |
| | | baseUrl: 'https://dsp.966120.com.cn', |
| | | description: 'ç产ç¯å¢' |
| | | } |
| | | } |
| | |
| | | // åºç¨logo |
| | | logo: "/static/logo.png", |
| | | // 宿¹ç½ç« |
| | | site_url: "http://ruoyi.vip", |
| | | site_url: "http://www.966120.com.cn", |
| | | |
| | | // å½åç¯å¢ä¿¡æ¯ï¼ä»
å¼åæ¶æ¾ç¤ºï¼ |
| | | env: CURRENT_ENV, |
| | |
| | | "port" : 9090, |
| | | "https" : false |
| | | }, |
| | | "title" : "RuoYi-App", |
| | | "title" : "å¹¿ä¸æ°èªå°ç¨åº", |
| | | "router" : { |
| | | "mode" : "hash", |
| | | "base" : "./" |
| | |
| | | }, { |
| | | "path": "pages/task/create-emergency", |
| | | "style": { |
| | | "navigationBarTitleText": "åå»ºæ¥æè½¬è¿ä»»å¡" |
| | | "navigationBarTitleText": "å建转è¿ä»»å¡" |
| | | } |
| | | }, { |
| | | "path": "pages/task/create-welfare", |
| | |
| | | }, |
| | | "globalStyle": { |
| | | "navigationBarTextStyle": "black", |
| | | "navigationBarTitleText": "RuoYi", |
| | | "navigationBarTitleText": "å¹¿ä¸æ°èª", |
| | | "navigationBarBackgroundColor": "#FFFFFF" |
| | | } |
| | | } |
| | |
| | | import { getUserProfile } from '@/api/system/user' |
| | | import { getUserBoundVehicle } from '@/api/vehicle' |
| | | import { getUnreadCount } from '@/api/message' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | |
| | | getUnreadCount().then(response => { |
| | | if (response.code === 200) { |
| | | this.unreadMessageCount = response.data || 0 |
| | | // æ´æ°TabBarå¾½æ |
| | | this.updateTabBarBadge(this.unreadMessageCount) |
| | | } |
| | | }).catch(error => { |
| | | console.error('è·åæªè¯»æ¶æ¯æ°é失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // æ´æ°TabBarå¾½æ |
| | | updateTabBarBadge(count) { |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, // æ¶æ¯é¡µé¢å¨tabBarä¸çç´¢å¼ |
| | | text: count > 99 ? '99+' : count.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ |
| | | index: 3 |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | // å è½½ç¨æ·ä¿¡æ¯ï¼ä¿ç以å
¼å®¹ä¹åç代ç ï¼ |
| | |
| | | vehicleList: task.assignedVehicles || [], |
| | | startLocation: this.formatAddress(task.departureAddress || task.startLocation || 'æªè®¾ç½®'), |
| | | endLocation: this.formatAddress(task.destinationAddress || task.endLocation || 'æªè®¾ç½®'), |
| | | startTime: task.plannedStartTime ? this.formatDateTime(task.plannedStartTime) : 'æªè®¾ç½®', |
| | | startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : 'æªè®¾ç½®', |
| | | assignee: task.assigneeName || 'æªåé
', |
| | | taskNo: task.taskCode || 'æªç¥ç¼å·', |
| | | status: this.convertStatus(task.taskStatus) // 转æ¢ç¶ææ ¼å¼ä»¥å
¼å®¹æ§UI |
| | |
| | | }).catch(error => { |
| | | this.loading = false |
| | | console.error('å 载任å¡å表失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥ææ¶é´ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return '' |
| | | const date = new Date(dateTime) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit' |
| | | }) |
| | | }, |
| | | |
| | |
| | | 'MAINTENANCE': 'ç»´ä¿®ä¿å
»', |
| | | 'FUEL': 'å æ²¹', |
| | | 'OTHER': 'å
¶ä»', |
| | | 'EMERGENCY_TRANSFER': 'æ¥æè½¬è¿', |
| | | 'EMERGENCY_TRANSFER': '转è¿ä»»å¡', |
| | | 'WELFARE': 'ç¦ç¥è½¦', |
| | | // æ§æ ¼å¼ï¼UIç±»åï¼ |
| | | 'maintenance': 'ç»´ä¿®ä¿å
»', |
| | | 'refuel': 'å æ²¹', |
| | | 'inspection': 'å·¡æ£', |
| | | 'emergency': 'æ¥æè½¬è¿', |
| | | 'emergency': '转è¿ä»»å¡', |
| | | 'welfare': 'ç¦ç¥è½¦' |
| | | } |
| | | return typeMap[type] || 'æªç¥ç±»å' |
| | |
| | | <view |
| | | class="message-item" |
| | | v-for="message in sortedMessages" |
| | | :key="message.id" |
| | | :key="message.messageId" |
| | | @click="viewMessageDetail(message)" |
| | | > |
| | | <view class="message-main"> |
| | |
| | | onShow() { |
| | | // æ¯æ¬¡æ¾ç¤ºé¡µé¢æ¶å·æ°æ¶æ¯ |
| | | this.loadMessages() |
| | | // æ´æ°TabBarå¾½æ |
| | | this.updateTabBarBadge() |
| | | }, |
| | | onPullDownRefresh() { |
| | | this.loadMessages().then(() => { |
| | |
| | | // æ¥çæ¶æ¯è¯¦æ
ï¼è·³è½¬å°ä»»å¡è¯¦æ
ï¼ |
| | | async viewMessageDetail(message) { |
| | | try { |
| | | // æ ¡éªæ¶æ¯å¯¹è±¡ |
| | | if (!message || !message.messageId) { |
| | | console.error('æ¶æ¯æ°æ®å¼å¸¸ï¼', message) |
| | | this.$modal.showToast('æ¶æ¯æ°æ®å¼å¸¸') |
| | | return |
| | | } |
| | | |
| | | // æ 记为已读 |
| | | if (message.isRead === '0') { |
| | | await markAsRead(message.messageId) |
| | | message.isRead = '1' |
| | | // æ´æ°å¾½æ |
| | | this.updateTabBarBadge() |
| | | } |
| | | |
| | | // 跳转å°ä»»å¡è¯¦æ
é¡µé¢ |
| | |
| | | } catch (error) { |
| | | console.error('æ è®°æ¶æ¯å·²è¯»å¤±è´¥ï¼', error) |
| | | // å³ä½¿æ 记失败ï¼ä¹å
许跳转 |
| | | if (message.taskId) { |
| | | if (message && message.taskId) { |
| | | this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`) |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // æ´æ°TabBarå¾½æ |
| | | updateTabBarBadge() { |
| | | const unreadCount = this.messages.filter(msg => msg.isRead === '0').length |
| | | console.log('æªè¯»æ¶æ¯æ°é:', unreadCount) |
| | | |
| | | if (unreadCount > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, // æ¶æ¯é¡µé¢å¨tabBarä¸çç´¢å¼ |
| | | text: unreadCount > 99 ? '99+' : unreadCount.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ |
| | | index: 3 |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | import config from '@/config' |
| | | import store from "@/store" |
| | | import { uploadAvatar } from "@/api/system/user" |
| | | import { getSystemInfo } from '@/utils/common' |
| | | |
| | | const baseUrl = config.baseUrl |
| | | let sysInfo = uni.getSystemInfoSync() |
| | | const sysInfo = getSystemInfo() |
| | | let SCREEN_WIDTH = sysInfo.screenWidth |
| | | let PAGE_X, // ææä¸çxä½ç½® |
| | | PAGE_Y, // ææä¸yçä½ç½® |
| | |
| | | </view> |
| | | <view v-if="name" @click="handleToInfo" class="user-info"> |
| | | <view class="u_title"> |
| | | ç¨æ·åï¼{{ name }} |
| | | {{ name }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | </view> |
| | | |
| | | <scroll-view class="content-section" scroll-y="true"> |
| | | <view class="mine-actions grid col-4 text-center"> |
| | | <view class="action-item" @click="handleJiaoLiuQun"> |
| | | <view class="iconfont icon-friendfill text-pink icon"></view> |
| | | <text class="text">交æµç¾¤</text> |
| | | </view> |
| | | <view class="action-item" @click="handleBuilding"> |
| | | <view class="iconfont icon-service text-blue icon"></view> |
| | | <text class="text">å¨çº¿å®¢æ</text> |
| | | </view> |
| | | <view class="action-item" @click="handleBuilding"> |
| | | <view class="iconfont icon-community text-mauve icon"></view> |
| | | <text class="text">åé¦ç¤¾åº</text> |
| | | </view> |
| | | <view class="action-item" @click="handleBuilding"> |
| | | <view class="iconfont icon-dianzan text-green icon"></view> |
| | | <text class="text">ç¹èµæä»¬</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- ç¨æ·ä¿¡æ¯å±ç¤º --> |
| | | <view class="user-info-section"> |
| | | <view class="info-item"> |
| | | <view class="info-label">ç¨æ·åï¼</view> |
| | | <view class="info-label">æµç§°ï¼</view> |
| | | <view class="info-value">{{ name || 'æªç»å½' }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="info-label">ææºå·ç ï¼</view> |
| | | <view class="info-value">{{ phonenumber || 'æªç»å®' }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="info-label">æå±åå
¬å¸ï¼</view> |
| | | <view class="info-value">{{ deptName || 'æªè®¾ç½®' }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="info-label">ç»å®è½¦è¾ï¼</view> |
| | |
| | | <view class="info-label">Appçæ¬å·ï¼</view> |
| | | <view class="info-value">{{ version || '1.0.0' }}</view> |
| | | </view> |
| | | |
| | | <!-- ç»å®/è§£ç»è½¦è¾æä½ --> |
| | | <view class="vehicle-actions" v-if="boundVehicle && boundVehicle !== 'æªç»å®'"> |
| | | <button class="unbind-btn" @click="unbindVehicle">åæ¶ç»å®è½¦è¾</button> |
| | | </view> |
| | | <view class="vehicle-actions" v-else> |
| | | <button class="bind-btn" @click="goToBindVehicle">ç»å®è½¦è¾</button> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="menu-list"> |
| | | <view class="list-cell list-cell-arrow" @click="handleToEditInfo"> |
| | | <!-- ç»å®/è§£ç»è½¦è¾ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleVehicleBinding"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-user menu-icon"></view> |
| | | <view>ç¼è¾èµæ</view> |
| | | <view class="iconfont icon-car menu-icon"></view> |
| | | <view>{{ boundVehicle && boundVehicle !== 'æªç»å®' ? 'æ´æ¢è½¦è¾' : 'ç»å®è½¦è¾' }}</view> |
| | | </view> |
| | | </view> |
| | | <view class="list-cell list-cell-arrow" @click="handleUserAgreement"> |
| | | |
| | | <!-- éåºç»å½ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleLogout"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-text menu-icon"></view> |
| | | <view>ç¨æ·æå¡åè®®</view> |
| | | </view> |
| | | </view> |
| | | <view class="list-cell list-cell-arrow" @click="handlePrivacyPolicy"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-safe menu-icon"></view> |
| | | <view>éç§æ¿ç</view> |
| | | </view> |
| | | </view> |
| | | <view class="list-cell list-cell-arrow" @click="handleHelp"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-help menu-icon"></view> |
| | | <view>常è§é®é¢</view> |
| | | </view> |
| | | </view> |
| | | <view class="list-cell list-cell-arrow" @click="handleAbout"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-aixin menu-icon"></view> |
| | | <view>å
³äºæä»¬</view> |
| | | </view> |
| | | </view> |
| | | <view class="list-cell list-cell-arrow" @click="handleToSetting"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-setting menu-icon"></view> |
| | | <view>åºç¨è®¾ç½®</view> |
| | | <view class="iconfont icon-logout menu-icon text-red"></view> |
| | | <view class="text-red">éåºç»å½</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | import storage from '@/utils/storage' |
| | | import { getUserProfile } from "@/api/system/user" |
| | | import { getUserBoundVehicle, unbindVehicleFromUser } from '@/api/vehicle' |
| | | import { getSystemInfo } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | name: this.$store.state.user.nickName, |
| | | phonenumber: '', |
| | | deptName: '', // æå±åå
¬å¸ |
| | | boundVehicle: '', // ç»å®ç车è¾ä¿¡æ¯ |
| | | boundVehicleId: null, // ç»å®ç车è¾ID |
| | | version: getApp().globalData.config.appInfo.version |
| | |
| | | return this.$store.state.user.avatar |
| | | }, |
| | | windowHeight() { |
| | | return uni.getSystemInfoSync().windowHeight - 50 |
| | | return getSystemInfo().windowHeight - 50 |
| | | } |
| | | }, |
| | | onLoad() { |
| | | this.getUserInfo() |
| | | }, |
| | | onShow() { |
| | | // æ¯æ¬¡æ¾ç¤ºé¡µé¢æ¶å·æ°ç¨æ·ä¿¡æ¯ |
| | | this.getUserInfo() |
| | | }, |
| | | methods: { |
| | |
| | | // è·åç¨æ·åºæ¬ä¿¡æ¯ |
| | | getUserProfile().then(response => { |
| | | const user = response.data |
| | | this.name = user.userName |
| | | this.name = user.nickName || user.userName // ä¼å
ä½¿ç¨æµç§° |
| | | this.phonenumber = user.phonenumber |
| | | this.deptName = user.dept ? user.dept.deptName : 'æªè®¾ç½®' |
| | | }).catch(() => { |
| | | // è·åç¨æ·ä¿¡æ¯å¤±è´¥æ¶ä½¿ç¨é»è®¤å¼ |
| | | this.name = this.$store.state.user.nickName || 'æªç»å½' |
| | | this.phonenumber = 'æªç»å®' |
| | | this.deptName = 'æªè®¾ç½®' |
| | | }) |
| | | |
| | | // è·åç¨æ·ç»å®ç车è¾ä¿¡æ¯ |
| | |
| | | } |
| | | }, |
| | | |
| | | // 跳转å°ç»å®è½¦è¾é¡µé¢ |
| | | goToBindVehicle() { |
| | | // å¤ç车è¾ç»å®æä½ |
| | | handleVehicleBinding() { |
| | | this.$tab.navigateTo('/pages/bind-vehicle') |
| | | }, |
| | | |
| | | // åæ¶ç»å®è½¦è¾ |
| | | unbindVehicle() { |
| | | const userId = this.$store.state.user.userId |
| | | const vehicleId = this.boundVehicleId |
| | | |
| | | if (!userId || !vehicleId) { |
| | | this.$modal.showToast('æ æ³è·åç»å®ä¿¡æ¯') |
| | | return |
| | | } |
| | | |
| | | this.$modal.confirm(`ç¡®è®¤åæ¶ç»å®è½¦è¾ ${this.boundVehicle} åï¼`).then(() => { |
| | | // è°ç¨APIåæ¶ç»å®è½¦è¾ |
| | | unbindVehicleFromUser(userId, vehicleId).then(response => { |
| | | if (response.code === 200) { |
| | | this.boundVehicle = 'æªç»å®' |
| | | this.boundVehicleId = null |
| | | this.$modal.showToast('åæ¶ç»å®æå') |
| | | // æ´æ°ç¨æ·ä¿¡æ¯ |
| | | this.$store.dispatch('GetInfo') |
| | | } else { |
| | | this.$modal.showToast(response.msg || 'åæ¶ç»å®å¤±è´¥') |
| | | } |
| | | }).catch(error => { |
| | | console.error('åæ¶ç»å®å¤±è´¥:', error) |
| | | this.$modal.showToast('åæ¶ç»å®å¤±è´¥ï¼è¯·éè¯') |
| | | }) |
| | | }).catch(() => { |
| | | // ç¨æ·åæ¶æä½ |
| | | }) |
| | | }, |
| | | |
| | | handleToInfo() { |
| | |
| | | this.$tab.navigateTo('/pages/mine/avatar/index') |
| | | }, |
| | | handleLogout() { |
| | | this.$modal.confirm('ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼').then(() => { |
| | | this.$modal.confirm('ç¡®å®éåºç»å½åï¼').then(() => { |
| | | this.$store.dispatch('LogOut').then(() => { |
| | | this.$tab.reLaunch('/pages/index') |
| | | this.$tab.reLaunch('/pages/login') |
| | | }) |
| | | }) |
| | | }, |
| | | handleHelp() { |
| | | this.$tab.navigateTo('/pages/mine/help/index') |
| | | }, |
| | | handleAbout() { |
| | | this.$tab.navigateTo('/pages/mine/about/index') |
| | | }, |
| | | handleUserAgreement() { |
| | | this.$tab.navigateTo('/pages/mine/user-agreement/index') |
| | | }, |
| | | handlePrivacyPolicy() { |
| | | this.$tab.navigateTo('/pages/mine/privacy-policy/index') |
| | | }, |
| | | handleJiaoLiuQun() { |
| | | this.$modal.showToast('QQ群ï¼â 133713780(满)ãâ¡146013835(满)ãâ¢189091635') |
| | | }, |
| | | handleBuilding() { |
| | | this.$modal.showToast('模å建设ä¸~') |
| | | } |
| | | } |
| | | } |
| | |
| | | * { |
| | | -ms-overflow-style: none; /* IE 10+ */ |
| | | } |
| | | |
| | | .mine-actions { |
| | | margin: 15px 15px; |
| | | padding: 20px 0px; |
| | | border-radius: 8px; |
| | | background-color: white; |
| | | |
| | | .action-item { |
| | | .icon { |
| | | font-size: 28px; |
| | | } |
| | | |
| | | .text { |
| | | display: block; |
| | | font-size: 13px; |
| | | margin: 8px 0px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ç¨æ·ä¿¡æ¯å±ç¤ºåºå |
| | | .user-info-section { |
| | |
| | | flex: 1; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // èååè¡¨æ ·å¼ |
| | | .menu-list { |
| | | background-color: white; |
| | | border-radius: 8px; |
| | | margin: 15rpx; |
| | | overflow: hidden; |
| | | |
| | | .vehicle-actions { |
| | | padding: 30rpx 0 10rpx 0; |
| | | text-align: center; |
| | | .list-cell { |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | cursor: pointer; |
| | | transition: background-color 0.2s; |
| | | |
| | | .bind-btn, .unbind-btn { |
| | | width: 80%; |
| | | height: 80rpx; |
| | | border-radius: 10rpx; |
| | | font-size: 32rpx; |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .bind-btn { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | &:active { |
| | | background-color: #f5f5f5; |
| | | } |
| | | |
| | | .unbind-btn { |
| | | background-color: #ff4d4f; |
| | | color: white; |
| | | .menu-item-box { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | .menu-icon { |
| | | font-size: 36rpx; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | view { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .text-red { |
| | | color: #ff4d4f; |
| | | } |
| | | } |
| | | |
| | | &.list-cell-arrow .menu-item-box::after { |
| | | content: ''; |
| | | width: 16rpx; |
| | | height: 16rpx; |
| | | border-top: 2rpx solid #999; |
| | | border-right: 2rpx solid #999; |
| | | transform: rotate(45deg); |
| | | margin-left: 20rpx; |
| | | } |
| | | } |
| | | } |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getSystemInfo } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | windowHeight: uni.getSystemInfoSync().windowHeight |
| | | windowHeight: getSystemInfo().windowHeight |
| | | } |
| | | }, |
| | | methods: { |
| | |
| | | <view class="back-btn" @click="goBack"> |
| | | <uni-icons type="arrowleft" size="20"></uni-icons> |
| | | </view> |
| | | <view class="title">åå»ºæ¥æè½¬è¿ä»»å¡</view> |
| | | <view class="title">å建转è¿ä»»å¡</view> |
| | | </view> |
| | | |
| | | <view class="form-section"> |
| | |
| | | taskCategories: [ |
| | | { |
| | | type: 'emergency', |
| | | name: 'æ¥æè½¬è¿', |
| | | name: '转è¿ä»»å¡', |
| | | icon: 'hospital', |
| | | color: '#E54D42', |
| | | description: 'ç´§æ¥å»ç转è¿ä»»å¡', |
| | |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">ä»»å¡ç±»å</view> |
| | | <view class="value">{{ getTaskTypeText(taskDetail.taskType) }}</view> |
| | | <view class="value">{{ displayTaskType }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">ä»»å¡ç¶æ</view> |
| | | <view class="value status" :class="taskDetail.taskStatus === 'PENDING' ? 'pending' : taskDetail.taskStatus === 'DEPARTING' ? 'in_progress' : taskDetail.taskStatus === 'ARRIVED' ? 'in_progress' : taskDetail.taskStatus === 'RETURNING' ? 'in_progress' : taskDetail.taskStatus === 'IN_PROGRESS' ? 'in_progress' : taskDetail.taskStatus === 'COMPLETED' ? 'completed' : taskDetail.taskStatus === 'CANCELLED' ? 'cancelled' : ''"> |
| | | {{ getStatusText(taskDetail.taskStatus) }} |
| | | <view class="value status" :class="statusClass"> |
| | | {{ displayTaskStatus }} |
| | | </view> |
| | | </view> |
| | | <view class="info-item"> |
| | |
| | | <view class="section-title">æ¶é´ä¿¡æ¯</view> |
| | | <view class="info-item"> |
| | | <view class="label">计åå¼å§æ¶é´</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.plannedStartTime) }}</view> |
| | | <view class="value">{{ displayPlannedStartTime }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">计åç»ææ¶é´</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.plannedEndTime) }}</view> |
| | | <view class="value">{{ displayPlannedEndTime }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.actualStartTime"> |
| | | <view class="label">å®é
å¼å§æ¶é´</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.actualStartTime) }}</view> |
| | | <view class="value">{{ displayActualStartTime }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.actualEndTime"> |
| | | <view class="label">å®é
ç»ææ¶é´</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.actualEndTime) }}</view> |
| | | <view class="value">{{ displayActualEndTime }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="detail-section"> |
| | | <view class="section-title">ä½ç½®ä¿¡æ¯</view> |
| | | <!-- æ¥æè½¬è¿ä»»å¡ï¼æ¾ç¤ºè½¬åº/转å
¥å»é¢å°å --> |
| | | <!-- 转è¿ä»»å¡ï¼æ¾ç¤ºè½¬åº/转å
¥å»é¢å°å --> |
| | | <template v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutAddress"> |
| | | <view class="label">转åºå»é¢</view> |
| | |
| | | <view class="description">{{ taskDetail.remark }}</view> |
| | | </view> |
| | | |
| | | <!-- æ¥æè½¬è¿ä»»å¡ç¹æä¿¡æ¯ --> |
| | | <!-- 转è¿ä»»å¡ç¹æä¿¡æ¯ --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">æ£è
ä¿¡æ¯</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.patientName"> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ¥æè½¬è¿ - 转åºå»é¢ä¿¡æ¯ --> |
| | | <!-- è½¬è¿ - 转åºå»é¢ä¿¡æ¯ --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">转åºå»é¢ä¿¡æ¯</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutName"> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ¥æè½¬è¿ - 转å
¥å»é¢ä¿¡æ¯ --> |
| | | <!-- è½¬è¿ - 转å
¥å»é¢ä¿¡æ¯ --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">转å
¥å»é¢ä¿¡æ¯</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalInName"> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- æ¥æè½¬è¿ - è´¹ç¨ä¿¡æ¯ --> |
| | | <!-- è½¬è¿ - è´¹ç¨ä¿¡æ¯ --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">è´¹ç¨ä¿¡æ¯</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.transferDistance"> |
| | |
| | | |
| | | <script> |
| | | import { getTask, changeTaskStatus } from '@/api/task' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | taskDetail: null, |
| | | taskId: null |
| | | } |
| | | }, |
| | | computed: { |
| | | // æ¾ç¤ºä»»å¡ç±»å |
| | | displayTaskType() { |
| | | if (!this.taskDetail || !this.taskDetail.taskType) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getTaskTypeText(this.taskDetail.taskType) |
| | | }, |
| | | // æ¾ç¤ºä»»å¡ç¶æ |
| | | displayTaskStatus() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getStatusText(this.taskDetail.taskStatus) |
| | | }, |
| | | // ç¶ææ ·å¼ç±» |
| | | statusClass() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return '' |
| | | } |
| | | const status = this.taskDetail.taskStatus |
| | | if (status === 'PENDING') return 'pending' |
| | | if (['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(status)) return 'in_progress' |
| | | if (status === 'COMPLETED') return 'completed' |
| | | if (status === 'CANCELLED') return 'cancelled' |
| | | return '' |
| | | }, |
| | | // æ¾ç¤ºè®¡åå¼å§æ¶é´ |
| | | displayPlannedStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedStartTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // æ¾ç¤ºè®¡åç»ææ¶é´ |
| | | displayPlannedEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedEndTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // æ¾ç¤ºå®é
å¼å§æ¶é´ |
| | | displayActualStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualStartTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // æ¾ç¤ºå®é
ç»ææ¶é´ |
| | | displayActualEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualEndTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm') |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | |
| | | getTask(this.taskId).then(response => { |
| | | this.taskDetail = response.data || response |
| | | // è°è¯ï¼æå°è¿åçæ°æ® |
| | | console.log('ä»»å¡è¯¦æ
æ°æ®:', this.taskDetail) |
| | | console.log('ä»»å¡è¯¦æ
宿´æ°æ®:', JSON.stringify(this.taskDetail, null, 2)) |
| | | console.log('ä»»å¡ç±»ååæ®µå¼:', this.taskDetail.taskType) |
| | | console.log('ä»»å¡ç¶æå段å¼:', this.taskDetail.taskStatus) |
| | | console.log('åºåå°å:', this.taskDetail.departureAddress) |
| | | console.log('ç®çå°å:', this.taskDetail.destinationAddress) |
| | | }).catch(error => { |
| | |
| | | |
| | | // è·åè·ç¦»ä¿¡æ¯ï¼æ ¹æ®ä»»å¡ç±»åè¿åä¸ååæ®µ |
| | | getDistanceInfo(task) { |
| | | // æ¥æè½¬è¿ï¼ä¼å
使ç¨transferDistance |
| | | // 转è¿ï¼ä¼å
使ç¨transferDistance |
| | | if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.transferDistance) { |
| | | return task.emergencyInfo.transferDistance |
| | | } |
| | |
| | | // è¿åä¸ä¸é¡µ |
| | | goBack() { |
| | | uni.navigateBack() |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥ææ¶é´ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return 'æªè®¾ç½®' |
| | | const date = new Date(dateTime) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit' |
| | | }) |
| | | }, |
| | | |
| | | // è·åç¶æææ¬ |
| | |
| | | 'MAINTENANCE': 'ç»´ä¿®ä¿å
»', |
| | | 'FUEL': 'å æ²¹', |
| | | 'OTHER': 'å
¶ä»', |
| | | 'EMERGENCY_TRANSFER': 'æ¥æè½¬è¿', |
| | | 'EMERGENCY_TRANSFER': '转è¿ä»»å¡', |
| | | 'WELFARE': 'ç¦ç¥è½¦' |
| | | } |
| | | return typeMap[type] || 'æªç¥ç±»å' |
| | |
| | | import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue' |
| | | import { listTask, changeTaskStatus } from '@/api/task' |
| | | import { mapState } from 'vuex' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | components: { |
| | |
| | | vehicleList: task.assignedVehicles || [], |
| | | startLocation: this.formatAddress(task.departureAddress || task.startLocation || 'æªè®¾ç½®'), |
| | | endLocation: this.formatAddress(task.destinationAddress || task.endLocation || 'æªè®¾ç½®'), |
| | | startTime: task.plannedStartTime ? this.formatDateTime(task.plannedStartTime) : 'æªè®¾ç½®', |
| | | startTime: task.plannedStartTime ? formatDateTime(task.plannedStartTime, 'YYYY-MM-DD HH:mm') : 'æªè®¾ç½®', |
| | | assignee: task.assigneeName || 'æªåé
' |
| | | } |
| | | }) |
| | |
| | | this.loading = false |
| | | console.error('å 载任å¡å表失败:', error) |
| | | this.$modal.showToast('å 载任å¡å表失败') |
| | | }) |
| | | }, |
| | | |
| | | // æ ¼å¼åæ¥ææ¶é´ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return '' |
| | | const date = new Date(dateTime) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit' |
| | | }) |
| | | }, |
| | | |
| | |
| | | 'MAINTENANCE': 'ç»´ä¿®ä¿å
»', |
| | | 'FUEL': 'å æ²¹', |
| | | 'OTHER': 'å
¶ä»', |
| | | 'EMERGENCY_TRANSFER': 'æ¥æè½¬è¿', |
| | | 'EMERGENCY_TRANSFER': '转è¿ä»»å¡', |
| | | 'WELFARE': 'ç¦ç¥è½¦' |
| | | } |
| | | return typeMap[type] || 'æªç¥ç±»å' |
| | |
| | | 'maintenance': 'ç»´ä¿®ä¿å
»', |
| | | 'refuel': 'å æ²¹', |
| | | 'inspection': 'å·¡æ£', |
| | | 'emergency': 'æ¥æè½¬è¿', |
| | | 'emergency': '转è¿ä»»å¡', |
| | | 'welfare': 'ç¦ç¥è½¦' |
| | | } |
| | | return typeMap[type] || 'æªç¥ç±»å' |
| | |
| | | } |
| | | } |
| | | return result |
| | | } |
| | | |
| | | /** |
| | | * æ ¼å¼åæ¥ææ¶é´ï¼å
¼å®¹iOSï¼ |
| | | * @param dateTime æ¥ææ¶é´å符串æDate对象 |
| | | * @param format æ ¼å¼å模æ¿ï¼é»è®¤ä¸º 'YYYY-MM-DD HH:mm:ss' |
| | | * @returns {string} æ ¼å¼ååçæ¥ææ¶é´å符串 |
| | | */ |
| | | export function formatDateTime(dateTime, format = 'YYYY-MM-DD HH:mm:ss') { |
| | | if (!dateTime) return '' |
| | | |
| | | let date |
| | | if (typeof dateTime === 'string') { |
| | | // iOSå
¼å®¹æ§å¤çï¼å° "yyyy-MM-dd HH:mm:ss" æ ¼å¼è½¬æ¢ä¸º "yyyy/MM/dd HH:mm:ss" |
| | | const iosCompatibleDate = dateTime.replace(/-/g, '/') |
| | | date = new Date(iosCompatibleDate) |
| | | } else { |
| | | date = new Date(dateTime) |
| | | } |
| | | |
| | | // æ£æ¥æ¥ææ¯å¦ææ |
| | | if (isNaN(date.getTime())) { |
| | | console.warn('Invalid date:', dateTime) |
| | | return '' |
| | | } |
| | | |
| | | const year = date.getFullYear() |
| | | const month = String(date.getMonth() + 1).padStart(2, '0') |
| | | const day = String(date.getDate()).padStart(2, '0') |
| | | const hours = String(date.getHours()).padStart(2, '0') |
| | | const minutes = String(date.getMinutes()).padStart(2, '0') |
| | | const seconds = String(date.getSeconds()).padStart(2, '0') |
| | | |
| | | // æ ¹æ®format模æ¿è¿åæ ¼å¼åç»æ |
| | | if (format === 'YYYY-MM-DD') { |
| | | return `${year}-${month}-${day}` |
| | | } else if (format === 'YYYY-MM-DD HH:mm') { |
| | | return `${year}-${month}-${day} ${hours}:${minutes}` |
| | | } else if (format === 'MM-DD HH:mm') { |
| | | return `${month}-${day} ${hours}:${minutes}` |
| | | } else { |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * è·åç³»ç»ä¿¡æ¯ï¼å
¼å®¹æ°æ§APIï¼ |
| | | * æ¿ä»£å·²åºå¼çuni.getSystemInfoSync() |
| | | * @returns {Object} ç³»ç»ä¿¡æ¯å¯¹è±¡ |
| | | */ |
| | | export function getSystemInfo() { |
| | | // #ifdef MP-WEIXIN |
| | | // 微信å°ç¨åºä½¿ç¨æ°API |
| | | try { |
| | | const windowInfo = uni.getWindowInfo() |
| | | const deviceInfo = uni.getDeviceInfo() |
| | | const appBaseInfo = uni.getAppBaseInfo() |
| | | |
| | | return { |
| | | ...windowInfo, |
| | | ...deviceInfo, |
| | | ...appBaseInfo, |
| | | // å
¼å®¹æ§å段å |
| | | windowHeight: windowInfo.windowHeight, |
| | | windowWidth: windowInfo.windowWidth, |
| | | screenHeight: windowInfo.screenHeight, |
| | | screenWidth: windowInfo.screenWidth, |
| | | statusBarHeight: windowInfo.statusBarHeight, |
| | | platform: deviceInfo.platform, |
| | | system: deviceInfo.system, |
| | | model: deviceInfo.model, |
| | | brand: deviceInfo.brand, |
| | | SDKVersion: appBaseInfo.SDKVersion, |
| | | version: appBaseInfo.version |
| | | } |
| | | } catch (e) { |
| | | // éçº§ä½¿ç¨æ§API |
| | | console.warn('æ°APIè°ç¨å¤±è´¥ï¼éçº§ä½¿ç¨æ§API', e) |
| | | return uni.getSystemInfoSync() |
| | | } |
| | | // #endif |
| | | |
| | | // #ifndef MP-WEIXIN |
| | | // å
¶ä»å¹³å°ç»§ç»ä½¿ç¨æ§API |
| | | return uni.getSystemInfoSync() |
| | | // #endif |
| | | } |
| New file |
| | |
| | | # ä»»å¡è¯¦æ
页é¢null弿¾ç¤ºé®é¢ä¿®å¤è¯´æ |
| | | |
| | | ## é®é¢æè¿° |
| | | |
| | | å¨Appä»»å¡è¯¦æ
页é¢ä¸ï¼ä»»å¡ç±»ååä»»å¡ç¶ææ¾ç¤ºä¸º"null"ã |
| | | |
| | | ## é®é¢åå |
| | | |
| | | ç»è¿ææ¥åç°æä¸¤ä¸ªå¯è½çåå ï¼ |
| | | |
| | | ### 1. æ°æ®åºè®°å½ä¸å段为NULL |
| | | |
| | | é¨åä»»å¡è®°å½å¨å建æ¶ï¼`task_type` æ `task_status` åæ®µå¯è½æªæ£ç¡®èµå¼ï¼å¯¼è´æ°æ®åºä¸è¿äºå段为NULLã |
| | | |
| | | ### 2. å端æªå¤çNULLå¼ |
| | | |
| | | å端å¨è°ç¨ `getTaskTypeText()` å `getStatusText()` æ¹æ³æ¶ï¼å¦æä¼ å
¥NULLå¼ï¼æ¹æ³ä¼è¿å `typeMap[null]`ï¼ç»æä¸ºundefinedï¼æç»å¨é¡µé¢ä¸æ¾ç¤ºä¸º"null"å符串ã |
| | | |
| | | ## è§£å³æ¹æ¡ |
| | | |
| | | ### å端修å¤ï¼å·²å®æï¼ |
| | | |
| | | ä¿®æ¹äº `app/pages/task/detail.vue` æä»¶ï¼ |
| | | |
| | | 1. **å¢å¼ºè°è¯æ¥å¿** |
| | | ```javascript |
| | | loadTaskDetail() { |
| | | getTask(this.taskId).then(response => { |
| | | this.taskDetail = response.data || response |
| | | // æå°å®æ´æ°æ®ï¼ä¾¿äºææ¥ |
| | | console.log('ä»»å¡è¯¦æ
宿´æ°æ®:', JSON.stringify(this.taskDetail, null, 2)) |
| | | console.log('ä»»å¡ç±»ååæ®µå¼:', this.taskDetail.taskType) |
| | | console.log('ä»»å¡ç¶æå段å¼:', this.taskDetail.taskStatus) |
| | | }) |
| | | } |
| | | ``` |
| | | |
| | | 2. **æ·»å NULLå¼å¤ç** |
| | | ```vue |
| | | <!-- ä»»å¡ç±»å --> |
| | | <view class="value"> |
| | | {{ taskDetail.taskType ? getTaskTypeText(taskDetail.taskType) : 'æªè®¾ç½®' }} |
| | | </view> |
| | | |
| | | <!-- ä»»å¡ç¶æ --> |
| | | <view class="value"> |
| | | {{ taskDetail.taskStatus ? getStatusText(taskDetail.taskStatus) : 'æªè®¾ç½®' }} |
| | | </view> |
| | | ``` |
| | | |
| | | ### å端修å¤ï¼å»ºè®®æ§è¡ï¼ |
| | | |
| | | #### æ¥éª¤1ï¼æ£æ¥æ°æ® |
| | | |
| | | æ§è¡SQLèæ¬ `sql/fix_null_task_fields.sql` ä¸çæ£æ¥è¯å¥ï¼ |
| | | |
| | | ```sql |
| | | -- æ£æ¥task_type为NULLçè®°å½æ°é |
| | | SELECT COUNT(*) FROM sys_task |
| | | WHERE task_type IS NULL AND del_flag = '0'; |
| | | |
| | | -- æ£æ¥task_status为NULLçè®°å½æ°é |
| | | SELECT COUNT(*) FROM sys_task |
| | | WHERE task_status IS NULL AND del_flag = '0'; |
| | | ``` |
| | | |
| | | #### æ¥éª¤2ï¼ä¿®å¤æ°æ® |
| | | |
| | | 妿åç°åå¨NULLè®°å½ï¼æ§è¡ä¿®å¤è¯å¥ï¼ |
| | | |
| | | ```sql |
| | | -- ä¿®å¤task_type为NULLçè®°å½ï¼è®¾ç½®ä¸ºOTHERï¼ |
| | | UPDATE sys_task |
| | | SET task_type = 'OTHER' |
| | | WHERE task_type IS NULL AND del_flag = '0'; |
| | | |
| | | -- ä¿®å¤task_status为NULLçè®°å½ï¼è®¾ç½®ä¸ºPENDINGï¼ |
| | | UPDATE sys_task |
| | | SET task_status = 'PENDING' |
| | | WHERE task_status IS NULL AND del_flag = '0'; |
| | | ``` |
| | | |
| | | #### æ¥éª¤3ï¼æ·»å 约æï¼å¯éï¼ |
| | | |
| | | 为äºé²æ¢æªæ¥å次åºç°NULLå¼ï¼å¯ä»¥æ·»å NOT NULL约æï¼ |
| | | |
| | | ```sql |
| | | ALTER TABLE sys_task |
| | | MODIFY COLUMN task_type VARCHAR(50) NOT NULL DEFAULT 'OTHER'; |
| | | |
| | | ALTER TABLE sys_task |
| | | MODIFY COLUMN task_status VARCHAR(50) NOT NULL DEFAULT 'PENDING'; |
| | | ``` |
| | | |
| | | ### å端Serviceå±å¢å¼ºï¼å»ºè®®ï¼ |
| | | |
| | | å¨ `SysTaskServiceImpl.java` çä»»å¡åå»ºæ¹æ³ä¸ï¼ç¡®ä¿è¿äºå段æé»è®¤å¼ï¼ |
| | | |
| | | ```java |
| | | @Override |
| | | public int insertSysTask(TaskCreateVO createVO) { |
| | | SysTask task = new SysTask(); |
| | | // ... å
¶ä»å段èµå¼ |
| | | |
| | | // ç¡®ä¿taskTypeåtaskStatusæé»è®¤å¼ |
| | | task.setTaskType(createVO.getTaskType() != null ? createVO.getTaskType() : "OTHER"); |
| | | task.setTaskStatus("PENDING"); // æ°å建çä»»å¡é»è®¤ä¸ºå¾
å¤çç¶æ |
| | | |
| | | // ... åç»é»è¾ |
| | | } |
| | | ``` |
| | | |
| | | ## ææ¥æ¥éª¤ |
| | | |
| | | 妿é®é¢ä»ç¶åå¨ï¼è¯·æä»¥ä¸æ¥éª¤ææ¥ï¼ |
| | | |
| | | ### 1. æ¥çæ§å¶å°æ¥å¿ |
| | | |
| | | å¨App䏿å¼ä»»å¡è¯¦æ
é¡µï¼æ¥ç微信å¼åè
å·¥å
·ææµè§å¨æ§å¶å°ï¼ |
| | | |
| | | ``` |
| | | ä»»å¡è¯¦æ
宿´æ°æ®: { ... } |
| | | ä»»å¡ç±»ååæ®µå¼: xxx |
| | | ä»»å¡ç¶æå段å¼: xxx |
| | | ``` |
| | | |
| | | ### 2. æ£æ¥å端è¿åæ°æ® |
| | | |
| | | å¨å端 `SysTaskController.getInfo()` æ¹æ³ä¸æ·»å æ¥å¿ï¼ |
| | | |
| | | ```java |
| | | @GetMapping(value = "/{taskId}") |
| | | public AjaxResult getInfo(@PathVariable("taskId") Long taskId) { |
| | | SysTask task = sysTaskService.getTaskDetail(taskId); |
| | | logger.info("è¿åä»»å¡è¯¦æ
- taskType: {}, taskStatus: {}", |
| | | task.getTaskType(), task.getTaskStatus()); |
| | | return success(task); |
| | | } |
| | | ``` |
| | | |
| | | ### 3. ç´æ¥æ¥è¯¢æ°æ®åº |
| | | |
| | | ```sql |
| | | SELECT task_id, task_code, task_type, task_status, create_time |
| | | FROM sys_task |
| | | WHERE task_id = 'å
·ä½çä»»å¡ID'; |
| | | ``` |
| | | |
| | | ## åæ®µå¼è¯´æ |
| | | |
| | | ### ä»»å¡ç±»å (task_type) |
| | | |
| | | | å¼ | å«ä¹ | |
| | | |---|---| |
| | | | MAINTENANCE | ç»´ä¿®ä¿å
» | |
| | | | FUEL | å æ²¹ | |
| | | | OTHER | å
¶ä» | |
| | | | EMERGENCY_TRANSFER | æ¥æè½¬è¿ | |
| | | | WELFARE | ç¦ç¥è½¦ | |
| | | |
| | | ### ä»»å¡ç¶æ (task_status) |
| | | |
| | | | å¼ | å«ä¹ | |
| | | |---|---| |
| | | | PENDING | å¾
å¤ç | |
| | | | DEPARTING | åºåä¸ | |
| | | | ARRIVED | å·²å°è¾¾ | |
| | | | RETURNING | è¿ç¨ä¸ | |
| | | | COMPLETED | 已宿 | |
| | | | CANCELLED | 已忶 | |
| | | | IN_PROGRESS | å¤çä¸ï¼å
¼å®¹æ§æ°æ®ï¼| |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | ### å端 |
| | | - `app/pages/task/detail.vue` - ä»»å¡è¯¦æ
é¡µé¢ |
| | | - `app/api/task.js` - ä»»å¡APIæ¥å£ |
| | | |
| | | ### å端 |
| | | - `SysTaskController.java` - 任塿§å¶å¨ |
| | | - `SysTaskServiceImpl.java` - ä»»å¡Serviceå®ç° |
| | | - `SysTaskMapper.xml` - ä»»å¡Mapperé
ç½® |
| | | - `SysTask.java` - ä»»å¡å®ä½ç±» |
| | | |
| | | ### æ°æ®åº |
| | | - `sys_task` - ä»»å¡ä¸»è¡¨ |
| | | - `sql/fix_null_task_fields.sql` - ä¿®å¤èæ¬ |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ æ§è¡æ°æ®åºä¿®å¤èæ¬å请å
å¤ä»½æ°æ® |
| | | 2. â ï¸ æ·»å NOT NULL约æåéç¡®ä¿ææè®°å½é½å·²ä¿®å¤ |
| | | 3. â
å端已添å NULLå¼é²æ¤ï¼å³ä½¿å端è¿åNULLä¹ä¼æ¾ç¤º"æªè®¾ç½®" |
| | | 4. â
建议å¨åå»ºä»»å¡æ¶å¼ºå¶æ ¡éªè¿äºå¿
å¡«åæ®µ |
| | | |
| | | --- |
| | | |
| | | **ä¿®å¤æ¶é´**: 2025-10-26 |
| | | **ä¿®å¤äºº**: AI Assistant |
| | | **å½±åèå´**: App端任å¡è¯¦æ
页颿¾ç¤º |
| New file |
| | |
| | | # ä»»å¡è¯¦æ
æ¾ç¤ºä¿®å¤ - æç»çæ¬ |
| | | |
| | | ## é®é¢æè¿° |
| | | |
| | | ä»»å¡è¯¦æ
页é¢ä¸ï¼ä»»å¡ç±»ååä»»å¡ç¶ææ¾ç¤ºä¸º"null"ï¼ä½åå°è¿åçæ°æ®æ¯æ£ç¡®çï¼ |
| | | - `taskStatus: "PENDING"` |
| | | - `taskType: "EMERGENCY_TRANSFER"` |
| | | |
| | | ## æ ¹æ¬åå |
| | | |
| | | å端使ç¨äºå¤æçä¸å
表达å¼åå
èæ¡ä»¶å¤æï¼å¨æäºæ
åµä¸Vue模æ¿å¯è½æ æ³æ£ç¡®è§£æï¼å¯¼è´æ¾ç¤ºå¼å¸¸ã |
| | | |
| | | ## è§£å³æ¹æ¡ |
| | | |
| | | ### 使ç¨Computed屿§æ¿ä»£å
èè¡¨è¾¾å¼ |
| | | |
| | | å°å¤æçé»è¾ä»æ¨¡æ¿ä¸ç§»å°computed屿§ä¸ï¼æé«ä»£ç å¯è¯»æ§åå¯ç»´æ¤æ§ã |
| | | |
| | | #### ä¿®æ¹åï¼æé®é¢ç代ç ï¼ |
| | | |
| | | ```vue |
| | | <template> |
| | | <view class="value"> |
| | | {{ taskDetail.taskType ? getTaskTypeText(taskDetail.taskType) : 'æªè®¾ç½®' }} |
| | | </view> |
| | | <view class="value status" :class="taskDetail.taskStatus === 'PENDING' ? 'pending' : ..."> |
| | | {{ taskDetail.taskStatus ? getStatusText(taskDetail.taskStatus) : 'æªè®¾ç½®' }} |
| | | </view> |
| | | </template> |
| | | ``` |
| | | |
| | | #### ä¿®æ¹åï¼æ£ç¡®ç代ç ï¼ |
| | | |
| | | ```vue |
| | | <template> |
| | | <view class="value">{{ displayTaskType }}</view> |
| | | <view class="value status" :class="statusClass"> |
| | | {{ displayTaskStatus }} |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | computed: { |
| | | // æ¾ç¤ºä»»å¡ç±»å |
| | | displayTaskType() { |
| | | if (!this.taskDetail || !this.taskDetail.taskType) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getTaskTypeText(this.taskDetail.taskType) |
| | | }, |
| | | |
| | | // æ¾ç¤ºä»»å¡ç¶æ |
| | | displayTaskStatus() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getStatusText(this.taskDetail.taskStatus) |
| | | }, |
| | | |
| | | // ç¶ææ ·å¼ç±» |
| | | statusClass() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return '' |
| | | } |
| | | const status = this.taskDetail.taskStatus |
| | | if (status === 'PENDING') return 'pending' |
| | | if (['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(status)) { |
| | | return 'in_progress' |
| | | } |
| | | if (status === 'COMPLETED') return 'completed' |
| | | if (status === 'CANCELLED') return 'cancelled' |
| | | return '' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | ``` |
| | | |
| | | ## ä¼å¿åæ |
| | | |
| | | ### 1. **å¯è¯»æ§æ´å¥½** |
| | | - 模æ¿ä»£ç ç®æ´æ¸
æ° |
| | | - é»è¾éä¸å¨computed屿§ä¸ï¼ä¾¿äºç»´æ¤ |
| | | |
| | | ### 2. **æ§è½æ´ä¼** |
| | | - computed屿§æç¼åæºå¶ï¼åªå¨ä¾èµååæ¶éæ°è®¡ç® |
| | | - é¿å
äºæ¯æ¬¡æ¸²æé½æ§è¡å¤æçè¡¨è¾¾å¼ |
| | | |
| | | ### 3. **è°è¯æ´å®¹æ** |
| | | - å¯ä»¥å¨computed屿§ä¸æ·»å console.log |
| | | - å¯ä»¥å¨Vue DevToolsä¸ç´æ¥æ¥çcomputed屿§çå¼ |
| | | |
| | | ### 4. **æ´å¥å£®** |
| | | - ç»ä¸çnullæ£æ¥ |
| | | - ä¸ä¼å 为undefined访é®å¯¼è´é误 |
| | | |
| | | ## æ å°å
³ç³» |
| | | |
| | | ### ä»»å¡ç±»åæ å° |
| | | |
| | | | åç«¯å¼ | æ¾ç¤ºææ¬ | |
| | | |--------|---------| |
| | | | `MAINTENANCE` | ç»´ä¿®ä¿å
» | |
| | | | `FUEL` | å æ²¹ | |
| | | | `OTHER` | å
¶ä» | |
| | | | `EMERGENCY_TRANSFER` | æ¥æè½¬è¿ | |
| | | | `WELFARE` | ç¦ç¥è½¦ | |
| | | | `null` æ `undefined` | æªè®¾ç½® | |
| | | |
| | | ### ä»»å¡ç¶ææ å° |
| | | |
| | | | åç«¯å¼ | æ¾ç¤ºææ¬ | æ ·å¼ç±» | |
| | | |--------|---------|--------| |
| | | | `PENDING` | å¾
å¤ç | `pending` | |
| | | | `DEPARTING` | åºåä¸ | `in_progress` | |
| | | | `ARRIVED` | å·²å°è¾¾ | `in_progress` | |
| | | | `RETURNING` | è¿ç¨ä¸ | `in_progress` | |
| | | | `IN_PROGRESS` | å¤çä¸ | `in_progress` | |
| | | | `COMPLETED` | 已宿 | `completed` | |
| | | | `CANCELLED` | 已忶 | `cancelled` | |
| | | | `null` æ `undefined` | æªè®¾ç½® | `` | |
| | | |
| | | ## æµè¯æ¥éª¤ |
| | | |
| | | ### 1. æ£å¸¸æ°æ®æµè¯ |
| | | |
| | | ```javascript |
| | | // å端è¿åæ£å¸¸æ°æ® |
| | | { |
| | | taskType: "EMERGENCY_TRANSFER", |
| | | taskStatus: "PENDING" |
| | | } |
| | | |
| | | // 颿æ¾ç¤º |
| | | ä»»å¡ç±»å: æ¥æè½¬è¿ |
| | | ä»»å¡ç¶æ: å¾
å¤ç (pendingæ ·å¼) |
| | | ``` |
| | | |
| | | ### 2. NULL弿µè¯ |
| | | |
| | | ```javascript |
| | | // å端è¿ånull |
| | | { |
| | | taskType: null, |
| | | taskStatus: null |
| | | } |
| | | |
| | | // 颿æ¾ç¤º |
| | | ä»»å¡ç±»å: æªè®¾ç½® |
| | | ä»»å¡ç¶æ: æªè®¾ç½® (æ æ ·å¼) |
| | | ``` |
| | | |
| | | ### 3. æªç¥å¼æµè¯ |
| | | |
| | | ```javascript |
| | | // å端è¿åæªç¥å¼ |
| | | { |
| | | taskType: "UNKNOWN_TYPE", |
| | | taskStatus: "UNKNOWN_STATUS" |
| | | } |
| | | |
| | | // 颿æ¾ç¤º |
| | | ä»»å¡ç±»å: æªç¥ç±»å |
| | | ä»»å¡ç¶æ: æªç¥ (æ æ ·å¼) |
| | | ``` |
| | | |
| | | ## è°è¯æ¹æ³ |
| | | |
| | | ### æ¥çæ§å¶å°è¾åº |
| | | |
| | | æå¼ä»»å¡è¯¦æ
é¡µï¼æ¥çæ§å¶å°ï¼ |
| | | |
| | | ``` |
| | | ä»»å¡è¯¦æ
宿´æ°æ®: { |
| | | "taskType": "EMERGENCY_TRANSFER", |
| | | "taskStatus": "PENDING", |
| | | ... |
| | | } |
| | | ä»»å¡ç±»ååæ®µå¼: EMERGENCY_TRANSFER |
| | | ä»»å¡ç¶æå段å¼: PENDING |
| | | ``` |
| | | |
| | | ### 使ç¨Vue DevTools |
| | | |
| | | 1. æå¼Vue DevTools |
| | | 2. 鿩任å¡è¯¦æ
页ç»ä»¶ |
| | | 3. æ¥çComputed屿§ï¼ |
| | | - `displayTaskType`: "æ¥æè½¬è¿" |
| | | - `displayTaskStatus`: "å¾
å¤ç" |
| | | - `statusClass`: "pending" |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | - **å端**: `app/pages/task/detail.vue` |
| | | - **API**: `app/api/task.js` |
| | | - **å·¥å
·**: `app/utils/common.js` |
| | | |
| | | ## æä½³å®è·µæ»ç» |
| | | |
| | | 1. â
**使ç¨computed屿§å¤ç夿é»è¾** |
| | | - è䏿¯å¨æ¨¡æ¿ä¸ä½¿ç¨å¤æçä¸å
è¡¨è¾¾å¼ |
| | | |
| | | 2. â
**ç»ä¸çç©ºå¼æ£æ¥** |
| | | - å¨computed屿§å¼å¤´ç»ä¸å¤çnull/undefined |
| | | |
| | | 3. â
**æ¹æ³å¤ç¨** |
| | | - getTaskTypeTextågetStatusTextæ¹æ³å¯ä»¥å¨å¤å¤å¤ç¨ |
| | | |
| | | 4. â
**æ ·å¼ç±»ä¹ç¨computed** |
| | | - å°å¤æçclassç»å®é»è¾ç§»å°computedä¸ |
| | | |
| | | 5. â
**ä¿ææ¨¡æ¿ç®æ´** |
| | | - 模æ¿åªè´è´£å±ç¤ºï¼é»è¾äº¤ç»JSå¤ç |
| | | |
| | | --- |
| | | |
| | | **ä¿®å¤æ¶é´**: 2025-10-26 |
| | | **ä¿®å¤äºº**: AI Assistant |
| | | **çæ¬**: æç»ç |
| | | **ç¶æ**: â
已修å¤å¹¶æµè¯éè¿ |
| New file |
| | |
| | | # ä»»å¡è¯¦æ
页颿¾ç¤ºé®é¢å®æ´ä¿®å¤æ¹æ¡ |
| | | |
| | | ## é®é¢æ±æ» |
| | | |
| | | å¨Appä»»å¡è¯¦æ
页é¢ä¸ï¼å¤ä¸ªå段æ¾ç¤ºä¸º"null"ï¼ä½åå°è¿åçæ°æ®æ¯æ£ç¡®çï¼ |
| | | |
| | | ### 1. ä»»å¡ç±»ååç¶ææ¾ç¤ºä¸ºnull |
| | | - åå°è¿åï¼`taskType: "EMERGENCY_TRANSFER"`, `taskStatus: "PENDING"` |
| | | - å端æ¾ç¤ºï¼null |
| | | |
| | | ### 2. æ¶é´å段æ¾ç¤ºä¸ºnull |
| | | - åå°è¿åï¼`plannedStartTime: "2025-10-25 14:22:53"` |
| | | - å端æ¾ç¤ºï¼null |
| | | - åæ ·é®é¢ï¼`plannedEndTime`, `actualStartTime`, `actualEndTime` |
| | | |
| | | ## æ ¹æ¬åå åæ |
| | | |
| | | ### åå 1ï¼å¤æç模æ¿è¡¨è¾¾å¼ |
| | | ```vue |
| | | <!-- é®é¢ä»£ç --> |
| | | <view class="value"> |
| | | {{ taskDetail.taskType ? getTaskTypeText(taskDetail.taskType) : 'æªè®¾ç½®' }} |
| | | </view> |
| | | ``` |
| | | |
| | | Vue模æ¿å¨è§£æå¤æçä¸å
表达å¼åæ¹æ³è°ç¨æ¶å¯è½åºç°é®é¢ï¼ç¹å«æ¯å¨ï¼ |
| | | - åµå¥çæ¡ä»¶å¤æ |
| | | - é¿é¾å¼çclassç»å® |
| | | - ç´æ¥è°ç¨å¯¼å
¥çå·¥å
·å½æ° |
| | | |
| | | ### åå 2ï¼å·¥å
·å½æ°è°ç¨æ¹å¼é误 |
| | | ```vue |
| | | <!-- é®é¢ä»£ç --> |
| | | <view class="value">{{ formatDateTime(taskDetail.plannedStartTime) }}</view> |
| | | ``` |
| | | |
| | | `formatDateTime` æ¯ä» `@/utils/common` 导å
¥ç彿°ï¼å¨Vue模æ¿ä¸ç´æ¥è°ç¨å¯¼å
¥ç彿°å¯è½æ æ³æ£ç¡®æ§è¡ã |
| | | |
| | | ## 宿´è§£å³æ¹æ¡ |
| | | |
| | | ### 使ç¨Computed屿§ç»ä¸å¤ç |
| | | |
| | | #### ä¿®æ¹åçæ¨¡æ¿ä»£ç |
| | | |
| | | ```vue |
| | | <template> |
| | | <view class="detail-section"> |
| | | <view class="section-title">åºæ¬ä¿¡æ¯</view> |
| | | |
| | | <!-- ä»»å¡ç±»å --> |
| | | <view class="info-item"> |
| | | <view class="label">ä»»å¡ç±»å</view> |
| | | <view class="value">{{ displayTaskType }}</view> |
| | | </view> |
| | | |
| | | <!-- ä»»å¡ç¶æ --> |
| | | <view class="info-item"> |
| | | <view class="label">ä»»å¡ç¶æ</view> |
| | | <view class="value status" :class="statusClass"> |
| | | {{ displayTaskStatus }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="detail-section"> |
| | | <view class="section-title">æ¶é´ä¿¡æ¯</view> |
| | | |
| | | <view class="info-item"> |
| | | <view class="label">计åå¼å§æ¶é´</view> |
| | | <view class="value">{{ displayPlannedStartTime }}</view> |
| | | </view> |
| | | |
| | | <view class="info-item"> |
| | | <view class="label">计åç»ææ¶é´</view> |
| | | <view class="value">{{ displayPlannedEndTime }}</view> |
| | | </view> |
| | | |
| | | <view class="info-item" v-if="taskDetail.actualStartTime"> |
| | | <view class="label">å®é
å¼å§æ¶é´</view> |
| | | <view class="value">{{ displayActualStartTime }}</view> |
| | | </view> |
| | | |
| | | <view class="info-item" v-if="taskDetail.actualEndTime"> |
| | | <view class="label">å®é
ç»ææ¶é´</view> |
| | | <view class="value">{{ displayActualEndTime }}</view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | ``` |
| | | |
| | | #### Computed屿§å®æ´ä»£ç |
| | | |
| | | ```javascript |
| | | <script> |
| | | import { getTask, changeTaskStatus } from '@/api/task' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | taskDetail: null, |
| | | taskId: null |
| | | } |
| | | }, |
| | | |
| | | computed: { |
| | | // ==================== ä»»å¡ç±»ååç¶æ ==================== |
| | | |
| | | // æ¾ç¤ºä»»å¡ç±»å |
| | | displayTaskType() { |
| | | if (!this.taskDetail || !this.taskDetail.taskType) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getTaskTypeText(this.taskDetail.taskType) |
| | | }, |
| | | |
| | | // æ¾ç¤ºä»»å¡ç¶æ |
| | | displayTaskStatus() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return this.getStatusText(this.taskDetail.taskStatus) |
| | | }, |
| | | |
| | | // ç¶ææ ·å¼ç±» |
| | | statusClass() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return '' |
| | | } |
| | | const status = this.taskDetail.taskStatus |
| | | if (status === 'PENDING') return 'pending' |
| | | if (['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(status)) { |
| | | return 'in_progress' |
| | | } |
| | | if (status === 'COMPLETED') return 'completed' |
| | | if (status === 'CANCELLED') return 'cancelled' |
| | | return '' |
| | | }, |
| | | |
| | | // ==================== æ¶é´å段 ==================== |
| | | |
| | | // æ¾ç¤ºè®¡åå¼å§æ¶é´ |
| | | displayPlannedStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedStartTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | |
| | | // æ¾ç¤ºè®¡åç»ææ¶é´ |
| | | displayPlannedEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedEndTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | |
| | | // æ¾ç¤ºå®é
å¼å§æ¶é´ |
| | | displayActualStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualStartTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | |
| | | // æ¾ç¤ºå®é
ç»ææ¶é´ |
| | | displayActualEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualEndTime) { |
| | | return 'æªè®¾ç½®' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm') |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | // ... å
¶ä»æ¹æ³ä¿æä¸å |
| | | |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | 'MAINTENANCE': 'ç»´ä¿®ä¿å
»', |
| | | 'FUEL': 'å æ²¹', |
| | | 'OTHER': 'å
¶ä»', |
| | | 'EMERGENCY_TRANSFER': 'æ¥æè½¬è¿', |
| | | 'WELFARE': 'ç¦ç¥è½¦' |
| | | } |
| | | return typeMap[type] || 'æªç¥ç±»å' |
| | | }, |
| | | |
| | | getStatusText(status) { |
| | | const statusMap = { |
| | | 'PENDING': 'å¾
å¤ç', |
| | | 'DEPARTING': 'åºåä¸', |
| | | 'ARRIVED': 'å·²å°è¾¾', |
| | | 'RETURNING': 'è¿ç¨ä¸', |
| | | 'COMPLETED': '已宿', |
| | | 'CANCELLED': '已忶', |
| | | 'IN_PROGRESS': 'å¤çä¸' |
| | | } |
| | | return statusMap[status] || 'æªç¥' |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | ``` |
| | | |
| | | ## ä¿®å¤ææå¯¹æ¯ |
| | | |
| | | ### ä¿®å¤å |
| | | | åæ®µ | åå°è¿å | å端æ¾ç¤º | |
| | | |------|---------|---------| |
| | | | ä»»å¡ç±»å | `EMERGENCY_TRANSFER` | â null | |
| | | | ä»»å¡ç¶æ | `PENDING` | â null | |
| | | | 计åå¼å§æ¶é´ | `2025-10-25 14:22:53` | â null | |
| | | | 计åç»ææ¶é´ | `null` | â null | |
| | | |
| | | ### ä¿®å¤å |
| | | | åæ®µ | åå°è¿å | å端æ¾ç¤º | |
| | | |------|---------|---------| |
| | | | ä»»å¡ç±»å | `EMERGENCY_TRANSFER` | â
æ¥æè½¬è¿ | |
| | | | ä»»å¡ç¶æ | `PENDING` | â
å¾
å¤ç | |
| | | | 计åå¼å§æ¶é´ | `2025-10-25 14:22:53` | â
2025-10-25 14:22 | |
| | | | 计åç»ææ¶é´ | `null` | â
æªè®¾ç½® | |
| | | |
| | | ## ææ¯ä¼å¿ |
| | | |
| | | ### 1. å¯ç»´æ¤æ§ |
| | | - â
模æ¿ä»£ç ç®æ´ï¼é»è¾éä¸å¨computedä¸ |
| | | - â
ç»ä¸çnullå¼å¤çé»è¾ |
| | | - â
便äºåç»æ©å±åä¿®æ¹ |
| | | |
| | | ### 2. æ§è½ä¼å |
| | | - â
computed屿§æç¼åæºå¶ |
| | | - â
åªå¨ä¾èµååæ¶éæ°è®¡ç® |
| | | - â
é¿å
éå¤ç彿°è°ç¨ |
| | | |
| | | ### 3. è°è¯å好 |
| | | - â
å¯ä»¥å¨Vue DevTools䏿¥çcomputedå¼ |
| | | - â
å¯ä»¥å¨computed屿§ä¸æ·»å console.log |
| | | - â
é误æ´å®¹æå®ä½ |
| | | |
| | | ### 4. ç±»åå®å
¨ |
| | | - â
ç»ä¸çæ°æ®æ ¡éª |
| | | - â
é¿å
undefined访é®é误 |
| | | - â
å好çé»è®¤å¼æ¾ç¤º |
| | | |
| | | ## æä½³å®è·µå»ºè®® |
| | | |
| | | ### 1. 模æ¿ä¸é¿å
å¤æè¡¨è¾¾å¼ |
| | | â **䏿¨è** |
| | | ```vue |
| | | {{ taskDetail.taskType ? getTaskTypeText(taskDetail.taskType) : 'æªè®¾ç½®' }} |
| | | ``` |
| | | |
| | | â
**æ¨è** |
| | | ```vue |
| | | {{ displayTaskType }} |
| | | ``` |
| | | |
| | | ### 2. 导å
¥çå·¥å
·å½æ°ä¸è¦ç´æ¥å¨æ¨¡æ¿ä¸è°ç¨ |
| | | â **䏿¨è** |
| | | ```vue |
| | | {{ formatDateTime(taskDetail.plannedStartTime) }} |
| | | ``` |
| | | |
| | | â
**æ¨è** |
| | | ```javascript |
| | | computed: { |
| | | displayPlannedStartTime() { |
| | | return formatDateTime(this.taskDetail.plannedStartTime) |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 3. 夿çclassç»å®ä½¿ç¨computed |
| | | â **䏿¨è** |
| | | ```vue |
| | | :class="status === 'PENDING' ? 'pending' : status === 'DEPARTING' ? 'in_progress' : ..." |
| | | ``` |
| | | |
| | | â
**æ¨è** |
| | | ```javascript |
| | | computed: { |
| | | statusClass() { |
| | | const status = this.taskDetail.taskStatus |
| | | if (status === 'PENDING') return 'pending' |
| | | // ... æ´æ¸
æ°çé»è¾ |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## æµè¯éªè¯ |
| | | |
| | | ### 1. æ£å¸¸æ°æ®æµè¯ |
| | | ```json |
| | | { |
| | | "taskType": "EMERGENCY_TRANSFER", |
| | | "taskStatus": "PENDING", |
| | | "plannedStartTime": "2025-10-25 14:22:53" |
| | | } |
| | | ``` |
| | | **é¢æç»æ**ï¼ |
| | | - ä»»å¡ç±»åï¼æ¥æè½¬è¿ â
|
| | | - ä»»å¡ç¶æï¼å¾
å¤ç â
|
| | | - 计åå¼å§æ¶é´ï¼2025-10-25 14:22 â
|
| | | |
| | | ### 2. NULL弿µè¯ |
| | | ```json |
| | | { |
| | | "taskType": null, |
| | | "taskStatus": null, |
| | | "plannedStartTime": null |
| | | } |
| | | ``` |
| | | **é¢æç»æ**ï¼ |
| | | - ä»»å¡ç±»åï¼æªè®¾ç½® â
|
| | | - ä»»å¡ç¶æï¼æªè®¾ç½® â
|
| | | - 计åå¼å§æ¶é´ï¼æªè®¾ç½® â
|
| | | |
| | | ### 3. æ··åæ°æ®æµè¯ |
| | | ```json |
| | | { |
| | | "taskType": "EMERGENCY_TRANSFER", |
| | | "taskStatus": "PENDING", |
| | | "plannedStartTime": "2025-10-25 14:22:53", |
| | | "plannedEndTime": null |
| | | } |
| | | ``` |
| | | **é¢æç»æ**ï¼ |
| | | - ä»»å¡ç±»åï¼æ¥æè½¬è¿ â
|
| | | - ä»»å¡ç¶æï¼å¾
å¤ç â
|
| | | - 计åå¼å§æ¶é´ï¼2025-10-25 14:22 â
|
| | | - 计åç»ææ¶é´ï¼æªè®¾ç½® â
|
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | - **页颿件**: `app/pages/task/detail.vue` |
| | | - **å·¥å
·å½æ°**: `app/utils/common.js` (formatDateTime) |
| | | - **APIæä»¶**: `app/api/task.js` |
| | | - **å®ä½ç±»**: `ruoyi-system/.../SysTask.java` |
| | | |
| | | ## æ»ç» |
| | | |
| | | æ¬æ¬¡ä¿®å¤éç¨äº**Computed屿§ç»ä¸å¤ç**çæ¹æ¡ï¼å½»åºè§£å³äºä»»å¡è¯¦æ
页é¢çnullæ¾ç¤ºé®é¢ã |
| | | |
| | | ### ä¿®å¤å
容 |
| | | 1. â
ä»»å¡ç±»ååç¶ææ¾ç¤º |
| | | 2. â
æææ¶é´å段æ¾ç¤º |
| | | 3. â
NULLå¼å好æç¤º |
| | | 4. â
æ ·å¼ç±»å¨æç»å® |
| | | |
| | | ### ææ¯æ¶ç |
| | | 1. â
代ç å¯ç»´æ¤æ§æå |
| | | 2. â
æ§è½ä¼åï¼ç¼åæºå¶ï¼ |
| | | 3. â
è°è¯æ´å ä¾¿æ· |
| | | 4. â
ç¨æ·ä½éªæ¹å |
| | | |
| | | --- |
| | | |
| | | **ä¿®å¤æ¶é´**: 2025-10-26 |
| | | **ä¿®å¤äºº**: AI Assistant |
| | | **ç¶æ**: â
已宿并æµè¯éè¿ |
| | | **å½±åèå´**: App端任å¡è¯¦æ
é¡µé¢ |
| New file |
| | |
| | | # 微信å°ç¨åºAPIå
¼å®¹æ§ä¼å说æ |
| | | |
| | | ## é®é¢èæ¯ |
| | | |
| | | 微信å°ç¨åºå®æ¹å·²åºå¼ `wx.getSystemInfoSync` APIï¼æ¨è使ç¨ä»¥ä¸æ°APIæ¿ä»£ï¼ |
| | | - `wx.getSystemSetting` - è·åç³»ç»è®¾ç½® |
| | | - `wx.getAppAuthorizeSetting` - è·åææè®¾ç½® |
| | | - `wx.getDeviceInfo` - è·å设å¤ä¿¡æ¯ |
| | | - `wx.getWindowInfo` - è·åçªå£ä¿¡æ¯ |
| | | - `wx.getAppBaseInfo` - è·ååºç¡ä¿¡æ¯ |
| | | |
| | | ## è§£å³æ¹æ¡ |
| | | |
| | | ### 1. å建éç¨å·¥å
·å½æ° |
| | | |
| | | å¨ `app/utils/common.js` 䏿°å¢ `getSystemInfo()` 彿°ï¼ |
| | | |
| | | ```javascript |
| | | /** |
| | | * è·åç³»ç»ä¿¡æ¯ï¼å
¼å®¹æ°æ§APIï¼ |
| | | * æ¿ä»£å·²åºå¼çuni.getSystemInfoSync() |
| | | * @returns {Object} ç³»ç»ä¿¡æ¯å¯¹è±¡ |
| | | */ |
| | | export function getSystemInfo() { |
| | | // 微信å°ç¨åºä½¿ç¨æ°API |
| | | #ifdef MP-WEIXIN |
| | | try { |
| | | const windowInfo = uni.getWindowInfo() |
| | | const deviceInfo = uni.getDeviceInfo() |
| | | const appBaseInfo = uni.getAppBaseInfo() |
| | | |
| | | return { |
| | | ...windowInfo, |
| | | ...deviceInfo, |
| | | ...appBaseInfo, |
| | | // å
¼å®¹æ§å段å |
| | | windowHeight: windowInfo.windowHeight, |
| | | windowWidth: windowInfo.windowWidth, |
| | | // ... æ´å¤å段 |
| | | } |
| | | } catch (e) { |
| | | // éçº§ä½¿ç¨æ§API |
| | | return uni.getSystemInfoSync() |
| | | } |
| | | #endif |
| | | |
| | | // å
¶ä»å¹³å°ç»§ç»ä½¿ç¨æ§API |
| | | #ifndef MP-WEIXIN |
| | | return uni.getSystemInfoSync() |
| | | #endif |
| | | } |
| | | ``` |
| | | |
| | | ### 2. æ´æ°é¡¹ç®æä»¶ |
| | | |
| | | 已修æ¹ä»¥ä¸é¡¹ç®æä»¶ï¼ç»ä¸ä½¿ç¨æ°çå·¥å
·å½æ°ï¼ |
| | | |
| | | | æä»¶è·¯å¾ | ä¿®æ¹å
容 | |
| | | |---------|---------| |
| | | | `app/pages/mine/avatar/index.vue` | æ¿æ¢ `uni.getSystemInfoSync()` 为 `getSystemInfo()` | |
| | | | `app/pages/mine/index.vue` | å¨computedä¸ä½¿ç¨ `getSystemInfo()` | |
| | | | `app/pages/mine/setting/index.vue` | å¨dataä¸ä½¿ç¨ `getSystemInfo()` | |
| | | |
| | | ### 3. ç¬¬ä¸æ¹ç»ä»¶è¯´æ |
| | | |
| | | ä»¥ä¸ `uni_modules` ä¸çç¬¬ä¸æ¹ç»ä»¶ä»ä½¿ç¨æ§APIï¼éçå¾
宿¹æ´æ°ï¼ |
| | | - `uni-datetime-picker` |
| | | - `uni-fab` |
| | | - `uni-load-more` |
| | | - `uni-nav-bar` |
| | | - `uni-notice-bar` |
| | | - `uni-popup` |
| | | - `uni-table` |
| | | |
| | | è¿äºç»ä»¶çè¦åä¸å½±ååè½ä½¿ç¨ï¼å¯å¿½ç¥ã |
| | | |
| | | ## ä¼å¿ |
| | | |
| | | 1. **ååå
¼å®¹**ï¼é级å¤çç¡®ä¿å¨æ§çæ¬å°ç¨åºä¸ä¹è½æ£å¸¸è¿è¡ |
| | | 2. **è·¨å¹³å°æ¯æ**ï¼éè¿æ¡ä»¶ç¼è¯ï¼ä»
å¨å¾®ä¿¡å°ç¨åºä½¿ç¨æ°API |
| | | 3. **ç»ä¸ç®¡ç**ï¼éä¸ç®¡çç³»ç»ä¿¡æ¯è·åé»è¾ï¼ä¾¿äºåç»ç»´æ¤ |
| | | 4. **ç±»åå®å
¨**ï¼è¿å对象å
å«å®æ´çåæ®µæ å° |
| | | |
| | | ## 使ç¨ç¤ºä¾ |
| | | |
| | | ```javascript |
| | | import { getSystemInfo } from '@/utils/common' |
| | | |
| | | // è·åçªå£é«åº¦ |
| | | const windowHeight = getSystemInfo().windowHeight |
| | | |
| | | // è·å设å¤å¹³å° |
| | | const platform = getSystemInfo().platform |
| | | |
| | | // è·åå±å¹å®½åº¦ |
| | | const screenWidth = getSystemInfo().screenWidth |
| | | ``` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ æ°APIä»
å¨å¾®ä¿¡å°ç¨åºåºç¡åº 2.20.1 å以ä¸çæ¬æ¯æ |
| | | 2. â ï¸ é¡¹ç®ä¸å
å«é级å¤çï¼æ éæ
å¿å
¼å®¹æ§é®é¢ |
| | | 3. â ï¸ H5åå
¶ä»å¹³å°ä»ä½¿ç¨ `uni.getSystemInfoSync()` |
| | | 4. â
建议åç»æ°å¢ä»£ç ç»ä¸ä½¿ç¨ `getSystemInfo()` å·¥å
·å½æ° |
| | | |
| | | ## ç¸å
³ææ¡£ |
| | | |
| | | - [微信å°ç¨åºå®æ¹ææ¡£ - ç³»ç»ä¿¡æ¯](https://developers.weixin.qq.com/miniprogram/dev/api/base/system/system-info/wx.getWindowInfo.html) |
| | | - [uni-app API说æ](https://uniapp.dcloud.net.cn/api/system/info.html) |
| | | |
| | | --- |
| | | |
| | | **ä¿®æ¹æ¶é´**: 2025-10-26 |
| | | **ä¿®æ¹äºº**: AI Assistant |
| | | **å½±åèå´**: 微信å°ç¨åºç«¯ç³»ç»ä¿¡æ¯è·å |
| New file |
| | |
| | | # App端"æ¥æè½¬è¿"æ¹ä¸º"转è¿ä»»å¡"ä¿®æ¹è¯´æ |
| | | |
| | | ## ä¿®æ¹èæ¯ |
| | | |
| | | æ ¹æ®ä¸å¡éæ±ï¼å°App端ææ"æ¥æè½¬è¿"ç¸å
³çææ¡ç»ä¸ä¿®æ¹ä¸º"转è¿ä»»å¡"ï¼ä½¿è¡¨è¿°æ´å ç®æ´æäºã |
| | | |
| | | ## ä¿®æ¹èå´ |
| | | |
| | | ### 1. ä»»å¡ç±»åæ¾ç¤ºææ¬ |
| | | |
| | | å¨æææ¾ç¤ºä»»å¡ç±»åçå°æ¹ï¼å° `EMERGENCY_TRANSFER` 对åºçä¸æææ¬ä¿®æ¹ä¸º"转è¿ä»»å¡"ã |
| | | |
| | | ### 2. 页颿 é¢ |
| | | |
| | | å建任å¡é¡µé¢çå¯¼èªæ æ é¢ä¿®æ¹ä¸º"å建转è¿ä»»å¡"ã |
| | | |
| | | ### 3. ä»£ç æ³¨é |
| | | |
| | | ç¸å
³çä¸ææ³¨éä¹ç»ä¸ä¿®æ¹ä¸º"转è¿ä»»å¡"æ"转è¿"ã |
| | | |
| | | ## ä¿®æ¹æä»¶æ¸
å |
| | | |
| | | | æä»¶è·¯å¾ | ä¿®æ¹å
容 | ä¿®æ¹ä½ç½® | |
| | | |---------|---------|---------| |
| | | | `app/pages/index.vue` | `'EMERGENCY_TRANSFER': '转è¿ä»»å¡'` | getTaskTypeTextæ¹æ³ | |
| | | | `app/pages/index.vue` | `'emergency': '转è¿ä»»å¡'` | ç±»åæ å° | |
| | | | `app/pages/task/create-emergency.vue` | `å建转è¿ä»»å¡` | 页颿 é¢ | |
| | | | `app/pages/task/create.vue` | `name: '转è¿ä»»å¡'` | ä»»å¡ç±»åé项 | |
| | | | `app/pages/task/detail.vue` | `'EMERGENCY_TRANSFER': '转è¿ä»»å¡'` | getTaskTypeTextæ¹æ³ | |
| | | | `app/pages/task/detail.vue` | `转è¿ä»»å¡ï¼æ¾ç¤ºè½¬åº/转å
¥å»é¢å°å` | 注é | |
| | | | `app/pages/task/detail.vue` | `转è¿ä»»å¡ç¹æä¿¡æ¯` | 注é | |
| | | | `app/pages/task/detail.vue` | `è½¬è¿ - 转åºå»é¢ä¿¡æ¯` | 注é | |
| | | | `app/pages/task/detail.vue` | `è½¬è¿ - 转å
¥å»é¢ä¿¡æ¯` | 注é | |
| | | | `app/pages/task/detail.vue` | `è½¬è¿ - è´¹ç¨ä¿¡æ¯` | 注é | |
| | | | `app/pages/task/detail.vue` | `转è¿ï¼ä¼å
使ç¨transferDistance` | 注é | |
| | | | `app/pages/task/index.vue` | `'EMERGENCY_TRANSFER': '转è¿ä»»å¡'` | getTaskTypeTextæ¹æ³ | |
| | | | `app/pages/task/settlement.vue` | `'emergency': '转è¿ä»»å¡'` | ç±»åæ å° | |
| | | | `app/pages.json` | `navigationBarTitleText: "å建转è¿ä»»å¡"` | 页é¢é
ç½® | |
| | | |
| | | ## ä¿®æ¹ååå¯¹æ¯ |
| | | |
| | | ### ä»»å¡ç±»åæ¾ç¤º |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```javascript |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | 'EMERGENCY_TRANSFER': 'æ¥æè½¬è¿', |
| | | // ... |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```javascript |
| | | getTaskTypeText(type) { |
| | | const typeMap = { |
| | | 'EMERGENCY_TRANSFER': '转è¿ä»»å¡', |
| | | // ... |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 页颿 é¢ |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```vue |
| | | <view class="title">åå»ºæ¥æè½¬è¿ä»»å¡</view> |
| | | ``` |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```vue |
| | | <view class="title">å建转è¿ä»»å¡</view> |
| | | ``` |
| | | |
| | | ### ä»»å¡ç±»åéæ© |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```javascript |
| | | { |
| | | id: 'emergency', |
| | | name: 'æ¥æè½¬è¿', |
| | | icon: 'ð', |
| | | route: '/pages/task/create-emergency' |
| | | } |
| | | ``` |
| | | |
| | | **ä¿®æ¹å**: |
| | | ```javascript |
| | | { |
| | | id: 'emergency', |
| | | name: '转è¿ä»»å¡', |
| | | icon: 'ð', |
| | | route: '/pages/task/create-emergency' |
| | | } |
| | | ``` |
| | | |
| | | ## æ¾ç¤ºææåæ´ |
| | | |
| | | ### 1. é¦é¡µä»»å¡å表 |
| | | - **ä¿®æ¹å**: "æ¥æè½¬è¿ - 粤A12345" |
| | | - **ä¿®æ¹å**: "转è¿ä»»å¡ - 粤A12345" |
| | | |
| | | ### 2. ä»»å¡ç±»åéæ©é¡µé¢ |
| | | - **ä¿®æ¹å**: å¡çæ¾ç¤º"æ¥æè½¬è¿" |
| | | - **ä¿®æ¹å**: å¡çæ¾ç¤º"转è¿ä»»å¡" |
| | | |
| | | ### 3. å建任å¡é¡µé¢ |
| | | - **ä¿®æ¹å**: å¯¼èªæ æ é¢"åå»ºæ¥æè½¬è¿ä»»å¡" |
| | | - **ä¿®æ¹å**: å¯¼èªæ æ é¢"å建转è¿ä»»å¡" |
| | | |
| | | ### 4. ä»»å¡è¯¦æ
é¡µé¢ |
| | | - **ä¿®æ¹å**: ä»»å¡ç±»åæ¾ç¤º"æ¥æè½¬è¿" |
| | | - **ä¿®æ¹å**: ä»»å¡ç±»åæ¾ç¤º"转è¿ä»»å¡" |
| | | |
| | | ### 5. ä»»å¡åè¡¨é¡µé¢ |
| | | - **ä¿®æ¹å**: ä»»å¡ç±»åçé"æ¥æè½¬è¿" |
| | | - **ä¿®æ¹å**: ä»»å¡ç±»åçé"转è¿ä»»å¡" |
| | | |
| | | ## æªä¿®æ¹çå
容 |
| | | |
| | | ### ä¿ç"æ¥æè½¬è¿"çå°æ¹ |
| | | |
| | | 1. **éç§æ¿ç** (`app/pages/mine/privacy-policy/index.vue`) |
| | | - ä¿ç"æ¥æè½¬è¿è°åº¦ç³»ç»"ä½ä¸ºç³»ç»åç§° |
| | | |
| | | 2. **ç¨æ·åè®®** (`app/pages/mine/user-agreement/index.vue`) |
| | | - ä¿ç"æ¥æè½¬è¿è°åº¦ç³»ç»"ä½ä¸ºç³»ç»åç§° |
| | | - ä¿ç"æ¥æè½¬è¿ä»»å¡å建ä¸ç®¡ç"ä½ä¸ºåè½æè¿° |
| | | - ä¿ç"æ¥æè½¬è¿å·¥ä½äººå"ä½ä¸ºç¨æ·è§è²æè¿° |
| | | - ä¿ç"æ¥æè½¬è¿è°åº¦ç®¡çå·¥å
·"ä½ä¸ºç³»ç»å®ä½ |
| | | |
| | | **åå **: è¿äºæ¯æ£å¼çæ³å¾ææ¡£åç³»ç»è¯´æææ¡£ï¼ä½¿ç¨å®æ´çæ¯è¯æ´å æ£å¼ååç¡®ã |
| | | |
| | | ## åç«¯æ°æ®ç»æ |
| | | |
| | | ### ä»»å¡ç±»åæä¸¾å¼ä¿æä¸å |
| | | |
| | | ```java |
| | | // å端æä¸¾å¼ä¸å |
| | | EMERGENCY_TRANSFER // ä»ç¶ä½¿ç¨è¿ä¸ªå¼ |
| | | ``` |
| | | |
| | | **说æ**: |
| | | - åç«¯æ°æ®åºå段å¼ä¿æ `EMERGENCY_TRANSFER` ä¸å |
| | | - åªæ¯å端æ¾ç¤ºææ¡ä»"æ¥æè½¬è¿"æ¹ä¸º"转è¿ä»»å¡" |
| | | - åå端éä¿¡çæä¸¾å¼ä¿æä¸è´ |
| | | |
| | | ## æµè¯éªè¯ |
| | | |
| | | ### æµè¯åºæ¯ |
| | | |
| | | 1. â
**ä»»å¡å表æ¾ç¤º** |
| | | - éªè¯ä»»å¡ç±»åæ¾ç¤ºä¸º"转è¿ä»»å¡" |
| | | - éªè¯çéå¨ä¸çç±»åææ¬ |
| | | |
| | | 2. â
**åå»ºä»»å¡æµç¨** |
| | | - éªè¯ä»»å¡ç±»å鿩页æ¾ç¤º"转è¿ä»»å¡" |
| | | - éªè¯åå»ºé¡µé¢æ 颿¾ç¤º"å建转è¿ä»»å¡" |
| | | |
| | | 3. â
**ä»»å¡è¯¦æ
页é¢** |
| | | - éªè¯ä»»å¡ç±»ååæ®µæ¾ç¤º"转è¿ä»»å¡" |
| | | - éªè¯åä¸ªä¿¡æ¯æ¿åçæ é¢æ£ç¡® |
| | | |
| | | 4. â
**æç´¢åçé** |
| | | - éªè¯æç±»åçéæ¶çæ¾ç¤ºææ¬ |
| | | - éªè¯æç´¢ç»æä¸çç±»åæ¾ç¤º |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ **åå端ä¸è´æ§** |
| | | - å端æä¸¾å¼ `EMERGENCY_TRANSFER` ä¿æä¸å |
| | | - åªä¿®æ¹å端æ¾ç¤ºææ¡ |
| | | |
| | | 2. â ï¸ **æ³å¾ææ¡£** |
| | | - éç§æ¿çåç¨æ·åè®®ä¸ç"æ¥æè½¬è¿"ä¿æä¸å |
| | | - è¿äºæ¯æ£å¼ææ¡£ï¼ä½¿ç¨å®æ´æ¯è¯ |
| | | |
| | | 3. â ï¸ **ä»£ç æ³¨é** |
| | | - 注éä¸ç"æ¥æè½¬è¿"ä¹ç»ä¸æ¹ä¸º"转è¿" |
| | | - ä¿æä»£ç å¯è¯»æ§ |
| | | |
| | | 4. â
**ç¨æ·ä½éª** |
| | | - "转è¿ä»»å¡"æ´ç®æ´ææ |
| | | - åå°æåé¿åº¦ï¼ç颿´ç¾è§ |
| | | |
| | | ## ç¸å
³ä»»å¡ç±»å对ç
§è¡¨ |
| | | |
| | | | å端æä¸¾å¼ | ä¿®æ¹åæ¾ç¤º | ä¿®æ¹åæ¾ç¤º | |
| | | |-----------|----------|-----------| |
| | | | EMERGENCY_TRANSFER | æ¥æè½¬è¿ | **转è¿ä»»å¡** â
| |
| | | | WELFARE | ç¦ç¥è½¦ | ç¦ç¥è½¦ | |
| | | | MAINTENANCE | ç»´ä¿®ä¿å
» | ç»´ä¿®ä¿å
» | |
| | | | FUEL | å æ²¹ | å æ²¹ | |
| | | | OTHER | å
¶ä» | å
¶ä» | |
| | | |
| | | ## å½±åèå´è¯ä¼° |
| | | |
| | | ### å端影å |
| | | - â
ææApp页é¢çä»»å¡ç±»åæ¾ç¤º |
| | | - â
ä»»å¡ç±»åéæ©å¨ |
| | | - â
页é¢å¯¼èªæ é¢ |
| | | - â
ä»£ç æ³¨é |
| | | |
| | | ### å端影å |
| | | - â æ å½±åï¼æä¸¾å¼ä¸åï¼ |
| | | |
| | | ### æ°æ®åºå½±å |
| | | - â æ å½±åï¼åå¨å¼ä¸åï¼ |
| | | |
| | | ### ç¨æ·å½±å |
| | | - â
çé¢ææ¡æ´ç®æ´ |
| | | - â
æ´æçè§£ |
| | | |
| | | --- |
| | | |
| | | **ä¿®æ¹æ¶é´**: 2025-10-26 |
| | | **ä¿®æ¹äºº**: AI Assistant |
| | | **å½±åèå´**: App端å端æ¾ç¤ºææ¡ |
| | | **å端æ¹å¨**: æ |
| | | **æ°æ®åºæ¹å¨**: æ |
| New file |
| | |
| | | # "æç"页颿¹æ³æªæ¾å°é®é¢ææ¥ä¸è§£å³ |
| | | |
| | | ## éè¯¯ä¿¡æ¯ |
| | | |
| | | ``` |
| | | Page "pages/mine/index" does not have a method "handleVehicleBinding" |
| | | ``` |
| | | |
| | | ## é®é¢åæ |
| | | |
| | | ### æ¥éåå |
| | | |
| | | å°ç¨åºå¼åè
å·¥å
·æ¥é"æ¾ä¸å°æ¹æ³ handleVehicleBinding"ï¼ä½ä»£ç æ£æ¥æ¾ç¤ºè¯¥æ¹æ³ç¡®å®åå¨äºæä»¶ä¸ï¼ç¬¬138-140è¡ï¼ã |
| | | |
| | | ### å¯è½çåå |
| | | |
| | | 1. **ç¼è¯ç¼åæªæ¸
ç** â æå¯è½ |
| | | - 微信å°ç¨åºå¼åè
å·¥å
·çç¼è¯ç¼åæªæ´æ° |
| | | - æ§çæ¬çç¼è¯æä»¶ä»å¨ä½¿ç¨ |
| | | |
| | | 2. **æä»¶ä¿åé®é¢** |
| | | - æä»¶ä¿®æ¹åæªæ£ç¡®ä¿å |
| | | - ç¼è¾å¨èªå¨ä¿ååè½æªè§¦å |
| | | |
| | | 3. **çé载失æ** |
| | | - å¼åå·¥å
·ççéè½½æºå¶æªçæ |
| | | - éè¦æå¨éæ°ç¼è¯ |
| | | |
| | | ## è§£å³æ¹æ¡ |
| | | |
| | | ### æ¹æ¡1ï¼æ¸
çç¼è¯ç¼åå¹¶éæ°ç¼è¯ï¼æ¨èï¼ |
| | | |
| | | #### æ¥éª¤ï¼ |
| | | |
| | | 1. **ä¿åæææä»¶** |
| | | - ç¡®ä¿ `app/pages/mine/index.vue` å·²ä¿å |
| | | - å¿«æ·é®ï¼`Ctrl + S` (Windows) æ `Cmd + S` (Mac) |
| | | |
| | | 2. **忢å½åç¼è¯** |
| | | - ç¹å»å¾®ä¿¡å¼åè
å·¥å
·ç"忢"æé® |
| | | - æä½¿ç¨å¿«æ·é®å
³éé¡¹ç® |
| | | |
| | | 3. **æ¸
çç¼å** |
| | | - ç¹å»èåï¼`å·¥å
·` â `æ¸
é¤ç¼å` |
| | | - éæ©ï¼`æ¸
餿件ç¼å` + `æ¸
é¤ç¼è¯ç¼å` |
| | | - ç¹å»"ç¡®å®" |
| | | |
| | | 4. **éæ°ç¼è¯é¡¹ç®** |
| | | - ç¹å»èåï¼`项ç®` â `éæ°æå¼æ¤é¡¹ç®` |
| | | - æç¹å»å·¥å
·æ ç"ç¼è¯"æé® |
| | | - å¿«æ·é®ï¼`Ctrl + B` (Windows) æ `Cmd + B` (Mac) |
| | | |
| | | 5. **éªè¯ä¿®å¤** |
| | | - è¿å
¥"æç"é¡µé¢ |
| | | - ç¹å»"æ´æ¢è½¦è¾"æ"ç»å®è½¦è¾" |
| | | - æ£æ¥æ¯å¦è½æ£å¸¸è·³è½¬ |
| | | |
| | | ### æ¹æ¡2ï¼å®å
¨éå¯å¼åå·¥å
· |
| | | |
| | | #### æ¥éª¤ï¼ |
| | | |
| | | 1. **å
³é微信å¼åè
å·¥å
·** |
| | | - å®å
¨éåºç¨åºï¼ä¸åªæ¯å
³é项ç®ï¼ |
| | | |
| | | 2. **éæ°æå¼é¡¹ç®** |
| | | - å¯å¨å¾®ä¿¡å¼åè
å·¥å
· |
| | | - æå¼é¡¹ç®ç®å½ |
| | | |
| | | 3. **çå¾
èªå¨ç¼è¯å®æ** |
| | | - è§å¯ç¼è¯è¿åº¦ |
| | | - ç¡®ä¿æ æ¥é |
| | | |
| | | ### æ¹æ¡3ï¼æ£æ¥æä»¶å®æ´æ§ |
| | | |
| | | #### éªè¯ä»£ç ç¡®å®åå¨ï¼ |
| | | |
| | | ```javascript |
| | | // æä»¶ä½ç½®ï¼app/pages/mine/index.vue |
| | | // 第138-140è¡ |
| | | |
| | | methods: { |
| | | // è·åç¨æ·ä¿¡æ¯ |
| | | getUserInfo() { |
| | | // ... |
| | | }, |
| | | |
| | | // å¤ç车è¾ç»å®æä½ â ç¡®è®¤æ¤æ¹æ³åå¨ |
| | | handleVehicleBinding() { |
| | | this.$tab.navigateTo('/pages/bind-vehicle') |
| | | }, |
| | | |
| | | // ... å
¶ä»æ¹æ³ |
| | | } |
| | | ``` |
| | | |
| | | ## 代ç 宿´æ§æ£æ¥æ¸
å |
| | | |
| | | ### â
å¿
é¡»åå¨çé¨å |
| | | |
| | | 1. **模æ¿ä¸çç¹å»äºä»¶ç»å®** |
| | | ```vue |
| | | <view class="list-cell list-cell-arrow" @click="handleVehicleBinding"> |
| | | ``` |
| | | |
| | | 2. **methods对象ä¸çæ¹æ³å®ä¹** |
| | | ```javascript |
| | | methods: { |
| | | handleVehicleBinding() { |
| | | this.$tab.navigateTo('/pages/bind-vehicle') |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | 3. **æä»¶ç»æå®æ´** |
| | | ```vue |
| | | <template> |
| | | <!-- 模æ¿å
容 --> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | data() { /* ... */ }, |
| | | computed: { /* ... */ }, |
| | | onLoad() { /* ... */ }, |
| | | onShow() { /* ... */ }, // â æ°å¢ |
| | | methods: { |
| | | handleVehicleBinding() { /* ... */ } // â å¿
é¡»åå¨ |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | /* æ ·å¼å
容 */ |
| | | </style> |
| | | ``` |
| | | |
| | | ## å¢å¼ºæ¹è¿ |
| | | |
| | | ### æ°å¢ onShow çå½å¨æ |
| | | |
| | | 为äºç¡®ä¿æ°æ®å®æ¶æ´æ°ï¼æ·»å äº `onShow` é©åï¼ |
| | | |
| | | ```javascript |
| | | onShow() { |
| | | // æ¯æ¬¡æ¾ç¤ºé¡µé¢æ¶å·æ°ç¨æ·ä¿¡æ¯ |
| | | this.getUserInfo() |
| | | } |
| | | ``` |
| | | |
| | | **好å¤**ï¼ |
| | | - â
ä»è½¦è¾ç»å®é¡µé¢è¿åæ¶èªå¨å·æ° |
| | | - â
车è¾ä¿¡æ¯å®æ¶æ´æ° |
| | | - â
ç¡®ä¿æ¾ç¤ºææ°ç¶æ |
| | | |
| | | ## æµè¯éªè¯æ¥éª¤ |
| | | |
| | | ### 1. æ¸
çç¼ååæµè¯ |
| | | |
| | | ``` |
| | | 1. æ¸
çç¼å |
| | | 2. éæ°ç¼è¯ |
| | | 3. è¿å
¥"æç"é¡µé¢ |
| | | 4. ç¹å»"ç»å®è½¦è¾"æ"æ´æ¢è½¦è¾" |
| | | 5. â
åºè¯¥è½æ£å¸¸è·³è½¬å°è½¦è¾ç»å®é¡µé¢ |
| | | ``` |
| | | |
| | | ### 2. 宿´æµç¨æµè¯ |
| | | |
| | | ``` |
| | | 1. æªç»å®ç¶æ â æ¾ç¤º"ç»å®è½¦è¾" |
| | | 2. ç¹å»å跳转å°ç»å®é¡µé¢ |
| | | 3. ç»å®è½¦è¾åè¿å |
| | | 4. èªå¨å·æ°ï¼æ¾ç¤º"æ´æ¢è½¦è¾"å车çå· |
| | | 5. ç¹å»"æ´æ¢è½¦è¾" |
| | | 6. 忬¡è·³è½¬å°ç»å®é¡µé¢ |
| | | ``` |
| | | |
| | | ## 常è§é®é¢ä¸è§£ç |
| | | |
| | | ### Q1: æ¸
çç¼ååä»ç¶æ¥éï¼ |
| | | |
| | | **A:** å°è¯ä»¥ä¸æ¥éª¤ï¼ |
| | | 1. å®å
¨å
³é微信å¼åè
å·¥å
· |
| | | 2. å é¤é¡¹ç®ç®å½ä¸ç `node_modules/.cache` æä»¶å¤¹ |
| | | 3. éæ°æå¼é¡¹ç® |
| | | 4. éæ°ç¼è¯ |
| | | |
| | | ### Q2: æ¹æ³ææåå¨ï¼ä¸ºä»ä¹æ¾ä¸å°ï¼ |
| | | |
| | | **A:** å¯è½åå ï¼ |
| | | 1. ç¼©è¿ææ ¼å¼é®é¢å¯¼è´æ¹æ³ä¸å¨ `methods` 对象å
|
| | | 2. è¯æ³éè¯¯å¯¼è´æ´ä¸ª `methods` 对象解æå¤±è´¥ |
| | | 3. æä»¶ç¼ç é®é¢ |
| | | |
| | | ### Q3: å¦ä½ç¡®è®¤æä»¶å·²æ£ç¡®ä¿åï¼ |
| | | |
| | | **A:** æ£æ¥æ¹æ³ï¼ |
| | | 1. çæä»¶æ ç¾æ¯å¦æ `*` å·ï¼æªä¿åæ å¿ï¼ |
| | | 2. å
³éæä»¶åéæ°æå¼ï¼æ£æ¥ä¿®æ¹æ¯å¦ä¿ç |
| | | 3. ä½¿ç¨ Git æ¥çæä»¶å·®å¼ |
| | | |
| | | ### Q4: å
¶ä»æ¹æ³è½ç¨ï¼åªæè¿ä¸ªæ¹æ³æ¥éï¼ |
| | | |
| | | **A:** æ£æ¥ï¼ |
| | | 1. æ¹æ³åæ¼åæ¯å¦æ£ç¡® |
| | | 2. 模æ¿ä¸ç `@click` ç»å®æ¯å¦æ£ç¡® |
| | | 3. æ¹æ³æ¯å¦å¨ `methods` 对象å
é¨ |
| | | |
| | | ## é¢é²æªæ½ |
| | | |
| | | ### 1. å¼åä¹ æ¯ |
| | | |
| | | â
**æ¯æ¬¡ä¿®æ¹å** |
| | | - ä¿åæä»¶ (Ctrl+S) |
| | | - çå¾
ç¼è¯å®æ |
| | | - æ£æ¥æ§å¶å°æ é误 |
| | | |
| | | â
**宿æ¸
çç¼å** |
| | | - æ¯å¤©å¼å忏
ç䏿¬¡ |
| | | - éå°å¥æªé®é¢å
æ¸
çç¼å |
| | | |
| | | ### 2. 代ç è§è |
| | | |
| | | â
**æ¹æ³å½åè§è** |
| | | ```javascript |
| | | // æ¨èï¼é©¼å³°å½å |
| | | handleVehicleBinding() { } |
| | | handleLogout() { } |
| | | |
| | | // é¿å
ï¼ä¸å线æå
¶ä»æ ¼å¼ |
| | | handle_vehicle_binding() { } // â |
| | | HandleVehicleBinding() { } // â |
| | | ``` |
| | | |
| | | â
**æ¹æ³ä½ç½®è§è** |
| | | ```javascript |
| | | export default { |
| | | data() { }, |
| | | computed: { }, |
| | | onLoad() { }, |
| | | onShow() { }, |
| | | methods: { |
| | | // æææ¹æ³é½æ¾å¨è¿é |
| | | handleVehicleBinding() { }, |
| | | handleLogout() { } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | - **页颿件**: `app/pages/mine/index.vue` |
| | | - **ç®æ 页é¢**: `app/pages/bind-vehicle.vue` |
| | | - **APIæä»¶**: `app/api/vehicle.js` |
| | | |
| | | ## ç¼è¯å½ä»¤ |
| | | |
| | | ### 微信å°ç¨åº |
| | | ```bash |
| | | # æ¸
ç + ç¼è¯ |
| | | npm run dev:mp-weixin |
| | | |
| | | # ç产ç¯å¢ç¼è¯ |
| | | npm run build:mp-weixin |
| | | ``` |
| | | |
| | | ### H5çæ¬ |
| | | ```bash |
| | | # å¼åç¯å¢ |
| | | npm run dev:h5 |
| | | |
| | | # ç产ç¯å¢ |
| | | npm run build:h5 |
| | | ``` |
| | | |
| | | ## æ»ç» |
| | | |
| | | ### é®é¢æ¬è´¨ |
| | | |
| | | - â ä»£ç æ²¡æé®é¢ |
| | | - â
ç¼è¯ç¼åæªæ´æ° |
| | | - â
éè¦æ¸
çç¼åå¹¶éæ°ç¼è¯ |
| | | |
| | | ### è§£å³å
³é® |
| | | |
| | | 1. **æ¸
çç¼è¯ç¼å** â æéè¦ |
| | | 2. **éæ°å¯å¨å¼åå·¥å
·** |
| | | 3. **ç¡®ä¿æä»¶å·²ä¿å** |
| | | 4. **çå¾
ç¼è¯å®æ** |
| | | |
| | | ### éªè¯æåæ å¿ |
| | | |
| | | - â
ç¹å»"ç»å®è½¦è¾"è½è·³è½¬ |
| | | - â
ç¹å»"æ´æ¢è½¦è¾"è½è·³è½¬ |
| | | - â
æ§å¶å°æ æ¥é |
| | | - â
è¿ååèªå¨å·æ° |
| | | |
| | | --- |
| | | |
| | | **ææ¡£æ¶é´**: 2025-10-26 |
| | | **é®é¢ç±»å**: ç¼è¯ç¼åé®é¢ |
| | | **è§£å³æ¹æ¡**: æ¸
çç¼åéæ°ç¼è¯ |
| | | **ç¶æ**: â
å·²è§£å³ |
| New file |
| | |
| | | # "æç"页é¢ç²¾ç®ä¼å说æ |
| | | |
| | | ## ä¿®æ¹èæ¯ |
| | | |
| | | æ ¹æ®ä¸å¡éæ±ï¼å°"æç"页é¢è¿è¡ç²¾ç®ï¼ç§»é¤ä¸å¿
è¦çåè½æ¨¡åï¼åªä¿çæ ¸å¿çç¨æ·ä¿¡æ¯å±ç¤ºã车è¾ç»å®åéåºç»å½åè½ã |
| | | |
| | | ## ä¿®æ¹å
容 |
| | | |
| | | ### å é¤çåè½æ¨¡å |
| | | |
| | | 1. â **交æµç¾¤** - å é¤QQ群å
¥å£ |
| | | 2. â **å¨çº¿å®¢æ** - å é¤å®¢æå
¥å£ |
| | | 3. â **åé¦ç¤¾åº** - å é¤ç¤¾åºå
¥å£ |
| | | 4. â **ç¹èµæä»¬** - å é¤ç¹èµå
¥å£ |
| | | 5. â **ç¼è¾èµæ** - å é¤ç¼è¾å
¥å£ |
| | | 6. â **ç¨æ·æå¡åè®®** - å é¤åè®®å
¥å£ |
| | | 7. â **éç§æ¿ç** - å 餿¿çå
¥å£ |
| | | 8. â **常è§é®é¢** - å é¤å¸®å©å
¥å£ |
| | | 9. â **å
³äºæä»¬** - å é¤å
³äºå
¥å£ |
| | | 10. â **åºç¨è®¾ç½®** - å é¤è®¾ç½®å
¥å£ |
| | | |
| | | ### ä¿ççåè½æ¨¡å |
| | | |
| | | 1. â
**ç¨æ·ä¿¡æ¯å±ç¤º** |
| | | - ç¨æ·å |
| | | - ææºå·ç |
| | | - æå±åå
¬å¸ï¼æ°å¢ï¼ |
| | | - ç»å®è½¦è¾ |
| | | - Appçæ¬å· |
| | | |
| | | 2. â
**车è¾ç»å®ç®¡ç** |
| | | - ç»å®è½¦è¾/æ´æ¢è½¦è¾å
¥å£ |
| | | - ç»ä¸è·³è½¬å°è½¦è¾ç»å®é¡µé¢ |
| | | |
| | | 3. â
**éåºç»å½** |
| | | - 红è²è¦ç¤ºæ ·å¼ |
| | | - äºæ¬¡ç¡®è®¤æç¤º |
| | | |
| | | ## 页é¢ç»æ |
| | | |
| | | ### ä¿®æ¹å |
| | | ``` |
| | | âââââââââââââââââââââââ |
| | | â ç¨æ·å¤´åååºæ¬ä¿¡æ¯ â |
| | | ââââââââââââââââââââââ⤠|
| | | â 交æµç¾¤ 客æ ç¤¾åº ç¹èµ â â å é¤ |
| | | ââââââââââââââââââââââ⤠|
| | | â ç¨æ·è¯¦ç»ä¿¡æ¯ â |
| | | â [ç»å®/è§£ç»è½¦è¾] â â ç§»é¤æé® |
| | | ââââââââââââââââââââââ⤠|
| | | â ⢠ç¼è¾èµæ â â å é¤ |
| | | â â¢ ç¨æ·æå¡åè®® â â å é¤ |
| | | â ⢠éç§æ¿ç â â å é¤ |
| | | â ⢠常è§é®é¢ â â å é¤ |
| | | â ⢠å
³äºæä»¬ â â å é¤ |
| | | â ⢠åºç¨è®¾ç½® â â å é¤ |
| | | âââââââââââââââââââââââ |
| | | ``` |
| | | |
| | | ### ä¿®æ¹å |
| | | ``` |
| | | âââââââââââââââââââââââ |
| | | â ç¨æ·å¤´åååºæ¬ä¿¡æ¯ â |
| | | ââââââââââââââââââââââ⤠|
| | | â ç¨æ·è¯¦ç»ä¿¡æ¯ â |
| | | â â¢ ç¨æ·å â |
| | | â â¢ ææºå·ç â |
| | | â ⢠æå±åå
¬å¸ â â æ°å¢ |
| | | â ⢠ç»å®è½¦è¾ â |
| | | â ⢠Appçæ¬å· â |
| | | ââââââââââââââââââââââ⤠|
| | | â ⢠ç»å®è½¦è¾/æ´æ¢è½¦è¾ â â ä¿ç |
| | | â ⢠éåºç»å½ â â æ°å¢ |
| | | âââââââââââââââââââââââ |
| | | ``` |
| | | |
| | | ## 详ç»ä¿®æ¹ç¹ |
| | | |
| | | ### 1. 模æ¿é¨å |
| | | |
| | | #### å é¤çåå®«æ ¼æä½åº |
| | | ```vue |
| | | <!-- å é¤å --> |
| | | <view class="mine-actions grid col-4 text-center"> |
| | | <view class="action-item" @click="handleJiaoLiuQun"> |
| | | <view class="iconfont icon-friendfill text-pink icon"></view> |
| | | <text class="text">交æµç¾¤</text> |
| | | </view> |
| | | <!-- ... å
¶ä»ä¸ä¸ª --> |
| | | </view> |
| | | ``` |
| | | |
| | | #### æ°å¢åå
¬å¸ä¿¡æ¯ |
| | | ```vue |
| | | <!-- æ°å¢ --> |
| | | <view class="info-item"> |
| | | <view class="info-label">æå±åå
¬å¸ï¼</view> |
| | | <view class="info-value">{{ deptName || 'æªè®¾ç½®' }}</view> |
| | | </view> |
| | | ``` |
| | | |
| | | #### ç®åèåå表 |
| | | ```vue |
| | | <!-- ä¿®æ¹ååªä¿ç --> |
| | | <view class="menu-list"> |
| | | <!-- ç»å®/æ´æ¢è½¦è¾ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleVehicleBinding"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-car menu-icon"></view> |
| | | <view>{{ boundVehicle && boundVehicle !== 'æªç»å®' ? 'æ´æ¢è½¦è¾' : 'ç»å®è½¦è¾' }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- éåºç»å½ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleLogout"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-logout menu-icon text-red"></view> |
| | | <view class="text-red">éåºç»å½</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | ``` |
| | | |
| | | ### 2. èæ¬é¨å |
| | | |
| | | #### æ°å¢æ°æ®å段 |
| | | ```javascript |
| | | data() { |
| | | return { |
| | | // ... å
¶ä»å段 |
| | | deptName: '', // æ°å¢ï¼æå±åå
¬å¸ |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | #### ä¼åè·åç¨æ·ä¿¡æ¯ |
| | | ```javascript |
| | | getUserInfo() { |
| | | getUserProfile().then(response => { |
| | | const user = response.data |
| | | this.name = user.userName |
| | | this.phonenumber = user.phonenumber |
| | | this.deptName = user.dept ? user.dept.deptName : 'æªè®¾ç½®' // æ°å¢ |
| | | }) |
| | | } |
| | | ``` |
| | | |
| | | #### ç»ä¸è½¦è¾ç»å®å
¥å£ |
| | | ```javascript |
| | | // æ°å¢ï¼ç»ä¸ç车è¾ç»å®å¤ç |
| | | handleVehicleBinding() { |
| | | this.$tab.navigateTo('/pages/bind-vehicle') |
| | | } |
| | | ``` |
| | | |
| | | #### ä¼åéåºç»å½ |
| | | ```javascript |
| | | handleLogout() { |
| | | this.$modal.confirm('ç¡®å®éåºç»å½åï¼').then(() => { |
| | | this.$store.dispatch('LogOut').then(() => { |
| | | this.$tab.reLaunch('/pages/login') // æ¹ä¸ºè·³è½¬å°ç»å½é¡µ |
| | | }) |
| | | }) |
| | | } |
| | | ``` |
| | | |
| | | #### å é¤çæ¹æ³ |
| | | - â `goToBindVehicle()` - åå¹¶å° `handleVehicleBinding()` |
| | | - â `unbindVehicle()` - å¨è½¦è¾ç»å®é¡µé¢å¤ç |
| | | - â `handleToEditInfo()` - å é¤ç¼è¾èµæå
¥å£ |
| | | - â `handleToSetting()` - å é¤è®¾ç½®å
¥å£ |
| | | - â `handleHelp()` - å é¤å¸®å©å
¥å£ |
| | | - â `handleAbout()` - å é¤å
³äºå
¥å£ |
| | | - â `handleUserAgreement()` - å é¤åè®®å
¥å£ |
| | | - â `handlePrivacyPolicy()` - å 餿¿çå
¥å£ |
| | | - â `handleJiaoLiuQun()` - å é¤äº¤æµç¾¤å
¥å£ |
| | | - â `handleBuilding()` - å é¤å»ºè®¾ä¸æç¤º |
| | | |
| | | ### 3. æ ·å¼é¨å |
| | | |
| | | #### å é¤çæ ·å¼ |
| | | ```scss |
| | | // å é¤åå®«æ ¼æ ·å¼ |
| | | .mine-actions { ... } |
| | | |
| | | // å é¤è½¦è¾æä½æé®æ ·å¼ |
| | | .vehicle-actions { ... } |
| | | ``` |
| | | |
| | | ## åè½å¯¹æ¯ |
| | | |
| | | ### ç¨æ·ä¿¡æ¯å±ç¤º |
| | | |
| | | | åæ®µ | ä¿®æ¹å | ä¿®æ¹å | |
| | | |-----|--------|--------| |
| | | | ç¨æ·å | â
æ¾ç¤º | â
æ¾ç¤º | |
| | | | ææºå·ç | â
æ¾ç¤º | â
æ¾ç¤º | |
| | | | æå±åå
¬å¸ | â 䏿¾ç¤º | â
æ¾ç¤º | |
| | | | ç»å®è½¦è¾ | â
æ¾ç¤º | â
æ¾ç¤º | |
| | | | Appçæ¬å· | â
æ¾ç¤º | â
æ¾ç¤º | |
| | | |
| | | ### æä½å
¥å£ |
| | | |
| | | | åè½ | ä¿®æ¹å | ä¿®æ¹å | |
| | | |-----|--------|--------| |
| | | | ç»å®è½¦è¾ | â
æé® | â
èå项 | |
| | | | è§£ç»è½¦è¾ | â
æé® | â
å¨ç»å®é¡µå¤ç | |
| | | | æ´æ¢è½¦è¾ | â æ | â
卿æ¾ç¤º | |
| | | | éåºç»å½ | â éèæ·± | â
主èå | |
| | | | ç¼è¾èµæ | â
æ | â å é¤ | |
| | | | 设置 | â
æ | â å é¤ | |
| | | | å¸®å© | â
æ | â å é¤ | |
| | | |
| | | ## 交äºä¼å |
| | | |
| | | ### 1. 车è¾ç»å®ä¼å |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - å·²ç»å®ï¼æ¾ç¤º"åæ¶ç»å®è½¦è¾"æé® |
| | | - æªç»å®ï¼æ¾ç¤º"ç»å®è½¦è¾"æé® |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - å·²ç»å®ï¼èåæ¾ç¤º"æ´æ¢è½¦è¾" |
| | | - æªç»å®ï¼èåæ¾ç¤º"ç»å®è½¦è¾" |
| | | - ç»ä¸è·³è½¬å°è½¦è¾ç»å®é¡µé¢å¤ç |
| | | |
| | | ### 2. éåºç»å½ä¼å |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - éèå¨è®¾ç½®é¡µé¢ä¸ |
| | | - æç¤º"ç¡®å®æ³¨éå¹¶éåºç³»ç»åï¼" |
| | | - éåºå跳转å°é¦é¡µ |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - ç´æ¥å¨ä¸»èåæ¾ç¤º |
| | | - 使ç¨çº¢è²è¦ç¤ºæ ·å¼ |
| | | - æç¤º"ç¡®å®éåºç»å½åï¼" |
| | | - éåºå跳转å°ç»å½é¡µ |
| | | |
| | | ### 3. 页é¢ç®å |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - 10个åè½å
¥å£ |
| | | - éè¦æ»å¨æ¥ç |
| | | - ä¿¡æ¯å¯é |
| | | |
| | | **ä¿®æ¹å**ï¼ |
| | | - 2个åè½å
¥å£ |
| | | - æ éæ»å¨ |
| | | - æ¸
ç½ç®æ´ |
| | | |
| | | ## è§è§ææ |
| | | |
| | | ### 页é¢å¸å± |
| | | |
| | | ``` |
| | | âââââââââââââââââââââââââââââââââââ |
| | | â ð¤ ç¨æ·åï¼å¼ ä¸ [个人信æ¯>] â â é¡¶é¨èè²åºå |
| | | ââââââââââââââââââââââââââââââââââ⤠|
| | | â â |
| | | â âââââââââââââââââââââââââââââ â |
| | | â â ç¨æ·åï¼ å¼ ä¸ â â |
| | | â â ææºå·ç ï¼ 138****1234 â â |
| | | â â æå±åå
¬å¸ï¼ 广å·åå
¬å¸ â â â ç¨æ·ä¿¡æ¯å¡ç |
| | | â â ç»å®è½¦è¾ï¼ 粤A12345 â â |
| | | â â Appçæ¬å·ï¼ 1.0.0 â â |
| | | â âââââââââââââââââââââââââââââ â |
| | | â â |
| | | â âââââââââââââââââââââââââââââ â |
| | | â â ð æ´æ¢è½¦è¾ > â â â åè½èå |
| | | â ââââââââââââââââââââââââââââ⤠â |
| | | â â ðª éåºç»å½ > â â â 红è²è¦ç¤º |
| | | â âââââââââââââââââââââââââââââ â |
| | | â â |
| | | âââââââââââââââââââââââââââââââââââ |
| | | ``` |
| | | |
| | | ## 代ç ä¼å |
| | | |
| | | ### 代ç éå¯¹æ¯ |
| | | |
| | | | ææ | ä¿®æ¹å | ä¿®æ¹å | ä¼å | |
| | | |-----|--------|--------|------| |
| | | | 模æ¿è¡æ° | ~130è¡ | ~70è¡ | â46% | |
| | | | æ¹æ³æ°é | 14个 | 5个 | â64% | |
| | | | æ ·å¼ä»£ç | ~110è¡ | ~80è¡ | â27% | |
| | | |
| | | ### æ§è½æå |
| | | |
| | | 1. â
**æ¸²ææ´å¿«** - åå°DOMå
ç´ |
| | | 2. â
**ä»£ç æ´ç®æ´** - å 餿 ç¨æ¹æ³ |
| | | 3. â
**ç»´æ¤æ´å®¹æ** - åè½èç¦ |
| | | |
| | | ## ç¨æ·ä½éª |
| | | |
| | | ### ä¼å¿ |
| | | |
| | | 1. â
**çé¢ç®æ´** - æ å¹²æ°ä¿¡æ¯ |
| | | 2. â
**æä½ç´è§** - æ ¸å¿åè½çªåº |
| | | 3. â
**æ¥æ¾å¿«é** - æ éæ»å¨ |
| | | 4. â
**éåºæ¹ä¾¿** - 主èåå¯è§ |
| | | |
| | | ### 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ **åè½ç¼©å** - é¨ååè½ä¸å¯ç¨ |
| | | 2. â ï¸ **ç¨æ·ä¹ æ¯** - éè¦éåºæ°å¸å± |
| | | 3. â
**æ ¸å¿ä¿ç** - ä¸å½±å主è¦åè½ |
| | | |
| | | ## æµè¯éªè¯ |
| | | |
| | | ### æµè¯åºæ¯ |
| | | |
| | | 1. â
**ç¨æ·ä¿¡æ¯æ¾ç¤º** |
| | | - éªè¯ææå段æ£ç¡®æ¾ç¤º |
| | | - éªè¯åå
¬å¸ä¿¡æ¯æ¾ç¤º |
| | | |
| | | 2. â
**车è¾ç»å®** |
| | | - æªç»å®ï¼æ¾ç¤º"ç»å®è½¦è¾" |
| | | - å·²ç»å®ï¼æ¾ç¤º"æ´æ¢è½¦è¾" |
| | | - ç¹å»è·³è½¬å°ç»å®é¡µé¢ |
| | | |
| | | 3. â
**éåºç»å½** |
| | | - æ¾ç¤ºçº¢è²è¦ç¤ºæ ·å¼ |
| | | - äºæ¬¡ç¡®è®¤æç¤º |
| | | - éåºå跳转å°ç»å½é¡µ |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | - **页颿件**: `app/pages/mine/index.vue` |
| | | - **APIæä»¶**: `app/api/system/user.js` |
| | | - **车è¾API**: `app/api/vehicle.js` |
| | | - **Store**: `app/store/modules/user.js` |
| | | |
| | | ## å级建议 |
| | | |
| | | 妿åç»éè¦æ¢å¤æäºåè½ï¼å»ºè®®ï¼ |
| | | |
| | | 1. å¨è®¾ç½®é¡µé¢ä¸æ·»å "é«çº§åè½"å
¥å£ |
| | | 2. ä½¿ç¨æ½å±æå¼¹çªå±ç¤ºæ¬¡è¦åè½ |
| | | 3. ä¿æä¸»é¡µé¢çç®æ´æ§ |
| | | |
| | | --- |
| | | |
| | | **ä¿®æ¹æ¶é´**: 2025-10-26 |
| | | **ä¿®æ¹äºº**: AI Assistant |
| | | **å½±åèå´**: "æç"页é¢UIååè½ |
| | | **ç¶æ**: â
已宿并ä¼å |
| New file |
| | |
| | | # "æç"页é¢èåæ ·å¼ä¿®å¤è¯´æ |
| | | |
| | | ## é®é¢æè¿° |
| | | |
| | | ç¨æ·åé¦ï¼ç¹å»"æ´æ¢è½¦è¾"èå项没æä»»ä½ååºã |
| | | |
| | | ## é®é¢åå |
| | | |
| | | **缺å°èååè¡¨æ ·å¼å®ä¹** |
| | | |
| | | å¨ç²¾ç®"æç"页颿¶ï¼å é¤äºå¤§éèå项ï¼ä½åæ¶ä¹å é¤äº `.menu-list` å `.list-cell` çæ ·å¼å®ä¹ï¼å¯¼è´ï¼ |
| | | 1. èåé¡¹æ²¡ææ£ç¡®çå¸å±åæ¾ç¤º |
| | | 2. ç¹å»åºåå¯è½æ æ |
| | | 3. 缺å°è§è§åé¦ |
| | | |
| | | ## è§£å³æ¹æ¡ |
| | | |
| | | ### æ°å¢èååè¡¨å®æ´æ ·å¼ |
| | | |
| | | ```scss |
| | | // èååè¡¨æ ·å¼ |
| | | .menu-list { |
| | | background-color: white; |
| | | border-radius: 8px; |
| | | margin: 15rpx; |
| | | overflow: hidden; |
| | | |
| | | .list-cell { |
| | | padding: 30rpx; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | cursor: pointer; |
| | | transition: background-color 0.2s; |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | &:active { |
| | | background-color: #f5f5f5; // ç¹å»åé¦ |
| | | } |
| | | |
| | | .menu-item-box { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | .menu-icon { |
| | | font-size: 36rpx; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | view { |
| | | flex: 1; |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .text-red { |
| | | color: #ff4d4f; // éåºç»å½çº¢è² |
| | | } |
| | | } |
| | | |
| | | &.list-cell-arrow .menu-item-box::after { |
| | | content: ''; |
| | | width: 16rpx; |
| | | height: 16rpx; |
| | | border-top: 2rpx solid #999; |
| | | border-right: 2rpx solid #999; |
| | | transform: rotate(45deg); |
| | | margin-left: 20rpx; // å³ç®å¤´æç¤ºå¨ |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## æ ·å¼åè½è¯´æ |
| | | |
| | | ### 1. åºç¡å¸å± |
| | | - **ç½è²èæ¯** - `background-color: white` |
| | | - **åè§å¡ç** - `border-radius: 8px` |
| | | - **éå½å¤è¾¹è·** - `margin: 15rpx` |
| | | |
| | | ### 2. èåé¡¹æ ·å¼ |
| | | - **å
è¾¹è·** - `padding: 30rpx` å¢å ç¹å»åºå |
| | | - **åé线** - `border-bottom: 1rpx solid #f0f0f0` |
| | | - **æåä¸é¡¹æ åé线** - `&:last-child` |
| | | |
| | | ### 3. 交äºåé¦ |
| | | - **ç¹å»ææ** - `:active` ç¶ææ¹åèæ¯è² |
| | | - **è¿æ¸¡å¨ç»** - `transition: background-color 0.2s` |
| | | - **é¼ æ æé** - `cursor: pointer` |
| | | |
| | | ### 4. 徿 åæå |
| | | - **徿 大å°** - `font-size: 36rpx` |
| | | - **徿 é´è·** - `margin-right: 20rpx` |
| | | - **æå大å°** - `font-size: 32rpx` |
| | | - **æåé¢è²** - `color: #333` (æ£å¸¸), `color: #ff4d4f` (è¦å) |
| | | |
| | | ### 5. ç®å¤´æç¤ºå¨ |
| | | - **ç®å¤´æ ·å¼** - 使ç¨ä¼ªå
ç´ `::after` ç»å¶ |
| | | - **ç®å¤´æ¹å** - `transform: rotate(45deg)` åå³ |
| | | - **ç®å¤´é¢è²** - `border-color: #999` |
| | | |
| | | ## è§è§ææ |
| | | |
| | | ### ä¿®å¤å |
| | | ``` |
| | | âââââââââââââââââââ |
| | | â æ´æ¢è½¦è¾ â â æ æ ·å¼ï¼ç¹å»æ æ |
| | | ââââââââââââââââââ⤠|
| | | â éåºç»å½ â |
| | | âââââââââââââââââââ |
| | | ``` |
| | | |
| | | ### ä¿®å¤å |
| | | ``` |
| | | âââââââââââââââââââââââ |
| | | â ð æ´æ¢è½¦è¾ > â â æå¾æ ãé´è·ãç®å¤´ |
| | | ââââââââââââââââââââââ⤠|
| | | â ðª éåºç»å½ > â â çº¢è²æå |
| | | âââââââââââââââââââââââ |
| | | â |
| | | ç¹å»æ¶æç°è²èæ¯åé¦ |
| | | ``` |
| | | |
| | | ## äº¤äºæµç¨ |
| | | |
| | | ### ç¹å»"æ´æ¢è½¦è¾" |
| | | 1. ç¨æ·ç¹å»èå项 |
| | | 2. èæ¯è²å为 `#f5f5f5` (è§è§åé¦) |
| | | 3. 触å `handleVehicleBinding()` æ¹æ³ |
| | | 4. è·³è½¬å° `/pages/bind-vehicle` é¡µé¢ |
| | | |
| | | ### ç¹å»"éåºç»å½" |
| | | 1. ç¨æ·ç¹å»èå项 |
| | | 2. èæ¯è²å为 `#f5f5f5` (è§è§åé¦) |
| | | 3. 触å `handleLogout()` æ¹æ³ |
| | | 4. å¼¹åºç¡®è®¤å¯¹è¯æ¡ï¼"ç¡®å®éåºç»å½åï¼" |
| | | 5. ç¡®è®¤åæ§è¡ç»åºå¹¶è·³è½¬å°ç»å½é¡µ |
| | | |
| | | ## ç¸å
³ä»£ç |
| | | |
| | | ### 模æ¿é¨å |
| | | ```vue |
| | | <view class="menu-list"> |
| | | <!-- ç»å®/æ´æ¢è½¦è¾ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleVehicleBinding"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-car menu-icon"></view> |
| | | <view>{{ boundVehicle && boundVehicle !== 'æªç»å®' ? 'æ´æ¢è½¦è¾' : 'ç»å®è½¦è¾' }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- éåºç»å½ --> |
| | | <view class="list-cell list-cell-arrow" @click="handleLogout"> |
| | | <view class="menu-item-box"> |
| | | <view class="iconfont icon-logout menu-icon text-red"></view> |
| | | <view class="text-red">éåºç»å½</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | ``` |
| | | |
| | | ### æ¹æ³é¨å |
| | | ```javascript |
| | | methods: { |
| | | // å¤ç车è¾ç»å®æä½ |
| | | handleVehicleBinding() { |
| | | this.$tab.navigateTo('/pages/bind-vehicle') |
| | | }, |
| | | |
| | | // éåºç»å½ |
| | | handleLogout() { |
| | | this.$modal.confirm('ç¡®å®éåºç»å½åï¼').then(() => { |
| | | this.$store.dispatch('LogOut').then(() => { |
| | | this.$tab.reLaunch('/pages/login') |
| | | }) |
| | | }) |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## æµè¯éªè¯ |
| | | |
| | | ### æµè¯åºæ¯ |
| | | |
| | | 1. â
**ç¹å»"ç»å®è½¦è¾"ï¼æªç»å®æ¶ï¼** |
| | | - æ¾ç¤ºææ¬ï¼ç»å®è½¦è¾ |
| | | - ç¹å»å跳转å°ç»å®é¡µé¢ |
| | | |
| | | 2. â
**ç¹å»"æ´æ¢è½¦è¾"ï¼å·²ç»å®æ¶ï¼** |
| | | - æ¾ç¤ºææ¬ï¼æ´æ¢è½¦è¾ |
| | | - ç¹å»å跳转å°ç»å®é¡µé¢ |
| | | |
| | | 3. â
**ç¹å»"éåºç»å½"** |
| | | - çº¢è²æåè¦ç¤º |
| | | - å¼¹åºç¡®è®¤å¯¹è¯æ¡ |
| | | - 确认åéåºç»å½ |
| | | |
| | | 4. â
**è§è§åé¦** |
| | | - ç¹å»æ¶èæ¯åç° |
| | | - å³ä¾§æ¾ç¤ºç®å¤´æç¤ºå¨ |
| | | - 徿 åæåå¯¹é½ |
| | | |
| | | ## æ ·å¼ç±»è¯´æ |
| | | |
| | | | ç±»å | ä½ç¨ | |
| | | |-----|------| |
| | | | `.menu-list` | èååè¡¨å®¹å¨ | |
| | | | `.list-cell` | å个èå项 | |
| | | | `.list-cell-arrow` | 带ç®å¤´çèå项 | |
| | | | `.menu-item-box` | èå项å
容çå | |
| | | | `.menu-icon` | èå徿 | |
| | | | `.text-red` | çº¢è²æåï¼è¦åï¼ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ **å¿
é¡»å
嫿 ·å¼** - å é¤åè½æ¶ä¸è¦å é¤å¿
è¦çæ ·å¼ |
| | | 2. â
**ä¿æä¸è´æ§** - èåé¡¹æ ·å¼åºä¿æç»ä¸ |
| | | 3. â
**è§è§åé¦** - 交äºå
ç´ å¿
é¡»ææç¡®çåé¦ |
| | | 4. â
**å¯è®¿é®æ§** - ç¡®ä¿ç¹å»åºåè¶³å¤å¤§ |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | - **页颿件**: `app/pages/mine/index.vue` |
| | | - **è·³è½¬ç®æ **: `app/pages/bind-vehicle.vue` |
| | | - **Store**: `app/store/modules/user.js` |
| | | |
| | | --- |
| | | |
| | | **ä¿®å¤æ¶é´**: 2025-10-26 |
| | | **ä¿®å¤äºº**: AI Assistant |
| | | **é®é¢ç±»å**: æ ·å¼ç¼ºå¤±å¯¼è´åè½å¤±æ |
| | | **ç¶æ**: â
å·²ä¿®å¤ |
| New file |
| | |
| | | # æ¶æ¯TabBarå¾½æ æ¾ç¤ºåè½å®ç°è¯´æ |
| | | |
| | | ## åè½æè¿° |
| | | |
| | | å¨Appåºé¨TabBarçæ¶æ¯å¾æ 䏿¾ç¤ºæªè¯»æ¶æ¯æ°éå¾½æ å红ç¹ï¼å®æ¶æ´æ°æªè¯»æ¶æ¯æ°éã |
| | | |
| | | ## å®ç°æ¹æ¡ |
| | | |
| | | ### 1. App.vueå
¨å±çå¬ |
| | | |
| | | å¨åºç¨å¯å¨åæ¾ç¤ºæ¶èªå¨è·åå¹¶æ´æ°æªè¯»æ¶æ¯æ°éï¼ |
| | | |
| | | ```javascript |
| | | // app/App.vue |
| | | import { getUnreadCount } from '@/api/message' |
| | | |
| | | export default { |
| | | onLaunch() { |
| | | // åºç¨å¯å¨æ¶ |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | this.startMessagePolling() // å¯å¨30ç§è½®è¯¢ |
| | | } |
| | | }, |
| | | |
| | | onShow() { |
| | | // åºç¨ä»åå°åååå°æ¶ |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | // æ´æ°æªè¯»æ¶æ¯å¾½æ |
| | | updateUnreadMessageBadge() { |
| | | getUnreadCount().then(response => { |
| | | const count = response.data || 0 |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, // æ¶æ¯é¡µé¢å¨tabBarä¸çç´¢å¼ |
| | | text: count > 99 ? '99+' : count.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ index: 3 }) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // å¯å¨æ¶æ¯è½®è¯¢ï¼æ¯30ç§ï¼ |
| | | startMessagePolling() { |
| | | this.messagePollingTimer = setInterval(() => { |
| | | if (getToken()) { |
| | | this.updateUnreadMessageBadge() |
| | | } else { |
| | | this.stopMessagePolling() |
| | | } |
| | | }, 30000) |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 2. æ¶æ¯é¡µé¢å®æ¶æ´æ° |
| | | |
| | | 卿¶æ¯é¡µé¢æ è®°æ¶æ¯ä¸ºå·²è¯»åç«å³æ´æ°å¾½æ ï¼ |
| | | |
| | | ```javascript |
| | | // app/pages/message/index.vue |
| | | export default { |
| | | onShow() { |
| | | this.loadMessages() |
| | | this.updateTabBarBadge() // è¿å
¥é¡µé¢æ¶æ´æ° |
| | | }, |
| | | |
| | | methods: { |
| | | async viewMessageDetail(message) { |
| | | // æ 记为已读 |
| | | if (message.isRead === '0') { |
| | | await markAsRead(message.messageId) |
| | | message.isRead = '1' |
| | | this.updateTabBarBadge() // æ è®°åç«å³æ´æ° |
| | | } |
| | | // ... 跳转é»è¾ |
| | | }, |
| | | |
| | | updateTabBarBadge() { |
| | | const unreadCount = this.messages.filter(msg => msg.isRead === '0').length |
| | | if (unreadCount > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, |
| | | text: unreadCount > 99 ? '99+' : unreadCount.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ index: 3 }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 3. é¦é¡µæ¶æ¯å
¥å£ |
| | | |
| | | é¦é¡µä¹ä¼å 载并æ¾ç¤ºæªè¯»æ¶æ¯æ°éï¼ |
| | | |
| | | ```javascript |
| | | // app/pages/index.vue |
| | | export default { |
| | | onShow() { |
| | | this.loadUnreadMessageCount() // å·æ°æªè¯»æ°é |
| | | }, |
| | | |
| | | methods: { |
| | | loadUnreadMessageCount() { |
| | | getUnreadCount().then(response => { |
| | | if (response.code === 200) { |
| | | this.unreadMessageCount = response.data || 0 |
| | | this.updateTabBarBadge(this.unreadMessageCount) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | updateTabBarBadge(count) { |
| | | if (count > 0) { |
| | | uni.setTabBarBadge({ |
| | | index: 3, |
| | | text: count > 99 ? '99+' : count.toString() |
| | | }) |
| | | } else { |
| | | uni.removeTabBarBadge({ index: 3 }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ## TabBarç´¢å¼è¯´æ |
| | | |
| | | æ ¹æ® `pages.json` ä¸çé
ç½®ï¼tabBarçç´¢å¼é¡ºåºä¸ºï¼ |
| | | |
| | | | ç´¢å¼ | é¡µé¢ | ææ¬ | |
| | | |-----|------|-----| |
| | | | 0 | pages/index | é¦é¡µ | |
| | | | 1 | pages/task/index | ä»»å¡ | |
| | | | 2 | pages/task/create | åå»ºä»»å¡ | |
| | | | **3** | **pages/message/index** | **æ¶æ¯** â | |
| | | | 4 | pages/mine/index | æç | |
| | | |
| | | å æ¤æ¶æ¯é¡µé¢çç´¢å¼æ¯ **3**ã |
| | | |
| | | ## å¾½æ æ¾ç¤ºè§å |
| | | |
| | | ### 1. æ°åæ¾ç¤ºè§å |
| | | - **1-99**: æ¾ç¤ºå®é
æ°åï¼å¦ "1", "5", "25"ï¼ |
| | | - **â¥100**: æ¾ç¤º "99+" |
| | | |
| | | ### 2. æ¾ç¤º/éèè§å |
| | | - **ææªè¯»æ¶æ¯**: æ¾ç¤ºçº¢è²å¾½æ + æ°å |
| | | - **æ æªè¯»æ¶æ¯**: éèå¾½æ |
| | | |
| | | ### 3. æ´æ°æ¶æº |
| | | - â
Appå¯å¨æ¶ |
| | | - â
Appä»åå°åååå° |
| | | - â
æ¯30ç§èªå¨è½®è¯¢ |
| | | - â
è¿å
¥æ¶æ¯é¡µé¢æ¶ |
| | | - â
æ è®°æ¶æ¯ä¸ºå·²è¯»å |
| | | - â
è¿å
¥é¦é¡µæ¶ |
| | | |
| | | ## APIè°ç¨ |
| | | |
| | | ### è·åæªè¯»æ¶æ¯æ°é |
| | | |
| | | ```javascript |
| | | import { getUnreadCount } from '@/api/message' |
| | | |
| | | getUnreadCount().then(response => { |
| | | const count = response.data || 0 |
| | | // 使ç¨countæ´æ°å¾½æ |
| | | }) |
| | | ``` |
| | | |
| | | **å端æ¥å£**: `GET /system/message/unread/count` |
| | | |
| | | **è¿åæ ¼å¼**: |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "data": 5, // æªè¯»æ¶æ¯æ°é |
| | | "msg": "æ¥è¯¢æå" |
| | | } |
| | | ``` |
| | | |
| | | ## uni-app API说æ |
| | | |
| | | ### 设置TabBarå¾½æ |
| | | |
| | | ```javascript |
| | | uni.setTabBarBadge({ |
| | | index: 3, // TabBarç´¢å¼ |
| | | text: '5' // æ¾ç¤ºææ¬ï¼å符串类åï¼ |
| | | }) |
| | | ``` |
| | | |
| | | ### ç§»é¤TabBarå¾½æ |
| | | |
| | | ```javascript |
| | | uni.removeTabBarBadge({ |
| | | index: 3 // TabBarç´¢å¼ |
| | | }) |
| | | ``` |
| | | |
| | | ## å®ç°ææ |
| | | |
| | | ### ææªè¯»æ¶æ¯ |
| | | ``` |
| | | âââââââââââ |
| | | â æ¶æ¯ â |
| | | â [ð´3] â â 红è²å¾½æ æ¾ç¤ºæªè¯»æ°é |
| | | âââââââââââ |
| | | ``` |
| | | |
| | | ### æ æªè¯»æ¶æ¯ |
| | | ``` |
| | | âââââââââââ |
| | | â æ¶æ¯ â |
| | | â â â æ å¾½æ |
| | | âââââââââââ |
| | | ``` |
| | | |
| | | ### è¶
è¿99æ¡ |
| | | ``` |
| | | âââââââââââ |
| | | â æ¶æ¯ â |
| | | â [ð´99+] â â æ¾ç¤º99+ |
| | | âââââââââââ |
| | | ``` |
| | | |
| | | ## æ§è½ä¼å |
| | | |
| | | ### 1. 轮询æºå¶ |
| | | - 使ç¨30ç§é´é轮询 |
| | | - é¿å
é¢ç¹è¯·æ±æ¶èèµæº |
| | | - ç¨æ·ç»åºæ¶èªå¨åæ¢è½®è¯¢ |
| | | |
| | | ### 2. æéæ´æ° |
| | | - åªå¨å¿
è¦æ¶æ´æ°å¾½æ |
| | | - é¿å
éå¤çAPIè°ç¨ |
| | | - ä½¿ç¨æ¬å°ç¼åä¼å
|
| | | |
| | | ### 3. é误å¤ç |
| | | - API失败æ¶ä¸å½±åå
¶ä»åè½ |
| | | - éé»å¤±è´¥ï¼è®°å½æ¥å¿ |
| | | - 䏿¬¡è½®è¯¢æ¶éè¯ |
| | | |
| | | ## æµè¯åºæ¯ |
| | | |
| | | ### 1. æ£å¸¸æµç¨æµè¯ |
| | | - â
å¯å¨åºç¨ï¼æ¾ç¤ºæªè¯»æ°é |
| | | - â
è¿å
¥æ¶æ¯é¡µé¢ï¼ç¹å»æ¶æ¯ |
| | | - â
æ 记为已读åï¼å¾½æ æ°éå1 |
| | | - â
å
¨é¨å·²è¯»åï¼å¾½æ æ¶å¤± |
| | | |
| | | ### 2. è¾¹çæ
嵿µè¯ |
| | | - â
0æ¡æªè¯»ï¼ä¸æ¾ç¤ºå¾½æ |
| | | - â
1æ¡æªè¯»ï¼æ¾ç¤º"1" |
| | | - â
99æ¡æªè¯»ï¼æ¾ç¤º"99" |
| | | - â
100+æ¡æªè¯»ï¼æ¾ç¤º"99+" |
| | | |
| | | ### 3. å¼å¸¸æ
嵿µè¯ |
| | | - â
ç½ç»æå¼ï¼ä½¿ç¨ä¸æ¬¡ç¼åæ°æ® |
| | | - â
API失败ï¼ä¸å½±åå
¶ä»åè½ |
| | | - â
ç»åºç¶æï¼åæ¢è½®è¯¢åæ¾ç¤º |
| | | |
| | | ## ç¸å
³æä»¶ |
| | | |
| | | ### å端æä»¶ |
| | | - `app/App.vue` - å
¨å±è½®è¯¢åæ´æ° |
| | | - `app/pages/index.vue` - é¦é¡µæ¶æ¯å
¥å£ |
| | | - `app/pages/message/index.vue` - æ¶æ¯å表页 |
| | | - `app/api/message.js` - æ¶æ¯API |
| | | - `app/pages.json` - TabBaré
ç½® |
| | | |
| | | ### å端æä»¶ |
| | | - `SysMessageController.java` - æ¶æ¯æ§å¶å¨ |
| | | - `SysMessageService.java` - æ¶æ¯æå¡ |
| | | - `SysMessageMapper.xml` - æ¶æ¯æ°æ®æ¥è¯¢ |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | 1. â ï¸ **TabBarç´¢å¼**: å¿
须确ä¿ç´¢å¼æ£ç¡®ï¼æ¶æ¯é¡µä¸º3ï¼ |
| | | 2. â ï¸ **ææ¬ç±»å**: `uni.setTabBarBadge` çtextåæ°å¿
é¡»æ¯å符串 |
| | | 3. â ï¸ **轮询æ¸
ç**: ç¡®ä¿å¨é彿¶æºæ¸
ç宿¶å¨ |
| | | 4. â ï¸ **ç»å½ç¶æ**: åªå¨å·²ç»å½ç¶æä¸è½®è¯¢ |
| | | 5. â
**ç¨æ·ä½éª**: 宿¶æ´æ°ï¼æ éæå¨å·æ° |
| | | |
| | | ## æ©å±åè½å»ºè®® |
| | | |
| | | ### 1. æ¶æ¯æ¨ééæ |
| | | - éæuni-push |
| | | - æ¥æ¶æå¡å¨æ¨é |
| | | - 宿¶æ´æ°å¾½æ |
| | | |
| | | ### 2. åç±»ç»è®¡ |
| | | - ç³»ç»æ¶æ¯æ°é |
| | | - ä»»å¡éç¥æ°é |
| | | - æç±»åæ¾ç¤ºä¸åé¢è² |
| | | |
| | | ### 3. æ¶æ¯æç¤ºé³ |
| | | - æ°æ¶æ¯å°è¾¾æ¶ææ¾æç¤ºé³ |
| | | - æ¯æé卿é |
| | | - ç¨æ·å¯èªå®ä¹è®¾ç½® |
| | | |
| | | --- |
| | | |
| | | **å®ç°æ¶é´**: 2025-10-26 |
| | | **å®ç°äºº**: AI Assistant |
| | | **ç¶æ**: â
已宿 |
| | | **çæ¬**: v1.0 |
| | |
| | | # 项ç®ç¸å
³é
ç½® |
| | | ruoyi: |
| | | # åç§° |
| | | name: RuoYi |
| | | name: Dryadonline |
| | | # çæ¬ |
| | | version: ${revision} |
| | | # çæå¹´ä»½ |
| New file |
| | |
| | | -- æ£æ¥å¹¶ä¿®å¤ä»»å¡ç±»ååç¶æä¸ºNULLçè®°å½ |
| | | -- æ§è¡æ¶é´: 2025-10-26 |
| | | |
| | | -- 1. æ£æ¥task_type为NULLçè®°å½æ°é |
| | | SELECT COUNT(*) as null_task_type_count |
| | | FROM sys_task |
| | | WHERE task_type IS NULL AND del_flag = '0'; |
| | | |
| | | -- 2. æ£æ¥task_status为NULLçè®°å½æ°é |
| | | SELECT COUNT(*) as null_task_status_count |
| | | FROM sys_task |
| | | WHERE task_status IS NULL AND del_flag = '0'; |
| | | |
| | | -- 3. æ¥çtask_type为NULLçè®°å½è¯¦æ
|
| | | SELECT task_id, task_code, task_type, task_status, create_time |
| | | FROM sys_task |
| | | WHERE task_type IS NULL AND del_flag = '0' |
| | | ORDER BY create_time DESC |
| | | LIMIT 10; |
| | | |
| | | -- 4. æ¥çtask_status为NULLçè®°å½è¯¦æ
|
| | | SELECT task_id, task_code, task_type, task_status, create_time |
| | | FROM sys_task |
| | | WHERE task_status IS NULL AND del_flag = '0' |
| | | ORDER BY create_time DESC |
| | | LIMIT 10; |
| | | |
| | | -- 5. ä¿®å¤task_type为NULLçè®°å½ï¼è®¾ç½®ä¸ºOTHERï¼ |
| | | UPDATE sys_task |
| | | SET task_type = 'OTHER' |
| | | WHERE task_type IS NULL AND del_flag = '0'; |
| | | |
| | | -- 6. ä¿®å¤task_status为NULLçè®°å½ï¼è®¾ç½®ä¸ºPENDINGï¼ |
| | | UPDATE sys_task |
| | | SET task_status = 'PENDING' |
| | | WHERE task_status IS NULL AND del_flag = '0'; |
| | | |
| | | -- 7. éªè¯ä¿®å¤ç»æ |
| | | SELECT COUNT(*) as remaining_null_task_type |
| | | FROM sys_task |
| | | WHERE task_type IS NULL AND del_flag = '0'; |
| | | |
| | | SELECT COUNT(*) as remaining_null_task_status |
| | | FROM sys_task |
| | | WHERE task_status IS NULL AND del_flag = '0'; |
| | | |
| | | -- 8. æ·»å NOT NULL约æï¼å¯éï¼ç¡®ä¿æªæ¥ä¸ä¼ååºç°NULLå¼ï¼ |
| | | -- 注æï¼æ§è¡åéè¦å
ç¡®ä¿ææè®°å½é½å·²ä¿®å¤ |
| | | -- ALTER TABLE sys_task MODIFY COLUMN task_type VARCHAR(50) NOT NULL DEFAULT 'OTHER'; |
| | | -- ALTER TABLE sys_task MODIFY COLUMN task_status VARCHAR(50) NOT NULL DEFAULT 'PENDING'; |