orders.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. import driverApiService from '../../utils/driver-api.js';
  2. import vehicleApiService from '../../utils/vehicle-api.js';
  3. import driverManagementApiService from '../../utils/driver-management-api.js';
  4. import orderApiService from '../../utils/order-api.js';
  5. Page({
  6. onShow() {
  7. if (typeof this.getTabBar === 'function' && this.getTabBar()) {
  8. this.getTabBar().setData({
  9. selected: 1
  10. });
  11. }
  12. },
  13. data:{
  14. orders:[],
  15. statusTabs: ['待出发', '行程中', '已完成', '已取消'],
  16. currentTab: 0,
  17. driverInfoMap: {}, // 存储订单对应的司机信息
  18. locationUpdateListener: null,
  19. orderStatusListener: null,
  20. orderDataListener: null
  21. },
  22. onLoad() {
  23. // 添加订单状态监听器
  24. this.orderStatusListener = (statusData) => {
  25. this.updateOrderStatus(statusData);
  26. };
  27. driverApiService.addOrderStatusListener(this.orderStatusListener);
  28. // 添加位置更新监听器
  29. this.locationUpdateListener = (locationData) => {
  30. this.updateDriverLocation(locationData);
  31. };
  32. driverApiService.addLocationListener(this.locationUpdateListener);
  33. // 添加订单数据监听器
  34. this.orderDataListener = (orders) => {
  35. this.syncOrderData(orders);
  36. };
  37. orderApiService.addListener(this.orderDataListener);
  38. },
  39. onUnload() {
  40. // 移除监听器
  41. if (this.orderStatusListener) {
  42. driverApiService.removeOrderStatusListener(this.orderStatusListener);
  43. }
  44. if (this.locationUpdateListener) {
  45. driverApiService.removeLocationListener(this.locationUpdateListener);
  46. }
  47. if (this.orderDataListener) {
  48. orderApiService.removeListener(this.orderDataListener);
  49. }
  50. // 停止位置模拟
  51. driverApiService.stopLocationSimulation();
  52. },
  53. onShow(){
  54. this.loadOrders();
  55. this.loadDriverInfo();
  56. this.syncOrderData();
  57. },
  58. onTabChange(e) {
  59. const index = e.currentTarget.dataset.index;
  60. this.setData({
  61. currentTab: index
  62. });
  63. this.filterOrders();
  64. },
  65. filterOrders() {
  66. const { currentTab } = this.data;
  67. const allOrders = this.getAllOrders();
  68. let filteredOrders = [];
  69. // 根据选项卡索引筛选订单
  70. // 0: 待出发, 1: 行程中, 2: 已完成, 3: 已取消
  71. switch(currentTab) {
  72. case 0: // 待出发
  73. filteredOrders = allOrders.filter(order => order.statusCode === 1);
  74. break;
  75. case 1: // 行程中
  76. filteredOrders = allOrders.filter(order => order.statusCode === 2);
  77. break;
  78. case 2: // 已完成
  79. filteredOrders = allOrders.filter(order => order.statusCode === 3);
  80. break;
  81. case 3: // 已取消
  82. filteredOrders = allOrders.filter(order => order.statusCode === 4);
  83. break;
  84. default:
  85. filteredOrders = allOrders;
  86. }
  87. this.setData({
  88. orders: filteredOrders
  89. });
  90. },
  91. getAllOrders() {
  92. // 返回所有订单数据
  93. return [
  94. {
  95. id:'1',
  96. orderNo: 'BUS202510020001',
  97. schedule:{
  98. fromLoc:'东直门地铁站A口',
  99. toLoc:'上海体育馆',
  100. time:'09:00',
  101. date: '2025-11-07',
  102. model:'宇通大巴',
  103. type: 'bus'
  104. },
  105. activity: '五月天演唱会',
  106. status: '待出发',
  107. statusCode: 1,
  108. totalPrice: 88,
  109. createTime: '2025-10-15 14:30',
  110. passengers: [
  111. {name: '张三', phone: '138****1234', idCard: '110***********1234'}
  112. ],
  113. driver: {
  114. name: '李师傅',
  115. phone: '139****5678',
  116. carNumber: '京A12345',
  117. avatar: '/images/avatar-default.png',
  118. location: {lat: 40.123, lng: 116.456}
  119. }
  120. },
  121. {
  122. id:'2',
  123. orderNo: 'BUS202510020002',
  124. schedule:{
  125. fromLoc:'虹桥机场T2',
  126. toLoc:'广州体育中心',
  127. time:'14:00',
  128. date: '2025-11-08',
  129. model:'金龙大巴',
  130. type: 'bus'
  131. },
  132. activity: '英雄联盟总决赛',
  133. status: '行程中',
  134. statusCode: 2,
  135. totalPrice: 120,
  136. createTime: '2025-10-16 09:15',
  137. passengers: [
  138. {name: '李四', phone: '159****9876', idCard: '310***********5678'}
  139. ],
  140. driver: {
  141. name: '王师傅',
  142. phone: '138****9999',
  143. carNumber: '沪B67890',
  144. avatar: '/images/avatar-default.png',
  145. location: {lat: 39.456, lng: 116.789}
  146. }
  147. },
  148. {
  149. id:'3',
  150. orderNo: 'CHT202510020003',
  151. schedule:{
  152. fromLoc:'指定地点接送',
  153. toLoc:'活动现场',
  154. time: '任意时间',
  155. date: '2025-11-05',
  156. model:'奔驰V级商务车',
  157. type: 'business-charter'
  158. },
  159. activity: '商务会议',
  160. status: '已完成',
  161. statusCode: 3,
  162. totalPrice: 1200,
  163. createTime: '2025-10-10 16:45',
  164. passengers: [
  165. {name: '王五', phone: '186****1111', idCard: '440***********9012'},
  166. {name: '赵六', phone: '177****2222', idCard: '440***********3456'}
  167. ],
  168. driver: {
  169. name: '陈师傅',
  170. phone: '150****7777',
  171. carNumber: '粤A88888',
  172. avatar: '/images/avatar-default.png'
  173. }
  174. },
  175. {
  176. id:'4',
  177. orderNo: 'BUS202510020004',
  178. schedule:{
  179. fromLoc:'西单地铁站',
  180. toLoc:'工人体育馆',
  181. time:'18:00',
  182. date: '2025-11-01',
  183. model:'宇通大巴',
  184. type: 'bus'
  185. },
  186. activity: '演唱会',
  187. status: '已取消',
  188. statusCode: 4,
  189. totalPrice: 68,
  190. createTime: '2025-10-05 11:20',
  191. passengers: [
  192. {name: '钱七', phone: '156****3333', idCard: '110***********7890'}
  193. ]
  194. }
  195. ];
  196. },
  197. loadOrders() {
  198. // 从订单API服务获取数据
  199. const allOrders = orderApiService.getAllOrders();
  200. this.setData({ orders: allOrders });
  201. this.filterOrders();
  202. },
  203. // 同步订单数据
  204. syncOrderData(orders = null) {
  205. if (orders) {
  206. this.setData({ orders });
  207. this.filterOrders();
  208. } else {
  209. const allOrders = orderApiService.getAllOrders();
  210. this.setData({ orders: allOrders });
  211. this.filterOrders();
  212. }
  213. },
  214. viewDetail(e){
  215. const id = e.currentTarget.dataset.id;
  216. wx.navigateTo({url:`/pages/order-detail/order-detail?id=${id}`});
  217. },
  218. // 加载司机信息
  219. loadDriverInfo() {
  220. const { orders } = this.data;
  221. const driverInfoMap = {};
  222. orders.forEach(order => {
  223. const driverInfo = driverApiService.getOrderDriverInfo(order.id);
  224. if (driverInfo) {
  225. // 获取司机详细信息
  226. const driverDetails = driverManagementApiService.getDriverById(driverInfo.driverId);
  227. if (driverDetails) {
  228. // 获取车辆信息
  229. const vehicleInfo = vehicleApiService.getVehicleById(driverDetails.vehicleId);
  230. driverInfoMap[order.id] = {
  231. ...driverInfo,
  232. driver: driverDetails,
  233. vehicle: vehicleInfo
  234. };
  235. } else {
  236. driverInfoMap[order.id] = driverInfo;
  237. }
  238. }
  239. });
  240. this.setData({ driverInfoMap });
  241. },
  242. // 更新订单状态
  243. updateOrderStatus(statusData) {
  244. const { orderId, status, statusText } = statusData;
  245. const orders = this.data.orders.map(order => {
  246. if (order.id === orderId) {
  247. // 根据司机端状态映射到订单状态
  248. let orderStatus = order.status;
  249. let orderStatusCode = order.statusCode;
  250. switch (status) {
  251. case 'picked_up':
  252. orderStatus = '行程中';
  253. orderStatusCode = 2;
  254. break;
  255. case 'in_transit':
  256. orderStatus = '行程中';
  257. orderStatusCode = 2;
  258. break;
  259. case 'completed':
  260. orderStatus = '已完成';
  261. orderStatusCode = 3;
  262. break;
  263. }
  264. return {
  265. ...order,
  266. status: orderStatus,
  267. statusCode: orderStatusCode
  268. };
  269. }
  270. return order;
  271. });
  272. this.setData({ orders });
  273. // 显示状态更新提示
  274. wx.showToast({
  275. title: statusText,
  276. icon: 'success'
  277. });
  278. },
  279. // 更新司机位置
  280. updateDriverLocation(locationData) {
  281. const { driverId, location } = locationData;
  282. const { driverInfoMap } = this.data;
  283. // 更新对应司机的位置信息
  284. Object.keys(driverInfoMap).forEach(orderId => {
  285. const driverInfo = driverInfoMap[orderId];
  286. if (driverInfo.driver.id === driverId) {
  287. driverInfoMap[orderId] = {
  288. ...driverInfo,
  289. driver: {
  290. ...driverInfo.driver,
  291. currentLocation: location
  292. },
  293. currentLocation: location
  294. };
  295. }
  296. });
  297. this.setData({ driverInfoMap });
  298. },
  299. // 查看司机位置
  300. viewDriverLocation(e) {
  301. e.stopPropagation();
  302. const { id } = e.currentTarget.dataset;
  303. const driverInfo = this.data.driverInfoMap[id];
  304. if (!driverInfo || !driverInfo.currentLocation) {
  305. wx.showToast({
  306. title: '暂无司机位置信息',
  307. icon: 'none'
  308. });
  309. return;
  310. }
  311. const { lng, lat, address } = driverInfo.currentLocation;
  312. wx.openLocation({
  313. latitude: lat,
  314. longitude: lng,
  315. name: '司机当前位置',
  316. address: address || '未知地址',
  317. scale: 18
  318. });
  319. },
  320. callDriver(e) {
  321. e.stopPropagation();
  322. const { id } = e.currentTarget.dataset;
  323. const driverInfo = this.data.driverInfoMap[id];
  324. if (driverInfo && driverInfo.driver.phone) {
  325. wx.makePhoneCall({
  326. phoneNumber: driverInfo.driver.phone,
  327. fail: () => {
  328. wx.showToast({title: '拨打失败', icon: 'none'});
  329. }
  330. });
  331. } else {
  332. // 兼容旧数据
  333. const phone = e.currentTarget.dataset.phone;
  334. if (phone) {
  335. wx.makePhoneCall({
  336. phoneNumber: phone.replace(/\*/g, ''),
  337. fail: () => {
  338. wx.showToast({title: '拨打失败', icon: 'none'});
  339. }
  340. });
  341. } else {
  342. wx.showToast({title: '暂无司机联系方式', icon: 'none'});
  343. }
  344. }
  345. },
  346. viewLocation(e) {
  347. e.stopPropagation();
  348. const order = this.data.orders.find(o => o.id === e.currentTarget.dataset.id);
  349. if (order && order.driver && order.driver.location) {
  350. wx.openLocation({
  351. latitude: order.driver.location.latitude,
  352. longitude: order.driver.location.longitude,
  353. name: '司机位置',
  354. address: order.driver.location.address,
  355. fail: () => {
  356. wx.showToast({title: '无法打开地图', icon: 'none'});
  357. }
  358. });
  359. } else {
  360. wx.showToast({title: '司机位置暂不可用', icon: 'none'});
  361. }
  362. }
  363. });