增加商品列表

This commit is contained in:
aaron 2025-01-12 00:02:47 +08:00
parent ac7764617f
commit 364c4c069b
4 changed files with 301 additions and 0 deletions

9
src/api/merchant.js Normal file
View File

@ -0,0 +1,9 @@
import request from '@/utils/request'
// 获取商家商品列表
export function getMerchantProducts(merchantId) {
return request({
url: `/api/merchant/product/merchant/${merchantId}`,
method: 'get'
})
}

View File

@ -54,6 +54,9 @@
<a-menu-item key="merchant-categories">
<router-link to="/merchant/categories">商家分类</router-link>
</a-menu-item>
<a-menu-item key="merchant-products">
<router-link to="/merchant/products">商品列表</router-link>
</a-menu-item>
</a-sub-menu>
</a-menu>
</a-layout-sider>

View File

@ -60,6 +60,11 @@ const routes = [
path: 'categories',
component: () => import('@/views/merchant/CategoryList.vue'),
meta: { title: '商家分类' }
},
{
path: 'products',
component: () => import('@/views/merchant/ProductList.vue'),
meta: { title: '商品列表' }
}
]
}

View File

@ -0,0 +1,284 @@
<template>
<page-container>
<div class="product-list">
<div class="table-header">
<h1>商品列表</h1>
</div>
<!-- 过滤区域 -->
<div class="table-filter">
<a-form layout="inline">
<a-form-item label="所属商家">
<a-select
v-model:value="filterForm.merchant_id"
placeholder="请选择商家"
style="width: 200px"
allowClear
@change="handleMerchantChange"
>
<a-select-option
v-for="item in merchantOptions"
:key="item.id"
:value="item.id"
>
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</div>
<a-table
:columns="columns"
:data-source="tableData"
:pagination="pagination"
:loading="loading"
@change="handleTableChange"
row-key="id"
>
<template #bodyCell="{ column, text, record }">
<!-- 图片列 -->
<template v-if="column.key === 'image_url'">
<div class="product-image">
<img :src="text" :alt="record.name" />
</div>
</template>
<!-- 价格列 -->
<template v-if="['product_price', 'sale_price', 'settlement_amount'].includes(column.key)">
¥{{ text }}
</template>
<!-- 标签列 -->
<template v-if="column.key === 'tags'">
<a-tag
v-for="tag in text?.split(',')"
:key="tag"
color="blue"
>
{{ tag }}
</a-tag>
</template>
<!-- 最高抵扣金额 -->
<template v-if="column.key === 'max_deduct_points'">
{{ text }} 消费金
</template>
<!-- 操作列 -->
<template v-if="column.key === 'action'">
<a-button type="link" @click="handleEdit(record)">修改</a-button>
</template>
</template>
</a-table>
</div>
</page-container>
</template>
<script>
import { defineComponent, ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import PageContainer from '@/components/PageContainer.vue'
import { getMerchantProducts } from '@/api/merchant'
import request from '@/utils/request'
export default defineComponent({
components: {
PageContainer
},
setup() {
const loading = ref(false)
const tableData = ref([])
const merchantOptions = ref([])
const filterForm = ref({
merchant_id: undefined
})
const pagination = ref({
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showTotal: (total) => `${total} 条记录`
})
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
width: 80,
align: 'center'
},
{
title: '商品图片',
dataIndex: 'image_url',
key: 'image_url',
width: 100,
align: 'center'
},
{
title: '商品名称',
dataIndex: 'name',
key: 'name',
width: 200
},
{
title: '商品原价',
dataIndex: 'product_price',
key: 'product_price',
width: 100,
align: 'right'
},
{
title: '销售价格',
dataIndex: 'sale_price',
key: 'sale_price',
width: 100,
align: 'right'
},
{
title: '结算价格',
dataIndex: 'settlement_amount',
key: 'settlement_amount',
width: 100,
align: 'right'
},
{
title: '标签',
dataIndex: 'tags',
key: 'tags',
width: 120
},
{
title: '最高抵扣消费金',
dataIndex: 'max_deduct_points',
key: 'max_deduct_points',
width: 120,
align: 'right'
},
{
title: '操作',
key: 'action',
width: 100,
align: 'center',
fixed: 'right'
}
]
//
const fetchMerchantOptions = async () => {
try {
const res = await request.get('/api/merchant', {
params: {
limit: 1000
}
})
if (res.code === 200) {
merchantOptions.value = res.data.items
}
} catch (error) {
console.error('获取商家列表失败:', error)
message.error('获取商家列表失败')
}
}
//
const fetchData = async () => {
if (!filterForm.value.merchant_id) {
tableData.value = []
return
}
try {
loading.value = true
const res = await getMerchantProducts(filterForm.value.merchant_id)
if (res.code === 200) {
tableData.value = res.data || []
pagination.value.total = res.data.length
}
} catch (error) {
console.error('获取商品列表失败:', error)
message.error('获取商品列表失败')
} finally {
loading.value = false
}
}
//
const handleMerchantChange = () => {
pagination.value.current = 1
fetchData()
}
//
const handleTableChange = (pag) => {
pagination.value.current = pag.current
pagination.value.pageSize = pag.pageSize
fetchData()
}
//
const handleEdit = (record) => {
// TODO:
console.log('修改商品:', record)
}
onMounted(() => {
fetchMerchantOptions()
})
return {
loading,
columns,
tableData,
pagination,
merchantOptions,
filterForm,
handleTableChange,
handleMerchantChange,
handleEdit
}
}
})
</script>
<style scoped>
.product-list {
padding: 24px;
}
.table-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.table-header h1 {
margin: 0;
}
.table-filter {
margin-bottom: 16px;
padding: 16px 24px;
background: #fff;
border-radius: 2px;
}
.product-image {
width: 50px;
height: 50px;
border-radius: 4px;
overflow: hidden;
display: inline-block;
}
.product-image img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
:deep(.ant-tag) {
margin: 2px;
}
</style>