my-order.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. <template>
  2. <view class="my-order-page">
  3. <!-- 标签页 -->
  4. <view class="tabs-wrapper">
  5. <u-tabs :list="tabList" :current="currentTab" @change="handleTabChange" active-color="#38C148"
  6. bar-width="60"></u-tabs>
  7. </view>
  8. <!-- 订单列表 -->
  9. <page-scroll :page-size="10" @updateList="handleUpdateList" ref="pageRef" slotEmpty
  10. :url="currentUrl" :params="params" :immediate="false">
  11. <view v-if="orderList.length > 0" class="order-list-container">
  12. <template v-if="currentTab === 5">
  13. <refund-order-item v-for="(order, index) in orderList" :key="index" :order="order"></refund-order-item>
  14. </template>
  15. <template v-else>
  16. <buy-order-item v-for="(order, index) in orderList" :key="index" :order="order"
  17. @action="handleAction"></buy-order-item>
  18. </template>
  19. </view>
  20. </page-scroll>
  21. <!-- 更多操作菜单 -->
  22. <u-action-sheet :list="actionSheetList" v-model="showActionSheet"
  23. @click="handleActionSheetClick"></u-action-sheet>
  24. <!-- 极速退款弹窗 -->
  25. <fast-refund-dialog ref="refundDialog" @refresh="loadOrders(true, params)"></fast-refund-dialog>
  26. <!-- 催发货弹窗 -->
  27. <urge-delivery-dialog ref="urgeDialog" @success="loadOrders(true, params)"></urge-delivery-dialog>
  28. <!-- 取消订单弹窗 -->
  29. <cancel-order-popup ref="cancelDialog" @success="loadOrders(true, params)"></cancel-order-popup>
  30. </view>
  31. </template>
  32. <script>
  33. import BuyOrderItem from '../components/buy-order-item.vue';
  34. import RefundOrderItem from '../components/refund-order-item.vue';
  35. import pageScroll from '@/components/pageScroll/index.vue';
  36. import FastRefundDialog from '../components/fast-refund-dialog.vue';
  37. import UrgeDeliveryDialog from '../components/urge-delivery-dialog.vue';
  38. import CancelOrderPopup from '../components/cancel-order-popup.vue';
  39. export default {
  40. components: {
  41. BuyOrderItem,
  42. RefundOrderItem,
  43. pageScroll,
  44. FastRefundDialog,
  45. UrgeDeliveryDialog,
  46. CancelOrderPopup
  47. },
  48. data() {
  49. return {
  50. currentUrl: '/token/shop/order/getShopOrderList',
  51. // value用于前端标识,params用于后端查询
  52. tabList: [
  53. { name: '全部', value: '0', params: {} },
  54. { name: '待付款', value: '1', params: { status: '1' } },
  55. { name: '待发货', value: '2', params: { status: '2' } },
  56. { name: '待收货', value: '3', params: { status: '3' } },
  57. { name: '已完成', value: '4', params: { status: '4' } },
  58. { name: '退款/售后', value: '5', params: { status: '5' } },
  59. ],
  60. currentTab: 0,
  61. orderList: [],
  62. params: {},
  63. showActionSheet: false,
  64. actionSheetList: [],
  65. currentOrder: null,
  66. modifyingOrderId: null
  67. };
  68. },
  69. onLoad(options) {
  70. if (options.status) {
  71. const index = this.tabList.findIndex(item => item.value == options.status);
  72. if (index !== -1) {
  73. this.currentTab = index;
  74. this.params = this.tabList[index].params;
  75. if (options.status === '5') {
  76. this.currentUrl = '/token/shop/order/getMyRefundOrderList';
  77. } else {
  78. this.currentUrl = '/token/shop/order/getShopOrderList';
  79. }
  80. }
  81. }
  82. // 监听地址选择
  83. uni.$on('selectAddr', this.onAddressSelected);
  84. },
  85. onShow() {
  86. this.loadOrders(true, this.params);
  87. },
  88. onUnload() {
  89. uni.$off('selectAddr', this.onAddressSelected);
  90. },
  91. methods: {
  92. onAddressSelected(addr) {
  93. if (this.modifyingOrderId && addr && addr.id) {
  94. this.$u.api.modifyOrderAddressAjax({
  95. orderId: this.modifyingOrderId,
  96. addressId: addr.id
  97. }).then(res => {
  98. uni.hideLoading();
  99. if (res.code == 200) {
  100. uni.showToast({ title: '修改成功', icon: 'success' });
  101. setTimeout(() => {
  102. this.loadOrders(true, this.params);
  103. }, 1000)
  104. }
  105. }).finally(() => {
  106. this.modifyingOrderId = null;
  107. });
  108. }
  109. },
  110. loadOrders(refresh = false, params = {}) {
  111. this.$nextTick(() => {
  112. this.$refs.pageRef?.loadData(refresh, params);
  113. });
  114. },
  115. handleTabChange(index) {
  116. this.currentTab = index;
  117. this.params = this.tabList[index].params;
  118. if (this.tabList[index].value === '5') {
  119. this.currentUrl = '/token/shop/order/getMyRefundOrderList';
  120. } else {
  121. this.currentUrl = '/token/shop/order/getShopOrderList';
  122. }
  123. this.loadOrders(true, this.params);
  124. },
  125. handleUpdateList(list) {
  126. this.orderList = list;
  127. },
  128. handleAction({ type, order, data }) {
  129. console.log('Action:', type, order);
  130. this.currentOrder = order;
  131. if (type === 'more') {
  132. // data contains the list of actions to show in sheet
  133. // Map internal keys to display text
  134. const actionMap = {
  135. 'applyAfterSales': { text: '申请售后', type: 'refund' },
  136. 'logistics': { text: '查看物流', type: 'logistics' },
  137. 'invoice': { text: '申请开票', type: 'invoice' }
  138. };
  139. this.actionSheetList = data.map(key => actionMap[key]).filter(Boolean);
  140. this.showActionSheet = true;
  141. return;
  142. }
  143. this.processAction(type, order);
  144. },
  145. handleActionSheetClick(index) {
  146. const action = this.actionSheetList[index];
  147. if (action && action.type) {
  148. this.processAction(action.type, this.currentOrder);
  149. }
  150. },
  151. addCartAjax(orderId) {
  152. uni.showLoading({ title: '处理中' });
  153. this.$u.api.orderAddToCartAjax({
  154. orderId: orderId
  155. }).then(res => {
  156. uni.hideLoading();
  157. if (res.code == 200) {
  158. uni.showToast({
  159. title: '已加入购物车',
  160. icon: 'success',
  161. duration: 3000
  162. });
  163. this.$updateCartBadge();
  164. }
  165. });
  166. },
  167. processAction(type, order) {
  168. if (type === 'rebuy') {
  169. uni.showLoading({ title: '加载中...' });
  170. this.$u.api.orderAddToCartAjax({
  171. orderId: order.orderId
  172. }).then(res => {
  173. uni.hideLoading();
  174. if (res.code === 200) {
  175. // 加入购物车成功,跳转到确认订单页面
  176. // 将 cartIdList 作为参数传递
  177. const cartIdList = res.data || [];
  178. uni.navigateTo({
  179. url: '/pages-car/pages/confirm-order?cartIdList=' + JSON.stringify(cartIdList)
  180. });
  181. } else {
  182. this.$u.toast(res.msg || '加入购物车失败');
  183. }
  184. }).catch(() => {
  185. uni.hideLoading();
  186. });
  187. } else if (type === 'addToCart') {
  188. this.addCartAjax(order.orderId);
  189. } else if (type === 'remind') {
  190. this.$refs.urgeDialog.open(order);
  191. } else if (type === 'overtime') {
  192. // 超时发货补偿
  193. uni.showModal({
  194. title: '提示',
  195. content: '确认申请超时发货补偿?',
  196. success: (res) => {
  197. if (res.confirm) {
  198. this.$u.api.sendTimeoutCompensationAjax(order.orderId).then(res => {
  199. if (res.code == 200) {
  200. uni.showToast({
  201. title: '申请成功',
  202. icon: 'success'
  203. });
  204. this.loadOrders(true, this.params);
  205. }
  206. });
  207. }
  208. }
  209. });
  210. } else if (type === 'priceMatch') {
  211. // 降价补差
  212. uni.showModal({
  213. title: '提示',
  214. content: '确认申请降价补差?',
  215. success: (res) => {
  216. if (res.confirm) {
  217. this.$u.api.priceReductionCompensationAjax(order.orderId).then(res => {
  218. if (res.code == 200) {
  219. uni.showToast({
  220. title: '申请成功',
  221. icon: 'success'
  222. });
  223. this.loadOrders(true, this.params);
  224. }
  225. });
  226. }
  227. }
  228. });
  229. } else if (type === 'refund') {
  230. if (order.status == '2') {
  231. this.$refs.refundDialog.open(order);
  232. } else {
  233. // 跳转到申请售后页面
  234. uni.navigateTo({
  235. url: `/pages-car/pages/apply-refund?orderId=${order.orderId}`
  236. });
  237. }
  238. } else if (type === 'confirm') {
  239. uni.showModal({
  240. title: '提示',
  241. content: '确认已收到商品?',
  242. success: (res) => {
  243. if (res.confirm) {
  244. uni.showToast({ title: '确认收货成功', icon: 'none' });
  245. this.loadOrders(true, this.params);
  246. }
  247. }
  248. });
  249. } else if (type === 'logistics') {
  250. uni.navigateTo({
  251. url: `/pages-car/pages/logistics-detail?orderId=${order.orderId}`
  252. });
  253. } else if (type === 'address') {
  254. this.modifyingOrderId = order.orderId;
  255. // 兼容列表和详情可能的字段差异
  256. const addressId = order.addressId || order.receiverAddressId || '';
  257. uni.navigateTo({
  258. url: `/pages-mine/pages/address/list?id=${addressId}&isSelect=1`
  259. });
  260. } else if (type === 'pay') {
  261. // 跳转到收银台
  262. uni.navigateTo({
  263. url: `/pages-car/pages/cashier-desk?id=${order.orderId}`
  264. });
  265. } else if (type === 'cancel') {
  266. this.$refs.cancelDialog.open(order.orderId);
  267. } else if (type === 'extend') {
  268. uni.showModal({
  269. title: '提示',
  270. content: '每笔订单只能延长一次收货时间,确认延长收货?',
  271. success: (res) => {
  272. if (res.confirm) {
  273. this.$u.api.orderAddDeadlineAjax(order.orderId).then(res => {
  274. if (res.code == 200) {
  275. uni.showToast({
  276. title: '延长收货成功',
  277. icon: 'success'
  278. });
  279. this.loadOrders(true, this.params);
  280. }
  281. });
  282. }
  283. }
  284. });
  285. } else if (type === 'complaint') {
  286. uni.setStorageSync('tempComplaintOrder', order);
  287. uni.navigateTo({
  288. url: `/pages-car/pages/complaint?orderId=${order.orderId}`
  289. });
  290. } else {
  291. uni.showToast({ title: '功能开发中', icon: 'none' });
  292. }
  293. }
  294. }
  295. }
  296. </script>
  297. <style lang="scss" scoped>
  298. .my-order-page {
  299. min-height: 100vh;
  300. background-color: #F5F5F5;
  301. .tabs-wrapper {
  302. position: sticky;
  303. top: 0;
  304. z-index: 99;
  305. background: #FFFFFF;
  306. border-bottom: 1rpx solid #eee;
  307. }
  308. .order-list-container {
  309. padding: 20rpx;
  310. }
  311. }
  312. </style>