feat: 前端页面和组件全面完善

- 优化通用组件:导航栏、页脚、图片上传、搜索
- 完善业务组件:商品卡片、秒杀卡片
- 更新用户端页面:首页、商品、秒杀、订单、购物车、个人中心
- 新增用户收藏页面
- 完善管理后台:仪表盘、商品/订单/用户/秒杀管理
- 新增管理后台:收藏管理、评价管理、系统监控页面
This commit is contained in:
2026-03-10 23:21:53 +08:00
parent abba469a20
commit c52d9c52e3
25 changed files with 3409 additions and 1467 deletions

View File

@@ -111,9 +111,7 @@
<el-form-item label="商品分类">
<el-select v-model="advancedForm.category" placeholder="选择分类">
<el-option label="全部分类" value="" />
<el-option label="电子产品" value="electronics" />
<el-option label="服装鞋包" value="fashion" />
<el-option label="食品饮料" value="food" />
<el-option v-for="item in categories" :key="item" :label="item" :value="item" />
<el-option label="图书音像" value="books" />
</el-select>
</el-form-item>
@@ -157,8 +155,9 @@
<script setup lang="ts">
import { ref, reactive, watch, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { debounce } from 'lodash-es'
import { productApi } from '@/api/modules/product'
import { flashsaleApi } from '@/api/modules/flashsale'
const router = useRouter()
@@ -181,6 +180,7 @@ const hotSearches = ref([
// 搜索建议
const suggestions = ref<any[]>([])
const categories = ref<string[]>([])
// 高级搜索表单
const advancedForm = reactive({
@@ -259,28 +259,38 @@ const fetchSuggestions = debounce(async () => {
suggestions.value = []
return
}
// 模拟搜索建议
suggestions.value = [
{
id: 1,
type: 'product',
name: `${searchQuery.value} Pro Max`,
price: 8999
},
{
id: 2,
type: 'product',
name: `${searchQuery.value} 标准版`,
price: 5999
},
{
id: 3,
type: 'flashsale',
name: `${searchQuery.value} 限时秒杀`,
price: 4999
}
]
try {
const [productRes, flashSaleRes] = await Promise.all([
productApi.getList({ keyword: searchQuery.value, page: 0, size: 5 }),
flashsaleApi.getList({ page: 0, size: 6 }),
])
const productSuggestions = productRes.success
? productRes.data.content.map((item) => ({
id: item.id,
type: 'product',
name: item.name,
price: item.price,
}))
: []
const flashSaleSuggestions = flashSaleRes.success
? flashSaleRes.data.content
.filter((item) => item.productName.includes(searchQuery.value))
.slice(0, 3)
.map((item) => ({
id: item.id,
type: 'flashsale',
name: item.productName,
price: item.flashPrice,
}))
: []
suggestions.value = [...productSuggestions, ...flashSaleSuggestions].slice(0, 8)
} catch (error) {
suggestions.value = []
}
}, 300)
// 快速搜索
@@ -337,8 +347,10 @@ watch(searchQuery, () => {
fetchSuggestions()
})
onMounted(() => {
onMounted(async () => {
loadSearchHistory()
const res = await productApi.getCategories()
categories.value = res.success ? res.data : []
})
</script>