after-sales-list.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <mescroll-uni ref="mescrollRef" top="80rpx" @init="mescrollInit" @down="downCallback" @up="upCallback"
  3. :down="downOption" :up="upOption">
  4. <view class="sale-list" v-if="type == 'normal'">
  5. <view v-for="(items, index) in lists" :key="index" class="sale-item bg-white m-t-20">
  6. <view class="sale-header">
  7. <shop-title :shop="{name: items.shop_name, id: items.sid}"></shop-title>
  8. </view>
  9. <view v-for="(item, index2) in items.order_goods" :key="index2" class="goods-item">
  10. <view class="sale-content flex row">
  11. <view class="goods-img">
  12. <u-image width="160rpx" height="160rpx" border-radius="6rpx" :src="item.image" />
  13. </view>
  14. <view class="goods-desc flex-1 m-l-24">
  15. <view class="goods-name line-2">{{item.goods_name}}</view>
  16. <view class="m-t-10 line-1 muted">{{item.spec_value_str}}</view>
  17. <view class="flex row-between m-t-20">
  18. <price-format class="sm" :first-size="30" :second-size="30" :subscript-size="26"
  19. :price="item.goods_price" />
  20. <view>x{{item.goods_num}}</view>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="sale-footer flex row-right">
  25. <view class="btn row-center primary br60"
  26. :class="{'gray-btn': items.after_sale.able_apply == 0}" @tap="applyRefund(items,item)">
  27. 申请售后
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="sale-list" v-else-if="type == 'apply'">
  34. <view v-for="(items, index) in lists" :key="index" class="sale-item bg-white m-t-20">
  35. <view class="sale-header flex row-between">
  36. <shop-title :shop="{name: items.shop_name, id: items.sid}"></shop-title>
  37. <view class="primary flex-none m-l-20">{{items.after_sale.type_text}}</view>
  38. </view>
  39. <view v-for="(item, index2) in items.order_goods" :key="index2">
  40. <router-link :to="{path: '/bundle/pages/after_sales_detail/after_sales_detail',
  41. query: { id: items.after_sale.after_sale_id,}}">
  42. <view class="sale-content">
  43. <view class="flex">
  44. <view class="goods-img">
  45. <u-image width="160rpx" height="160rpx" border-radius="6rpx" :src="item.image" />
  46. </view>
  47. <view class="goods-desc m-l-24">
  48. <view class="goods-name line-2">{{item.goods_name}}</view>
  49. <view class="m-t-10 xs line-1 muted">{{item.spec_value_str}}</view>
  50. <view class="flex row-between m-t-20">
  51. <price-format class="sm" :first-size="30" :second-size="30" :subscript-size="26"
  52. :price="item.goods_price" />
  53. <view>x{{item.goods_num}}</view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="sale-status m-t-20 flex">
  58. <view class="bold">申请状态</view>
  59. <view class="m-l-20">{{items.after_sale.desc}}</view>
  60. </view>
  61. </view>
  62. </router-link>
  63. <view class="sale-footer flex row-right">
  64. <view class="row-center flex br60 m-r-20 btn black-btn"
  65. @tap="onShowDialog(items.after_sale.after_sale_id)">
  66. 撤销申请
  67. </view>
  68. <router-link :to="{path: '/bundle/pages/apply_refund/apply_refund',
  69. query: {
  70. after_sale_id: items.after_sale.after_sale_id,
  71. order_id: items.order_id,
  72. item_id: item.item_id}}" v-if="items.after_sale.status == 4 || items.after_sale.status == 1">
  73. <view class="row-center flex br60 m-r-20 btn primary">重新申请</view>
  74. </router-link>
  75. <router-link
  76. :to="{path: '/bundle/pages/input_express_info/input_express_info', query: { id: items.after_sale.after_sale_id}}"
  77. v-if="items.after_sale.status == 2">
  78. <view class="row-center flex br60 m-r-20 btn black-btn">
  79. 填写快递单号
  80. </view>
  81. </router-link>
  82. </view>
  83. </view>
  84. </view>
  85. </view>
  86. <view class="sale-list" v-else>
  87. <view v-for="(items, index) in lists" :key="index" class="sale-item bg-white m-t-20">
  88. <view class="sale-header flex row-between">
  89. <shop-title :shop="{name: items.shop_name, id: items.sid}"></shop-title>
  90. <view class="primary flex-none m-l-20">{{items.after_sale.type_text}}</view>
  91. </view>
  92. <view v-for="(item, index2) in items.order_goods" :key="index2">
  93. <router-link :to="{path: '/bundle/pages/after_sales_detail/after_sales_detail',
  94. query: { id: items.after_sale.after_sale_id,}}">
  95. <view class="sale-content">
  96. <view class="flex">
  97. <view class="goods-img">
  98. <u-image width="160rpx" height="160rpx" border-radius="6rpx" :src="item.image" />
  99. </view>
  100. <view class="goods-desc m-l-24">
  101. <view class="goods-name line-2">{{item.goods_name}}</view>
  102. <view class="m-t-10 line-1 muted">{{item.spec_value_str}}</view>
  103. <view class="flex row-between m-t-20">
  104. <price-format class="sm" :first-size="30" :second-size="30" :subscript-size="26"
  105. :price="item.goods_price" />
  106. <view>x{{item.goods_num}}</view>
  107. </view>
  108. </view>
  109. </view>
  110. <view class="sale-status m-t-20 flex">
  111. <view class="bold">申请状态</view>
  112. <view class="m-l-20">{{items.after_sale.desc}}</view>
  113. </view>
  114. </view>
  115. </router-link>
  116. </view>
  117. </view>
  118. </view>
  119. <u-modal v-model="showDialog" confirm-text="确定" :showCancelButton="true" :confirm-color="colorConfig.primary"
  120. @confirm="cancelApplyFun">
  121. <view class="flex-col col-center tips-dialog" style="padding: 30rpx 0;">
  122. <image class="icon-lg" src="/static/images/icon_warning.png"></image>
  123. <view class="m-t-30">是否要撤销申请?</view>
  124. </view>
  125. </u-modal>
  126. </mescroll-uni>
  127. </template>
  128. <script>
  129. import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js";
  130. import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js";
  131. import {
  132. afterSaleType
  133. } from "@/utils/type";
  134. import {
  135. getAfterSaleList,
  136. cancelApply,
  137. afterSaleDetail,
  138. applyAgain
  139. } from "@/api/user";
  140. export default {
  141. mixins: [MescrollMixin, MescrollMoreItemMixin],
  142. props: {
  143. type: {
  144. type: String,
  145. default: afterSaleType.NORMAL
  146. }
  147. },
  148. data() {
  149. return {
  150. lists: [],
  151. downOption: {
  152. auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
  153. },
  154. upOption: {
  155. auto: false, // 不自动加载
  156. noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
  157. empty: {
  158. icon: '/static/images/order_null.png',
  159. tip: '暂无售后~', // 提示
  160. fixed: true
  161. }
  162. },
  163. showDialog: false
  164. };
  165. },
  166. created() {
  167. uni.$on("refreshsale", () => {
  168. this.downCallback()
  169. })
  170. },
  171. destroyed() {
  172. uni.$off("refreshsale")
  173. },
  174. methods: {
  175. applyRefund(items, item) {
  176. const {
  177. after_sale: {
  178. able_apply
  179. },
  180. order_id
  181. } = items
  182. const {
  183. item_id
  184. } = item
  185. if (able_apply != 1) {
  186. return
  187. }
  188. this.$Router.push({
  189. path: '/bundle/pages/apply_refund/apply_refund',
  190. query: {
  191. order_id,
  192. item_id
  193. }
  194. })
  195. },
  196. cancelApplyFun() {
  197. cancelApply({
  198. id: this.id
  199. }).then(res => {
  200. if (res.code == 1) {
  201. this.$toast({
  202. title: res.msg
  203. });
  204. uni.$emit("refreshsale")
  205. }
  206. });
  207. },
  208. async upCallback(page) {
  209. const {
  210. type,
  211. } = this;
  212. const params = {
  213. page_size: page.size,
  214. page_no: page.num,
  215. type
  216. }
  217. const {
  218. data,
  219. code
  220. } = await getAfterSaleList(params)
  221. if (code == 1) {
  222. const curPageData = data.list;
  223. const curPageLen = curPageData.length;
  224. const hasNext = !!data.more;
  225. if (page.num == 1) this.lists = [];
  226. this.lists = this.lists.concat(curPageData);
  227. this.mescroll.endSuccess(curPageLen, hasNext);
  228. }
  229. },
  230. onShowDialog(id) {
  231. this.id = id;
  232. this.showDialog = true
  233. }
  234. }
  235. };
  236. </script>
  237. <style lang="scss">
  238. .sale-list {
  239. overflow: hidden;
  240. .sale-item {
  241. .sale-header {
  242. padding: 0 20rpx;
  243. }
  244. .sale-content {
  245. padding: 20rpx 24rpx;
  246. .sale-status {
  247. padding: 20rpx 40rpx;
  248. background-color: #F6F6F6;
  249. border-radius: 6rpx;
  250. }
  251. .goods-desc {
  252. min-width: 500rpx;
  253. }
  254. }
  255. .sale-footer {
  256. padding: 0 24rpx 22rpx;
  257. .btn {
  258. padding: 9rpx 34rpx;
  259. border: 1px solid $-color-primary;
  260. &.gray-btn {
  261. border-color: $-color-border;
  262. color: $-color-muted;
  263. }
  264. &.black-btn {
  265. border-color: $-color-border;
  266. color: $-color-normal;
  267. }
  268. }
  269. }
  270. }
  271. }
  272. </style>