list.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <!-- 售后列表 -->
  2. <template>
  3. <s-layout :title="t('order.after_sales_list')">
  4. <!-- tab -->
  5. <su-sticky bgColor="#fff">
  6. <su-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" />
  7. </su-sticky>
  8. <s-empty v-if="state.pagination.total === 0" icon="/static/data-empty.png" :text="t('common.no_data')" />
  9. <!-- 列表 -->
  10. <view v-if="state.pagination.total > 0">
  11. <view class="list-box ss-m-y-20" v-for="order in state.pagination.list" :key="order.id"
  12. @tap="sheep.$router.go('/pages/order/aftersale/detail', { id: order.id })">
  13. <view class="order-head ss-flex ss-col-center ss-row-between">
  14. <text class="no">{{t('order.service_order_number')}}:{{ order.no }}</text>
  15. <text class="state">{{ formatAfterSaleStatus(order) }}</text>
  16. </view>
  17. <s-goods-item
  18. :img="order.picUrl"
  19. :title="order.spuName"
  20. :skuText="order.properties.map((property) => property.valueName).join(' ')"
  21. :price="order.refundIntegral"
  22. :areaId="order.refundIntegralType"
  23. />
  24. <view class="apply-box ss-flex ss-col-center ss-row-between border-bottom ss-p-x-20">
  25. <view class="ss-flex ss-col-center">
  26. <view class="title ss-m-r-20">{{ order.way === 10 ? t('order.refund_only') : t('order.refund_and_return') }}</view>
  27. <view class="value">{{ formatAfterSaleStatusDescription(order) }}</view>
  28. </view>
  29. <text class="_icon-forward"></text>
  30. </view>
  31. <view class="tool-btn-box ss-flex ss-col-center ss-row-right ss-p-r-20">
  32. <!-- TODO 功能缺失:填写退货信息 -->
  33. <view>
  34. <button class="ss-reset-button tool-btn" @tap.stop="onApply(order.id)"
  35. v-if="order?.buttons.includes('cancel')">{{t('order.cancel_request')}}</button>
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. <uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
  41. contentdown: '上拉加载更多',
  42. }" @tap="loadMore" />
  43. </s-layout>
  44. </template>
  45. <script setup>
  46. import sheep from '@/sheep';
  47. import { onLoad, onReachBottom } from '@dcloudio/uni-app';
  48. import { reactive } from 'vue';
  49. import _ from 'lodash';
  50. import { formatAfterSaleStatus, formatAfterSaleStatusDescription, handleAfterSaleButtons } from '@/sheep/hooks/useGoods';
  51. import AfterSaleApi from '@/sheep/api/trade/afterSale';
  52. import { t } from '@/locale'
  53. const paginationNull = {
  54. list: [],
  55. total: 0,
  56. pageNo: 1,
  57. pageSize: 10
  58. };
  59. const state = reactive({
  60. currentTab: 0,
  61. showApply: false,
  62. pagination: {
  63. list: [],
  64. total: 0,
  65. pageNo: 1,
  66. pageSize: 10
  67. },
  68. loadStatus: '',
  69. });
  70. // TODO 非繁人:优化点,增加筛选
  71. const tabMaps = [{
  72. name: t('common.all'),
  73. value: 'all',
  74. },
  75. // {
  76. // name: '申请中',
  77. // value: 'nooper',
  78. // },
  79. // {
  80. // name: '处理中',
  81. // value: 'ing',
  82. // },
  83. // {
  84. // name: '已完成',
  85. // value: 'completed',
  86. // },
  87. // {
  88. // name: '已拒绝',
  89. // value: 'refuse',
  90. // },
  91. ];
  92. // 切换选项卡
  93. function onTabsChange(e) {
  94. state.pagination = paginationNull
  95. state.currentTab = e.index;
  96. getOrderList();
  97. }
  98. // 获取售后列表
  99. async function getOrderList() {
  100. state.loadStatus = 'loading';
  101. let { data, code } = await AfterSaleApi.getAfterSalePage({
  102. // type: tabMaps[state.currentTab].value,
  103. pageNo: state.pagination.pageNo,
  104. pageSize: state.pagination.pageSize,
  105. });
  106. if (code !== 0) {
  107. return;
  108. }
  109. data.list.forEach(order => handleAfterSaleButtons(order));
  110. state.pagination.list = _.concat(state.pagination.list, data.list);
  111. state.pagination.total = data.total;
  112. state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';
  113. }
  114. function onApply(orderId) {
  115. uni.showModal({
  116. title: t('setting.prompt'),
  117. content: t('order.confirm_cancel_request'),
  118. success: async function(res) {
  119. if (!res.confirm) {
  120. return;
  121. }
  122. const { code } = await AfterSaleApi.cancelAfterSale(orderId);
  123. if (code === 0) {
  124. state.pagination = paginationNull
  125. await getOrderList();
  126. }
  127. },
  128. });
  129. }
  130. onLoad(async (options) => {
  131. if (options.type) {
  132. state.currentTab = options.type;
  133. }
  134. await getOrderList();
  135. });
  136. // 加载更多
  137. function loadMore() {
  138. if (state.loadStatus === 'noMore') {
  139. return
  140. }
  141. state.pagination.pageNo++;
  142. getOrderList();
  143. }
  144. // 上拉加载更多
  145. onReachBottom(() => {
  146. loadMore();
  147. });
  148. </script>
  149. <style lang="scss" scoped>
  150. .list-box {
  151. background-color: #fff;
  152. .order-head {
  153. padding: 0 25rpx;
  154. height: 77rpx;
  155. }
  156. .apply-box {
  157. height: 82rpx;
  158. .title {
  159. font-size: 24rpx;
  160. }
  161. .value {
  162. font-size: 22rpx;
  163. color: $dark-6;
  164. }
  165. }
  166. .tool-btn-box {
  167. height: 100rpx;
  168. .tool-btn {
  169. // width: 160rpx;
  170. padding:0 10rpx;
  171. height: 60rpx;
  172. background: #f6f6f6;
  173. border-radius: 30rpx;
  174. font-size: 26rpx;
  175. font-weight: 400;
  176. }
  177. }
  178. }
  179. </style>