my-order.vue 12 KB

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