jufubao-takeorder 1.0.1 → 1.0.2-beta10

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 (46) hide show
  1. package/package.json +1 -1
  2. package/src/components/JfbTakeorderFilterOrderList/Api.js +43 -0
  3. package/src/components/JfbTakeorderFilterOrderList/Attr.js +16 -0
  4. package/src/components/JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderList.vue +353 -0
  5. package/src/components/JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderListLess.less +80 -0
  6. package/src/components/JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderListMixin.js +30 -0
  7. package/src/components/JfbTakeorderFilterOrderList/Mock.js +13 -0
  8. package/src/components/JfbTakeorderFilterOrderList/cusAttr/advanced.js +26 -0
  9. package/src/components/JfbTakeorderFilterOrderList/cusAttr/content.js +9 -0
  10. package/src/components/JfbTakeorderFilterOrderList/cusAttr/style.js +11 -0
  11. package/src/components/JfbTakeorderIndex/Api.js +72 -0
  12. package/src/components/JfbTakeorderIndex/Attr.js +16 -0
  13. package/src/components/JfbTakeorderIndex/JfbTakeorderIndex.vue +851 -0
  14. package/src/components/JfbTakeorderIndex/JfbTakeorderIndexLess.less +80 -0
  15. package/src/components/JfbTakeorderIndex/JfbTakeorderIndexMixin.js +30 -0
  16. package/src/components/JfbTakeorderIndex/Mock.js +13 -0
  17. package/src/components/JfbTakeorderIndex/components/cityPicker.vue +307 -0
  18. package/src/components/JfbTakeorderIndex/cusAttr/advanced.js +26 -0
  19. package/src/components/JfbTakeorderIndex/cusAttr/content.js +9 -0
  20. package/src/components/JfbTakeorderIndex/cusAttr/style.js +11 -0
  21. package/src/components/JfbTakeorderOrderDetail/Api.js +125 -0
  22. package/src/components/JfbTakeorderOrderDetail/Attr.js +16 -0
  23. package/src/components/JfbTakeorderOrderDetail/JfbTakeorderOrderDetail.vue +1211 -0
  24. package/src/components/JfbTakeorderOrderDetail/JfbTakeorderOrderDetailLess.less +80 -0
  25. package/src/components/JfbTakeorderOrderDetail/JfbTakeorderOrderDetailMixin.js +30 -0
  26. package/src/components/JfbTakeorderOrderDetail/Mock.js +13 -0
  27. package/src/components/JfbTakeorderOrderDetail/components/CusEditQuote.vue +150 -0
  28. package/src/components/JfbTakeorderOrderDetail/components/products.vue +141 -0
  29. package/src/components/JfbTakeorderOrderDetail/cusAttr/advanced.js +12 -0
  30. package/src/components/JfbTakeorderOrderDetail/cusAttr/content.js +233 -0
  31. package/src/components/JfbTakeorderOrderDetail/cusAttr/style.js +11 -0
  32. package/src/components/JfbTakeorderOrderList/Api.js +43 -0
  33. package/src/components/JfbTakeorderOrderList/Attr.js +16 -0
  34. package/src/components/JfbTakeorderOrderList/JfbTakeorderOrderList.vue +320 -0
  35. package/src/components/JfbTakeorderOrderList/JfbTakeorderOrderListLess.less +80 -0
  36. package/src/components/JfbTakeorderOrderList/JfbTakeorderOrderListMixin.js +30 -0
  37. package/src/components/JfbTakeorderOrderList/Mock.js +13 -0
  38. package/src/components/JfbTakeorderOrderList/cusAttr/advanced.js +26 -0
  39. package/src/components/JfbTakeorderOrderList/cusAttr/content.js +23 -0
  40. package/src/components/JfbTakeorderOrderList/cusAttr/style.js +11 -0
  41. package/src/components/JfbTakeorderVoiceSwitch/Api.js +39 -0
  42. package/src/components/JfbTakeorderVoiceSwitch/Attr.js +12 -0
  43. package/src/components/JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitch.vue +191 -0
  44. package/src/components/JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitchLess.less +80 -0
  45. package/src/components/JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitchMixin.js +30 -0
  46. package/src/components/JfbTakeorderVoiceSwitch/Mock.js +5 -0
