my-order.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <template>
  2. <view class="my-order-page">
  3. <!-- 标签页 -->
  4. <view class="tabs-wrapper">
  5. <u-tabs
  6. :list="tabList"
  7. :current="currentTab"
  8. @change="handleTabChange"
  9. :is-scroll="false"
  10. active-color="#333"
  11. inactive-color="#666"
  12. bar-width="40"
  13. bar-height="6"
  14. bar-style="{backgroundColor: '#ff5b5b'}"
  15. ></u-tabs>
  16. <!-- Note: u-tabs styling might need adjustment to match image (red underline) -->
  17. </view>
  18. <!-- 订单列表 -->
  19. <page-scroll
  20. :page-size="10"
  21. @updateList="handleUpdateList"
  22. ref="pageRef"
  23. slotEmpty
  24. url="/token/order/getMyBuyOrderList"
  25. :params="params"
  26. :immediate="false"
  27. >
  28. <view v-if="orderList.length > 0" class="order-list-container">
  29. <buy-order-item
  30. v-for="(order, index) in orderList"
  31. :key="index"
  32. :order="order"
  33. @action="handleAction"
  34. ></buy-order-item>
  35. </view>
  36. </page-scroll>
  37. <!-- 更多操作菜单 -->
  38. <u-action-sheet :list="actionSheetList" v-model="showActionSheet" @click="handleActionSheetClick"></u-action-sheet>
  39. </view>
  40. </template>
  41. <script>
  42. import BuyOrderItem from '../components/buy-order-item.vue';
  43. import pageScroll from '@/components/pageScroll/index.vue';
  44. export default {
  45. components: {
  46. BuyOrderItem,
  47. pageScroll
  48. },
  49. data() {
  50. return {
  51. tabList: [
  52. { name: '全部', status: '' },
  53. { name: '待付款', status: '2' },
  54. { name: '待发货', status: '3' },
  55. { name: '待收货', status: '8' },
  56. { name: '已完成', status: '12' },
  57. { name: '退款/售后', status: '10' }
  58. ],
  59. currentTab: 0,
  60. orderList: [],
  61. params: {},
  62. showActionSheet: false,
  63. actionSheetList: [],
  64. currentOrder: null
  65. };
  66. },
  67. onLoad(options) {
  68. if (options.status) {
  69. const index = this.tabList.findIndex(item => item.status === options.status);
  70. if (index !== -1) {
  71. this.currentTab = index;
  72. this.params.status = options.status;
  73. }
  74. }
  75. // Load mock data for now since API might not be ready
  76. // But pageScroll calls API. We can mock in updateList if API fails or returns empty.
  77. // For now let's rely on pageScroll but maybe we need to mock response in pageScroll or here.
  78. // Actually, let's trigger load.
  79. this.loadOrders(true, this.params);
  80. },
  81. methods: {
  82. loadOrders(refresh = false, params = {}) {
  83. this.$nextTick(() => {
  84. // If API is not real, pageScroll might fail.
  85. // We can mock data here if needed by directly setting list if API fails.
  86. // Let's try to use pageScroll mechanism.
  87. this.$refs.pageRef?.loadData(refresh, params);
  88. });
  89. },
  90. handleTabChange(index) {
  91. this.currentTab = index;
  92. this.params.status = this.tabList[index].status;
  93. this.loadOrders(true, this.params);
  94. },
  95. handleUpdateList(list) {
  96. // Mock data injection if list is empty (for development)
  97. if (!list || list.length === 0) {
  98. this.orderList = this.getMockOrders(this.params.status);
  99. } else {
  100. this.orderList = list;
  101. }
  102. },
  103. handleAction({ type, order, data }) {
  104. console.log('Action:', type, order);
  105. this.currentOrder = order;
  106. if (type === 'more') {
  107. // data contains the list of actions to show in sheet
  108. // Map internal keys to display text
  109. const actionMap = {
  110. 'applyAfterSales': { text: '申请售后', type: 'refund' },
  111. 'logistics': { text: '查看物流', type: 'logistics' },
  112. 'invoice': { text: '申请开票', type: 'invoice' }
  113. };
  114. this.actionSheetList = data.map(key => actionMap[key]).filter(Boolean);
  115. this.showActionSheet = true;
  116. return;
  117. }
  118. this.processAction(type, order);
  119. },
  120. handleActionSheetClick(index) {
  121. const action = this.actionSheetList[index];
  122. if (action && action.type) {
  123. this.processAction(action.type, this.currentOrder);
  124. }
  125. },
  126. processAction(type, order) {
  127. if (type === 'rebuy' || type === 'addToCart') {
  128. // Logic to add to cart
  129. uni.showToast({ title: '已加入购物车', icon: 'none' });
  130. } else if (type === 'delete') {
  131. uni.showModal({
  132. title: '提示',
  133. content: '确定要删除该订单吗?',
  134. success: (res) => {
  135. if (res.confirm) {
  136. // Remove from list
  137. this.orderList = this.orderList.filter(item => item.orderNo !== order.orderNo);
  138. uni.showToast({ title: '删除成功', icon: 'none' });
  139. }
  140. }
  141. });
  142. } else if (type === 'remind') {
  143. uni.showToast({ title: '已提醒商家发货', icon: 'none' });
  144. } else if (type === 'refund') {
  145. uni.showToast({ title: '进入极速退款/售后流程', icon: 'none' });
  146. } else if (type === 'confirm') {
  147. uni.showModal({
  148. title: '提示',
  149. content: '确认已收到商品?',
  150. success: (res) => {
  151. if (res.confirm) {
  152. uni.showToast({ title: '确认收货成功', icon: 'none' });
  153. // Update status locally or reload
  154. this.loadOrders(true, this.params);
  155. }
  156. }
  157. });
  158. } else if (type === 'logistics') {
  159. uni.showToast({ title: '查看物流信息', icon: 'none' });
  160. } else if (type === 'address') {
  161. uni.showToast({ title: '修改地址', icon: 'none' });
  162. } else if (type === 'pay') {
  163. uni.showToast({ title: '去支付', icon: 'none' });
  164. } else if (type === 'cancel') {
  165. uni.showModal({
  166. title: '提示',
  167. content: '确定要取消订单吗?',
  168. success: (res) => {
  169. if (res.confirm) {
  170. uni.showToast({ title: '订单已取消', icon: 'none' });
  171. this.loadOrders(true, this.params);
  172. }
  173. }
  174. });
  175. } else {
  176. uni.showToast({ title: '功能开发中', icon: 'none' });
  177. }
  178. },
  179. getMockOrders(status) {
  180. // Generate some mock data based on status
  181. const allOrders = [
  182. {
  183. orderNo: 'SN1893294923003',
  184. status: 2, // 待付款
  185. totalPrice: 17.2,
  186. realPayPrice: 17.2,
  187. goodsList: [
  188. {
  189. title: '马克思主义基本原理',
  190. cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
  191. price: 8.60,
  192. num: 2,
  193. quality: '中等'
  194. }
  195. ]
  196. },
  197. {
  198. orderNo: 'SN1893294923004',
  199. status: 3, // 待发货
  200. totalPrice: 17.2,
  201. realPayPrice: 17.2,
  202. goodsList: [
  203. { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }, { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }, { cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg' }
  204. ]
  205. },
  206. {
  207. orderNo: 'SN1893294923005',
  208. status: -1, // 已取消
  209. totalPrice: 17.2,
  210. realPayPrice: 17.2,
  211. goodsList: [
  212. {
  213. title: '马克思主义基本原理',
  214. cover: 'https://k.sinaimg.cn/n/sinakd20116/234/w1000h1634/20251003/b66b-587c9ff400fcf01be52c6693594b6a6d.jpg/w700d1q75cms.jpg',
  215. price: 8.60,
  216. num: 2,
  217. quality: '中等'
  218. }
  219. ]
  220. }
  221. ];
  222. if (!status) return allOrders;
  223. return allOrders.filter(o => o.status == status);
  224. }
  225. }
  226. }
  227. </script>
  228. <style lang="scss" scoped>
  229. .my-order-page {
  230. min-height: 100vh;
  231. background-color: #F5F5F5;
  232. .tabs-wrapper {
  233. position: sticky;
  234. top: 0;
  235. z-index: 99;
  236. background: #FFFFFF;
  237. border-bottom: 1rpx solid #eee;
  238. }
  239. .order-list-container {
  240. padding: 20rpx;
  241. }
  242. }
  243. </style>