jufubao-takeorder 1.0.2-beta1 → 1.0.2-beta3

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 (43) hide show
  1. package/package.json +1 -1
  2. package/src/components/{JfbTakeorderQuotedDetail → JfbTakeorderFilterOrderList}/Api.js +9 -9
  3. package/src/components/{JfbTakeorderUnquotedDetail/JfbTakeorderUnquotedDetail.vue → JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderList.vue} +9 -9
  4. package/src/components/{JfbTakeorderUnquotedDetail/JfbTakeorderUnquotedDetailLess.less → JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderListLess.less} +2 -2
  5. package/src/components/{JfbTakeorderUnquotedDetail/JfbTakeorderUnquotedDetailMixin.js → JfbTakeorderFilterOrderList/JfbTakeorderFilterOrderListMixin.js} +1 -1
  6. package/src/components/JfbTakeorderFilterOrderList/Mock.js +13 -0
  7. package/src/components/JfbTakeorderIndex/Api.js +9 -41
  8. package/src/components/JfbTakeorderIndex/Attr.js +9 -41
  9. package/src/components/JfbTakeorderIndex/JfbTakeorderIndex.vue +681 -85
  10. package/src/components/JfbTakeorderIndex/components/cityPicker.vue +299 -0
  11. package/src/components/JfbTakeorderIndex/components/order.vue +273 -0
  12. package/src/components/JfbTakeorderIndex/cusAttr/advanced.js +26 -0
  13. package/src/components/JfbTakeorderIndex/cusAttr/content.js +9 -0
  14. package/src/components/JfbTakeorderIndex/cusAttr/style.js +11 -0
  15. package/src/components/{JfbTakeorderQuotedList → JfbTakeorderOrderDetail}/Api.js +9 -9
  16. package/src/components/{JfbTakeorderQuotedList/JfbTakeorderQuotedList.vue → JfbTakeorderOrderDetail/JfbTakeorderOrderDetail.vue} +9 -9
  17. package/src/components/{JfbTakeorderUnquotedList/JfbTakeorderUnquotedListLess.less → JfbTakeorderOrderDetail/JfbTakeorderOrderDetailLess.less} +2 -2
  18. package/src/components/{JfbTakeorderQuotedDetail/JfbTakeorderQuotedDetailMixin.js → JfbTakeorderOrderDetail/JfbTakeorderOrderDetailMixin.js} +1 -1
  19. package/src/components/JfbTakeorderOrderDetail/Mock.js +13 -0
  20. package/src/components/{JfbTakeorderUnquotedDetail → JfbTakeorderOrderList}/Api.js +9 -9
  21. package/src/components/JfbTakeorderOrderList/Attr.js +16 -0
  22. package/src/components/JfbTakeorderOrderList/JfbTakeorderOrderList.vue +168 -0
  23. package/src/components/{JfbTakeorderQuotedList/JfbTakeorderQuotedListLess.less → JfbTakeorderOrderList/JfbTakeorderOrderListLess.less} +2 -2
  24. package/src/components/{JfbTakeorderQuotedList/JfbTakeorderQuotedListMixin.js → JfbTakeorderOrderList/JfbTakeorderOrderListMixin.js} +1 -1
  25. package/src/components/JfbTakeorderOrderList/Mock.js +13 -0
  26. package/src/components/JfbTakeorderOrderList/components/order.vue +273 -0
  27. package/src/components/JfbTakeorderOrderList/cusAttr/advanced.js +26 -0
  28. package/src/components/JfbTakeorderOrderList/cusAttr/content.js +9 -0
  29. package/src/components/JfbTakeorderOrderList/cusAttr/style.js +11 -0
  30. package/src/components/{JfbTakeorderUnquotedList → JfbTakeorderVoiceSwitch}/Api.js +9 -9
  31. package/src/components/{JfbTakeorderQuotedDetail/JfbTakeorderQuotedDetail.vue → JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitch.vue} +9 -9
  32. package/src/components/{JfbTakeorderQuotedDetail/JfbTakeorderQuotedDetailLess.less → JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitchLess.less} +2 -2
  33. package/src/components/{JfbTakeorderUnquotedList/JfbTakeorderUnquotedListMixin.js → JfbTakeorderVoiceSwitch/JfbTakeorderVoiceSwitchMixin.js} +1 -1
  34. package/src/components/JfbTakeorderVoiceSwitch/Mock.js +13 -0
  35. package/src/components/JfbTakeorderQuotedDetail/Mock.js +0 -13
  36. package/src/components/JfbTakeorderQuotedList/Mock.js +0 -13
  37. package/src/components/JfbTakeorderUnquotedDetail/Mock.js +0 -13
  38. package/src/components/JfbTakeorderUnquotedList/Attr.js +0 -48
  39. package/src/components/JfbTakeorderUnquotedList/JfbTakeorderUnquotedList.vue +0 -113
  40. package/src/components/JfbTakeorderUnquotedList/Mock.js +0 -13
  41. /package/src/components/{JfbTakeorderQuotedDetail → JfbTakeorderFilterOrderList}/Attr.js +0 -0
  42. /package/src/components/{JfbTakeorderQuotedList → JfbTakeorderOrderDetail}/Attr.js +0 -0
  43. /package/src/components/{JfbTakeorderUnquotedDetail → JfbTakeorderVoiceSwitch}/Attr.js +0 -0
