jufubao-takeorder 1.0.2-beta4 → 1.0.2-beta6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/package.json +1 -1
  2. package/src/components/JfbTakeorderFilterOrderList/Api.js +16 -31
  3. package/src/components/JfbTakeorderFilterOrderList/Attr.js +10 -6
  4. package/src/components/JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderList.vue +304 -161
  5. package/src/components/JfbTakeorderFilterOrderList/Mock.js +1 -1
  6. package/src/components/JfbTakeorderFilterOrderList/cusAttr/advanced.js +26 -0
  7. package/src/components/JfbTakeorderFilterOrderList/cusAttr/content.js +9 -0
  8. package/src/components/JfbTakeorderFilterOrderList/cusAttr/style.js +11 -0
  9. package/src/components/JfbTakeorderIndex/Api.js +47 -1
  10. package/src/components/JfbTakeorderIndex/JfbTakeorderIndex.vue +221 -129
  11. package/src/components/JfbTakeorderIndex/Mock.js +4 -4
  12. package/src/components/JfbTakeorderIndex/components/cityPicker.vue +29 -21
  13. package/src/components/JfbTakeorderOrderDetail/Api.js +102 -0
  14. package/src/components/JfbTakeorderOrderDetail/JfbTakeorderOrderDetail.vue +1031 -665
  15. package/src/components/JfbTakeorderOrderDetail/Mock.js +9 -9
  16. package/src/components/JfbTakeorderOrderDetail/components/CusEditQuote.vue +2 -13
  17. package/src/components/JfbTakeorderOrderDetail/components/products.vue +16 -13
  18. package/src/components/JfbTakeorderOrderList/Api.js +16 -31
  19. package/src/components/JfbTakeorderOrderList/JfbTakeorderOrderList.vue +259 -123
  20. package/src/components/JfbTakeorderOrderList/Mock.js +1 -1
  21. package/src/components/JfbTakeorderOrderList/cusAttr/content.js +5 -5
  22. package/src/components/JfbTakeorderVoiceSwitch/Api.js +14 -33
  23. package/src/components/JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitch.vue +154 -105
  24. package/src/components/JfbTakeorderVoiceSwitch/Mock.js +2 -10
  25. package/src/components/JfbTakeorderFilterOrderList/components/order.vue +0 -277
  26. package/src/components/JfbTakeorderIndex/components/order.vue +0 -273
  27. package/src/components/JfbTakeorderOrderList/components/order.vue +0 -273
@@ -22,5 +22,51 @@ module.exports = [
22
22
  params: {},
23
23
  isConsole: true,
24
24
  disabled: true,
25
- }
25
+ },
26
+ {
27
+ mapFnName: 'getOrderList',
28
+ title: '订单列表',
29
+ path: '/takeorder/v1/order',
30
+ isRule: false,
31
+ params: {
32
+ tab: ['tab', 'String', '必选'],
33
+ order_type: ['订单类型', 'Number', '必选'],
34
+ page_token: ['page_token', 'Number', ''],
35
+ page_size: ['page_size', 'Number', ''],
36
+ },
37
+ isConsole: true,
38
+ disabled: true,
39
+ },
40
+ {
41
+ mapFnName: 'getNewOrderNotify',
42
+ title: '新订单通知-轮询(5s轮询一次)',
43
+ path: '/takeorder/v1/new-order/notify',
44
+ isRule: false,
45
+ params: {
46
+ order_type: ['订单类型', 'Number', '必选'],
47
+ max_id: ['订单列表的最大ID,如果不存在,直接传递 0', 'Number', ''],
48
+ },
49
+ isConsole: true,
50
+ disabled: true,
51
+ },
52
+ {
53
+ mapFnName: 'getBrandOptions',
54
+ title: '品牌列表',
55
+ path: '/takeorder/v1/brand/options',
56
+ isRule: false,
57
+ params: {
58
+ order_type: ['订单类型', 'Number', '必选'],
59
+ },
60
+ isConsole: true,
61
+ disabled: true,
62
+ },
63
+ {
64
+ mapFnName: 'getUserConfig',
65
+ title: '获取用户配置',
66
+ path: '/takeorder/v1/user-config',
67
+ isRule: false,
68
+ params: {},
69
+ isConsole: true,
70
+ disabled: true,
71
+ },
26
72
  ];