@@ -0,0 +1,851 @@
1
+ <template>
2
+ <view
3
+ class="jfb-takeorder-index"
4
+ @click="handleEditxSelect"
5
+ :class="{ editx: isEditx && active }"
6
+ >
7
+ <!--#ifdef H5-->
8
+ <view
9
+ class="jfb-takeorder-index__edit"
10
+ :class="{ editx: isEditx && active }"
11
+ v-if="isEditx && active"
12
+ >
13
+ <view class="jfb-takeorder-index__edit-icon" @click.stop="delEdit">
14
+ <xd-font-icon
15
+ icon="iconshanchu-01"
16
+ color="#fff"
17
+ size="30"
18
+ ></xd-font-icon>
19
+ </view>
20
+ </view>
21
+ <!-- #endif -->
22
+ <view class="jfb-takeorder-index__body">
23
+ <view class="menu_wrap" :style="[menuWrapBoxStyle]">
24
+ <view class="jfb-takeorder-index__body-filter">
25
+ <view
26
+ :style="{
27
+ color:
28
+ filterType === 'province' || selectedProvs.length > 0
29
+ ? mainColor
30
+ : '',
31
+ }"
32
+ @click="handleSwitchFilter('province')"
33
+ class="jfb-takeorder-index__body-filter-item"
34
+ >
35
+ <view v-if="selectedProvs.length === 0">省份</view>
36
+ <view v-else class="jfb-takeorder-index__body-filter-text">{{
37
+ selectedProvsName.join("")
38
+ }}</view>
39
+ <XdFontIcon
40
+ style="font-weight: bolder"
41
+ size="20"
42
+ icon="iconxia_down"
43
+ ></XdFontIcon
44
+ ></view>
45
+ <view
46
+ :style="{
47
+ color:
48
+ filterType === 'city' || selectedCity.length > 0
49
+ ? mainColor
50
+ : '',
51
+ }"
52
+ @click="handleSwitchFilter('city')"
53
+ class="jfb-takeorder-index__body-filter-item"
54
+ ><view v-if="selectedCity.length === 0">城市</view
55
+ ><view v-else class="jfb-takeorder-index__body-filter-text">{{
56
+ selectedCityName.join("")
57
+ }}</view>
58
+ <XdFontIcon
59
+ style="font-weight: bolder"
60
+ size="20"
61
+ icon="iconxia_down"
62
+ ></XdFontIcon
63
+ ></view>
64
+ <view
65
+ :style="{
66
+ color:
67
+ filterType === 'brand' || selectedBrands.length > 0
68
+ ? mainColor
69
+ : '',
70
+ }"
71
+ @click="handleSwitchFilter('brand')"
72
+ class="jfb-takeorder-index__body-filter-item"
73
+ ><view v-if="selectedBrands.length === 0">品牌</view
74
+ ><view v-else class="jfb-takeorder-index__body-filter-text">{{
75
+ selectedBrandsName.join("")
76
+ }}</view>
77
+ <XdFontIcon
78
+ style="font-weight: bolder"
79
+ size="20"
80
+ icon="iconxia_down"
81
+ ></XdFontIcon
82
+ ></view>
83
+ </view>
84
+ <view
85
+ v-if="showFilterQuery"
86
+ class="jfb-takeorder-index__body-query-filter"
87
+ >
88
+ <view class="jfb-takeorder-index__body-query-filter-wrap">
89
+ <view
90
+ v-if="filterType === 'province'"
91
+ class="jfb-takeorder-index__body-query-filter-province"
92
+ >
93
+ <view
94
+ @click="handleChooseProvince(item)"
95
+ class="jfb-takeorder-index__body-query-filter-item"
96
+ :style="{
97
+ color: isOptionSelected(item) ? mainColor : '',
98
+ border: isOptionSelected(item)
99
+ ? `1px solid ${filterBorderColor}`
100
+ : '',
101
+ backgroundColor: item.label
102
+ ? isOptionSelected(item)
103
+ ? filterBackground
104
+ : ''
105
+ : '#fff',
106
+ }"
107
+ v-for="(item, index) in provinceList"
108
+ :key="index"
109
+ >
110
+ {{ item.label }}
111
+ </view>
112
+ </view>
113
+ <view v-if="filterType === 'city'">
114
+ <CityPicker
115
+ :hot-cities="hotCities"
116
+ :city-groups="cityGroups"
117
+ :letters="letters"
118
+ :selected-city="selectedCity"
119
+ :mainColor="mainColor"
120
+ :filterBorderColor="filterBorderColor"
121
+ :filterBackground="filterBackground"
122
+ @citySelect="handleCitySelect"
123
+ />
124
+ </view>
125
+ <view
126
+ v-if="filterType === 'brand'"
127
+ class="jfb-takeorder-index__body-query-filter-province"
128
+ >
129
+ <view
130
+ @click="handleChooseBrand(item)"
131
+ class="jfb-takeorder-index__body-query-filter-item"
132
+ :style="{
133
+ color: isOptionSelected(item) ? mainColor : '',
134
+ border: isOptionSelected(item)
135
+ ? `1px solid ${filterBorderColor}`
136
+ : '',
137
+ backgroundColor: item.label
138
+ ? isOptionSelected(item)
139
+ ? filterBackground
140
+ : ''
141
+ : '#fff',
142
+ }"
143
+ v-for="(item, index) in brandList"
144
+ :key="index"
145
+ >
146
+ {{ item.label }}
147
+ </view>
148
+ </view>
149
+ <view style="height: 92rpx"></view>
150
+ </view>
151
+ <view class="bottom_btn">
152
+ <xd-button
153
+ class="xd-button"
154
+ type="info"
155
+ width="248rpx"
156
+ bgColor="#DDDDDD"
157
+ size="small"
158
+ @click="handleResetFilter"
159
+ >重置</xd-button
160
+ >
161
+ <xd-button
162
+ class="xd-button"
163
+ type="primary"
164
+ width="248rpx"
165
+ size="small"
166
+ @click="handleConfirmFilter"
167
+ >确定</xd-button
168
+ >
169
+ </view>
170
+ </view>
171
+ </view>
172
+ <view v-show="showFilterQuery" class="modal"></view>
173
+ <view v-if="!isPreview" style="height: 92rpx"></view>
174
+ <view
175
+ v-if="showNew"
176
+ @click="handleRefresh"
177
+ :style="{ color: warningColor, background: newBackgroundColor }"
178
+ class="jfb-takeorder-index__body-new"
179
+ ><XdFontIcon size="24" icon="iconIM"></XdFontIcon>
180
+ <view>新的订单来了,点我立即刷新</view></view
181
+ >
182
+ <view v-for="(item, index) in orderList" :key="index">
183
+ <CusTakeorder
184
+ :item="item"
185
+ :mainColor="mainColor"
186
+ @expire="handleOrderExpire"
187
+ @btnEvent="handleBtnEvent"
188
+ ></CusTakeorder>
189
+ </view>
190
+ <xd-no-data
191
+ icon-type="order"
192
+ :scale-size="2"
193
+ v-if="orderList && orderList.length === 0"
194
+ >暂无订单</xd-no-data
195
+ >
196
+ </view>
197
+ </view>
198
+ </template>
199
+
200
+ <script>
201
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
202
+ import { jfbRootExec } from "@/utils/xd.event";
203
+ import JfbTakeorderIndexMixin from "./JfbTakeorderIndexMixin";
204
+ import XdButton from "@/components/XdButton/XdButton";
205
+ import { getContainerPropsValue } from "@/utils/xd.base";
206
+ import componentsMixins from "@/mixins/componentsMixins";
207
+ import CusTakeorder from "@/components/CusTakeorder/CusTakeorder";
208
+ import CityPicker from "./components/cityPicker.vue";
209
+ import extsMixins from "@/mixins/extsMixins";
210
+ import getServiceUrl from "@/common/getServiceUrl";
211
+ import XdNoData from "@/components/XdNoData/XdNoData";
212
+ import { mapActions } from "vuex";
213
+ const Color = require("color");
214
+
215
+ export default {
216
+ name: "JfbTakeorderIndex",
217
+ components: {
218
+ XdFontIcon,
219
+ XdButton,
220
+ CusTakeorder,
221
+ CityPicker,
222
+ XdNoData,
223
+ },
224
+ mixins: [componentsMixins, extsMixins, JfbTakeorderIndexMixin],
225
+ data() {
226
+ return {
227
+ newBackgroundColor: "",
228
+ showNew: false,
229
+ pollTimer: null, // 轮询定时器
230
+ orderList: [],
231
+ filterType: "",
232
+ closeMask: false,
233
+ cityList: [],
234
+ provinceList: [],
235
+ selectedProvs: [],
236
+ brandList: [],
237
+ selectedBrands: [],
238
+ showFilterQuery: false,
239
+ filterBackground: "",
240
+ filterBorderColor: "",
241
+ hotCities: [],
242
+ cityGroups: [],
243
+ letters: [],
244
+ selectedCity: [],
245
+ order_type: "hourdash",
246
+ orderTab: "index",
247
+ page_size: 10,
248
+ page_token: 1,
249
+ hasNext: true,
250
+ next_page_token: "",
251
+ max_id: 0,
252
+ order_detail_path: "",
253
+ isPreview: false,
254
+ isOpenNew: "N",
255
+ isOpenWin: "N",
256
+ selectedProvsName: [],
257
+ selectedCityName: [],
258
+ selectedBrandsName: [],
259
+ };
260
+ },
261
+ computed: {
262
+ menuWrapBoxStyle() {
263
+ let style = {};
264
+ if (!this.isPreview) {
265
+ style["position"] = "fixed";
266
+ style["top"] = `${this.layoutInfo.top}rpx`;
267
+ }
268
+ return this.styleObjectToString(style);
269
+ },
270
+ },
271
+ watch: {
272
+ container(value, oldValue) {
273
+ if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
274
+ if (this.$configProject["isPreview"]) this.init(value);
275
+ },
276
+ },
277
+ created() {
278
+ this.init(this.container);
279
+ },
280
+ destroyed() {
281
+ // 清除定时器
282
+ this.stopPolling();
283
+ },
284
+ methods: {
285
+ ...mapActions(["voiceAlert", "playWebSpeech", "playAudioFile"]),
286
+ onJfbLoad(options) {
287
+ this.initFilter();
288
+ // 获取订单列表
289
+ this.getList();
290
+
291
+ // 立即调用一次
292
+ if (!this.isPreview) {
293
+ jfbRootExec("getUserConfig", {
294
+ vm: this,
295
+ data: {},
296
+ }).then((res) => {
297
+ this.isOpenNew = res.is_open_new_order_notify_audio;
298
+ this.isOpenWin = res.is_open_win_order_audio;
299
+ // 立即调用一次
300
+ this.handleGetNew();
301
+ // 启动定时器,每5秒调用一次
302
+ this.startPolling();
303
+ });
304
+ }
305
+ },
306
+ /**
307
+ * @description 监听事件变化
308
+ * @param container {object} 业务组件对象自己
309
+ */
310
+ init(container) {
311
+ this.newBackgroundColor = Color(this.warningColor).alpha(0.15).toString();
312
+ this.filterBackground = Color(this.mainColor).alpha(0.15).toString();
313
+ this.filterBorderColor = Color(this.mainColor).alpha(0.5).toString();
314
+ this.order_detail_path = getContainerPropsValue(
315
+ container,
316
+ "content.order_detail_path",
317
+ { value: "" }
318
+ ).value;
319
+ if (this.$configProject["isPreview"]) {
320
+ this.isPreview = true;
321
+ }
322
+ },
323
+ initFilter() {
324
+ Promise.all([
325
+ jfbRootExec("getIndexAllMapCity", {
326
+ vm: this,
327
+ data: {},
328
+ }),
329
+ jfbRootExec("getIndexProvince", {
330
+ vm: this,
331
+ data: {},
332
+ }),
333
+ jfbRootExec("getBrandOptions", {
334
+ vm: this,
335
+ data: {
336
+ order_type: this.order_type,
337
+ },
338
+ }),
339
+ ])
340
+ .then((res) => {
341
+ res[1].list.unshift({ label: "全部", value: "all" });
342
+ const processedData = this.processCityData(res[0]);
343
+ this.hotCities = processedData.hotCities;
344
+ this.cityGroups = processedData.cityGroups;
345
+ this.letters = processedData.letters;
346
+ this.provinceList = this.ensureLengthMultipleOfFour(res[1].list);
347
+ this.brandList = this.ensureLengthMultipleOfFour(res[2].list);
348
+ })
349
+ .catch();
350
+ },
351
+ /**
352
+ * 获取订单列表
353
+ */
354
+ getList() {
355
+ // 构建请求参数
356
+ const params = {
357
+ tab: this.orderTab, // tab参数,暂时传空字符串
358
+ order_type: this.order_type,
359
+ page_token: this.page_token, // 初始分页token
360
+ page_size: this.page_size, // 每页数量
361
+ };
362
+
363
+ // 只有当有选择时,才添加筛选参数,如果选择了 'all' 则不传
364
+ if (this.selectedProvs && this.selectedProvs.length > 0) {
365
+ // 如果只有一个选项且为 'all',则不传 province_codes
366
+ if (
367
+ !(this.selectedProvs.length === 1 && this.selectedProvs[0] === "all")
368
+ ) {
369
+ params.province_codes = this.selectedProvs;
370
+ }
371
+ }
372
+ if (this.selectedCity && this.selectedCity.length > 0) {
373
+ params.city_codes = this.selectedCity;
374
+ }
375
+ if (this.selectedBrands && this.selectedBrands.length > 0) {
376
+ params.brand_ids = this.selectedBrands;
377
+ }
378
+
379
+ jfbRootExec("getOrderList", {
380
+ vm: this,
381
+ data: params,
382
+ })
383
+ .then((res) => {
384
+ // 设置订单列表数据
385
+ let list = res.list.map((item) => {
386
+ item.product_list = item.product_list.map((prod, i) => {
387
+ prod["product_thumb"] = prod.product_thumb
388
+ ? getServiceUrl(prod.product_thumb, "size3")
389
+ : "";
390
+ return prod;
391
+ });
392
+ return item;
393
+ });
394
+ if (this.page_token === 1) {
395
+ this.orderList = list;
396
+ } else {
397
+ this.orderList = this.orderList.concat(list);
398
+ }
399
+ this.hasNext = res.next_page_token !== "";
400
+ this.next_page_token = res.next_page_token;
401
+ })
402
+ .catch((err) => {
403
+ console.error("获取订单列表失败:", err);
404
+ });
405
+ },
406
+ /**
407
+ * 处理城市接口数据,转换为组件所需格式
408
+ * @param {Object} rawData - 接口返回的原始城市数据
409
+ * @returns {Object} 处理后的城市数据,包含hotCities, cityGroups, letters三个属性
410
+ */
411
+ processCityData(rawData) {
412
+ // 初始化返回结果
413
+ const result = {
414
+ hotCities: [], // 热门城市列表
415
+ cityGroups: [], // 按字母分组的城市列表
416
+ letters: [], // 字母索引列表
417
+ };
418
+
419
+ // 处理热门城市数据
420
+ if (rawData.hot_city_data && typeof rawData.hot_city_data === "object") {
421
+ for (const code in rawData.hot_city_data) {
422
+ // 跳过原型链上的属性
423
+ if (rawData.hot_city_data.hasOwnProperty(code)) {
424
+ result.hotCities.push({
425
+ city_code: code,
426
+ city_name: rawData.hot_city_data[code],
427
+ // 如需其他字段可在此处添加
428
+ });
429
+ }
430
+ }
431
+ }
432
+
433
+ // 处理字母列表
434
+ if (Array.isArray(rawData.letters)) {
435
+ result.letters = [...rawData.letters];
436
+ }
437
+
438
+ // 处理按字母分组的城市数据
439
+ if (rawData.city_data && typeof rawData.city_data === "object") {
440
+ // 遍历每个字母分组
441
+ for (const letter in rawData.city_data) {
442
+ // 跳过原型链上的属性
443
+ if (rawData.city_data.hasOwnProperty(letter)) {
444
+ const cityItems = rawData.city_data[letter];
445
+
446
+ // 转换每个城市的数据格式
447
+ const cities = cityItems.map((item) => {
448
+ const cityObj = {};
449
+ // 将[{label: 'xxx', value: 'xxx'}, ...]格式转换为{xxx: 'xxx', ...}
450
+ item.forEach((prop) => {
451
+ cityObj[prop.label] = prop.value;
452
+ });
453
+ return cityObj;
454
+ });
455
+
456
+ // 添加到分组列表
457
+ result.cityGroups.push({
458
+ letter,
459
+ cities,
460
+ });
461
+ }
462
+ }
463
+
464
+ // 确保城市分组与字母列表顺序一致
465
+ result.cityGroups.sort((a, b) => {
466
+ return (
467
+ result.letters.indexOf(a.letter) - result.letters.indexOf(b.letter)
468
+ );
469
+ });
470
+ }
471
+
472
+ return result;
473
+ },
474
+ /**
475
+ * 确保数据数组的长度是 4 的倍数。
476
+ * 如果不是,会在数组末尾添加占位符对象,直到长度满足条件。
477
+ *
478
+ * @param {Array} data - 原始数据数组
479
+ * @param {*} placeholder - 占位符内容,可以是对象、字符串等
480
+ * @returns {Array} - 处理后的新数组
481
+ */
482
+ ensureLengthMultipleOfFour(data, placeholder = {}) {
483
+ // 1. 检查输入是否为数组
484
+ if (!Array.isArray(data)) {
485
+ console.warn("输入的数据不是一个数组");
486
+ return data;
487
+ }
488
+
489
+ // 2. 获取当前数组长度
490
+ const currentLength = data.length;
491
+
492
+ // 3. 如果长度已经是 4 的倍数,直接返回原数组
493
+ if (currentLength % 4 === 0) {
494
+ return [...data]; // 返回一个新数组,避免直接修改原数据
495
+ }
496
+
497
+ // 4. 计算需要添加的占位符数量
498
+ // nextMultiple = ((currentLength + 3) // 4) * 4
499
+ const nextMultiple = Math.ceil(currentLength / 4) * 4;
500
+ const placeholdersToAdd = nextMultiple - currentLength;
501
+
502
+ // 5. 创建一个包含占位符的新数组
503
+ const placeholders = Array.from(
504
+ { length: placeholdersToAdd },
505
+ () => placeholder
506
+ );
507
+
508
+ // 6. 合并原始数据和占位符,并返回新数组
509
+ return [...data, ...placeholders];
510
+ },
511
+ isOptionSelected(item) {
512
+ let selects = [];
513
+ if (this.filterType === "province") selects = this.selectedProvs;
514
+ if (this.filterType === "brand") selects = this.selectedBrands;
515
+ return selects.some((Sitem) => Sitem === item.value);
516
+ },
517
+ /**
518
+ * 处理子组件派发的 'expire' 事件
519
+ * 订单倒计时结束后,从列表中删除该订单
520
+ */
521
+ handleOrderExpire(order) {
522
+ if (this.isPreview) return;
523
+ const orderIndex = this.orderList.findIndex(
524
+ (item) => item.order_id === order.order_id
525
+ );
526
+ if (orderIndex === -1) return;
527
+ if (order.user_quotation_status === "quoted") {
528
+ this.handleRefresh();
529
+ return;
530
+ }
531
+ // 从列表中删除该订单
532
+ this.orderList.splice(orderIndex, 1);
533
+ },
534
+ handleSwitchFilter(type) {
535
+ if (this.filterType === type) {
536
+ this.filterType = "";
537
+ this.showFilterQuery = false;
538
+ return;
539
+ }
540
+ this.filterType = type;
541
+ this.showFilterQuery = true;
542
+ },
543
+ handleChooseProvince(item) {
544
+ if (!item.value) return;
545
+ if (item.value === "all") {
546
+ // 如果“全部”已被选中,则取消选择(可选,根据业务需求)
547
+ if (this.selectedProvs.includes("all")) {
548
+ // this.selectedOptions[key] = []; // 取消全部选择
549
+ // 通常“全部”是默认状态,点击后可以不做任何事,或保持选中
550
+ }
551
+ // 如果“全部”未被选中,则只选中“全部”
552
+ else {
553
+ this.selectedProvs = ["all"];
554
+ this.selectedProvsName = ["全部"];
555
+ }
556
+ } else {
557
+ // 如果当前选中了“全部”,则先取消“全部”的选择
558
+ if (this.selectedProvs.includes("all")) {
559
+ this.selectedProvs = []; // 清空,准备添加具体选项
560
+ this.selectedProvsName = [];
561
+ }
562
+
563
+ const index = this.selectedProvs.findIndex(
564
+ (value) => value === item.value
565
+ );
566
+ if (index > -1) {
567
+ // 如果已选中,则取消选择
568
+ this.selectedProvs.splice(index, 1);
569
+ this.selectedProvsName.splice(index, 1);
570
+ // 【可选】当所有具体选项都被取消时,自动选中“全部”
571
+ if (this.selectedProvs.length === 0) {
572
+ this.selectedProvs = ["all"];
573
+ this.selectedProvsName = ["全部"];
574
+ }
575
+ } else {
576
+ // 如果未选中,则添加
577
+ this.selectedProvs.push(item.value);
578
+ this.selectedProvsName.push(item.label);
579
+ }
580
+ }
581
+ },
582
+ handleChooseBrand(item) {
583
+ if (!item.value) return;
584
+ const index = this.selectedBrands.findIndex(
585
+ (value) => value === item.value
586
+ );
587
+ if (index > -1) {
588
+ // 如果已选中,则取消选择
589
+ this.selectedBrands.splice(index, 1);
590
+ this.selectedBrandsName.splice(index, 1);
591
+ } else {
592
+ // 如果未选中,则添加
593
+ this.selectedBrands.push(item.value);
594
+ this.selectedBrandsName.push(item.label);
595
+ }
596
+ },
597
+ handleGetNew() {
598
+ jfbRootExec("getNewOrderNotify", {
599
+ vm: this,
600
+ data: {
601
+ order_type: this.order_type,
602
+ max_id: this.max_id,
603
+ },
604
+ })
605
+ .then((res) => {
606
+ if (res.is_exist_new_order && res.is_exist_win_order) {
607
+ if (this.isOpenNew === "Y") {
608
+ this.voiceAlert({
609
+ type: "new",
610
+ filePath: "https://img.jufubao.cn/takeorder/new_order.mp3",
611
+ });
612
+ }
613
+ if (this.isOpenWin === "Y") {
614
+ setTimeout(() => {
615
+ this.voiceAlert({
616
+ type: "win",
617
+ filePath: "https://img.jufubao.cn/takeorder/wait_order.mp3",
618
+ });
619
+ }, 1000);
620
+ }
621
+ } else if (res.is_exist_new_order) {
622
+ if (this.isOpenNew === "Y") {
623
+ this.voiceAlert({
624
+ type: "new",
625
+ filePath: "https://img.jufubao.cn/takeorder/new_order.mp3",
626
+ });
627
+ }
628
+ } else if (res.is_exist_win_order) {
629
+ if (this.isOpenWin === "Y") {
630
+ this.voiceAlert({
631
+ type: "win",
632
+ filePath: "https://img.jufubao.cn/takeorder/wait_order.mp3",
633
+ });
634
+ }
635
+ }
636
+ if (res.new_order_max_id > this.max_id) {
637
+ this.max_id = res.new_order_max_id;
638
+ }
639
+ this.showNew = res.is_exist_new_order;
640
+ })
641
+ .catch((err) => {
642
+ console.error("获取新订单通知失败:", err);
643
+ });
644
+ },
645
+ /**
646
+ * 启动轮询定时器
647
+ */
648
+ startPolling() {
649
+ // 如果已经存在定时器,先清除
650
+ if (this.pollTimer) {
651
+ clearInterval(this.pollTimer);
652
+ }
653
+ // 每5秒调用一次接口
654
+ this.pollTimer = setInterval(() => {
655
+ console.log("startPolling");
656
+ this.handleGetNew();
657
+ }, 5000);
658
+ },
659
+ /**
660
+ * 停止轮询定时器
661
+ */
662
+ stopPolling() {
663
+ if (this.pollTimer) {
664
+ clearInterval(this.pollTimer);
665
+ this.pollTimer = null;
666
+ }
667
+ },
668
+ handleRefresh() {
669
+ // 刷新列表
670
+ this.getList();
671
+ this.showNew = false;
672
+ },
673
+ handleCitySelect(city) {
674
+ const index = this.selectedCity.findIndex(
675
+ (value) => value === city.city_code
676
+ );
677
+ if (index > -1) {
678
+ // 如果已选中,则取消选择
679
+ this.selectedCity.splice(index, 1);
680
+ this.selectedCityName.splice(index, 1);
681
+ } else {
682
+ // 如果未选中,则添加
683
+ this.selectedCity.push(city.city_code);
684
+ this.selectedCityName.push(city.city_name);
685
+ }
686
+ },
687
+ handleResetFilter() {
688
+ if (this.filterType === "province") {
689
+ this.selectedProvs = [];
690
+ this.selectedProvsName = [];
691
+ }
692
+ if (this.filterType === "brand") {
693
+ this.selectedBrands = [];
694
+ this.selectedBrandsName = [];
695
+ }
696
+ if (this.filterType === "city") {
697
+ this.selectedCity = [];
698
+ this.selectedCityName = [];
699
+ }
700
+ this.filterType = "";
701
+ this.showFilterQuery = false;
702
+ this.getList();
703
+ },
704
+ handleConfirmFilter() {
705
+ this.showFilterQuery = false;
706
+ this.filterType = "";
707
+ // 重新调用接口
708
+ this.getList();
709
+ },
710
+ /**
711
+ * 处理按钮事件,跳转到订单详情
712
+ * @param {Object} item - 订单对象
713
+ */
714
+ handleBtnEvent({ item, btn }) {
715
+ // 跳转到订单详情页
716
+ this.$xdUniHelper.navigateTo({
717
+ url: `${this.order_detail_path}?order_id=${item.order_id}`,
718
+ });
719
+ },
720
+ onJfbScroll(options) {},
721
+ onJfbReachBottom(options) {
722
+ if (this.hasNext) {
723
+ this.page_token = this.next_page_token;
724
+ this.getList();
725
+ }
726
+ },
727
+ onJfbShow(options) {
728
+ this.onJfbLoad(options);
729
+ console.log("event.onJfbShow", options);
730
+ },
731
+ onJfbHide(options) {
732
+ // 页面隐藏时暂停轮询
733
+ this.stopPolling();
734
+ console.log("event.onJfbHide", options);
735
+ },
736
+ onJfbBack(options) {
737
+ console.log("event.onJfbBack", options);
738
+ },
739
+ onJfbUpdate(...data) {
740
+ console.log("event.onJfbUpdate", data);
741
+ },
742
+ onJfbCustomEvent(options) {
743
+ console.log("event.onJfbReachBottom", options);
744
+ },
745
+ },
746
+ };
747
+ </script>
748
+
749
+ <style scoped lang="less">
750
+ @import "./JfbTakeorderIndexLess.less";
751
+
752
+ .jfb-takeorder-index {
753
+ &__body {
754
+ position: relative;
755
+ .menu_wrap {
756
+ box-sizing: border-box;
757
+ width: 100%;
758
+ left: 0;
759
+ z-index: 999;
760
+ }
761
+ .bottom_btn {
762
+ display: flex;
763
+ justify-content: center;
764
+ padding: 16rpx 32rpx;
765
+ border-top: 2rpx solid #f8f8f8;
766
+ background: #fff;
767
+ position: absolute;
768
+ bottom: 0;
769
+ .xd-button {
770
+ margin: 0 32rpx;
771
+ }
772
+ }
773
+ &-filter {
774
+ display: flex;
775
+ align-items: center;
776
+ justify-content: space-around;
777
+ background: #fff;
778
+ padding: 26rpx 0;
779
+ &-item {
780
+ display: flex;
781
+ align-items: center;
782
+ color: #333;
783
+ font-size: 28rpx;
784
+ font-weight: bold;
785
+ & > view {
786
+ margin-right: 10rpx;
787
+ }
788
+ }
789
+ &-text {
790
+ max-width: 90rpx;
791
+ overflow: hidden;
792
+ text-overflow: ellipsis;
793
+ white-space: nowrap;
794
+ min-width: 0;
795
+ }
796
+ }
797
+ &-query {
798
+ &-filter {
799
+ background-color: #fff;
800
+ padding: 32rpx;
801
+ border-top: 1px solid #fafafa;
802
+ max-height: 65vh;
803
+ overflow-y: auto;
804
+ &-wrap {
805
+ max-height: 65vh;
806
+ }
807
+ &-province {
808
+ display: flex;
809
+ align-items: center;
810
+ justify-content: space-around;
811
+ flex-wrap: wrap;
812
+ gap: 24rpx;
813
+ width: 100%;
814
+ }
815
+ &-item {
816
+ border-radius: 4rpx;
817
+ background: #fafafa;
818
+ display: flex;
819
+ justify-content: center;
820
+ align-items: center;
821
+ padding: 16rpx 0;
822
+ margin-bottom: 24rpx;
823
+ color: #666666;
824
+ font-size: 24rpx;
825
+ flex: 0 0 calc((100% - 3 * 24rpx) / 4); /* flex-grow: 0, flex-shrink: 0, flex-basis: ... */
826
+ box-sizing: border-box;
827
+ }
828
+ }
829
+ }
830
+ &-new {
831
+ display: flex;
832
+ align-items: center;
833
+ justify-content: center;
834
+ padding: 20rpx 0;
835
+ font-size: 24rpx;
836
+ & > view {
837
+ margin-left: 26rpx;
838
+ }
839
+ }
840
+ .modal {
841
+ position: fixed;
842
+ width: 100%;
843
+ height: 100%;
844
+ left: 0;
845
+ top: 0;
846
+ background: rgba(0, 0, 0, 0.4);
847
+ z-index: 102;
848
+ }
849
+ }
850
+ }
851
+ </style>