@@ -2,112 +2,708 @@
2
2
  <view
3
3
  class="jfb-takeorder-index"
4
4
  @click="handleEditxSelect"
5
- :class="{ editx : isEditx && active }"
5
+ :class="{ editx: isEditx && active }"
6
6
  >
7
7
  <!--#ifdef H5-->
8
8
  <view
9
9
  class="jfb-takeorder-index__edit"
10
- :class="{ editx : isEditx && active }"
10
+ :class="{ editx: isEditx && active }"
11
11
  v-if="isEditx && active"
12
12
  >
13
13
  <view class="jfb-takeorder-index__edit-icon" @click.stop="delEdit">
14
- <xd-font-icon icon="iconshanchu-01" color="#fff" size="30"></xd-font-icon>
14
+ <xd-font-icon
15
+ icon="iconshanchu-01"
16
+ color="#fff"
17
+ size="30"
18
+ ></xd-font-icon>
15
19
  </view>
16
20
  </view>
17
21
  <!-- #endif -->
18
22
  <view class="jfb-takeorder-index__body">
19
- <view>测试插件( {{containerId}} )</view>
23
+ <view class="menu_wrap" :style="[menuWrapBoxStyle]">
24
+ <view class="jfb-takeorder-index__body-filter">
25
+ <view
26
+ :style="{ color: filterType === 'province' ? mainColor : '' }"
27
+ @click="handleSwitchFilter('province')"
28
+ class="jfb-takeorder-index__body-filter-item"
29
+ ><view>省份</view
30
+ ><XdFontIcon
31
+ style="font-weight: bolder"
32
+ size="20"
33
+ icon="iconxia_down"
34
+ ></XdFontIcon
35
+ ></view>
36
+ <view
37
+ :style="{ color: filterType === 'city' ? mainColor : '' }"
38
+ @click="handleSwitchFilter('city')"
39
+ class="jfb-takeorder-index__body-filter-item"
40
+ ><view>城市</view
41
+ ><XdFontIcon
42
+ style="font-weight: bolder"
43
+ size="20"
44
+ icon="iconxia_down"
45
+ ></XdFontIcon
46
+ ></view>
47
+ <view
48
+ :style="{ color: filterType === 'brand' ? mainColor : '' }"
49
+ @click="handleSwitchFilter('brand')"
50
+ class="jfb-takeorder-index__body-filter-item"
51
+ ><view>品牌</view
52
+ ><XdFontIcon
53
+ style="font-weight: bolder"
54
+ size="20"
55
+ icon="iconxia_down"
56
+ ></XdFontIcon
57
+ ></view>
58
+ </view>
59
+ <view
60
+ v-if="showFilterQuery"
61
+ class="jfb-takeorder-index__body-query-filter"
62
+ >
63
+ <view class="jfb-takeorder-index__body-query-filter-wrap">
64
+ <view
65
+ v-if="filterType === 'province'"
66
+ class="jfb-takeorder-index__body-query-filter-province"
67
+ >
68
+ <view
69
+ @click="handleChooseProvince(item)"
70
+ class="jfb-takeorder-index__body-query-filter-item"
71
+ :style="{
72
+ color: isOptionSelected(item) ? mainColor : '',
73
+ border: isOptionSelected(item)
74
+ ? `1px solid ${filterBorderColor}`
75
+ : '',
76
+ backgroundColor: item.label
77
+ ? isOptionSelected(item)
78
+ ? filterBackground
79
+ : ''
80
+ : '#fff',
81
+ }"
82
+ v-for="(item, index) in provinceList"
83
+ :key="index"
84
+ >
85
+ {{ item.label }}
86
+ </view>
87
+ </view>
88
+ <view v-if="filterType === 'city'">
89
+ <CityPicker
90
+ :hot-cities="hotCities"
91
+ :city-groups="cityGroups"
92
+ :letters="letters"
93
+ :selected-city="selectedCity"
94
+ :mainColor="mainColor"
95
+ :filterBorderColor="filterBorderColor"
96
+ :filterBackground="filterBackground"
97
+ @citySelect="handleCitySelect"
98
+ />
99
+ </view>
100
+ <view
101
+ v-if="filterType === 'brand'"
102
+ class="jfb-takeorder-index__body-query-filter-province"
103
+ >
104
+ <view
105
+ @click="handleChooseBrand(item)"
106
+ class="jfb-takeorder-index__body-query-filter-item"
107
+ :style="{
108
+ color: isOptionSelected(item) ? mainColor : '',
109
+ border: isOptionSelected(item)
110
+ ? `1px solid ${filterBorderColor}`
111
+ : '',
112
+ backgroundColor: item.label
113
+ ? isOptionSelected(item)
114
+ ? filterBackground
115
+ : ''
116
+ : '#fff',
117
+ }"
118
+ v-for="(item, index) in brandList"
119
+ :key="index"
120
+ >
121
+ {{ item.label }}
122
+ </view>
123
+ </view>
124
+ <view style="height: 92rpx"></view>
125
+ </view>
126
+ <view class="bottom_btn">
127
+ <xd-button
128
+ class="xd-button"
129
+ type="info"
130
+ width="248rpx"
131
+ bgColor="#DDDDDD"
132
+ size="small"
133
+ @click="handleResetFilter"
134
+ >重置</xd-button
135
+ >
136
+ <xd-button
137
+ class="xd-button"
138
+ type="primary"
139
+ width="248rpx"
140
+ size="small"
141
+ @click="handleConfirmFilter"
142
+ >确定</xd-button
143
+ >
144
+ </view>
145
+ </view>
146
+ </view>
147
+ <view v-show="showFilterQuery" class="modal"></view>
148
+ <view style="height: 92rpx"></view>
149
+ <view
150
+ v-if="showNew"
151
+ @click="handleRefresh"
152
+ :style="{ color: warningColor, background: newBackgroundColor }"
153
+ class="jfb-takeorder-index__body-new"
154
+ ><XdFontIcon size="24" icon="iconIM"></XdFontIcon>
155
+ <view>新的订单来了,点我立即刷新</view></view
156
+ >
157
+ <view v-for="(item, index) in orderList" :key="index">
158
+ <Order
159
+ :item="item"
160
+ :mainColor="mainColor"
161
+ @expire="handleOrderExpire"
162
+ @btnEvent="handleBtnEvent"
163
+ ></Order>
164
+ </view>
20
165
  </view>
