import { getMyProfile } from '@/api/fulfiller/fulfiller' import { getPendingOrders, acceptOrder, getOrderCount, rejectOrderApi } from '@/api/order/subOrder' import { listAllService } from '@/api/service/list' import { getAreaStationList } from '@/api/system/areaStation' import { isLoggedIn } from '@/utils/auth' import { reportGps } from '@/utils/gps' import customTabbar from '@/components/custom-tabbar/index.vue' export default { components: { customTabbar }, data() { return { taskList: [], currentFilter: 'default', // default, distance, time filterCondition: '筛选条件', sortDistance: 'asc', // asc, desc sortTime: 'asc', scrollTop: 0, // Track scroll position isFilterShow: false, tempFilter: { service: null, distance: '全部', amount: '全部' }, activeFilter: { service: null, distance: '全部', amount: '全部' }, workStatus: 'resting', // resting | busy | disabled showConfirmModal: false, showPetModal: false, currentPetInfo: {}, showRejectModal: false, rejectReason: '', currentOrder: null, showAcceptConfirmModal: false, showNavModal: false, navTargetItem: null, navTargetPointType: '', profile: null, profileLoading: false, serviceList: [], orderStats: { total: 0, reject: 0, completed: 0, price: 0 } } }, onPageScroll(e) { this.scrollTop = e.scrollTop; }, async onLoad() { // Initial load this.checkWorkStatus(); await this.loadServiceList(); this.loadTaskList(); // 显式请求一次定位授权 reportGps(true).catch(e => console.log('Init GPS check skipped', e)); }, onShow() { uni.hideTabBar() this.checkWorkStatus(); if (isLoggedIn()) { // 每次进入页面强制刷新所有展示数据 this.loadProfile() this.loadOrderStats() this.loadTaskList() this.loadServiceList() // 确保服务配置也是最新的 } }, async onPullDownRefresh() { this.checkWorkStatus(); try { await this.loadServiceList(); const tasks = [ this.loadTaskList() ]; if (isLoggedIn()) { tasks.push(this.loadProfile()); tasks.push(this.loadOrderStats()); } await Promise.all(tasks); } catch (err) { console.error('刷新异常:', err); } finally { uni.stopPullDownRefresh(); uni.showToast({ title: '刷新成功', icon: 'success' }); } }, methods: { async loadProfile() { if (this.profileLoading) return this.profileLoading = true try { const res = await getMyProfile() const data = res.data || null if (data) { // 以服务器返回的状态为准进行更新 if (data.status) { this.workStatus = data.status; uni.setStorageSync('workStatus', data.status); } // 需求:头部的接单城市使用站点往上找到城市,而非直接显示站点 if (data.stationId) { try { const stationRes = await getAreaStationList(); const list = stationRes.data || []; const currentStation = list.find(i => i.id === data.stationId); if (currentStation) { // 向上溯源:直到找到 parentId 为 0 的节点(即顶层城市) let node = currentStation; while (node && node.parentId !== 0) { let parent = list.find(i => i.id === node.parentId); if (parent) { node = parent; } else { break; } } // 将溯源到的节点名称作为显示城市 data.cityName = node.name; } } catch (e) { console.error('溯源城市失败:', e); } } } this.profile = data } catch (err) { console.error('获取个人信息失败:', err) } finally { this.profileLoading = false } }, async loadServiceList() { try { const res = await listAllService() this.serviceList = res.data || [] } catch (err) { console.error('获取服务类型失败:', err) } }, async loadOrderStats() { try { const res = await getOrderCount() this.orderStats = res.data || { total: 0, reject: 0, completed: 0, price: 0 } } catch (err) { console.error('获取订单统计失败:', err) } }, checkWorkStatus() { const status = uni.getStorageSync('workStatus'); if (status) { this.workStatus = status; } else { // 默认状态为休息 this.workStatus = 'resting'; uni.setStorageSync('workStatus', 'resting'); } }, toggleFilter() { if (this.workStatus === 'resting') return; // Disable filter when resting? Or keep it? User didn't specify, but usually disabled. Let's keep it enabled for now as they might look at filters before working. this.isFilterShow = !this.isFilterShow; }, goToWorkStatus() { uni.navigateTo({ url: '/pages/home/work-status' }); }, async handleManualLocation() { try { uni.showLoading({ title: '定位获取中...', mask: true }); await reportGps(true); uni.showToast({ title: '位置已更新', icon: 'success' }); } catch (e) { console.error('Manual location failed', e); } finally { uni.hideLoading(); } }, startWork() { this.showConfirmModal = true; }, confirmStartWork() { this.workStatus = 'busy'; uni.setStorageSync('workStatus', 'busy'); this.loadTaskList(); this.showConfirmModal = false; uni.showToast({ title: '已开始接单', icon: 'success' }); }, closeConfirmModal() { this.showConfirmModal = false; }, showPetProfile(item) { this.currentPetInfo = item; this.showPetModal = true; }, closePetProfile() { this.showPetModal = false; }, openRejectModal(item) { this.currentOrder = item; this.rejectReason = ''; this.showRejectModal = true; }, closeRejectModal() { this.showRejectModal = false; this.currentOrder = null; }, async confirmReject() { if (!this.rejectReason.trim()) { uni.showToast({ title: '请输入拒绝理由', icon: 'none' }); return; } if (!this.currentOrder?.id) return try { uni.showLoading({ title: '提交中...', mask: true }); await rejectOrderApi({ orderId: this.currentOrder.id, rejectReason: this.rejectReason }); uni.showToast({ title: '已拒绝接单', icon: 'success' }); this.showRejectModal = false; this.currentOrder = null; this.loadTaskList(); this.loadOrderStats(); } catch (err) { console.error('拒绝接单失败:', err); uni.showToast({ title: '操作失败', icon: 'none' }); } finally { uni.hideLoading(); } }, openAcceptModal(item) { this.currentOrder = item; this.showAcceptConfirmModal = true; }, closeAcceptModal() { this.showAcceptConfirmModal = false; this.currentOrder = null; }, async confirmAccept() { if (!this.currentOrder?.id) return try { await acceptOrder(this.currentOrder.id) uni.showToast({ title: '接单成功', icon: 'success' }) this.showAcceptConfirmModal = false this.currentOrder = null this.loadTaskList() this.loadProfile() this.loadOrderStats() } catch (err) { console.error('接单失败:', err) uni.showToast({ title: '接单失败', icon: 'none' }) } }, openNavigation(item, pointType) { this.navTargetItem = item; this.navTargetPointType = pointType; this.showNavModal = true; }, closeNavModal() { this.showNavModal = false; }, chooseMap(mapType) { let item = this.navTargetItem; let pointType = this.navTargetPointType; // 起 -> fromAddress ; 终 -> toAddress let name = pointType === 'start' ? (item.fromAddress || '起点') : (item.toAddress || '终点'); let address = pointType === 'start' ? (item.fromAddress || '起点地址') : (item.toAddress || '终点地址'); let latitude = pointType === 'start' ? Number(item.fromLat) : Number(item.toLat); let longitude = pointType === 'start' ? Number(item.fromLng) : Number(item.toLng); this.showNavModal = false; // 统一定义打开地图的函数 const navigateTo = (lat, lng, addrName, addrDesc) => { uni.openLocation({ latitude: lat, longitude: lng, name: addrName, address: addrDesc || '无法获取详细地址', success: function () { console.log('打开导航成功: ' + mapType); }, fail: function (err) { console.error('打开导航失败:', err); uni.showToast({ title: '打开地图失败', icon: 'none' }); } }); }; // 如果有目标经纬度,直接打开 if (latitude && longitude && !isNaN(latitude) && !isNaN(longitude)) { navigateTo(latitude, longitude, name, address); } else { // 如果没有经纬度,按照需求:使用自己当前的经纬度,然后搜索 fromAddress 或者 toAddress uni.showLoading({ title: '获取当前位置...', mask: true }); uni.getLocation({ type: 'gcj02', success: (res) => { uni.hideLoading(); // 使用用户当前经纬度作为锚点打开地图,展示目标地址信息 navigateTo(res.latitude, res.longitude, name, address); }, fail: (err) => { uni.hideLoading(); console.error('获取地理位置失败:', err); uni.showToast({ title: '无法获取当前位置信息', icon: 'none' }); } }); } }, selectService(type) { this.tempFilter.service = type; }, selectDistance(type) { this.tempFilter.distance = type; }, selectAmount(type) { this.tempFilter.amount = type; }, resetFilter() { this.tempFilter = { service: null, distance: '全部', amount: '全部' }; }, confirmFilter() { this.activeFilter = { ...this.tempFilter }; this.isFilterShow = false; this.loadTaskList(); }, closeFilter() { this.isFilterShow = false; }, goToDetail(item) { console.log('Go to detail', item); }, async loadTaskList() { try { const params = { service: this.activeFilter.service, minPrice: this.getMinPrice(), maxPrice: this.getMaxPrice(), pageNum: 1, pageSize: 20 } const res = await getPendingOrders(params) this.taskList = (res.rows || []).map(item => this.transformOrder(item)) } catch (err) { console.error('获取订单列表失败:', err) uni.showToast({ title: '加载失败', icon: 'none' }) this.taskList = [] } }, getMinPrice() { const amount = this.activeFilter.amount if (amount === '100以下') return 0 if (amount === '100-200') return 10000 if (amount === '200-500') return 20000 if (amount === '500以上') return 50000 return undefined }, getMaxPrice() { const amount = this.activeFilter.amount if (amount === '100以下') return 10000 if (amount === '100-200') return 20000 if (amount === '200-500') return 50000 return undefined }, transformOrder(item) { const service = this.serviceList.find(s => s.id === item.service) const serviceText = service?.name || '未知' const serviceIcon = service?.iconUrl || '' const mode = service?.mode || 0 const isRoundTrip = mode === 1 return { id: item.id, type: isRoundTrip ? 1 : item.service, typeText: serviceText, typeIcon: serviceIcon, price: (item.price / 100).toFixed(2), timeLabel: '服务时间', time: item.serviceTime, petAvatar: item.petAvatar || '/static/dog.png', petAvatarUrl: item.petAvatarUrl || '', petName: item.petName, petBreed: item.breed, petGender: 'M', petAge: '', petWeight: '', petPersonality: '', petHobby: '', petRemark: '', petTags: [], petLogs: [], startLocation: item.fromAddress || '暂无起点', startAddress: item.fromAddress || '', fromAddress: item.fromAddress || '', fromLat: item.fromLat, fromLng: item.fromLng, startDistance: '0km', endLocation: (item.customerName || item.contact || '') + ' ' + (item.customerPhone || ''), endAddress: item.toAddress || '', toAddress: item.toAddress || '', toLat: item.toLat, toLng: item.toLng, endDistance: '0km', serviceContent: '', remark: item.remark || '' } }, setFilter(type) { this.currentFilter = type; if (type === 'distance') { this.sortDistance = this.sortDistance === 'asc' ? 'desc' : 'asc'; uni.showToast({ title: `按距离${this.sortDistance === 'asc' ? '升序' : '降序'}`, icon: 'none' }); } else if (type === 'time') { this.sortTime = this.sortTime === 'asc' ? 'desc' : 'asc'; uni.showToast({ title: `按时间${this.sortTime === 'asc' ? '升序' : '降序'}`, icon: 'none' }); } }, showFilterDropdown() { this.toggleFilter(); } } }