driver-management-api.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /**
  2. * 司机管理API接口系统
  3. * 支持司机信息的增删改查、状态管理、车辆分配
  4. */
  5. class DriverManagementApiService {
  6. constructor() {
  7. this.listeners = []; // 数据变化监听器
  8. this.initDriverData();
  9. }
  10. // 初始化司机数据
  11. initDriverData() {
  12. const drivers = this.getAllDrivers();
  13. if (drivers.length === 0) {
  14. const sampleDrivers = [
  15. {
  16. id: 'driver_001',
  17. name: '张师傅',
  18. phone: '13800138001',
  19. idCard: '110101199001011234',
  20. licenseNumber: 'A123456789',
  21. licenseType: 'A1',
  22. licenseExpiry: '2026-01-15',
  23. experience: '5年',
  24. rating: 4.8,
  25. totalTrips: 1250,
  26. totalDistance: 150000,
  27. status: 'active', // active, inactive, busy, vacation
  28. vehicleId: 'vehicle_001',
  29. vehicleModel: '宇通ZK6127H',
  30. licensePlate: '京A12345',
  31. emergencyContact: {
  32. name: '张太太',
  33. phone: '13900139001',
  34. relationship: '配偶'
  35. },
  36. address: '北京市朝阳区某某街道123号',
  37. joinDate: '2019-03-15',
  38. lastLogin: '2024-01-15 08:30:00',
  39. createTime: '2024-01-15 10:00:00',
  40. updateTime: '2024-01-15 10:00:00',
  41. skills: ['安全驾驶', '客户服务', '路线熟悉'],
  42. certifications: ['驾驶证', '从业资格证', '健康证']
  43. },
  44. {
  45. id: 'driver_002',
  46. name: '李师傅',
  47. phone: '13800138002',
  48. idCard: '110101198501011234',
  49. licenseNumber: 'A987654321',
  50. licenseType: 'A2',
  51. licenseExpiry: '2027-02-20',
  52. experience: '8年',
  53. rating: 4.9,
  54. totalTrips: 2100,
  55. totalDistance: 280000,
  56. status: 'active',
  57. vehicleId: 'vehicle_002',
  58. vehicleModel: '奔驰V级',
  59. licensePlate: '京B67890',
  60. emergencyContact: {
  61. name: '李太太',
  62. phone: '13900139002',
  63. relationship: '配偶'
  64. },
  65. address: '北京市海淀区某某街道456号',
  66. joinDate: '2018-06-20',
  67. lastLogin: '2024-01-15 09:15:00',
  68. createTime: '2024-01-15 10:00:00',
  69. updateTime: '2024-01-15 10:00:00',
  70. skills: ['安全驾驶', '客户服务', '路线熟悉', '商务接待'],
  71. certifications: ['驾驶证', '从业资格证', '健康证', '商务礼仪证']
  72. },
  73. {
  74. id: 'driver_003',
  75. name: '王师傅',
  76. phone: '13800138003',
  77. idCard: '110101198001011234',
  78. licenseNumber: 'A555666777',
  79. licenseType: 'A1',
  80. licenseExpiry: '2028-03-10',
  81. experience: '10年',
  82. rating: 5.0,
  83. totalTrips: 3200,
  84. totalDistance: 450000,
  85. status: 'active',
  86. vehicleId: 'vehicle_003',
  87. vehicleModel: '奔驰V级豪华版',
  88. licensePlate: '京C11111',
  89. emergencyContact: {
  90. name: '王太太',
  91. phone: '13900139003',
  92. relationship: '配偶'
  93. },
  94. address: '北京市西城区某某街道789号',
  95. joinDate: '2017-01-10',
  96. lastLogin: '2024-01-15 10:00:00',
  97. createTime: '2024-01-15 10:00:00',
  98. updateTime: '2024-01-15 10:00:00',
  99. skills: ['安全驾驶', '客户服务', '路线熟悉', '商务接待', 'VIP服务'],
  100. certifications: ['驾驶证', '从业资格证', '健康证', '商务礼仪证', 'VIP服务证']
  101. }
  102. ];
  103. this.saveDrivers(sampleDrivers);
  104. }
  105. }
  106. // 获取所有司机
  107. getAllDrivers() {
  108. try {
  109. return wx.getStorageSync('drivers') || [];
  110. } catch (error) {
  111. console.error('获取司机数据失败:', error);
  112. return [];
  113. }
  114. }
  115. // 保存司机数据
  116. saveDrivers(drivers) {
  117. try {
  118. wx.setStorageSync('drivers', drivers);
  119. this.notifyListeners(drivers);
  120. return true;
  121. } catch (error) {
  122. console.error('保存司机数据失败:', error);
  123. return false;
  124. }
  125. }
  126. // 根据ID获取司机
  127. getDriverById(driverId) {
  128. const drivers = this.getAllDrivers();
  129. return drivers.find(driver => driver.id === driverId);
  130. }
  131. // 根据电话获取司机
  132. getDriverByPhone(phone) {
  133. const drivers = this.getAllDrivers();
  134. return drivers.find(driver => driver.phone === phone);
  135. }
  136. // 根据车辆ID获取司机
  137. getDriverByVehicleId(vehicleId) {
  138. const drivers = this.getAllDrivers();
  139. return drivers.find(driver => driver.vehicleId === vehicleId);
  140. }
  141. // 创建司机
  142. createDriver(driverData) {
  143. const drivers = this.getAllDrivers();
  144. const newDriver = {
  145. ...driverData,
  146. id: this.generateDriverId(),
  147. createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
  148. updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
  149. status: driverData.status || 'active',
  150. rating: driverData.rating || 5.0,
  151. totalTrips: driverData.totalTrips || 0,
  152. totalDistance: driverData.totalDistance || 0
  153. };
  154. drivers.push(newDriver);
  155. this.saveDrivers(drivers);
  156. return newDriver;
  157. }
  158. // 更新司机
  159. updateDriver(driverId, updateData) {
  160. const drivers = this.getAllDrivers();
  161. const driverIndex = drivers.findIndex(driver => driver.id === driverId);
  162. if (driverIndex === -1) {
  163. throw new Error('司机不存在');
  164. }
  165. drivers[driverIndex] = {
  166. ...drivers[driverIndex],
  167. ...updateData,
  168. updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
  169. };
  170. this.saveDrivers(drivers);
  171. return drivers[driverIndex];
  172. }
  173. // 删除司机
  174. deleteDriver(driverId) {
  175. const drivers = this.getAllDrivers();
  176. const filteredDrivers = drivers.filter(driver => driver.id !== driverId);
  177. if (filteredDrivers.length === drivers.length) {
  178. throw new Error('司机不存在');
  179. }
  180. this.saveDrivers(filteredDrivers);
  181. return true;
  182. }
  183. // 分配司机到车辆
  184. assignDriverToVehicle(driverId, vehicleId) {
  185. const drivers = this.getAllDrivers();
  186. const driverIndex = drivers.findIndex(driver => driver.id === driverId);
  187. if (driverIndex === -1) {
  188. throw new Error('司机不存在');
  189. }
  190. drivers[driverIndex].vehicleId = vehicleId;
  191. drivers[driverIndex].updateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
  192. this.saveDrivers(drivers);
  193. return drivers[driverIndex];
  194. }
  195. // 更新司机状态
  196. updateDriverStatus(driverId, status) {
  197. const drivers = this.getAllDrivers();
  198. const driverIndex = drivers.findIndex(driver => driver.id === driverId);
  199. if (driverIndex === -1) {
  200. throw new Error('司机不存在');
  201. }
  202. drivers[driverIndex].status = status;
  203. drivers[driverIndex].updateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
  204. this.saveDrivers(drivers);
  205. return drivers[driverIndex];
  206. }
  207. // 更新司机评分
  208. updateDriverRating(driverId, newRating) {
  209. const drivers = this.getAllDrivers();
  210. const driverIndex = drivers.findIndex(driver => driver.id === driverId);
  211. if (driverIndex === -1) {
  212. throw new Error('司机不存在');
  213. }
  214. // 计算新的平均评分
  215. const currentRating = drivers[driverIndex].rating;
  216. const totalTrips = drivers[driverIndex].totalTrips;
  217. const newAverageRating = ((currentRating * totalTrips) + newRating) / (totalTrips + 1);
  218. drivers[driverIndex].rating = Math.round(newAverageRating * 10) / 10;
  219. drivers[driverIndex].totalTrips += 1;
  220. drivers[driverIndex].updateTime = new Date().toISOString().replace('T', ' ').substring(0, 19);
  221. this.saveDrivers(drivers);
  222. return drivers[driverIndex];
  223. }
  224. // 搜索司机
  225. searchDrivers(searchParams) {
  226. const drivers = this.getAllDrivers();
  227. let filteredDrivers = [...drivers];
  228. // 按姓名搜索
  229. if (searchParams.name) {
  230. filteredDrivers = filteredDrivers.filter(driver =>
  231. driver.name.toLowerCase().includes(searchParams.name.toLowerCase())
  232. );
  233. }
  234. // 按电话搜索
  235. if (searchParams.phone) {
  236. filteredDrivers = filteredDrivers.filter(driver =>
  237. driver.phone.includes(searchParams.phone)
  238. );
  239. }
  240. // 按状态搜索
  241. if (searchParams.status) {
  242. filteredDrivers = filteredDrivers.filter(driver =>
  243. driver.status === searchParams.status
  244. );
  245. }
  246. // 按驾驶证类型搜索
  247. if (searchParams.licenseType) {
  248. filteredDrivers = filteredDrivers.filter(driver =>
  249. driver.licenseType === searchParams.licenseType
  250. );
  251. }
  252. // 按车辆ID搜索
  253. if (searchParams.vehicleId) {
  254. filteredDrivers = filteredDrivers.filter(driver =>
  255. driver.vehicleId === searchParams.vehicleId
  256. );
  257. }
  258. // 按评分范围搜索
  259. if (searchParams.minRating) {
  260. filteredDrivers = filteredDrivers.filter(driver =>
  261. driver.rating >= searchParams.minRating
  262. );
  263. }
  264. if (searchParams.maxRating) {
  265. filteredDrivers = filteredDrivers.filter(driver =>
  266. driver.rating <= searchParams.maxRating
  267. );
  268. }
  269. // 排序
  270. const sortBy = searchParams.sortBy || 'createTime';
  271. const sortOrder = searchParams.sortOrder || 'desc';
  272. filteredDrivers.sort((a, b) => {
  273. let aValue = a[sortBy];
  274. let bValue = b[sortBy];
  275. if (sortBy === 'createTime' || sortBy === 'updateTime' || sortBy === 'lastLogin') {
  276. aValue = new Date(aValue);
  277. bValue = new Date(bValue);
  278. }
  279. if (sortOrder === 'asc') {
  280. return aValue > bValue ? 1 : -1;
  281. } else {
  282. return aValue < bValue ? 1 : -1;
  283. }
  284. });
  285. return {
  286. drivers: filteredDrivers,
  287. total: filteredDrivers.length,
  288. page: searchParams.page || 1,
  289. pageSize: searchParams.pageSize || 20
  290. };
  291. }
  292. // 获取司机统计信息
  293. getDriverStatistics() {
  294. const drivers = this.getAllDrivers();
  295. const stats = {
  296. total: drivers.length,
  297. byStatus: {},
  298. byLicenseType: {},
  299. byRating: {},
  300. totalTrips: 0,
  301. totalDistance: 0,
  302. averageRating: 0
  303. };
  304. let totalRating = 0;
  305. let ratedDrivers = 0;
  306. drivers.forEach(driver => {
  307. // 按状态统计
  308. stats.byStatus[driver.status] = (stats.byStatus[driver.status] || 0) + 1;
  309. // 按驾驶证类型统计
  310. stats.byLicenseType[driver.licenseType] = (stats.byLicenseType[driver.licenseType] || 0) + 1;
  311. // 按评分统计
  312. const ratingRange = Math.floor(driver.rating);
  313. stats.byRating[ratingRange] = (stats.byRating[ratingRange] || 0) + 1;
  314. // 累计数据
  315. stats.totalTrips += driver.totalTrips;
  316. stats.totalDistance += driver.totalDistance;
  317. if (driver.rating > 0) {
  318. totalRating += driver.rating;
  319. ratedDrivers++;
  320. }
  321. });
  322. // 计算平均评分
  323. if (ratedDrivers > 0) {
  324. stats.averageRating = Math.round((totalRating / ratedDrivers) * 10) / 10;
  325. }
  326. return stats;
  327. }
  328. // 批量更新司机状态
  329. batchUpdateDriverStatus(driverIds, status) {
  330. const drivers = this.getAllDrivers();
  331. const updatedDrivers = drivers.map(driver => {
  332. if (driverIds.includes(driver.id)) {
  333. return {
  334. ...driver,
  335. status,
  336. updateTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
  337. };
  338. }
  339. return driver;
  340. });
  341. this.saveDrivers(updatedDrivers);
  342. return true;
  343. }
  344. // 获取可用司机(用于订单分配)
  345. getAvailableDrivers(vehicleType = null, minRating = 0) {
  346. const drivers = this.getAllDrivers();
  347. return drivers.filter(driver => {
  348. // 状态检查
  349. if (driver.status !== 'active') return false;
  350. // 评分检查
  351. if (driver.rating < minRating) return false;
  352. // 车辆类型检查
  353. if (vehicleType) {
  354. // 这里可以根据车辆类型匹配司机
  355. // 例如:A1驾照可以开大巴,A2驾照可以开商务车等
  356. const licenseTypeMap = {
  357. 'bus': ['A1'],
  358. 'business': ['A1', 'A2'],
  359. 'charter': ['A1', 'A2']
  360. };
  361. if (licenseTypeMap[vehicleType] && !licenseTypeMap[vehicleType].includes(driver.licenseType)) {
  362. return false;
  363. }
  364. }
  365. return true;
  366. });
  367. }
  368. // 导出司机数据
  369. exportDrivers(searchParams = {}) {
  370. const result = this.searchDrivers(searchParams);
  371. return {
  372. drivers: result.drivers,
  373. exportTime: new Date().toISOString(),
  374. total: result.total,
  375. searchParams
  376. };
  377. }
  378. // 生成司机ID
  379. generateDriverId() {
  380. const timestamp = Date.now();
  381. const random = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
  382. return `driver_${timestamp}_${random}`;
  383. }
  384. // 监听器管理
  385. addListener(callback) {
  386. this.listeners.push(callback);
  387. }
  388. removeListener(callback) {
  389. const index = this.listeners.indexOf(callback);
  390. if (index > -1) {
  391. this.listeners.splice(index, 1);
  392. }
  393. }
  394. notifyListeners(drivers) {
  395. this.listeners.forEach(callback => {
  396. try {
  397. callback(drivers);
  398. } catch (error) {
  399. console.error('司机数据监听器回调执行失败:', error);
  400. }
  401. });
  402. }
  403. // 同步司机数据
  404. syncDriverData() {
  405. const drivers = this.getAllDrivers();
  406. this.notifyListeners(drivers);
  407. return drivers;
  408. }
  409. }
  410. // 创建单例实例
  411. const driverManagementApiService = new DriverManagementApiService();
  412. export default driverManagementApiService;