21
166
  </view>
22
167
  </template>
23
168
 
24
169
  <script>
25
- import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
26
- import { jfbRootExec } from "@/utils/xd.event";
27
- import JfbTakeorderIndexMixin from "./JfbTakeorderIndexMixin";
28
- import { getContainerPropsValue } from "@/utils/xd.base";
29
- import componentsMixins from "@/mixins/componentsMixins";
30
- import extsMixins from "@/mixins/extsMixins";
31
- export default {
32
- name: "JfbTakeorderIndex",
33
- components: {
34
- XdFontIcon
35
- },
36
- mixins: [
37
- componentsMixins, extsMixins, JfbTakeorderIndexMixin
38
- ],
39
- data() {
40
- return {
41
-
42
- //todo
43
- }
44
- },
45
- watch: {
46
- container(value, oldValue) {
47
- if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
48
- if (this.$configProject['isPreview']) this.init(value)
49
- },
50
- },
51
- created() {
52
- this.init(this.container);
53
-
54
- //todo
55
- },
56
- methods: {
57
- onJfbLoad(options) {
58
-
59
- // jfbRootExec('baiduUserLogin', {
60
-
61
- // vm: this,// data: {
62
-
63
- // account: 'gaoshiyong',// password: '123456789',// type: 3,// ...options
64
-
65
- // }
66
-
67
- // }).then().catch()
68
- },
69
- /**
70
- * @description 监听事件变化
71
- * @param container {object} 业务组件对象自己
72
- */
73
- init(container) {
74
-
75
- //this.bgcolor = getContainerPropsValue(container, 'content.bgcolor', '#fff');
76
-
77
- //this.height = getContainerPropsValue(container, 'content.height', 10);
78
- },
79
- onJfbScroll(options) {
80
- console.log('event.onJfbScroll', options)
81
- },
82
- onJfbReachBottom(options) {
83
- console.log('event.onJfbReachBottom', options)
84
- },
85
- onJfbShow(options) {
86
- console.log('event.onJfbShow', options)
87
- },
88
- onJfbHide(options) {
89
- console.log('event.onJfbHide', options)
90
- },
91
- onJfbBack(options) {
92
- console.log('event.onJfbBack', options)
93
- },
94
- onJfbUpdate(...data) {
95
- console.log('event.onJfbUpdate', data)
96
- },
97
- onJfbCustomEvent(options) {
98
- console.log('event.onJfbReachBottom', options)
99
- },
100
- }
101
- }
170
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
171
+ import { jfbRootExec } from "@/utils/xd.event";
172
+ import JfbTakeorderIndexMixin from "./JfbTakeorderIndexMixin";
173
+ import XdButton from "@/components/XdButton/XdButton";
174
+ import { getContainerPropsValue } from "@/utils/xd.base";
175
+ import componentsMixins from "@/mixins/componentsMixins";
176
+ import Order from "./components/order.vue";
177
+ import CityPicker from "./components/cityPicker.vue";
178
+ import extsMixins from "@/mixins/extsMixins";
179
+ const Color = require("color");
180
+
181
+ export default {
182
+ name: "JfbTakeorderIndex",
183
+ components: {
184
+ XdFontIcon,
185
+ XdButton,
186
+ Order,
187
+ CityPicker,
188
+ },
189
+ mixins: [componentsMixins, extsMixins, JfbTakeorderIndexMixin],
190
+ data() {
191
+ return {
192
+ newBackgroundColor: "",
193
+ 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
+ ],
231
+ filterType: "",
232
+ closeMask: true,
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
+ };
246
+ },
247
+ computed: {
248
+ menuWrapBoxStyle() {
249
+ let style = {};
250
+ // if (!this.isPreview) {
251
+ style["position"] = "fixed";
252
+ style["top"] = `${this.layoutInfo.top}rpx`;
253
+ // }
254
+ return this.styleObjectToString(style);
255
+ },
256
+ },
257
+ watch: {
258
+ container(value, oldValue) {
259
+ if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
260
+ if (this.$configProject["isPreview"]) this.init(value);
261
+ },
262
+ },
263
+ created() {
264
+ this.init(this.container);
265
+ },
266
+ methods: {
267
+ onJfbLoad(options) {
268
+ this.initFilter();
269
+ setTimeout(() => {
270
+ this.handleGetNew();
271
+ }, 1000);
272
+ },
273
+ /**
274
+ * @description 监听事件变化
275
+ * @param container {object} 业务组件对象自己
276
+ */
277
+ init(container) {
278
+ this.newBackgroundColor = Color(this.warningColor).alpha(0.15).toString();
279
+ this.filterBackground = Color(this.mainColor).alpha(0.15).toString();
280
+ this.filterBorderColor = Color(this.mainColor).alpha(0.5).toString();
281
+ if (this.$configProject["isPreview"]) {
282
+ this.isPreview = true;
283
+ }
284
+ },
285
+ initFilter() {
286
+ Promise.all([
287
+ jfbRootExec("getIndexAllMapCity", {
288
+ vm: this,
289
+ data: {},
290
+ }),
291
+ jfbRootExec("getIndexProvince", {
292
+ vm: this,
293
+ data: {},
294
+ }),
295
+ ])
296
+ .then((res) => {
297
+ debugger;
298
+ res[1].list.unshift({ label: "全部", value: "all" });
299
+ const processedData = this.processCityData(res[0]);
300
+ this.hotCities = processedData.hotCities;
301
+ this.cityGroups = processedData.cityGroups;
302
+ this.letters = processedData.letters;
303
+ 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
+ ]);
312
+ })
313
+ .catch();
314
+ },
315
+ /**
316
+ * 处理城市接口数据,转换为组件所需格式
317
+ * @param {Object} rawData - 接口返回的原始城市数据
318
+ * @returns {Object} 处理后的城市数据,包含hotCities, cityGroups, letters三个属性
319
+ */
320
+ processCityData(rawData) {
321
+ // 初始化返回结果
322
+ const result = {
323
+ hotCities: [], // 热门城市列表
324
+ cityGroups: [], // 按字母分组的城市列表
325
+ letters: [], // 字母索引列表
326
+ };
327
+
328
+ // 处理热门城市数据
329
+ if (rawData.hot_city_data && typeof rawData.hot_city_data === "object") {
330
+ for (const code in rawData.hot_city_data) {
331
+ // 跳过原型链上的属性
332
+ if (rawData.hot_city_data.hasOwnProperty(code)) {
333
+ result.hotCities.push({
334
+ city_code: code,
335
+ city_name: rawData.hot_city_data[code],
336
+ // 如需其他字段可在此处添加
337
+ });
338
+ }
339
+ }
340
+ }
341
+
342
+ // 处理字母列表
343
+ if (Array.isArray(rawData.letters)) {
344
+ result.letters = [...rawData.letters];
345
+ }
346
+
347
+ // 处理按字母分组的城市数据
348
+ if (rawData.city_data && typeof rawData.city_data === "object") {
349
+ // 遍历每个字母分组
350
+ for (const letter in rawData.city_data) {
351
+ // 跳过原型链上的属性
352
+ if (rawData.city_data.hasOwnProperty(letter)) {
353
+ const cityItems = rawData.city_data[letter];
354
+
355
+ // 转换每个城市的数据格式
356
+ const cities = cityItems.map((item) => {
357
+ const cityObj = {};
358
+ // 将[{label: 'xxx', value: 'xxx'}, ...]格式转换为{xxx: 'xxx', ...}
359
+ item.forEach((prop) => {
360
+ cityObj[prop.label] = prop.value;
361
+ });
362
+ return cityObj;
363
+ });
364
+
365
+ // 添加到分组列表
366
+ result.cityGroups.push({
367
+ letter,
368
+ cities,
369
+ });
370
+ }
371
+ }
372
+
373
+ // 确保城市分组与字母列表顺序一致
374
+ result.cityGroups.sort((a, b) => {
375
+ return (
376
+ result.letters.indexOf(a.letter) - result.letters.indexOf(b.letter)
377
+ );
378
+ });
379
+ }
380
+
381
+ return result;
382
+ },
383
+ /**
384
+ * 确保数据数组的长度是 4 的倍数。
385
+ * 如果不是,会在数组末尾添加占位符对象,直到长度满足条件。
386
+ *
387
+ * @param {Array} data - 原始数据数组
388
+ * @param {*} placeholder - 占位符内容,可以是对象、字符串等
389
+ * @returns {Array} - 处理后的新数组
390
+ */
391
+ ensureLengthMultipleOfFour(data, placeholder = {}) {
392
+ // 1. 检查输入是否为数组
393
+ if (!Array.isArray(data)) {
394
+ console.warn("输入的数据不是一个数组");
395
+ return data;
396
+ }
397
+
398
+ // 2. 获取当前数组长度
399
+ const currentLength = data.length;
400
+
401
+ // 3. 如果长度已经是 4 的倍数,直接返回原数组
402
+ if (currentLength % 4 === 0) {
403
+ return [...data]; // 返回一个新数组,避免直接修改原数据
404
+ }
405
+
406
+ // 4. 计算需要添加的占位符数量
407
+ // nextMultiple = ((currentLength + 3) // 4) * 4
408
+ const nextMultiple = Math.ceil(currentLength / 4) * 4;
409
+ const placeholdersToAdd = nextMultiple - currentLength;
410
+
411
+ // 5. 创建一个包含占位符的新数组
412
+ const placeholders = Array.from(
413
+ { length: placeholdersToAdd },
414
+ () => placeholder
415
+ );
416
+
417
+ // 6. 合并原始数据和占位符,并返回新数组
418
+ return [...data, ...placeholders];
419
+ },
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
+ isOptionSelected(item) {
443
+ let selects = [];
444
+ if (this.filterType === "province") selects = this.selectedProvs;
445
+ if (this.filterType === "brand") selects = this.selectedBrands;
446
+ return selects.some((Sitem) => Sitem === item.value);
447
+ },
448
+ /**
449
+ * 处理子组件派发的 'expire' 事件
450
+ */
451
+ async handleOrderExpire(orderId) {
452
+ const orderIndex = this.orderList.findIndex(
453
+ (item) => item.id === orderId
454
+ );
455
+ if (orderIndex === -1) return;
456
+
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);
102
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
+ // }
495
+ },
496
+ handleSwitchFilter(type) {
497
+ if (this.filterType === type) {
498
+ this.filterType = "";
499
+ this.showFilterQuery = false;
500
+ return;
501
+ }
502
+ this.filterType = type;
503
+ this.showFilterQuery = true;
504
+ },
505
+ handleChooseProvince(item) {
506
+ if (!item.value) return;
507
+ if (item.value === "all") {
508
+ // 如果“全部”已被选中,则取消选择(可选,根据业务需求)
509
+ if (this.selectedProvs.includes("all")) {
510
+ // this.selectedOptions[key] = []; // 取消全部选择
511
+ // 通常“全部”是默认状态,点击后可以不做任何事,或保持选中
512
+ }
513
+ // 如果“全部”未被选中,则只选中“全部”
514
+ else {
515
+ this.selectedProvs = ["all"];
516
+ }
517
+ } else {
518
+ // 如果当前选中了“全部”,则先取消“全部”的选择
519
+ if (this.selectedProvs.includes("all")) {
520
+ this.selectedProvs = []; // 清空,准备添加具体选项
521
+ }
522
+
523
+ const index = this.selectedProvs.findIndex(
524
+ (value) => value === item.value
525
+ );
526
+ if (index > -1) {
527
+ // 如果已选中,则取消选择
528
+ this.selectedProvs.splice(index, 1);
529
+
530
+ // 【可选】当所有具体选项都被取消时,自动选中“全部”
531
+ if (this.selectedProvs.length === 0) {
532
+ this.selectedProvs = ["all"];
533
+ }
534
+ } else {
535
+ // 如果未选中,则添加
536
+ this.selectedProvs.push(item.value);
537
+ }
538
+ }
539
+ },
540
+ handleChooseBrand(item) {
541
+ if (!item.value) return;
542
+ const index = this.selectedBrands.findIndex(
543
+ (value) => value === item.value
544
+ );
545
+ if (index > -1) {
546
+ // 如果已选中,则取消选择
547
+ this.selectedBrands.splice(index, 1);
548
+ } else {
549
+ // 如果未选中,则添加
550
+ this.selectedBrands.push(item.value);
551
+ }
552
+ },
553
+ handleGetNew() {
554
+ console.log("获取是否有新订单");
555
+ this.showNew = true;
556
+ },
557
+ handleRefresh() {
558
+ //刷新列表
559
+ },
560
+ handleCitySelect(city) {
561
+ const index = this.selectedCity.findIndex(
562
+ (value) => value === city.city_code
563
+ );
564
+ if (index > -1) {
565
+ // 如果已选中,则取消选择
566
+ this.selectedCity.splice(index, 1);
567
+ } else {
568
+ // 如果未选中,则添加
569
+ this.selectedCity.push(city.city_code);
570
+ }
571
+ },
572
+ handleResetFilter() {
573
+ if (this.filterType === "province") {
574
+ this.selectedProvs = [];
575
+ }
576
+ if (this.filterType === "brand") {
577
+ this.selectedBrands = [];
578
+ }
579
+ if (this.filterType === "city") {
580
+ this.selectedCity = [];
581
+ }
582
+ this.showFilterQuery = false;
583
+ },
584
+ handleConfirmFilter() {
585
+ this.showFilterQuery = false;
586
+ //重新调用接口
587
+ },
588
+ onJfbScroll(options) {
589
+ console.log("event.onJfbScroll", options);
590
+ },
591
+ onJfbReachBottom(options) {
592
+ console.log("event.onJfbReachBottom", options);
593
+ },
594
+ onJfbShow(options) {
595
+ this.calibrateAllCountdowns();
596
+ console.log("event.onJfbShow", options);
597
+ },
598
+ onJfbHide(options) {
599
+ console.log("event.onJfbHide", options);
600
+ },
601
+ onJfbBack(options) {
602
+ console.log("event.onJfbBack", options);
603
+ },
604
+ onJfbUpdate(...data) {
605
+ console.log("event.onJfbUpdate", data);
606
+ },
607
+ onJfbCustomEvent(options) {
608
+ console.log("event.onJfbReachBottom", options);
609
+ },
610
+ },
611
+ };
103
612
  </script>