@@ -145,7 +145,7 @@
145
145
  </view>
146
146
  </view>
147
147
  <view v-show="showFilterQuery" class="modal"></view>
148
- <view style="height: 92rpx"></view>
148
+ <view v-if="!isPreview" style="height: 92rpx"></view>
149
149
  <view
150
150
  v-if="showNew"
151
151
  @click="handleRefresh"
@@ -155,13 +155,19 @@
155
155
  <view>新的订单来了,点我立即刷新</view></view
156
156
  >
157
157
  <view v-for="(item, index) in orderList" :key="index">
158
- <Order
158
+ <CusTakeorder
159
159
  :item="item"
160
160
  :mainColor="mainColor"
161
161
  @expire="handleOrderExpire"
162
162
  @btnEvent="handleBtnEvent"
163
- ></Order>
163
+ ></CusTakeorder>
164
164
  </view>
165
+ <xd-no-data
166
+ icon-type="order"
167
+ :scale-size="2"
168
+ v-if="orderList && orderList.length === 0"
169
+ >暂无订单</xd-no-data
170
+ >
165
171
  </view>
166
172
  </view>
167
173
  </template>
@@ -173,9 +179,12 @@ import JfbTakeorderIndexMixin from "./JfbTakeorderIndexMixin";
173
179
  import XdButton from "@/components/XdButton/XdButton";
174
180
  import { getContainerPropsValue } from "@/utils/xd.base";
175
181
  import componentsMixins from "@/mixins/componentsMixins";
176
- import Order from "./components/order.vue";
182
+ import CusTakeorder from "@/components/CusTakeorder/CusTakeorder";
177
183
  import CityPicker from "./components/cityPicker.vue";
178
184
  import extsMixins from "@/mixins/extsMixins";
185
+ import getServiceUrl from "@/common/getServiceUrl";
186
+ import XdNoData from "@/components/XdNoData/XdNoData";
187
+ import { mapActions } from "vuex";
179
188
  const Color = require("color");
180
189
 
