order.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // order.js
  2. const mockData = require('../../utils/mockData.js')
  3. Page({
  4. data: {
  5. currentTab: 0,
  6. hospitalKeyword: '',
  7. medicineKeyword: '',
  8. hospitals: mockData.hospitals,
  9. filteredHospitals: mockData.hospitals,
  10. priceResults: [],
  11. selectedMedicine: null,
  12. hotMedicines: [
  13. { name: '阿莫西林胶囊', minPrice: 24.8 },
  14. { name: '布洛芬缓释胶囊', minPrice: 17.5 },
  15. { name: '氯雷他定片', minPrice: 30.5 },
  16. { name: '奥美拉唑肠溶胶囊', minPrice: 45.0 }
  17. ],
  18. otherMedicines: [],
  19. selectedMedicineQuantity: {},
  20. showCaseModal: false,
  21. showMedicineModal: false,
  22. showPriceConfirmModal: false,
  23. selectedHospital: null,
  24. selectedCase: null,
  25. selectedMedicines: [],
  26. selectedPriceItem: null,
  27. totalPrice: 0,
  28. deliveryAddress: ''
  29. },
  30. onLoad() {
  31. console.log('下单页面加载完成')
  32. this.loadOtherMedicines()
  33. },
  34. loadOtherMedicines() {
  35. const hotMedicineNames = this.data.hotMedicines.map(m => m.name)
  36. const otherMedicines = []
  37. for (const medicineName in mockData.medicinePrices) {
  38. if (!hotMedicineNames.includes(medicineName)) {
  39. const prices = mockData.medicinePrices[medicineName]
  40. const minPrice = Math.min(...prices.map(p => p.price))
  41. otherMedicines.push({
  42. name: medicineName,
  43. minPrice: minPrice
  44. })
  45. }
  46. }
  47. this.setData({
  48. otherMedicines: otherMedicines
  49. })
  50. },
  51. // 切换选项卡
  52. switchTab(e) {
  53. const tab = parseInt(e.currentTarget.dataset.tab)
  54. this.setData({
  55. currentTab: tab
  56. })
  57. },
  58. // 医院搜索
  59. onHospitalSearch(e) {
  60. const keyword = e.detail.value
  61. const filteredHospitals = this.data.hospitals.filter(hospital =>
  62. hospital.name.includes(keyword) || hospital.address.includes(keyword)
  63. )
  64. this.setData({
  65. hospitalKeyword: keyword,
  66. filteredHospitals: filteredHospitals
  67. })
  68. },
  69. // 药品搜索
  70. onMedicineSearch(e) {
  71. const keyword = e.detail.value.trim()
  72. this.setData({
  73. medicineKeyword: keyword,
  74. selectedMedicine: null,
  75. priceResults: []
  76. })
  77. if (!keyword) {
  78. // 清空搜索时,重新加载所有药品信息
  79. this.loadOtherMedicines()
  80. return
  81. }
  82. // 模糊搜索:查找包含关键词的药品
  83. const matchedMedicines = []
  84. for (const medicineName in mockData.medicinePrices) {
  85. if (medicineName.includes(keyword)) {
  86. const prices = mockData.medicinePrices[medicineName]
  87. const minPrice = Math.min(...prices.map(p => p.price))
  88. matchedMedicines.push({
  89. name: medicineName,
  90. minPrice: minPrice
  91. })
  92. }
  93. }
  94. // 将搜索结果显示在药品信息模块中
  95. this.setData({
  96. otherMedicines: matchedMedicines
  97. })
  98. },
  99. // 选择医院
  100. selectHospital(e) {
  101. const hospital = e.currentTarget.dataset.hospital
  102. this.setData({
  103. selectedHospital: hospital,
  104. showCaseModal: true
  105. })
  106. },
  107. // 关闭病例单模态框
  108. closeCaseModal() {
  109. this.setData({
  110. showCaseModal: false,
  111. selectedHospital: null
  112. })
  113. },
  114. // 选择病例单
  115. selectCase(e) {
  116. const selectedCase = e.currentTarget.dataset.case
  117. // 初始化药品数量
  118. const medicines = selectedCase.medicines.map(medicine => ({
  119. ...medicine,
  120. quantity: 0
  121. }))
  122. this.setData({
  123. selectedCase: { ...selectedCase, medicines },
  124. showCaseModal: false,
  125. showMedicineModal: true
  126. })
  127. },
  128. // 关闭药品模态框
  129. closeMedicineModal() {
  130. this.setData({
  131. showMedicineModal: false,
  132. selectedCase: null,
  133. selectedMedicines: [],
  134. totalPrice: 0,
  135. deliveryAddress: ''
  136. })
  137. },
  138. // 增加药品数量
  139. increaseQuantity(e) {
  140. const medicine = e.currentTarget.dataset.medicine
  141. const medicines = this.data.selectedCase.medicines.map(item => {
  142. if (item.id === medicine.id) {
  143. const quantity = (item.quantity || 0) + 1
  144. return { ...item, quantity }
  145. }
  146. return item
  147. })
  148. const totalPrice = medicines.reduce((total, item) => total + (item.price * (item.quantity || 0)), 0)
  149. this.setData({
  150. 'selectedCase.medicines': medicines,
  151. totalPrice: totalPrice
  152. })
  153. },
  154. // 减少药品数量
  155. decreaseQuantity(e) {
  156. const medicine = e.currentTarget.dataset.medicine
  157. const medicines = this.data.selectedCase.medicines.map(item => {
  158. if (item.id === medicine.id && (item.quantity || 0) > 0) {
  159. const quantity = item.quantity - 1
  160. return { ...item, quantity }
  161. }
  162. return item
  163. })
  164. const totalPrice = medicines.reduce((total, item) => total + (item.price * (item.quantity || 0)), 0)
  165. this.setData({
  166. 'selectedCase.medicines': medicines,
  167. totalPrice: totalPrice
  168. })
  169. },
  170. // 地址输入处理
  171. onAddressInput(e) {
  172. this.setData({
  173. deliveryAddress: e.detail.value
  174. })
  175. },
  176. // 使用默认地址
  177. useDefaultAddress() {
  178. const app = getApp()
  179. const userInfo = app.globalData.userInfo || mockData.userInfo
  180. if (userInfo && userInfo.defaultAddress) {
  181. this.setData({
  182. deliveryAddress: userInfo.defaultAddress
  183. })
  184. wx.showToast({
  185. title: '已使用默认地址',
  186. icon: 'success'
  187. })
  188. } else {
  189. wx.showToast({
  190. title: '暂无默认地址',
  191. icon: 'none'
  192. })
  193. }
  194. },
  195. // 确认下单
  196. confirmOrder() {
  197. const selectedMedicines = this.data.selectedCase.medicines
  198. .filter(item => item.quantity > 0)
  199. .map(item => ({
  200. name: item.name,
  201. price: item.price,
  202. quantity: item.quantity
  203. }))
  204. if (selectedMedicines.length === 0) {
  205. wx.showToast({
  206. title: '请选择至少一种药品',
  207. icon: 'none'
  208. })
  209. return
  210. }
  211. // 验证送货地址
  212. if (!this.data.deliveryAddress || this.data.deliveryAddress.trim() === '') {
  213. wx.showToast({
  214. title: '请输入送货地址',
  215. icon: 'none'
  216. })
  217. return
  218. }
  219. // 根据医院生成地图轨迹数据
  220. const hospitalLocation = this.getHospitalLocation(this.data.selectedHospital.name)
  221. const mapTracking = this.generateMapTracking(hospitalLocation)
  222. // 创建订单数据
  223. const order = {
  224. id: Date.now(),
  225. hospital: this.data.selectedHospital.name,
  226. medicines: selectedMedicines.map(m => m.name),
  227. totalPrice: this.data.totalPrice,
  228. status: '配送中',
  229. date: new Date().toISOString().split('T')[0],
  230. deliveryAddress: this.data.deliveryAddress,
  231. droneTracking: {
  232. status: '配送中',
  233. steps: ['订单确认', '药品准备', '无人机起飞', '配送中', '待送达']
  234. },
  235. mapTracking: mapTracking
  236. }
  237. // 保存订单到全局变量和本地存储
  238. const app = getApp()
  239. app.addOrder(order)
  240. // 模拟下单成功
  241. wx.showModal({
  242. title: '下单成功',
  243. content: `订单总价:¥${this.data.totalPrice}\n送货地址:${this.data.deliveryAddress}\n药品将尽快通过无人机配送`,
  244. showCancel: false,
  245. success: () => {
  246. this.closeMedicineModal()
  247. // 跳转到我的页面查看订单
  248. setTimeout(() => {
  249. wx.switchTab({
  250. url: '/pages/profile/profile'
  251. })
  252. }, 500)
  253. }
  254. })
  255. },
  256. // 选择药品
  257. selectMedicine(e) {
  258. const medicineName = e.currentTarget.dataset.medicine
  259. this.setData({
  260. selectedMedicine: medicineName
  261. })
  262. if (mockData.medicinePrices[medicineName]) {
  263. const priceResults = mockData.medicinePrices[medicineName].map(item => {
  264. const hospital = this.data.hospitals.find(h => h.name === item.hospital)
  265. return {
  266. ...item,
  267. distance: hospital ? hospital.distance : '未知'
  268. }
  269. })
  270. this.setData({
  271. priceResults: priceResults
  272. })
  273. }
  274. },
  275. // 获取医院位置
  276. getHospitalLocation(hospitalName) {
  277. const locations = {
  278. '北京协和医院': { latitude: 39.9139, longitude: 116.3917 },
  279. '上海瑞金医院': { latitude: 31.2304, longitude: 121.4737 },
  280. '广州中山医院': { latitude: 23.1291, longitude: 113.2644 },
  281. '北京大学第一医院': { latitude: 39.9289, longitude: 116.3883 },
  282. '上海华山医院': { latitude: 31.2165, longitude: 121.4449 },
  283. '广东省人民医院': { latitude: 23.1256, longitude: 113.2732 },
  284. '北京301医院': { latitude: 39.9135, longitude: 116.2766 },
  285. '上海仁济医院': { latitude: 31.2269, longitude: 121.4997 },
  286. '广州南方医院': { latitude: 23.1825, longitude: 113.2767 },
  287. '北京中日友好医院': { latitude: 39.9792, longitude: 116.4472 },
  288. '上海长征医院': { latitude: 31.2317, longitude: 121.4708 },
  289. '广东省中医院': { latitude: 23.1215, longitude: 113.2665 },
  290. '北京天坛医院': { latitude: 39.8726, longitude: 116.4168 },
  291. '上海第九人民医院': { latitude: 31.2304, longitude: 121.4851 },
  292. '广州华侨医院': { latitude: 23.1358, longitude: 113.3245 },
  293. '北京安贞医院': { latitude: 39.9432, longitude: 116.4134 },
  294. '上海新华医院': { latitude: 31.2576, longitude: 121.5119 },
  295. '广州医科大学附属第一医院': { latitude: 23.1258, longitude: 113.2587 },
  296. '北京朝阳医院': { latitude: 39.9299, longitude: 116.4443 },
  297. '上海第六人民医院': { latitude: 31.1884, longitude: 121.4367 }
  298. }
  299. return locations[hospitalName] || { latitude: 39.9042, longitude: 116.4074 }
  300. },
  301. // 生成地图轨迹数据
  302. generateMapTracking(hospitalLocation) {
  303. const points = []
  304. const numPoints = 5
  305. for (let i = 0; i < numPoints; i++) {
  306. const latOffset = (i * 0.004) / numPoints
  307. const lngOffset = (i * 0.007) / numPoints
  308. points.push({
  309. latitude: hospitalLocation.latitude + latOffset,
  310. longitude: hospitalLocation.longitude + lngOffset
  311. })
  312. }
  313. return {
  314. polyline: [
  315. {
  316. points: points,
  317. color: '#007AFF',
  318. width: 4,
  319. dottedLine: false
  320. }
  321. ],
  322. markers: [
  323. {
  324. id: 1,
  325. latitude: hospitalLocation.latitude,
  326. longitude: hospitalLocation.longitude,
  327. iconPath: '/images/hospital-marker.png',
  328. width: 30,
  329. height: 30,
  330. title: '医院位置'
  331. },
  332. {
  333. id: 2,
  334. latitude: points[points.length - 1].latitude,
  335. longitude: points[points.length - 1].longitude,
  336. iconPath: '/images/drone-marker.png',
  337. width: 30,
  338. height: 30,
  339. title: '无人机位置'
  340. }
  341. ]
  342. }
  343. },
  344. // 返回药品列表
  345. backToMedicines() {
  346. this.setData({
  347. selectedMedicine: null,
  348. priceResults: []
  349. })
  350. },
  351. // 通过价格选择医院
  352. selectByPrice(e) {
  353. const priceInfo = e.currentTarget.dataset.price
  354. const medicineName = this.data.selectedMedicine
  355. // 显示确认模态框
  356. this.setData({
  357. showPriceConfirmModal: true,
  358. selectedPriceItem: {
  359. medicine: medicineName,
  360. hospital: priceInfo.hospital,
  361. price: priceInfo.price,
  362. distance: priceInfo.distance
  363. },
  364. deliveryAddress: ''
  365. })
  366. },
  367. // 增加比价药品数量
  368. increasePriceQuantity(e) {
  369. const hospital = e.currentTarget.dataset.hospital
  370. const selectedMedicineQuantity = { ...this.data.selectedMedicineQuantity }
  371. selectedMedicineQuantity[hospital] = (selectedMedicineQuantity[hospital] || 0) + 1
  372. this.setData({
  373. selectedMedicineQuantity
  374. })
  375. },
  376. // 减少比价药品数量
  377. decreasePriceQuantity(e) {
  378. const hospital = e.currentTarget.dataset.hospital
  379. const selectedMedicineQuantity = { ...this.data.selectedMedicineQuantity }
  380. if ((selectedMedicineQuantity[hospital] || 0) > 0) {
  381. selectedMedicineQuantity[hospital] = selectedMedicineQuantity[hospital] - 1
  382. this.setData({
  383. selectedMedicineQuantity
  384. })
  385. }
  386. },
  387. // 关闭比价确认模态框
  388. closePriceConfirmModal() {
  389. this.setData({
  390. showPriceConfirmModal: false,
  391. selectedPriceItem: null,
  392. deliveryAddress: ''
  393. })
  394. },
  395. // 确认比价下单
  396. confirmPriceOrder() {
  397. // 验证送货地址
  398. if (!this.data.deliveryAddress || this.data.deliveryAddress.trim() === '') {
  399. wx.showToast({
  400. title: '请输入送货地址',
  401. icon: 'none'
  402. })
  403. return
  404. }
  405. const selectedPriceItem = this.data.selectedPriceItem
  406. const quantity = this.data.selectedMedicineQuantity[selectedPriceItem.hospital] || 1
  407. // 根据医院生成地图轨迹数据
  408. const hospitalLocation = this.getHospitalLocation(selectedPriceItem.hospital)
  409. const mapTracking = this.generateMapTracking(hospitalLocation)
  410. // 创建订单数据
  411. const order = {
  412. id: Date.now(),
  413. hospital: selectedPriceItem.hospital,
  414. medicines: [selectedPriceItem.medicine],
  415. totalPrice: selectedPriceItem.price * quantity,
  416. quantity: quantity,
  417. status: '配送中',
  418. date: new Date().toISOString().split('T')[0],
  419. deliveryAddress: this.data.deliveryAddress,
  420. droneTracking: {
  421. status: '配送中',
  422. steps: ['订单确认', '药品准备', '无人机起飞', '配送中', '待送达']
  423. },
  424. mapTracking: mapTracking
  425. }
  426. // 保存订单到全局变量和本地存储
  427. const app = getApp()
  428. app.addOrder(order)
  429. // 保存地址用于显示
  430. const savedAddress = this.data.deliveryAddress
  431. // 关闭模态框
  432. this.setData({
  433. showPriceConfirmModal: false,
  434. selectedPriceItem: null,
  435. deliveryAddress: '',
  436. selectedMedicineQuantity: {}
  437. })
  438. wx.showModal({
  439. title: '下单成功',
  440. content: `订单总价:¥${selectedPriceItem.price * quantity}\n药品数量:${quantity}\n送货地址:${savedAddress}\n药品将尽快通过无人机配送`,
  441. showCancel: false,
  442. success: () => {
  443. // 跳转到我的页面查看订单
  444. setTimeout(() => {
  445. wx.switchTab({
  446. url: '/pages/profile/profile'
  447. })
  448. }, 500)
  449. }
  450. })
  451. }
  452. })