104
613
 
105
614
  <style scoped lang="less">
106
- @import "./JfbTakeorderIndexLess.less";
107
-
108
- .jfb-takeorder-index {
109
- &__body{
615
+ @import "./JfbTakeorderIndexLess.less";
110
616
 
617
+ .jfb-takeorder-index {
618
+ &__body {
619
+ position: relative;
620
+ .menu_wrap {
621
+ box-sizing: border-box;
622
+ width: 100%;
623
+ left: 0;
624
+ z-index: 999;
625
+ }
626
+ .bottom_btn {
627
+ display: flex;
628
+ justify-content: center;
629
+ padding: 16rpx 32rpx;
630
+ border-top: 2rpx solid #f8f8f8;
631
+ background: #fff;
632
+ position: absolute;
633
+ bottom: 0;
634
+ .xd-button {
635
+ margin: 0 32rpx;
636
+ }
637
+ }
638
+ &-filter {
639
+ display: flex;
640
+ align-items: center;
641
+ justify-content: space-around;
642
+ background: #fff;
643
+ padding: 26rpx 0;
644
+ &-item {
645
+ display: flex;
646
+ align-items: center;
647
+ color: #333;
648
+ font-size: 28rpx;
649
+ font-weight: bold;
650
+ & > view {
651
+ margin-right: 10rpx;
652
+ }
653
+ }
654
+ }
655
+ &-query {
656
+ &-filter {
657
+ background-color: #fff;
658
+ padding: 32rpx;
659
+ border-top: 1px solid #fafafa;
660
+ max-height: 65vh;
661
+ overflow-y: auto;
662
+ &-wrap {
663
+ max-height: 65vh;
664
+ }
665
+ &-province {
666
+ display: flex;
667
+ align-items: center;
668
+ justify-content: space-around;
669
+ flex-wrap: wrap;
670
+ gap: 24rpx;
671
+ width: 100%;
672
+ }
673
+ &-item {
674
+ border-radius: 4rpx;
675
+ background: #fafafa;
676
+ display: flex;
677
+ justify-content: center;
678
+ align-items: center;
679
+ padding: 16rpx 0;
680
+ margin-bottom: 24rpx;
681
+ color: #666666;
682
+ font-size: 24rpx;
683
+ flex: 0 0 calc((100% - 3 * 24rpx) / 4); /* flex-grow: 0, flex-shrink: 0, flex-basis: ... */
684
+ box-sizing: border-box;
685
+ }
686
+ }
687
+ }
688
+ &-new {
689
+ display: flex;
690
+ align-items: center;
691
+ justify-content: center;
692
+ padding: 20rpx 0;
693
+ font-size: 24rpx;
694
+ & > view {
695
+ margin-left: 26rpx;
696
+ }
697
+ }
698
+ .modal {
699
+ position: fixed;
700
+ width: 100%;
701
+ height: 100%;
702
+ left: 0;
703
+ top: 0;
704
+ background: rgba(0, 0, 0, 0.4);
705
+ z-index: 102;
111
706
  }
112
707
  }
708
+ }
113
709
  </style>