OrdersView.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <template>
  2. <div class="orders-page">
  3. <div class="filter-bar">
  4. <el-radio-group v-model="activeFilter" @change="doFilter">
  5. <el-radio-button value="all">全部</el-radio-button>
  6. <el-radio-button value="unpaid">未支付</el-radio-button>
  7. <el-radio-button value="cancelled">已取消</el-radio-button>
  8. <el-radio-button value="completed">已完成</el-radio-button>
  9. </el-radio-group>
  10. </div>
  11. <div v-loading="orderStore.loading" class="order-list">
  12. <div v-for="order in orderStore.orders" :key="order.id" class="order-card">
  13. <div class="order-top">
  14. <span class="order-title">{{ order.postTitle }}</span>
  15. <el-tag :type="statusType(order.status)" size="small">{{ order.status }}</el-tag>
  16. </div>
  17. <div class="order-meta">
  18. <span>{{ order.expertName }}</span>
  19. <span class="order-amount">¥{{ order.amount }}</span>
  20. </div>
  21. <div class="order-bottom">
  22. <span class="order-time">{{ order.createTime }}</span>
  23. <el-button v-if="order.status === '未支付'" size="small" type="primary">去支付</el-button>
  24. </div>
  25. </div>
  26. <EmptyState v-if="!orderStore.loading && orderStore.orders.length === 0" description="暂无订单" />
  27. </div>
  28. </div>
  29. </template>
  30. <script setup lang="ts">
  31. import { ref, onMounted } from 'vue'
  32. import { useOrderStore } from '../store'
  33. import EmptyState from '../components/EmptyState.vue'
  34. const orderStore = useOrderStore()
  35. const activeFilter = ref('all')
  36. function doFilter() {
  37. orderStore.fetchOrders(activeFilter.value)
  38. }
  39. function statusType(status: string): string {
  40. if (status === 'completed') return 'success'
  41. if (status === 'unpaid') return 'warning'
  42. if (status === 'cancelled') return 'info'
  43. return ''
  44. }
  45. onMounted(() => {
  46. orderStore.fetchOrders()
  47. })
  48. </script>
  49. <style scoped>
  50. .orders-page {
  51. padding: 0;
  52. }
  53. .filter-bar {
  54. padding: 12px 16px;
  55. overflow-x: auto;
  56. }
  57. .order-list {
  58. padding: 0 16px;
  59. }
  60. .order-card {
  61. background: var(--color-card, #fff);
  62. border-radius: 8px;
  63. padding: 12px 16px;
  64. margin-bottom: 10px;
  65. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  66. }
  67. .order-top {
  68. display: flex;
  69. align-items: center;
  70. justify-content: space-between;
  71. margin-bottom: 6px;
  72. }
  73. .order-title {
  74. font-size: 14px;
  75. font-weight: 600;
  76. flex: 1;
  77. overflow: hidden;
  78. text-overflow: ellipsis;
  79. white-space: nowrap;
  80. margin-right: 8px;
  81. }
  82. .order-meta {
  83. display: flex;
  84. justify-content: space-between;
  85. font-size: 13px;
  86. color: var(--color-text-secondary, #999);
  87. margin-bottom: 6px;
  88. }
  89. .order-amount {
  90. color: var(--color-primary, #db2777);
  91. font-weight: 600;
  92. }
  93. .order-bottom {
  94. display: flex;
  95. justify-content: space-between;
  96. align-items: center;
  97. }
  98. .order-time {
  99. font-size: 12px;
  100. color: var(--color-text-secondary, #999);
  101. }
  102. </style>