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,1211 @@
1
+ <template>
2
+ <view
3
+ class="jfb-takeorder-order-detail"
4
+ @click="handleEditxSelect"
5
+ :class="{ editx: isEditx && active }"
6
+ >
7
+ <!--#ifdef H5-->
8
+ <view
9
+ class="jfb-takeorder-order-detail__edit"
10
+ :class="{ editx: isEditx && active }"
11
+ v-if="isEditx && active"
12
+ >
13
+ <view class="jfb-takeorder-order-detail__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
+ <!-- 待上报状态倒计时横幅 -->
23
+ <view
24
+ class="jfb-takeorder-order-detail__body"
25
+ :style="{ minHeight: layoutInfo.bodyMinHeight }"
26
+ v-if="info"
27
+ >
28
+ <view
29
+ v-if="
30
+ info.user_quotation_status === 'received' ||
31
+ info.user_quotation_status === 'win_order'
32
+ "
33
+ class="jfb-takeorder-order-detail__countdown-banner"
34
+ :style="{ backgroundColor: mainColor }"
35
+ >
36
+ <xd-font-icon
37
+ style="margin-right: 10rpx"
38
+ icon="iconshijian-01"
39
+ color="#fff"
40
+ size="36"
41
+ ></xd-font-icon>
42
+ <view
43
+ v-if="info.user_quotation_status === 'received'"
44
+ class="jfb-takeorder-order-detail__countdown-text"
45
+ >
46
+ 订单剩余完成时间: {{ formatCountdownTime(reportCountdownSeconds) }}
47
+ </view>
48
+ <view
49
+ v-if="info.user_quotation_status === 'win_order'"
50
+ class="jfb-takeorder-order-detail__countdown-text"
51
+ >
52
+ 订单剩余完成时间: {{ formatCountdownTime(receiveCountdownSeconds) }}
53
+ </view>
54
+ </view>
55
+ <Products :info="info"></Products>
56
+ <view
57
+ v-if="
58
+ info.user_quotation_status === 'wait_quote' ||
59
+ info.user_quotation_status === 'quoted' ||
60
+ info.user_quotation_status === 'close' ||
61
+ info.user_quotation_status === 'cancel_quotation'
62
+ "
63
+ class="wrap"
64
+ >
65
+ <view
66
+ class="other-info-item"
67
+ v-if="
68
+ step === 1 ||
69
+ info.user_quotation_status === 'quoted' ||
70
+ info.user_quotation_status === 'close'
71
+ "
72
+ >
73
+ <view>市场原价(仅供参考)</view>
74
+ <view :style="{ color: mainColor }"
75
+ ><text>¥ </text
76
+ >{{
77
+ $xdUniHelper.divisionFloatNumber(info.market_amount, 100)
78
+ }}</view
79
+ >
80
+ </view>
81
+ <view class="other-info-item">
82
+ <view>商品总数</view>
83
+ <view style="display: flex; align-items: center"
84
+ ><xd-font-icon size="28" icon="iconguanbi"></xd-font-icon
85
+ >{{ info.product_total }}</view
86
+ >
87
+ </view>
88
+ <view
89
+ class="other-info-item"
90
+ v-if="
91
+ step === 1 ||
92
+ info.user_quotation_status === 'quoted' ||
93
+ info.user_quotation_status === 'close'
94
+ "
95
+ >
96
+ <view>报价人数</view>
97
+ <view>{{ info.quotation_person_count }}人</view>
98
+ </view>
99
+ <view
100
+ class="other-info-item"
101
+ v-if="
102
+ step === 1 ||
103
+ info.user_quotation_status === 'quoted' ||
104
+ info.user_quotation_status === 'close'
105
+ "
106
+ >
107
+ <view>报价倒计时</view>
108
+ <view :style="{ color: mainColor }">{{
109
+ !isCountdownEnd ? formatTime(info.rest_quotation_time) : "报价结束"
110
+ }}</view>
111
+ </view>
112
+ <view class="other-info-item" v-if="step === 2">
113
+ <view>您的报价</view>
114
+ <view :style="{ color: mainColor }"
115
+ ><text>¥ </text>{{ quotePrice }}</view
116
+ >
117
+ </view>
118
+ <view class="other-info-item" v-if="step === 2">
119
+ <view>预计结算</view>
120
+ <view :style="{ color: mainColor }"
121
+ ><text>¥ </text>{{ quotePriceTotal }}</view
122
+ >
123
+ </view>
124
+ </view>
125
+ <view v-else class="wrap">
126
+ <view class="other-info-item">
127
+ <view>订单编号</view>
128
+ <view>{{ info.order_id }}</view>
129
+ </view>
130
+ <view class="other-info-item">
131
+ <view>商品总数</view>
132
+ <view style="display: flex; align-items: center"
133
+ ><xd-font-icon size="28" icon="iconguanbi"></xd-font-icon
134
+ >{{ info.product_total }}</view
135
+ >
136
+ </view>
137
+ <view class="other-info-item">
138
+ <view>订购电话</view>
139
+ <view>{{ info.buyer_phone_number }}</view>
140
+ </view>
141
+ <view class="other-info-item">
142
+ <view>订单结算价</view>
143
+ <view :style="{ color: mainColor }"
144
+ ><text>¥ </text>
145
+ {{
146
+ $xdUniHelper.divisionFloatNumber(
147
+ info.receive_user_settle_amount,
148
+ 100
149
+ )
150
+ }}</view
151
+ >
152
+ </view>
153
+ </view>
154
+ <view
155
+ class="wrap"
156
+ v-if="
157
+ (info.user_quotation_status === 'cancel_quotation' ||
158
+ info.user_quotation_status === 'wait_quote' ||
159
+ info.user_quotation_status === 'quoted') &&
160
+ step !== 2
161
+ "
162
+ >
163
+ <view class="quote-title">订单报价</view>
164
+ <view class="quote-input">
165
+ <view class="quote-input-unit">¥</view>
166
+ <input
167
+ :disabled="quoteDisabled"
168
+ v-model="quotePrice"
169
+ placeholder="请输入订单报价金额"
170
+ />
171
+ </view>
172
+ <view class="quote-advice"
173
+ >建议报价:<text :style="{ color: mainColor }"
174
+ >¥{{
175
+ $xdUniHelper.divisionFloatNumber(info.suggest_min_quotation, 100)
176
+ }}~ ¥{{
177
+ $xdUniHelper.divisionFloatNumber(info.suggest_max_quotation, 100)
178
+ }}</text
179
+ ></view
180
+ >
181
+ </view>
182
+ <view
183
+ class="wrap upload"
184
+ v-if="
185
+ info.user_quotation_status === 'received' ||
186
+ info.user_quotation_status === 'reported'
187
+ "
188
+ >
189
+ <view class="voucher" v-if="voucherImages && voucherImages.length > 0">
190
+ <view
191
+ class="voucher-item"
192
+ v-for="(item, index) in voucherImages"
193
+ :key="index"
194
+ >
195
+ <view class="voucher-item-image">
196
+ <image :src="item.report_voucher_preview_url" />
197
+ <view>凭证图</view>
198
+ </view>
199
+ <view>
200
+ <view
201
+ class="voucher-item-info"
202
+ v-for="(code, index) in item.code_list"
203
+ :key="index"
204
+ >
205
+ <view
206
+ v-if="code.show_type === 'text'"
207
+ class="voucher-item-info-number"
208
+ >
209
+ <text class="voucher-item-info-label">凭证号</text>
210
+ <view>{{ code.code }}</view>
211
+ </view>
212
+ <view
213
+ v-if="code.show_type === 'qrcode'"
214
+ class="voucher-item-info-qrcode"
215
+ >
216
+ <text class="voucher-item-info-label">二维码</text>
217
+ <image :src="code.code_preview_url"></image>
218
+ </view>
219
+ </view>
220
+ </view>
221
+ </view>
222
+ </view>
223
+ <view v-if="info.user_quotation_status === 'received'" style="display: flex; justify-content: center">
224
+ <xd-upload
225
+ @on-done="handleUploadDone"
226
+ selectType="image"
227
+ :selectSource="['album']"
228
+ ossType="private"
229
+ borderWidth="2rpx"
230
+ borderRadius="4rpx"
231
+ :backgroundColor="uploadBackground"
232
+ :borderColor="mainColor"
233
+ borderStyle="solid"
234
+ width="654"
235
+ height="88"
236
+ >
237
+ <view :style="{ color: mainColor, fontSize: '28rpx' }"
238
+ >上传凭证</view
239
+ >
240
+ </xd-upload>
241
+ </view>
242
+ <view v-if="info.user_quotation_status === 'received'" class="upload-notice">
243
+ <text>请务必按真实报单并仔细校对取餐码正确无误,</text>
244
+ <text :style="{ color: mainColor }"
245
+ >取餐码错误或未上报真实取餐码造成客诉产生损失将由您承担!</text
246
+ >
247
+ </view>
248
+ </view>
249
+ <view
250
+ v-if="
251
+ (info.user_quotation_status === 'close' ||
252
+ info.user_quotation_status === 'quoted') &&
253
+ notice
254
+ "
255
+ class="special-tip wrap"
256
+ style="padding: 24rpx 32rpx"
257
+ >
258
+ <view>特别提示</view>
259
+ <XdContentXss
260
+ v-if="
261
+ (info.user_quotation_status === 'wait_quote' && step !== 2) ||
262
+ info.user_quotation_status === 'quoted'
263
+ "
264
+ :html="notice"
265
+ ></XdContentXss>
266
+ <view v-else :style="{ color: mainColor }"
267
+ >因各平台市场价有出入,建议报价前自主核实价格,避免因价格出入问题弃单导致的纠纷!</view
268
+ >
269
+ </view>
270
+ <view v-if="!isCountdownEnd" :style="{ height: '100rpx' }"></view>
271
+ <view
272
+ :key="info.user_quotation_status"
273
+ v-if="
274
+ info.user_quotation_status !== 'close' &&
275
+ info.user_quotation_status !== 'reported'
276
+ "
277
+ class="fixe_bottom"
278
+ :style="prod_bottom"
279
+ >
280
+ <XdButton
281
+ v-if="
282
+ step === 1 &&
283
+ (info.user_quotation_status === 'wait_quote' ||
284
+ info.user_quotation_status === 'cancel_quotation')
285
+ "
286
+ width="680rpx"
287
+ @click="toConfirmQuote"
288
+ size="small"
289
+ type="primary"
290
+ >确认报价</XdButton
291
+ >
292
+ <XdButton
293
+ v-if="
294
+ step === 2 &&
295
+ (info.user_quotation_status === 'wait_quote' ||
296
+ info.user_quotation_status === 'cancel_quotation')
297
+ "
298
+ width="320rpx"
299
+ @click="step = 1"
300
+ size="small"
301
+ :cusStyle="[btnStyle]"
302
+ >再想想</XdButton
303
+ >
304
+ <XdButton
305
+ v-if="
306
+ step === 2 &&
307
+ (info.user_quotation_status === 'wait_quote' ||
308
+ info.user_quotation_status === 'cancel_quotation')
309
+ "
310
+ width="320rpx"
311
+ @click="handleSubmitQuote"
312
+ size="small"
313
+ type="primary"
314
+ >提交报价</XdButton
315
+ >
316
+ <XdButton
317
+ v-if="info.user_quotation_status === 'quoted'"
318
+ width="320rpx"
319
+ @click="showCancelDialog = true"
320
+ size="small"
321
+ :cusStyle="[btnStyle]"
322
+ >取消报价</XdButton
323
+ >
324
+ <XdButton
325
+ v-if="info.user_quotation_status === 'quoted'"
326
+ width="320rpx"
327
+ @click="showEditQuoteDialog = true"
328
+ size="small"
329
+ type="primary"
330
+ >修改报价</XdButton
331
+ >
332
+ <XdButton
333
+ v-if="
334
+ info.user_quotation_status === 'received'
335
+ "
336
+ width="320rpx"
337
+ @click="showDiscardDialog = true"
338
+ size="small"
339
+ :cusStyle="[btnStyle]"
340
+ >放弃订单</XdButton
341
+ >
342
+ <XdButton
343
+ v-if="info.user_quotation_status === 'received'"
344
+ width="320rpx"
345
+ size="small"
346
+ type="primary"
347
+ @click="handleReportOrder"
348
+ >上报订单</XdButton
349
+ >
350
+ <XdButton
351
+ v-if="info.user_quotation_status === 'win_order'"
352
+ width="320rpx"
353
+ @click="handleAcceptOrder"
354
+ size="small"
355
+ type="primary"
356
+ >接单</XdButton
357
+ >
358
+ </view>
359
+ <XdDailog width="70%" :showClose="false" :show.sync="showMsgDialog">
360
+ <template slot="title">
361
+ <view class="dialog-title">{{ msgTitle }}</view>
362
+ </template>
363
+ <view style="font-size: 28rpx">{{ msg }}</view>
364
+ <template slot="btn">
365
+ <XdButton
366
+ width="180rpx"
367
+ size="small"
368
+ type="primary"
369
+ @click="showMsgDialog = false"
370
+ >确定</XdButton
371
+ >
372
+ </template>
373
+ </XdDailog>
374
+ <XdDailog width="70%" :showClose="false" :show.sync="showCancelDialog">
375
+ <template slot="title">
376
+ <view class="dialog-title">提示</view>
377
+ </template>
378
+ <view style="font-size: 28rpx">是否确认取消报价</view>
379
+ <template slot="btn">
380
+ <XdButton
381
+ width="180rpx"
382
+ size="small"
383
+ bgColor="#EEE"
384
+ color="#999"
385
+ type="primary"
386
+ @click="showCancelDialog = false"
387
+ >取消</XdButton
388
+ >
389
+ <XdButton
390
+ width="180rpx"
391
+ size="small"
392
+ type="primary"
393
+ @click="handleCancelQuote"
394
+ >确定</XdButton
395
+ >
396
+ </template>
397
+ </XdDailog>
398
+ <XdDailog width="70%" :showClose="false" :show.sync="showDiscardDialog">
399
+ <template slot="title">
400
+ <view class="dialog-title">提示</view>
401
+ </template>
402
+ <view style="font-size: 28rpx">是否确认放弃订单</view>
403
+ <template slot="btn">
404
+ <XdButton
405
+ width="180rpx"
406
+ size="small"
407
+ bgColor="#EEE"
408
+ color="#999"
409
+ type="primary"
410
+ @click="showDiscardDialog = false"
411
+ >取消</XdButton
412
+ >
413
+ <XdButton
414
+ width="180rpx"
415
+ size="small"
416
+ type="primary"
417
+ @click="handleDiscardOrder"
418
+ >确定</XdButton
419
+ >
420
+ </template>
421
+ </XdDailog>
422
+ <CusEditQuote
423
+ v-if="showEditQuoteDialog"
424
+ :mainColor="mainColor"
425
+ :info="info"
426
+ @close="showEditQuoteDialog = false"
427
+ @confirm="handleConfirmEditQuote"
428
+ ></CusEditQuote>
429
+ </view>
430
+ </view>
431
+ </template>
432
+
433
+ <script>
434
+ import XdFontIcon from "@/components/XdFontIcon/XdFontIcon";
435
+ import XdContentXss from "@/components/XdContentXss/XdContentXss";
436
+ import XdDailog from "@/components/XdDailog/XdDailog";
437
+ import XdButton from "@/components/XdButton/XdButton";
438
+ import XdUpload from "@/components/XdUpload/XdUpload";
439
+ import Products from "./components/products.vue";
440
+ import CusEditQuote from "./components/CusEditQuote.vue";
441
+ import { jfbRootExec } from "@/utils/xd.event";
442
+ import JfbTakeorderOrderDetailMixin from "./JfbTakeorderOrderDetailMixin";
443
+ import { getContainerPropsValue } from "@/utils/xd.base";
444
+ import getServiceUrl from "@/common/getServiceUrl";
445
+ import componentsMixins from "@/mixins/componentsMixins";
446
+ import extsMixins from "@/mixins/extsMixins";
447
+ const Color = require("color");
448
+ import { mapState } from "vuex";
449
+ export default {
450
+ name: "JfbTakeorderOrderDetail",
451
+ components: {
452
+ XdFontIcon,
453
+ XdContentXss,
454
+ XdDailog,
455
+ XdButton,
456
+ Products,
457
+ CusEditQuote,
458
+ XdUpload,
459
+ },
460
+ mixins: [componentsMixins, extsMixins, JfbTakeorderOrderDetailMixin],
461
+ data() {
462
+ return {
463
+ info: null,
464
+ notice: "",
465
+ // 报价倒计时是否结束
466
+ isCountdownEnd: false,
467
+ // 报价倒计时定时器标识(用于清除定时器)
468
+ countdownTimer: null,
469
+ // 接单倒计时是否结束
470
+ isReceiveCountdownEnd: false,
471
+ // 接单倒计时定时器标识
472
+ receiveCountdownTimer: null,
473
+ // 接单倒计时剩余秒数(3分钟 = 180秒)
474
+ receiveCountdownSeconds: 180,
475
+ // 上报倒计时是否结束
476
+ isReportCountdownEnd: false,
477
+ // 上报倒计时定时器标识
478
+ reportCountdownTimer: null,
479
+ // 上报倒计时剩余秒数(10分钟 = 600秒)
480
+ reportCountdownSeconds: 0,
481
+ quotePrice: "",
482
+ closeMask: true,
483
+ showConfirmDialog: false,
484
+ quoteDisabled: false,
485
+ showMsgDialog: false,
486
+ step: 1,
487
+ showCancelDialog: false,
488
+ msg: "",
489
+ msgTitle: "",
490
+ showEditQuoteDialog: false,
491
+ status: "daishangbao",
492
+ uploadBackground: "",
493
+ order_id: "",
494
+ showDiscardDialog: false,
495
+ // 上传的凭证图片列表
496
+ voucherImages: [],
497
+ };
498
+ },
499
+ computed: {
500
+ ...mapState(["brandInfo"]),
501
+ prod_bottom() {
502
+ return this.fixedStyle({ height: 0, zIndex: 111 });
503
+ },
504
+ btnStyle() {
505
+ return {
506
+ color: this.mainColor,
507
+ border: `1px solid ${this.mainColor}`,
508
+ };
509
+ },
510
+ quotePriceTotal() {
511
+ return this.$xdUniHelper.multiplyFloatNumber(
512
+ this.quotePrice,
513
+ this.info.product_total
514
+ );
515
+ },
516
+ },
517
+ watch: {
518
+ container(value, oldValue) {
519
+ if (JSON.stringify(value) === JSON.stringify(oldValue)) return;
520
+ if (this.$configProject["isPreview"]) this.init(value);
521
+ },
522
+ },
523
+ created() {
524
+ this.init(this.container);
525
+
526
+ //todo
527
+ },
528
+ methods: {
529
+ onJfbLoad(options) {
530
+ this.order_id = options.order_id;
531
+ this.getOrderDetail();
532
+ this.getContent();
533
+ },
534
+ getContent() {
535
+ jfbRootExec("getListOrderNewsContent", {
536
+ vm: this,
537
+ data: {
538
+ page_id: this.pageAttr["page_id"], //页面ID
539
+ container_id: this.containerId, //组件ID
540
+ limit: 1,
541
+ },
542
+ })
543
+ .then((res) => {
544
+ if (res.list.length > 0) {
545
+ if (res.list && res.list.length > 0) {
546
+ this.notice = this.$xdUniHelper.filterHtml(res.list[0].content);
547
+ }
548
+ }
549
+ })
550
+ .catch((error) => {
551
+ this.$xdLog.catch(err);
552
+ });
553
+ },
554
+ getOrderDetail() {
555
+ jfbRootExec("getTakeorderOrderDetail", {
556
+ vm: this,
557
+ data: {
558
+ order_id: this.order_id,
559
+ },
560
+ })
561
+ .then((res) => {
562
+ this.info = res;
563
+ if (this.info.user_quotation_status === "quoted") {
564
+ this.quotePrice = this.$xdUniHelper.divisionFloatNumber(
565
+ this.info.user_quotation,
566
+ 100
567
+ );
568
+ this.quoteDisabled = true;
569
+ }
570
+ if (
571
+ this.info.user_quotation_status === "cancel_quotation" ||
572
+ this.info.user_quotation_status === "wait_quote" ||
573
+ this.info.user_quotation_status === "quoted"
574
+ ) {
575
+ this.startCountdown();
576
+ }
577
+ if (this.info.user_quotation_status === "win_order") {
578
+ //如果中标,则显示接单按钮,并开启三分钟接单倒计时
579
+ this.startReceiveCountdown();
580
+ }
581
+ if (this.info.user_quotation_status === "received") {
582
+ //如果已接单,开启十分钟上报订单倒计时
583
+ this.startReportCountdown();
584
+ }
585
+ if (this.info.user_quotation_status === "close") {
586
+ //如果订单已关闭,则隐藏所有按钮,并且清除倒计时
587
+ this.isCountdownEnd = true;
588
+ this.clearReceiveCountdown();
589
+ this.clearReportCountdown();
590
+ }
591
+ })
592
+ .catch((error) => {
593
+ this.$xdLog.catch(err);
594
+ });
595
+ },
596
+ /**
597
+ * @description 监听事件变化
598
+ * @param container {object} 业务组件对象自己
599
+ */
600
+ init(container) {
601
+ this.uploadBackground = Color(this.mainColor).alpha(0.15).toString();
602
+ //this.bgcolor = getContainerPropsValue(container, 'content.bgcolor', '#fff');
603
+
604
+ //this.height = getContainerPropsValue(container, 'content.height', 10);
605
+ },
606
+ toConfirmQuote() {
607
+ if (!this.quotePrice) {
608
+ this.$xdAlert({ content: "请输入报价" });
609
+ return;
610
+ }
611
+ // 校验报价范围
612
+ const min = this.$xdUniHelper.divisionFloatNumber(
613
+ this.info.suggest_min_quotation,
614
+ 100
615
+ );
616
+ const max = this.$xdUniHelper.divisionFloatNumber(
617
+ this.info.suggest_max_quotation,
618
+ 100
619
+ );
620
+ const price = parseFloat(this.quotePrice);
621
+ if (price > max) {
622
+ this.$xdAlert({ content: `报价价格只能在建议报价区间内` });
623
+ return;
624
+ }
625
+ this.step = 2;
626
+ },
627
+ handleSubmitQuote() {
628
+ this.$xdShowLoading({});
629
+ jfbRootExec("createQuotation", {
630
+ vm: this,
631
+ data: {
632
+ order_id: this.order_id,
633
+ amount: this.$xdUniHelper.multiplyFloatNumber(this.quotePrice, 100),
634
+ },
635
+ })
636
+ .then((res) => {
637
+ this.$xdHideLoading();
638
+ this.step = "";
639
+ // 提交创建报价之后重新刷新订单详情
640
+ this.getOrderDetail();
641
+ })
642
+ .catch((error) => {
643
+ this.$xdHideLoading();
644
+ });
645
+ },
646
+ handleCancelQuote() {
647
+ //请求接口,判断是否可以取消报价
648
+ jfbRootExec("cancelQuotation", {
649
+ vm: this,
650
+ data: {
651
+ order_id: this.order_id,
652
+ },
653
+ }).then((res) => {
654
+ this.$xdUniHelper.navigateBack();
655
+ });
656
+ },
657
+ handleConfirmEditQuote(price) {
658
+ jfbRootExec("updateQuotation", {
659
+ vm: this,
660
+ data: {
661
+ order_id: this.order_id,
662
+ amount: this.$xdUniHelper.multiplyFloatNumber(price, 100),
663
+ },
664
+ })
665
+ .then((res) => {
666
+ if (res.msg) {
667
+ this.msg = "报价已结束";
668
+ this.msgTitle = "提示";
669
+ this.showMsgDialog = true;
670
+ }
671
+ this.showEditQuoteDialog = false;
672
+ this.getOrderDetail();
673
+ })
674
+ .catch((error) => {
675
+ this.$xdLog.catch(err);
676
+ });
677
+ },
678
+ startCountdown() {
679
+ // 先清除可能存在的旧定时器,防止重复计时
680
+ this.clearCountdown();
681
+ // 创建每秒执行的定时器
682
+ this.countdownTimer = setInterval(() => {
683
+ if (this.info.rest_quotation_time > 0) {
684
+ // 剩余秒数减1
685
+ this.info.rest_quotation_time--;
686
+ } else {
687
+ // 倒计时结束:清除定时器 + 标记结束状态
688
+ this.clearCountdown();
689
+ if (this.isPreview) return;
690
+ this.getOrderDetail();
691
+ console.log("报价倒计时结束");
692
+ }
693
+ }, 1000);
694
+ },
695
+ /**
696
+ * 格式化秒数为 分:秒 格式(比如 60秒 → 01:00,5秒 → 00:05)
697
+ * @param {Number} seconds 待格式化的秒数
698
+ * @returns {String} 格式化后的时间字符串
699
+ */
700
+ formatTime(seconds) {
701
+ // 计算分钟
702
+ const minutes = Math.floor(seconds / 60);
703
+ // 计算剩余秒数
704
+ const secs = seconds % 60;
705
+ // 补零处理(确保两位数显示)
706
+ const formatMinutes = minutes.toString().padStart(2, "0");
707
+ const formatSecs = secs.toString().padStart(2, "0");
708
+ return `${formatMinutes}:${formatSecs}`;
709
+ },
710
+ /**
711
+ * 格式化秒数为 XX分XX秒 格式(用于待上报状态倒计时显示)
712
+ * @param {Number} seconds 待格式化的秒数
713
+ * @returns {String} 格式化后的时间字符串,如 "02分59秒"
714
+ */
715
+ formatCountdownTime(seconds) {
716
+ // 计算分钟
717
+ const minutes = Math.floor(seconds / 60);
718
+ // 计算剩余秒数
719
+ const secs = seconds % 60;
720
+ // 补零处理(确保两位数显示)
721
+ const formatMinutes = minutes.toString().padStart(2, "0");
722
+ const formatSecs = secs.toString().padStart(2, "0");
723
+ return `${formatMinutes}分${formatSecs}秒`;
724
+ },
725
+ /**
726
+ * 清除报价倒计时定时器
727
+ */
728
+ clearCountdown() {
729
+ if (this.countdownTimer) {
730
+ clearInterval(this.countdownTimer);
731
+ this.countdownTimer = null;
732
+ }
733
+ },
734
+ /**
735
+ * 启动接单倒计时(3分钟)
736
+ */
737
+ startReceiveCountdown() {
738
+ // 先清除可能存在的旧定时器,防止重复计时
739
+ this.clearReceiveCountdown();
740
+ // 初始化倒计时秒数(3分钟 = 180秒)
741
+ this.receiveCountdownSeconds = this.info.rest_receive_time;
742
+ this.isReceiveCountdownEnd = false;
743
+
744
+ // 创建每秒执行的定时器
745
+ this.receiveCountdownTimer = setInterval(() => {
746
+ if (this.receiveCountdownSeconds > 0) {
747
+ // 剩余秒数减1
748
+ this.receiveCountdownSeconds--;
749
+ } else {
750
+ // 倒计时结束:清除定时器 + 标记结束状态
751
+ this.clearReceiveCountdown();
752
+ this.isReceiveCountdownEnd = true;
753
+ // 倒计时结束请求详情接口
754
+ this.getOrderDetail();
755
+ console.log("接单倒计时结束");
756
+ }
757
+ }, 1000);
758
+ },
759
+ /**
760
+ * 清除接单倒计时定时器
761
+ */
762
+ clearReceiveCountdown() {
763
+ if (this.receiveCountdownTimer) {
764
+ clearInterval(this.receiveCountdownTimer);
765
+ this.receiveCountdownTimer = null;
766
+ }
767
+ },
768
+ /**
769
+ * 启动上报倒计时(10分钟)
770
+ */
771
+ startReportCountdown() {
772
+ // 先清除可能存在的旧定时器,防止重复计时
773
+ this.clearReportCountdown();
774
+ // 初始化倒计时秒数(10分钟 = 600秒),如果有接口返回的时间则使用接口返回的时间
775
+ this.reportCountdownSeconds = this.info.rest_report_time;
776
+ this.isReportCountdownEnd = false;
777
+
778
+ // 创建每秒执行的定时器
779
+ this.reportCountdownTimer = setInterval(() => {
780
+ if (this.reportCountdownSeconds > 0) {
781
+ // 剩余秒数减1
782
+ this.reportCountdownSeconds--;
783
+ } else {
784
+ // 倒计时结束:清除定时器 + 标记结束状态
785
+ this.clearReportCountdown();
786
+ this.isReportCountdownEnd = true;
787
+ // 倒计时结束请求详情接口
788
+ this.getOrderDetail();
789
+ console.log("上报倒计时结束");
790
+ }
791
+ }, 1000);
792
+ },
793
+ /**
794
+ * 清除上报倒计时定时器
795
+ */
796
+ clearReportCountdown() {
797
+ if (this.reportCountdownTimer) {
798
+ clearInterval(this.reportCountdownTimer);
799
+ this.reportCountdownTimer = null;
800
+ }
801
+ },
802
+ /**
803
+ * 处理放弃订单
804
+ */
805
+ handleDiscardOrder() {
806
+ this.$xdShowLoading({});
807
+ jfbRootExec("discardOrder", {
808
+ vm: this,
809
+ data: {
810
+ order_id: this.order_id,
811
+ },
812
+ })
813
+ .then((res) => {
814
+ this.$xdHideLoading();
815
+ this.showDiscardDialog = false;
816
+ // 接口成功后重新请求订单详情
817
+ this.getOrderDetail();
818
+ })
819
+ .catch((error) => {
820
+ this.$xdHideLoading();
821
+ this.$xdLog.catch(error);
822
+ });
823
+ },
824
+ /**
825
+ * 处理接受订单
826
+ */
827
+ handleAcceptOrder() {
828
+ this.$xdShowLoading({});
829
+ jfbRootExec("acceptOrder", {
830
+ vm: this,
831
+ data: {
832
+ order_id: this.order_id,
833
+ },
834
+ })
835
+ .then((res) => {
836
+ this.$xdHideLoading();
837
+ // 清除接单倒计时
838
+ this.clearReceiveCountdown();
839
+ // 接口成功后重新请求订单详情
840
+ this.getOrderDetail();
841
+ })
842
+ .catch((error) => {
843
+ this.$xdHideLoading();
844
+ this.$xdLog.catch(error);
845
+ });
846
+ },
847
+ handleUploadDone(files) {
848
+ console.log("event.handleUploadDone", files);
849
+ this.$xdShowLoading({});
850
+ jfbRootExec("imageRecognition", {
851
+ vm: this,
852
+ data: {
853
+ image_url: files[0].url,
854
+ },
855
+ })
856
+ .then((res) => {
857
+ console.log("event.handleUploadDone", res);
858
+ jfbRootExec("getImagePreview", {
859
+ vm: this,
860
+ data: {
861
+ image_url: files[0].url,
862
+ },
863
+ })
864
+ .then((res1) => {
865
+ console.log("event.getImagePreview", res);
866
+ let obj = {
867
+ report_voucher: files[0].url,
868
+ report_voucher_preview_url: res1.preview_url,
869
+ code_list: res.list.map((item) => {
870
+ if (item.show_type === "qrcode") {
871
+ let reg = /^(http:\/\/|https:\/\/|\/\/)+.+$/;
872
+ item.code_preview_url = reg.test(item.preview_url)
873
+ ? item.preview_url
874
+ : `${this.brandInfo["api_host"]}${item.preview_url}`;
875
+ } else {
876
+ item.code = item.code;
877
+ }
878
+ return item;
879
+ }),
880
+ };
881
+ this.voucherImages.push(obj);
882
+ this.$xdHideLoading();
883
+ })
884
+ .catch((error) => {
885
+ this.$xdHideLoading();
886
+ this.$xdLog.catch(error);
887
+ });
888
+ })
889
+ .catch((error) => {
890
+ this.$xdHideLoading();
891
+ this.$xdLog.catch(error);
892
+ });
893
+ },
894
+ /**
895
+ * 处理上报订单
896
+ */
897
+ handleReportOrder() {
898
+ // 检查是否上传了凭证
899
+ if (!this.voucherImages || this.voucherImages.length === 0) {
900
+ this.$xdAlert({ content: "请先上传凭证" });
901
+ return;
902
+ }
903
+ this.$xdShowLoading({});
904
+ jfbRootExec("reportOrder", {
905
+ vm: this,
906
+ data: {
907
+ order_id: this.order_id,
908
+ report_voucher_list: this.voucherImages,
909
+ },
910
+ })
911
+ .then((res) => {
912
+ this.$xdHideLoading();
913
+ // 清除上报倒计时
914
+ this.clearReportCountdown();
915
+ // 接口成功后重新请求订单详情
916
+ this.getOrderDetail();
917
+ })
918
+ .catch((error) => {
919
+ this.$xdHideLoading();
920
+ this.$xdLog.catch(error);
921
+ });
922
+ },
923
+ onJfbScroll(options) {
924
+ console.log("event.onJfbScroll", options);
925
+ },
926
+ onJfbReachBottom(options) {
927
+ console.log("event.onJfbReachBottom", options);
928
+ },
929
+ onJfbShow(options) {
930
+ console.log("event.onJfbShow", options);
931
+ },
932
+ onJfbHide(options) {
933
+ console.log("event.onJfbHide", options);
934
+ },
935
+ onJfbBack(options) {
936
+ console.log("event.onJfbBack", options);
937
+ },
938
+ onJfbUpdate(...data) {
939
+ console.log("event.onJfbUpdate", data);
940
+ },
941
+ onJfbCustomEvent(options) {
942
+ console.log("event.onJfbReachBottom", options);
943
+ },
944
+ onJfbUnload() {
945
+ this.clearCountdown();
946
+ this.clearReceiveCountdown();
947
+ this.clearReportCountdown();
948
+ },
949
+ },
950
+ };
951
+ </script>
952
+
953
+ <style scoped lang="less">
954
+ @import "./JfbTakeorderOrderDetailLess.less";
955
+
956
+ .jfb-takeorder-order-detail {
957
+ &__countdown-banner {
958
+ display: flex;
959
+ align-items: center;
960
+ padding: 24rpx 32rpx;
961
+ margin: 16rpx 16rpx 0 16rpx;
962
+ border-radius: 16rpx 16rpx 0 0;
963
+ background: #e5010e;
964
+ & > xd-font-icon {
965
+ margin-right: 16rpx;
966
+ }
967
+ }
968
+ &__countdown-text {
969
+ color: #fff;
970
+ font-size: 28rpx;
971
+ flex: 1;
972
+ }
973
+ &__body {
974
+ .wrap {
975
+ background: #fff;
976
+ margin: 16rpx;
977
+ border-radius: 16rpx;
978
+ }
979
+ .special-tip {
980
+ padding: 24rpx 32rpx;
981
+ color: #333;
982
+ & > view:first-child {
983
+ font-size: 28rpx;
984
+ color: #333;
985
+ margin-bottom: 20rpx;
986
+ }
987
+ & > view:last-child {
988
+ font-size: 24rpx;
989
+ }
990
+ }
991
+ .order-info {
992
+ &-title {
993
+ display: flex;
994
+ justify-content: space-between;
995
+ padding: 24rpx 32rpx;
996
+ border-bottom: 1px solid #f4f4f4;
997
+ &-left {
998
+ display: flex;
999
+ align-items: center;
1000
+ }
1001
+ &-right {
1002
+ font-weight: 500;
1003
+ }
1004
+ }
1005
+ &-product {
1006
+ display: flex;
1007
+ padding: 16rpx 32rpx;
1008
+ border-bottom: 1px solid #f4f4f4;
1009
+ & > image {
1010
+ width: 180rpx;
1011
+ height: 180rpx;
1012
+ flex-shrink: 0;
1013
+ border: 10rpx;
1014
+ }
1015
+ &-info {
1016
+ margin-left: 24rpx;
1017
+ &-name {
1018
+ .uni-max-cut(2,80);
1019
+ margin-bottom: 10rpx;
1020
+ }
1021
+ &-sku {
1022
+ font-size: 24rpx;
1023
+ color: #999;
1024
+ }
1025
+ &-price {
1026
+ margin-top: 10rpx;
1027
+ display: flex;
1028
+ justify-content: space-between;
1029
+ align-items: center;
1030
+ &-left {
1031
+ color: #ff2c18;
1032
+ font-size: 32rpx;
1033
+ font-weight: 500;
1034
+ & > text {
1035
+ font-size: 24rpx;
1036
+ margin-right: 10rpx;
1037
+ }
1038
+ .range {
1039
+ margin: 0 10rpx;
1040
+ }
1041
+ }
1042
+ &-right {
1043
+ color: #999;
1044
+ display: flex;
1045
+ align-items: baseline;
1046
+ & > view {
1047
+ margin-left: 10rpx;
1048
+ }
1049
+ }
1050
+ }
1051
+ }
1052
+ }
1053
+ }
1054
+ .other-info-item {
1055
+ display: flex;
1056
+ justify-content: space-between;
1057
+ padding: 20rpx 32rpx;
1058
+ color: #333;
1059
+ font-size: 28rpx;
1060
+ border-bottom: 2rpx solid #f8f8f8;
1061
+ }
1062
+ .quote {
1063
+ &-title {
1064
+ font-size: 28rpx;
1065
+ color: #333;
1066
+ padding: 24rpx 0 24rpx 32rpx;
1067
+ }
1068
+ &-input {
1069
+ position: relative;
1070
+ padding: 0 32rpx 24rpx 32rpx;
1071
+ &-unit {
1072
+ position: absolute;
1073
+ left: 55rpx;
1074
+ top: 50%;
1075
+ transform: translateY(-80%);
1076
+ font-size: 28rpx;
1077
+ color: #333;
1078
+ font-weight: 700;
1079
+ }
1080
+ & > input {
1081
+ background: #f8f8f8;
1082
+ font-size: 28rpx;
1083
+ padding: 20rpx 46rpx 20rpx 60rpx;
1084
+ border-radius: 16rpx;
1085
+ }
1086
+ }
1087
+ &-advice {
1088
+ font-size: 24rpx;
1089
+ color: #666666;
1090
+ padding: 0 0 24rpx 32rpx;
1091
+ }
1092
+ }
1093
+ .fixe_bottom {
1094
+ display: flex;
1095
+ align-items: center;
1096
+ justify-content: space-around;
1097
+ height: unit(100, rpx);
1098
+ padding: 0 unit(40, rpx);
1099
+ flex-flow: nowrap;
1100
+ background: #fff;
1101
+ box-shadow: 0 0 unit(16, rpx) rgba(0, 0, 0, 0.05);
1102
+ .flex_l {
1103
+ display: flex;
1104
+ align-items: center;
1105
+ font-size: unit(32, rpx);
1106
+ }
1107
+
1108
+ & > view {
1109
+ flex: 1;
1110
+ padding: 0 unit(15, rpx);
1111
+ }
1112
+ }
1113
+ .dialog-title {
1114
+ color: #666666;
1115
+ font-size: 28rpx;
1116
+ }
1117
+ .confirm-info {
1118
+ display: flex;
1119
+ flex-direction: column;
1120
+ align-items: center;
1121
+ justify-content: center;
1122
+ margin-bottom: 32rpx;
1123
+
1124
+ &-item {
1125
+ display: flex;
1126
+ justify-content: center;
1127
+ margin-bottom: 16rpx;
1128
+ font-size: 28rpx;
1129
+ color: #333;
1130
+ &-label {
1131
+ width: 140rpx;
1132
+ flex-shrink: 0;
1133
+ }
1134
+ &-value {
1135
+ margin-left: 48rpx;
1136
+ width: 120rpx;
1137
+ flex: 1;
1138
+ flex-wrap: wrap;
1139
+ display: flex;
1140
+ justify-content: flex-start;
1141
+ }
1142
+ }
1143
+ }
1144
+ .upload-title {
1145
+ border-radius: 4rpx;
1146
+ background: #e5010e;
1147
+ border: 1px solid #e5010e;
1148
+ padding: 24rpx 0;
1149
+ text-align: center;
1150
+ }
1151
+ .upload {
1152
+ padding: 24rpx 32rpx;
1153
+ }
1154
+ .upload-notice {
1155
+ color: #999999;
1156
+ font-size: 24rpx;
1157
+ margin-top: 24rpx;
1158
+ }
1159
+ .voucher {
1160
+ &-item {
1161
+ display: flex;
1162
+ margin-bottom: 26rpx;
1163
+ &-image {
1164
+ flex-shrink: 0;
1165
+ display: flex;
1166
+ flex-direction: column;
1167
+ align-items: center;
1168
+ justify-content: center;
1169
+ & > image {
1170
+ width: 180rpx;
1171
+ height: 180rpx;
1172
+ border-radius: 4rpx;
1173
+ }
1174
+ & > view {
1175
+ color: #666;
1176
+ font-size: 24rpx;
1177
+ }
1178
+ }
1179
+ &-info {
1180
+ &-label {
1181
+ color: #666;
1182
+ font-size: 24rpx;
1183
+ margin-left: 24rpx;
1184
+ }
1185
+ &-number {
1186
+ display: flex;
1187
+ align-items: center;
1188
+ margin-bottom: 24rpx;
1189
+ & > view {
1190
+ font-size: 28rpx;
1191
+ color: #999;
1192
+ background: #f8f8f8;
1193
+ padding: 20rpx;
1194
+ border-radius: 16rpx;
1195
+ }
1196
+ }
1197
+ &-qrcode {
1198
+ display: flex;
1199
+ align-items: flex-start;
1200
+ & > image {
1201
+ width: 120rpx;
1202
+ height: 120rpx;
1203
+ border-radius: 4rpx;
1204
+ }
1205
+ }
1206
+ }
1207
+ }
1208
+ }
1209
+ }
1210
+ }
1211
+ </style>