list.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <!-- 页面 -->
  2. <template>
  3. <s-layout title="我的订单">
  4. <su-sticky bgColor="#fff">
  5. <su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab"></su-tabs>
  6. </su-sticky>
  7. <s-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单"></s-empty>
  8. <view v-if="state.pagination.total > 0">
  9. <view class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" v-for="order in state.pagination.data"
  10. :key="order.id" @tap="onOrderDetail(order.id)">
  11. <view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
  12. <view class="order-no">订单号:{{ order.no }}</view>
  13. <view class="order-state ss-font-26" :class="formatOrderColor(order.status_code)">{{
  14. order.status
  15. }}</view>
  16. </view>
  17. <view class="border-bottom" v-for="item in order.items" :key="item.id">
  18. <s-goods-item :img="item.picUrl" :title="item.spuName"
  19. :skuText="item.properties.length>1? item.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.properties[0].valueName"
  20. :price="item.price/100" :score="order.score_amount" :num="item.count">
  21. <template #tool>
  22. <view class="ss-flex">
  23. <!-- <button class="ss-reset-button apply-btn" v-if="item.btns.includes('aftersale')"
  24. @tap.stop="
  25. sheep.$router.go('/pages/order/aftersale/apply', {
  26. item: JSON.stringify(item),
  27. })
  28. ">
  29. 申请售后
  30. </button>
  31. <button class="ss-reset-button apply-btn" v-if="item.btns.includes('re_aftersale')"
  32. @tap.stop="
  33. sheep.$router.go('/pages/order/aftersale/apply', {
  34. item: JSON.stringify(item),
  35. })
  36. ">
  37. 重新售后
  38. </button>
  39. <button class="ss-reset-button apply-btn" v-if="item.btns.includes('aftersale_info')"
  40. @tap.stop="
  41. sheep.$router.go('/pages/order/aftersale/detail', {
  42. id: item.ext.aftersale_id,
  43. })
  44. ">
  45. 售后详情
  46. </button>
  47. <button class="ss-reset-button apply-btn" v-if="item.btns.includes('buy_again')"
  48. @tap.stop="
  49. sheep.$router.go('/pages/goods/index', {
  50. id: item.goods_id,
  51. })
  52. ">
  53. 再次购买
  54. </button> -->
  55. </view>
  56. </template>
  57. </s-goods-item>
  58. </view>
  59. <view class="pay-box ss-m-t-30 ss-flex ss-row-right ss-p-r-20">
  60. <!-- <view v-if="order.total_discount_fee > 0" class="ss-flex ss-col-center ss-m-r-8">
  61. <view class="discounts-title">优惠:¥</view>
  62. <view class="discounts-money">{{ order.total_discount_fee }}</view>
  63. </view> -->
  64. <!-- <view class="ss-flex ss-col-center ss-m-r-8">
  65. <view class="discounts-title">运费:¥</view>
  66. <view class="discounts-money">{{ order.dispatch_amount }}</view>
  67. </view> -->
  68. <view class="ss-flex ss-col-center">
  69. <view class="discounts-title pay-color">共{{count}}件商品,总金额:</view>
  70. <view class="discounts-money pay-color" v-if="Number(order.payPrice) > 0">
  71. ¥{{ order.payPrice/100 }}</view>
  72. <view v-if="order.score_amount && Number(order.payPrice) > 0">+</view>
  73. <view class="discounts-money pay-color ss-flex ss-col-center" v-if="order.score_amount">
  74. <image :src="sheep.$url.static('/static/img/shop/goods/score1.svg')" class="score-img">
  75. </image>
  76. <view>{{ order.score_amount }}</view>
  77. </view>
  78. </view>
  79. </view>
  80. <!-- :class="order.btns.length > 3 ? 'ss-row-between' : 'ss-row-right'" -->
  81. <view class="order-card-footer ss-flex ss-col-center ss-p-x-20">
  82. <!-- <su-popover>
  83. <button class="more-btn ss-reset-button" @click.stop>更多</button>
  84. <template #content>
  85. <view class="more-item-box">
  86. <view class="more-item ss-flex ss-col-center ss-reset-button">
  87. <view class="item-title">删除订单</view>
  88. </view>
  89. <view class="more-item ss-flex ss-col-center ss-reset-button">
  90. <view class="item-title">查看发票</view>
  91. </view>
  92. <view class="more-item ss-flex ss-col-center ss-reset-button">
  93. <view class="item-title">评价晒单</view>
  94. </view>
  95. </view>
  96. </template>
  97. </su-popover> -->
  98. <view class="ss-flex ss-col-center">
  99. <!-- <button v-if="order.btns.includes('groupon')" class="tool-btn ss-reset-button"
  100. @tap.stop="onOrderGroupon(order)">
  101. {{ order.status_code === 'groupon_ing' ? '邀请拼团' : '拼团详情' }}
  102. </button>
  103. <button v-if="order.btns.includes('invoice')" class="tool-btn ss-reset-button"
  104. @tap.stop="onOrderInvoice(order.invoice?.id)">
  105. 查看发票
  106. </button>
  107. <button v-if="order.btns.length === 0" class="tool-btn ss-reset-button"
  108. @tap.stop="onOrderDetail(order.order_sn)">
  109. 查看详情
  110. </button>
  111. <button v-if="order.btns.includes('confirm')" class="tool-btn ss-reset-button"
  112. @tap.stop="onConfirm(order)">
  113. 确认收货
  114. </button>
  115. <button v-if="order.btns.includes('express')" class="tool-btn ss-reset-button"
  116. @tap.stop="onExpress(order.id)">
  117. 查看物流
  118. </button>
  119. <button v-if="order.btns.includes('apply_refund')" class="tool-btn ss-reset-button"
  120. @tap.stop="onRefund(order.id)">
  121. 申请退款
  122. </button>
  123. <button v-if="order.btns.includes('re_apply_refund')" class="tool-btn ss-reset-button"
  124. @tap.stop="onRefund(order.id)">
  125. 重新退款
  126. </button>
  127. <button v-if="order.btns.includes('cancel')" class="tool-btn ss-reset-button"
  128. @tap.stop="onCancel(order.id)">
  129. 取消订单
  130. </button>
  131. <button v-if="order.btns.includes('comment')" class="tool-btn ss-reset-button"
  132. @tap.stop="onComment(order.order_sn)">
  133. 评价晒单
  134. </button>
  135. <button v-if="order.btns.includes('delete')" class="delete-btn ss-reset-button"
  136. @tap.stop="onDelete(order.id)">
  137. 删除订单
  138. </button>
  139. <button v-if="order.btns.includes('pay')" class="tool-btn ss-reset-button ui-BG-Main-Gradient"
  140. @tap.stop="onPay(order.order_sn)">
  141. 继续支付
  142. </button> -->
  143. </view>
  144. </view>
  145. </view>
  146. </view>
  147. <!-- 加载更多 -->
  148. <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
  149. contentdown: '上拉加载更多',
  150. }" @tap="loadmore" />
  151. </s-layout>
  152. </template>
  153. <script setup>
  154. import {
  155. computed,
  156. reactive
  157. } from 'vue';
  158. import {
  159. onLoad,
  160. onReachBottom,
  161. onPullDownRefresh
  162. } from '@dcloudio/uni-app';
  163. import {
  164. formatOrderColor
  165. } from '@/sheep/hooks/useGoods';
  166. import sheep from '@/sheep';
  167. import _ from 'lodash';
  168. import {
  169. isEmpty
  170. } from 'lodash';
  171. const pagination = {
  172. data: [],
  173. current_page: 1,
  174. total: 1,
  175. last_page: 1,
  176. };
  177. // 数据
  178. const state = reactive({
  179. currentTab: 0,
  180. pagination: {
  181. data: [],
  182. current_page: 1,
  183. total: 1,
  184. last_page: 1,
  185. },
  186. loadStatus: '',
  187. deleteOrderId: 0,
  188. error: 0,
  189. });
  190. const tabMaps = [{
  191. name: '全部',
  192. // value: 'all',
  193. },
  194. {
  195. name: '待付款',
  196. value: 0,
  197. },
  198. {
  199. name: '待发货',
  200. value: 10,
  201. },
  202. {
  203. name: '待收货',
  204. value: 20,
  205. },
  206. {
  207. name: '待评价',
  208. value: 30,
  209. },
  210. ];
  211. // 切换选项卡
  212. function onTabsChange(e) {
  213. if (state.currentTab === e.index) return;
  214. state.pagination = pagination;
  215. state.currentTab = e.index;
  216. getOrderList();
  217. }
  218. // 订单详情
  219. function onOrderDetail(orderSN) {
  220. sheep.$router.go('/pages/order/detail', {
  221. orderSN,
  222. });
  223. }
  224. // 分享拼团
  225. function onOrderGroupon(order) {
  226. sheep.$router.go('/pages/activity/groupon/detail', {
  227. id: order.ext.groupon_id,
  228. });
  229. }
  230. // 查看发票
  231. function onOrderInvoice(invoiceId) {
  232. sheep.$router.go('/pages/order/invoice', {
  233. invoiceId,
  234. });
  235. }
  236. // 继续支付
  237. function onPay(orderSN) {
  238. sheep.$router.go('/pages/pay/index', {
  239. orderSN,
  240. });
  241. }
  242. // 评价
  243. function onComment(orderSN) {
  244. sheep.$router.go('/pages/goods/comment/add', {
  245. orderSN,
  246. });
  247. }
  248. // 确认收货
  249. async function onConfirm(order, ignore = false) {
  250. // 需开启确认收货组件
  251. // todo:
  252. // 1.怎么检测是否开启了发货组件功能?如果没有开启的话就不能在这里return出去
  253. // 2.如果开启了走mpConfirm方法,需要在App.vue的show方法中拿到确认收货结果
  254. let isOpenBusinessView = true;
  255. if (
  256. sheep.$platform.name === 'WechatMiniProgram' &&
  257. !isEmpty(order.wechat_extra_data) &&
  258. isOpenBusinessView &&
  259. !ignore
  260. ) {
  261. mpConfirm(order);
  262. return;
  263. }
  264. // 正常的确认收货流程
  265. const {
  266. error
  267. } = await sheep.$api.order.confirm(order.id);
  268. if (error === 0) {
  269. state.pagination = pagination;
  270. getOrderList();
  271. }
  272. }
  273. // #ifdef MP-WEIXIN
  274. // 小程序确认收货组件
  275. function mpConfirm(order) {
  276. if (!wx.openBusinessView) {
  277. sheep.$helper.toast(`请升级微信版本`);
  278. return;
  279. }
  280. wx.openBusinessView({
  281. businessType: 'weappOrderConfirm',
  282. extraData: {
  283. merchant_id: '1481069012',
  284. merchant_trade_no: order.wechat_extra_data.merchant_trade_no,
  285. transaction_id: order.wechat_extra_data.transaction_id,
  286. },
  287. success(response) {
  288. console.log('success:', response);
  289. if (response.errMsg === 'openBusinessView:ok') {
  290. if (response.extraData.status === 'success') {
  291. onConfirm(order, true);
  292. }
  293. }
  294. },
  295. fail(error) {
  296. console.log('error:', error);
  297. },
  298. complete(result) {
  299. console.log('result:', result);
  300. },
  301. });
  302. }
  303. // #endif
  304. // 查看物流
  305. async function onExpress(orderId) {
  306. sheep.$router.go('/pages/order/express/list', {
  307. orderId,
  308. });
  309. }
  310. // 取消订单
  311. async function onCancel(orderId) {
  312. uni.showModal({
  313. title: '提示',
  314. content: '确定要取消订单吗?',
  315. success: async function(res) {
  316. if (res.confirm) {
  317. const {
  318. error,
  319. data
  320. } = await sheep.$api.order.cancel(orderId);
  321. if (error === 0) {
  322. let index = state.pagination.data.findIndex((order) => order.id === orderId);
  323. state.pagination.data[index] = data;
  324. }
  325. }
  326. },
  327. });
  328. }
  329. // 删除订单
  330. function onDelete(orderId) {
  331. uni.showModal({
  332. title: '提示',
  333. content: '确定要删除订单吗?',
  334. success: async function(res) {
  335. if (res.confirm) {
  336. const {
  337. error,
  338. data
  339. } = await sheep.$api.order.delete(orderId);
  340. if (error === 0) {
  341. let index = state.pagination.data.findIndex((order) => order.id === orderId);
  342. state.pagination.data.splice(index, 1);
  343. }
  344. }
  345. },
  346. });
  347. }
  348. // 申请退款
  349. async function onRefund(orderId) {
  350. uni.showModal({
  351. title: '提示',
  352. content: '确定要申请退款吗?',
  353. success: async function(res) {
  354. if (res.confirm) {
  355. // #ifdef MP
  356. sheep.$platform.useProvider('wechat').subscribeMessage('order_refund');
  357. // #endif
  358. const {
  359. error,
  360. data
  361. } = await sheep.$api.order.applyRefund(orderId);
  362. if (error === 0) {
  363. let index = state.pagination.data.findIndex((order) => order.id === orderId);
  364. state.pagination.data[index] = data;
  365. }
  366. }
  367. },
  368. });
  369. }
  370. // 获取订单列表
  371. async function getOrderList(page = 1, list_rows = 5) {
  372. state.loadStatus = 'loading';
  373. let res = await sheep.$api.order.list({
  374. status: tabMaps[state.currentTab].value,
  375. pageSize: list_rows,
  376. pageNo: page,
  377. commentStatus: tabMaps[state.currentTab].value == 30 ? false : null
  378. });
  379. state.error = res.code;
  380. if (res.code === 0) {
  381. let orderList = _.concat(state.pagination.data, res.data.list);
  382. state.pagination = {
  383. ...res.data,
  384. data: orderList,
  385. };
  386. console.log(state.pagination)
  387. if (state.pagination.data.length < state.pagination.total) {
  388. state.loadStatus = 'more';
  389. } else {
  390. state.loadStatus = 'noMore';
  391. }
  392. }
  393. }
  394. onLoad(async (options) => {
  395. if (options.type) {
  396. state.currentTab = options.type;
  397. }
  398. getOrderList();
  399. });
  400. // 加载更多
  401. function loadmore() {
  402. if (state.loadStatus !== 'noMore') {
  403. getOrderList(parseInt((state.pagination.data.length / 5) + 1));
  404. }
  405. }
  406. // 上拉加载更多
  407. onReachBottom(() => {
  408. loadmore();
  409. });
  410. //下拉刷新
  411. onPullDownRefresh(() => {
  412. state.pagination = pagination;
  413. getOrderList();
  414. setTimeout(function() {
  415. uni.stopPullDownRefresh();
  416. }, 800);
  417. });
  418. </script>
  419. <style lang="scss" scoped>
  420. .score-img {
  421. width: 36rpx;
  422. height: 36rpx;
  423. margin: 0 4rpx;
  424. }
  425. .tool-btn {
  426. width: 160rpx;
  427. height: 60rpx;
  428. background: #f6f6f6;
  429. font-size: 26rpx;
  430. border-radius: 30rpx;
  431. margin-right: 10rpx;
  432. &:last-of-type {
  433. margin-right: 0;
  434. }
  435. }
  436. .delete-btn {
  437. width: 160rpx;
  438. height: 56rpx;
  439. color: #ff3000;
  440. background: #fee;
  441. border-radius: 28rpx;
  442. font-size: 26rpx;
  443. margin-right: 10rpx;
  444. line-height: normal;
  445. &:last-of-type {
  446. margin-right: 0;
  447. }
  448. }
  449. .apply-btn {
  450. width: 140rpx;
  451. height: 50rpx;
  452. border-radius: 25rpx;
  453. font-size: 24rpx;
  454. border: 2rpx solid #dcdcdc;
  455. line-height: normal;
  456. margin-left: 16rpx;
  457. }
  458. .swiper-box {
  459. flex: 1;
  460. .swiper-item {
  461. height: 100%;
  462. width: 100%;
  463. }
  464. }
  465. .order-list-card-box {
  466. .order-card-header {
  467. height: 80rpx;
  468. .order-no {
  469. font-size: 26rpx;
  470. font-weight: 500;
  471. }
  472. .order-state {}
  473. }
  474. .pay-box {
  475. .discounts-title {
  476. font-size: 24rpx;
  477. line-height: normal;
  478. color: #999999;
  479. }
  480. .discounts-money {
  481. font-size: 24rpx;
  482. line-height: normal;
  483. color: #999;
  484. font-family: OPPOSANS;
  485. }
  486. .pay-color {
  487. color: #333;
  488. }
  489. }
  490. .order-card-footer {
  491. height: 100rpx;
  492. .more-item-box {
  493. padding: 20rpx;
  494. .more-item {
  495. height: 60rpx;
  496. .title {
  497. font-size: 26rpx;
  498. }
  499. }
  500. }
  501. .more-btn {
  502. color: $dark-9;
  503. font-size: 24rpx;
  504. }
  505. .content {
  506. width: 154rpx;
  507. color: #333333;
  508. font-size: 26rpx;
  509. font-weight: 500;
  510. }
  511. }
  512. }
  513. :deep(.uni-tooltip-popup) {
  514. background: var(--ui-BG);
  515. }
  516. .warning-color {
  517. color: #faad14;
  518. }
  519. .danger-color {
  520. color: #ff3000;
  521. }
  522. .success-color {
  523. color: #52c41a;
  524. }
  525. .info-color {
  526. color: #999999;
  527. }
  528. </style>