my-order.vue 14 KB

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