181
190
  export default {
@@ -183,53 +192,19 @@ export default {
183
192
  components: {
184
193
  XdFontIcon,
185
194
  XdButton,
186
- Order,
195
+ CusTakeorder,
187
196
  CityPicker,
197
+ XdNoData,
188
198
  },
189
199
  mixins: [componentsMixins, extsMixins, JfbTakeorderIndexMixin],
190
200
  data() {
191
201
  return {
192
202
  newBackgroundColor: "",
193
203
  showNew: false,
194
- orderList: [
195
- {
196
- id: 1,
197
- num: 15,
198
- people: 30,
199
- remainingTime: 10,
200
- shop_name: "味多美(北京西单大悦城店)",
201
- brand_name: "味多美",
202
- city: "北京市",
203
- products: [
204
- {
205
- product_thumb:
206
- "https://img.js.design/assets/img/68b554c9c3a1ea02642d7d2f.png#afa2b9b9d50bcd2f1394619ecc488a99",
207
- product_name:
208
- "贝欧宝 BIOBOR贝欧宝维生素C+叶黄素酯软糖118g多重营养3D小熊造型糖果Q弹维生素C+叶黄素酯软糖",
209
- product_sku: "118g",
210
- minPrice: 132,
211
- maxPrice: 1232,
212
- num: 15,
213
- },
214
- {
215
- product_thumb:
216
- "https://img.js.design/assets/img/68b554c9c3a1ea02642d7d2f.png#afa2b9b9d50bcd2f1394619ecc488a99",
217
- product_name:
218
- "贝欧宝 BIOBOR贝欧宝维生素C+叶黄素酯软糖118g多重营养3D小熊造型糖果Q弹维生素C+叶黄素酯软糖",
219
- product_sku: "450g",
220
- minPrice: 456,
221
- maxPrice: 1546,
222
- num: 16,
223
- },
224
- ],
225
- market_price: 4000,
226
- minPrice: 456,
227
- maxPrice: 1546,
228
- order_status: 1,
229
- },
230
- ],
204
+ pollTimer: null, // 轮询定时器
205
+ orderList: [],
231
206
  filterType: "",
232
- closeMask: true,
207
+ closeMask: false,
233
208
  cityList: [],
234
209
  provinceList: [],
235
210
  selectedProvs: [],
@@ -242,15 +217,26 @@ export default {
242
217
  cityGroups: [],
243
218
  letters: [],
244
219
  selectedCity: [],
220
+ order_type: "hourdash",
221
+ orderTab: "index",
222
+ page_size: 10,
223
+ page_token: 1,
224
+ hasNext: true,
225
+ next_page_token: "",
226
+ max_id: null,
227
+ order_detail_path: "",
228
+ isPreview: false,
229
+ isOpenNew: "N",
230
+ isOpenWin: "N",
245
231
  };
246
232
  },
247
233
  computed: {
248
234
  menuWrapBoxStyle() {
249
235
  let style = {};
250
- // if (!this.isPreview) {
251
- style["position"] = "fixed";
252
- style["top"] = `${this.layoutInfo.top}rpx`;
253
- // }
236
+ if (!this.isPreview) {
237
+ style["position"] = "fixed";
238
+ style["top"] = `${this.layoutInfo.top}rpx`;
239
+ }
254
240
  return this.styleObjectToString(style);
255
241
  },
256
242
  },
@@ -263,12 +249,31 @@ export default {
263
249
  created() {
264
250
  this.init(this.container);
265
251
  },
252
+ destroyed() {
253
+ // 清除定时器
254
+ this.stopPolling();
255
+ },
266
256
  methods: {
257
+ ...mapActions(["voiceAlert", "playWebSpeech", "playAudioFile"]),
267
258
  onJfbLoad(options) {
268
259
  this.initFilter();
269
- setTimeout(() => {
270
- this.handleGetNew();
271
- }, 1000);
260
+ // 获取订单列表
261
+ this.getList();
262
+
263
+ // 立即调用一次
264
+ if (!this.isPreview) {
265
+ jfbRootExec("getUserConfig", {
266
+ vm: this,
267
+ data: {},
268
+ }).then((res) => {
269
+ this.isOpenNew = res.is_open_new_order_notify_audio;
270
+ this.isOpenWin = res.is_open_win_order_audio;
271
+ // 立即调用一次
272
+ this.handleGetNew();
273
+ // 启动定时器,每5秒调用一次
274
+ this.startPolling();
275
+ });
276
+ }
272
277
  },
273
278
  /**
274
279
  * @description 监听事件变化
@@ -278,6 +283,11 @@ export default {
278
283
  this.newBackgroundColor = Color(this.warningColor).alpha(0.15).toString();
279
284
  this.filterBackground = Color(this.mainColor).alpha(0.15).toString();
280
285
  this.filterBorderColor = Color(this.mainColor).alpha(0.5).toString();
286
+ this.order_detail_path = getContainerPropsValue(
287
+ container,
288
+ "content.order_detail_path",
289
+ { value: "" }
290
+ ).value;
281
291
  if (this.$configProject["isPreview"]) {
282
292
  this.isPreview = true;
283
293
  }
@@ -292,26 +302,77 @@ export default {
292
302
  vm: this,
293
303
  data: {},
294
304
  }),
305
+ jfbRootExec("getBrandOptions", {
306
+ vm: this,
307
+ data: {
308
+ order_type: this.order_type,
309
+ },
310
+ }),
295
311
  ])
296
312
  .then((res) => {
297
- debugger;
298
313
  res[1].list.unshift({ label: "全部", value: "all" });
299
314
  const processedData = this.processCityData(res[0]);
300
315
  this.hotCities = processedData.hotCities;
301
316
  this.cityGroups = processedData.cityGroups;
302
317
  this.letters = processedData.letters;
303
318
  this.provinceList = this.ensureLengthMultipleOfFour(res[1].list);
304
- this.brandList = this.ensureLengthMultipleOfFour([
305
- { label: "味多美", value: "味多美" },
306
- { label: "好利来", value: "好利来" },
307
- { label: "哈根达斯", value: "哈根达斯" },
308
- { label: "必胜客", value: "必胜客" },
309
- { label: "麦当劳", value: "麦当劳" },
310
- { label: "肯德基", value: "肯德基" },
311
- ]);
319
+ this.brandList = this.ensureLengthMultipleOfFour(res[2].list);
312
320
  })
313
321
  .catch();
314
322
  },
323
+ /**
324
+ * 获取订单列表
325
+ */
326
+ getList() {
327
+ // 构建请求参数
328
+ const params = {
329
+ tab: this.orderTab, // tab参数,暂时传空字符串
330
+ order_type: this.order_type,
331
+ page_token: this.page_token, // 初始分页token
332
+ page_size: this.page_size, // 每页数量
333
+ };
334
+
335
+ // 只有当有选择时,才添加筛选参数,如果选择了 'all' 则不传
336
+ if (this.selectedProvs && this.selectedProvs.length > 0) {
337
+ // 如果只有一个选项且为 'all',则不传 province_codes
338
+ if (!(this.selectedProvs.length === 1 && this.selectedProvs[0] === 'all')) {
339
+ params.province_codes = this.selectedProvs;
340
+ }
341
+ }
342
+ if (this.selectedCity && this.selectedCity.length > 0) {
343
+ params.city_codes = this.selectedCity;
344
+ }
345
+ if (this.selectedBrands && this.selectedBrands.length > 0) {
346
+ params.brand_ids = this.selectedBrands;
347
+ }
348
+
349
+ jfbRootExec("getOrderList", {
350
+ vm: this,
351
+ data: params,
352
+ })
353
+ .then((res) => {
354
+ // 设置订单列表数据
355
+ let list = res.list.map((item) => {
356
+ item.product_list = item.product_list.map((prod, i) => {
357
+ prod["product_thumb"] = prod.product_thumb
358
+ ? getServiceUrl(prod.product_thumb, "size3")
359
+ : "";
360
+ return prod;
361
+ });
362
+ return item;
363
+ });
364
+ if (this.page_token === 1) {
365
+ this.orderList = list;
366
+ } else {
367
+ this.orderList = this.orderList.concat(list);
368
+ }
369
+ this.hasNext = res.next_page_token !== "";
370
+ this.next_page_token = res.next_page_token;
371
+ })
372
+ .catch((err) => {
373
+ console.error("获取订单列表失败:", err);
374
+ });
375
+ },
315
376
  /**
316
377
  * 处理城市接口数据,转换为组件所需格式
317
378
  * @param {Object} rawData - 接口返回的原始城市数据
@@ -417,28 +478,6 @@ export default {
417
478
  // 6. 合并原始数据和占位符,并返回新数组
418
479
  return [...data, ...placeholders];
419
480
  },
420
- /**
421
- * 计算订单剩余时间(秒)
422
- */
423
- calculateRemainingTime(expireTime) {
424
- const now = Date.now();
425
- return expireTime > now ? Math.floor((expireTime - now) / 1000) : 0;
426
- },
427
- /**
428
- * 校准所有订单的倒计时
429
- */
430
- calibrateAllCountdowns() {
431
- this.orderList.forEach((order) => {
432
- if (order.status === "pending") {
433
- const remainingTime = this.calculateRemainingTime(order.expireTime);
434
- this.$set(order, "remainingTime", remainingTime);
435
- // 如果校准后发现订单已经过期,直接触发状态更新
436
- if (remainingTime <= 0 && !order.isUpdating) {
437
- this.handleOrderExpire(order.id);
438
- }
439
- }
440
- });
441
- },
442
481
  isOptionSelected(item) {
443
482
  let selects = [];
444
483
  if (this.filterType === "province") selects = this.selectedProvs;
@@ -447,51 +486,17 @@ export default {
447
486
  },
448
487
  /**
449
488
  * 处理子组件派发的 'expire' 事件
489
+ * 订单倒计时结束后,从列表中删除该订单
450
490
  */
451
- async handleOrderExpire(orderId) {
491
+ handleOrderExpire(orderId) {
492
+ if (this.isPreview) return;
452
493
  const orderIndex = this.orderList.findIndex(
453
- (item) => item.id === orderId
494
+ (item) => item.order_id === orderId
454
495
  );
455
496
  if (orderIndex === -1) return;
456
497
 
457
- // 在发起请求前,先在本地标记为更新中,以防止重复请求
458
- this.$set(this.orderList[orderIndex], "isUpdating", true);
459
- this.$set(this.orderList[orderIndex], "status", "pending");
460
- this.$set(this.orderList[orderIndex], "remainingTime", 50);
461
- // try {
462
- // // 父组件统一发起 API 请求
463
- // const res = await uni.request({
464
- // url: `https://api.example.com/orders/${orderId}/expire`,
465
- // method: "PUT",
466
- // });
467
-
468
- // if (res.statusCode === 200 && res.data.success) {
469
- // // API 请求成功,更新本地数据
470
- // this.$set(this.orderList[orderIndex], "status", "expired");
471
- // this.$set(this.orderList[orderIndex], "remainingTime", 0);
472
- // } else {
473
- // throw new Error("API 请求返回失败");
474
- // }
475
- // } catch (error) {
476
- // console.error(`订单 ${orderId} 状态更新失败:`, error);
477
- // // 请求失败,取消本地更新中状态,并可以实现重试逻辑
478
- // this.$set(this.orderList[orderIndex], "isUpdating", false);
479
-
480
- // // 简单的重试逻辑
481
- // uni.showToast({ title: "订单状态更新失败,正在重试...", icon: "none" });
482
- // setTimeout(() => {
483
- // this.handleOrderExpire(orderId);
484
- // }, 3000);
485
- // } finally {
486
- // // 无论成功失败,都清除更新中标记(如果还存在的话)
487
- // // 注意:在 try 块的成功分支中已经改变了状态,这里主要处理失败的情况
488
- // if (
489
- // this.orderList[orderIndex] &&
490
- // this.orderList[orderIndex].isUpdating
491
- // ) {
492
- // this.$set(this.orderList[orderIndex], "isUpdating", false);
493
- // }
494
- // }
498
+ // 从列表中删除该订单
499
+ this.orderList.splice(orderIndex, 1);
495
500
  },
496
501
  handleSwitchFilter(type) {
497
502
  if (this.filterType === type) {
@@ -551,11 +556,78 @@ export default {
551
556
  }
552
557
  },
553
558
  handleGetNew() {
554
- console.log("获取是否有新订单");
555
- this.showNew = true;
559
+ jfbRootExec("getNewOrderNotify", {
560
+ vm: this,
561
+ data: {
562
+ order_type: this.order_type,
563
+ max_id: this.max_id || 0,
564
+ },
565
+ })
566
+ .then((res) => {
567
+ if (res.is_exist_new_order && res.is_exist_win_order) {
568
+ if (this.isOpenNew === "Y") {
569
+ this.voiceAlert({
570
+ type: "new",
571
+ filePath: "https://img.jufubao.cn/takeorder/new_order.mp3",
572
+ });
573
+ }
574
+ if (this.isOpenWin === "Y") {
575
+ setTimeout(() => {
576
+ this.voiceAlert({
577
+ type: "win",
578
+ filePath: "https://img.jufubao.cn/takeorder/wait_order.mp3",
579
+ });
580
+ }, 1000);
581
+ }
582
+ } else if (res.is_exist_new_order) {
583
+ if (this.isOpenNew === "Y") {
584
+ this.voiceAlert({
585
+ type: "new",
586
+ filePath: "https://img.jufubao.cn/takeorder/new_order.mp3",
587
+ });
588
+ }
589
+ } else if (res.is_exist_win_order) {
590
+ if (this.isOpenWin === "Y") {
591
+ this.voiceAlert({
592
+ type: "win",
593
+ filePath: "https://img.jufubao.cn/takeorder/wait_order.mp3",
594
+ });
595
+ }
596
+ }
597
+ this.max_id = res.new_order_max_id;
598
+ this.showNew = res.is_exist_new_order;
599
+ })
600
+ .catch((err) => {
601
+ console.error("获取新订单通知失败:", err);
602
+ });
603
+ },
604
+ /**
605
+ * 启动轮询定时器
606
+ */
607
+ startPolling() {
608
+ // 如果已经存在定时器,先清除
609
+ if (this.pollTimer) {
610
+ clearInterval(this.pollTimer);
611
+ }
612
+ // 每5秒调用一次接口
613
+ this.pollTimer = setInterval(() => {
614
+ console.log("startPolling");
615
+ this.handleGetNew();
616
+ }, 5000);
617
+ },
618
+ /**
619
+ * 停止轮询定时器
620
+ */
621
+ stopPolling() {
622
+ if (this.pollTimer) {
623
+ clearInterval(this.pollTimer);
624
+ this.pollTimer = null;
625
+ }
556
626
  },
557
627
  handleRefresh() {
558
- //刷新列表
628
+ // 刷新列表
629
+ this.getList();
630
+ this.showNew = false;
559
631
  },
560
632
  handleCitySelect(city) {
561
633
  const index = this.selectedCity.findIndex(
@@ -579,23 +651,43 @@ export default {
579
651
  if (this.filterType === "city") {
580
652
  this.selectedCity = [];
581
653
  }
654
+ this.filterType = "";
582
655
  this.showFilterQuery = false;
656
+ this.getList();
583
657
  },
584
658
  handleConfirmFilter() {
585
659
  this.showFilterQuery = false;
586
- //重新调用接口
660
+ this.filterType = "";
661
+ // 重新调用接口
662
+ this.getList();
587
663
  },
588
- onJfbScroll(options) {
589
- console.log("event.onJfbScroll", options);
664
+ /**
665
+ * 处理按钮事件,跳转到订单详情
666
+ * @param {Object} item - 订单对象
667
+ */
668
+ handleBtnEvent({ item, btn }) {
669
+ // 跳转到订单详情页
670
+ this.$xdUniHelper.navigateTo({
671
+ url: `${this.order_detail_path}?order_id=${item.order_id}`,
672
+ });
590
673
  },
674
+ onJfbScroll(options) {},
591
675
  onJfbReachBottom(options) {
592
- console.log("event.onJfbReachBottom", options);
676
+ if (this.hasNext) {
677
+ this.page_token = this.next_page_token;
678
+ this.getList();
679
+ }
593
680
  },
594
681
  onJfbShow(options) {
595
- this.calibrateAllCountdowns();
682
+ // 页面显示时恢复轮询
683
+ if (!this.pollTimer) {
684
+ this.startPolling();
685
+ }
596
686
  console.log("event.onJfbShow", options);
597
687
  },
598
688
  onJfbHide(options) {
689
+ // 页面隐藏时暂停轮询
690
+ this.stopPolling();
599
691
  console.log("event.onJfbHide", options);
600
692
  },
601
693
  onJfbBack(options) {