index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <div class="page-container">
  3. <PageTitle title="历史购买" />
  4. <!-- 搜索栏 -->
  5. <div class="search-bar">
  6. <el-input v-model="queryParams.keyword" placeholder="搜索" style="width: 180px" clearable>
  7. <template #prefix><el-icon><Search /></el-icon></template>
  8. </el-input>
  9. <div class="price-range">
  10. <el-input v-model="queryParams.minPrice" placeholder="¥ 最高价" style="width: 100px" />
  11. <span class="range-separator">—</span>
  12. <el-input v-model="queryParams.maxPrice" placeholder="¥ 最低价" style="width: 100px" />
  13. </div>
  14. <el-date-picker v-model="queryParams.dateRange" type="daterange" range-separator="—" start-placeholder="请选择购买时间" end-placeholder="" style="width: 240px" />
  15. </div>
  16. <!-- 筛选栏 -->
  17. <div class="filter-bar">
  18. <span class="filter-label">商品类别</span>
  19. <el-select v-model="queryParams.category1" placeholder="请选择" style="width: 100px" clearable @change="handleCategory1Change">
  20. <el-option label="电脑" value="电脑" />
  21. <el-option label="办公设备" value="办公设备" />
  22. <el-option label="家用电器" value="家用电器" />
  23. </el-select>
  24. <el-select v-model="queryParams.category2" placeholder="请选择" style="width: 100px" clearable @change="handleCategory2Change">
  25. <el-option v-for="item in category2Options" :key="item" :label="item" :value="item" />
  26. </el-select>
  27. <el-select v-model="queryParams.category3" placeholder="请选择" style="width: 100px" clearable>
  28. <el-option v-for="item in category3Options" :key="item" :label="item" :value="item" />
  29. </el-select>
  30. <span class="filter-label">商品品牌</span>
  31. <el-select v-model="queryParams.brand" placeholder="请选择" style="width: 100px" clearable>
  32. <el-option label="清华同方" value="清华同方" />
  33. <el-option label="联想" value="联想" />
  34. <el-option label="戴尔" value="戴尔" />
  35. </el-select>
  36. </div>
  37. <!-- 排序栏 -->
  38. <div class="sort-bar">
  39. <el-select v-model="queryParams.sortType" placeholder="默认排序" style="width: 110px"><el-option label="默认排序" value="default" /><el-option label="购买时间" value="time" /></el-select>
  40. <el-select v-model="queryParams.priceSort" placeholder="价格排序" style="width: 110px"><el-option label="价格排序" value="" /><el-option label="价格从低到高" value="asc" /><el-option label="价格从高到低" value="desc" /></el-select>
  41. </div>
  42. <!-- 订单列表 -->
  43. <div class="order-list">
  44. <div v-for="(order, orderIndex) in orderList" :key="orderIndex" class="order-card">
  45. <div class="order-header">
  46. <div class="order-info">
  47. <span class="order-date">{{ order.date }}</span>
  48. <span class="order-no">订单号:{{ order.orderNo }}</span>
  49. </div>
  50. <el-button type="danger" link @click="handleReorder(order)">一键复购</el-button>
  51. </div>
  52. <div class="product-list">
  53. <div v-for="(item, itemIndex) in order.products" :key="itemIndex" class="product-item">
  54. <div class="product-image">
  55. <el-image :src="item.image" fit="contain">
  56. <template #error><div class="image-placeholder"><el-icon :size="30" color="#ccc"><Picture /></el-icon></div></template>
  57. </el-image>
  58. </div>
  59. <div class="product-info">
  60. <div class="product-name">{{ item.name }}</div>
  61. <div class="product-spec">{{ item.spec1 }}</div>
  62. <div class="product-spec">{{ item.spec2 }}</div>
  63. </div>
  64. <div class="product-price">
  65. <span class="price">¥{{ item.price }}</span>
  66. <span class="quantity">x{{ item.quantity }}</span>
  67. </div>
  68. <div class="product-total" v-if="itemIndex === 0">
  69. <span class="total-label">支付款</span>
  70. <span class="total-price">¥{{ order.totalAmount }}</span>
  71. </div>
  72. <div class="product-action"><el-button type="danger" link @click="handleBuyAgain(item)">再次购买</el-button></div>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. <el-empty v-if="orderList.length === 0" description="暂无购买记录" />
  78. <TablePagination v-if="orderList.length > 0" v-model:page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :total="total" @change="handleQuery" />
  79. </div>
  80. </template>
  81. <script setup lang="ts">
  82. import { ref, reactive, computed } from 'vue'
  83. import { Search, Picture } from '@element-plus/icons-vue'
  84. import { ElMessage } from 'element-plus'
  85. import { PageTitle, TablePagination } from '@/components'
  86. const queryParams = reactive({ pageNum: 1, pageSize: 10, keyword: '', minPrice: '', maxPrice: '', dateRange: null, category1: '', category2: '', category3: '', brand: '', sortType: 'default', priceSort: '' })
  87. const total = ref(100)
  88. // 三级分类数据
  89. const categoryData: Record<string, Record<string, string[]>> = {
  90. '电脑': {
  91. '台式机': ['商用台式机', '家用台式机', '一体机'],
  92. '笔记本': ['商务本', '游戏本', '轻薄本'],
  93. '平板电脑': ['安卓平板', 'iPad', 'Windows平板']
  94. },
  95. '办公设备': {
  96. '打印机': ['激光打印机', '喷墨打印机', '针式打印机'],
  97. '复印机': ['黑白复印机', '彩色复印机'],
  98. '投影仪': ['商务投影', '家用投影']
  99. },
  100. '家用电器': {
  101. '空调': ['挂机', '柜机', '中央空调'],
  102. '冰箱': ['双门冰箱', '多门冰箱', '对开门冰箱'],
  103. '洗衣机': ['滚筒洗衣机', '波轮洗衣机']
  104. }
  105. }
  106. const category2Options = computed(() => {
  107. if (!queryParams.category1) return []
  108. return Object.keys(categoryData[queryParams.category1] || {})
  109. })
  110. const category3Options = computed(() => {
  111. if (!queryParams.category1 || !queryParams.category2) return []
  112. return categoryData[queryParams.category1]?.[queryParams.category2] || []
  113. })
  114. const handleCategory1Change = () => {
  115. queryParams.category2 = ''
  116. queryParams.category3 = ''
  117. }
  118. const handleCategory2Change = () => {
  119. queryParams.category3 = ''
  120. }
  121. const orderList = ref([
  122. { date: '2025/12/05', orderNo: '489283929283298392', totalAmount: '181', products: [
  123. { id: 1, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' },
  124. { id: 2, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }
  125. ]},
  126. { date: '2025/12/05', orderNo: '489283929283298393', totalAmount: '181', products: [
  127. { id: 3, name: '清华同方超越E500台式机电脑(i3-6100/4G/1T/19.5寸)', spec1: '规格02', spec2: '规格01', price: '181', quantity: 1, image: '' }
  128. ]}
  129. ])
  130. const handleQuery = () => {}
  131. const handleReorder = (_order: any) => { ElMessage.success('已将订单商品加入购物车') }
  132. const handleBuyAgain = (_item: any) => { ElMessage.success('已加入购物车') }
  133. </script>
  134. <style scoped lang="scss">
  135. .search-bar { display: flex; align-items: center; gap: 15px; margin-bottom: 15px; .price-range { display: flex; align-items: center; gap: 5px; .range-separator { color: #999; } } }
  136. .filter-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 15px; .filter-label { font-size: 14px; color: #666; } }
  137. .sort-bar { display: flex; gap: 10px; margin-bottom: 20px; }
  138. .order-list { .order-card { border: 1px solid #eee; border-radius: 4px; margin-bottom: 15px; overflow: hidden; .order-header { display: flex; justify-content: space-between; align-items: center; padding: 12px 15px; background: #f9f9f9; border-bottom: 1px solid #eee; .order-info { display: flex; align-items: center; gap: 20px; .order-date { font-size: 14px; color: #333; font-weight: 500; } .order-no { font-size: 13px; color: #666; } } } .product-list { .product-item { display: flex; align-items: center; padding: 15px; border-bottom: 1px solid #f5f5f5; &:last-child { border-bottom: none; } .product-image { width: 80px; height: 80px; background: #f5f5f5; border-radius: 4px; overflow: hidden; flex-shrink: 0; .el-image { width: 100%; height: 100%; } .image-placeholder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } } .product-info { flex: 1; padding: 0 20px; .product-name { font-size: 14px; color: #333; margin-bottom: 8px; line-height: 1.4; } .product-spec { font-size: 12px; color: #999; margin-bottom: 3px; } } .product-price { width: 100px; text-align: center; .price { display: block; font-size: 16px; font-weight: bold; color: #e60012; } .quantity { display: block; font-size: 12px; color: #999; margin-top: 5px; } } .product-total { width: 120px; text-align: center; .total-label { display: block; font-size: 12px; color: #999; } .total-price { display: block; font-size: 16px; font-weight: bold; color: #e60012; margin-top: 5px; } } .product-action { width: 80px; text-align: right; } } } } }
  139. </style>