feat(product): 添加商品下架和多条件查询功能

- 实现了商品下架功能,下架后SKU库存变为0且链接失效
- 添加了支持多条件查询的商品列表功能
- 增加了包含商品名称、链接码、状态、发售地区等查询条件
- 在商品管理页面添加了查询表单界面
- 实现了下架按钮的禁用逻辑和状态显示
- 添加了移动端响应式查询表单适配
- 集成了API接口和错误处理机制
This commit is contained in:
2025-12-25 16:26:11 +08:00
parent a27327c7fa
commit 01bda65010
2 changed files with 210 additions and 19 deletions

View File

@@ -65,3 +65,30 @@ export function uploadProductImage(file) {
// 注意:不设置 Content-Type让浏览器自动设置包含 boundary // 注意:不设置 Content-Type让浏览器自动设置包含 boundary
}) })
} }
/**
* 下架商品
* 下架后商品所有SKU库存改为0链接失效无法再被访问
*/
export function offShelfProductById(id) {
return request({
url: `/product/${id}/off-shelf`,
method: 'put'
})
}
/**
* 查询商品列表(支持多条件查询)
* @param {Object} query - 查询条件
* @param {string} query.name - 商品名称(模糊查询)
* @param {string} query.linkCode - 商品链接码(精确查询)
* @param {string} query.status - 商品状态ACTIVE-上架INACTIVE-下架)
* @param {string} query.salesRegion - 发售地区货币代码MYR, PHP, THB, VND, SGD, CNY, USD等
*/
export function queryProducts(query) {
return request({
url: '/product/query',
method: 'post',
data: query
})
}

View File

@@ -17,6 +17,69 @@
</div> </div>
</template> </template>
<!-- 查询表单 -->
<el-card class="search-card" style="margin-bottom: 20px">
<el-form :model="queryForm" :inline="true" class="search-form">
<el-form-item label="商品名称">
<el-input
v-model="queryForm.name"
placeholder="请输入商品名称"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="链接码">
<el-input
v-model="queryForm.linkCode"
placeholder="请输入链接码"
clearable
style="width: 200px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="商品状态">
<el-select
v-model="queryForm.status"
placeholder="请选择状态"
clearable
style="width: 150px"
>
<el-option label="上架" value="ACTIVE" />
<el-option label="下架" value="INACTIVE" />
</el-select>
</el-form-item>
<el-form-item label="发售地区">
<el-select
v-model="queryForm.salesRegion"
placeholder="请选择地区"
clearable
style="width: 150px"
>
<el-option label="马来西亚" value="MYR" />
<el-option label="菲律宾" value="PHP" />
<el-option label="泰国" value="THB" />
<el-option label="越南" value="VND" />
<el-option label="新加坡" value="SGD" />
<el-option label="中国" value="CNY" />
<el-option label="美国" value="USD" />
<el-option label="欧洲" value="EUR" />
<el-option label="英国" value="GBP" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">
<el-icon><Search /></el-icon>
查询
</el-button>
<el-button @click="handleReset">
<el-icon><Refresh /></el-icon>
重置
</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 商品列表 --> <!-- 商品列表 -->
<el-table :data="productList" v-loading="loading" style="width: 100%"> <el-table :data="productList" v-loading="loading" style="width: 100%">
<!-- 商品封面图 --> <!-- 商品封面图 -->
@@ -115,8 +178,14 @@
<el-button type="success" link size="small" @click="copyProductUrl(row.id, row.productUrl)"> <el-button type="success" link size="small" @click="copyProductUrl(row.id, row.productUrl)">
复制 复制
</el-button> </el-button>
<el-button type="danger" link size="small" @click="deleteProduct(row.id)"> <el-button
删除 type="danger"
link
size="small"
@click="offShelfProduct(row.id)"
:disabled="row.status === 'INACTIVE'"
>
{{ row.status === 'INACTIVE' ? '已下架' : '下架' }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -130,14 +199,22 @@
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, User } from '@element-plus/icons-vue' import { Plus, User, Search, Refresh } from '@element-plus/icons-vue'
import { getProductList, getProductUrl } from '../api/product' import { getProductList, getProductUrl, offShelfProductById, queryProducts } from '../api/product'
import { formatAmount } from '../utils/helpers' import { formatAmount } from '../utils/helpers'
const router = useRouter() const router = useRouter()
const loading = ref(false) const loading = ref(false)
const productList = ref([]) const productList = ref([])
// 查询表单
const queryForm = ref({
name: '',
linkCode: '',
status: '',
salesRegion: ''
})
// 跳转到新增商品页面 // 跳转到新增商品页面
const goToCreate = () => { const goToCreate = () => {
router.push('/manage/product/create') router.push('/manage/product/create')
@@ -191,7 +268,7 @@ const getSalesRegions = (row) => {
return regions return regions
} }
// 加载商品列表 // 加载商品列表(无查询条件)
const loadProductList = async () => { const loadProductList = async () => {
loading.value = true loading.value = true
try { try {
@@ -212,6 +289,57 @@ const loadProductList = async () => {
} }
} }
// 查询商品列表
const handleQuery = async () => {
loading.value = true
try {
// 构建查询条件(只包含非空字段)
const query = {}
if (queryForm.value.name && queryForm.value.name.trim()) {
query.name = queryForm.value.name.trim()
}
if (queryForm.value.linkCode && queryForm.value.linkCode.trim()) {
query.linkCode = queryForm.value.linkCode.trim()
}
if (queryForm.value.status) {
query.status = queryForm.value.status
}
if (queryForm.value.salesRegion) {
query.salesRegion = queryForm.value.salesRegion
}
const response = await queryProducts(query)
if (response.code === '0000' && response.data) {
productList.value = response.data
if (productList.value.length === 0) {
ElMessage.info('未找到符合条件的商品')
} else {
ElMessage.success(`查询到 ${productList.value.length} 条商品`)
}
} else {
ElMessage.error(response.message || '查询商品列表失败')
productList.value = []
}
} catch (error) {
console.error('查询商品列表失败:', error)
ElMessage.error('查询商品列表失败')
productList.value = []
} finally {
loading.value = false
}
}
// 重置查询条件
const handleReset = () => {
queryForm.value = {
name: '',
linkCode: '',
status: '',
salesRegion: ''
}
loadProductList()
}
// 编辑商品 // 编辑商品
const editProduct = (id) => { const editProduct = (id) => {
// TODO: 实现编辑功能,跳转到编辑页面 // TODO: 实现编辑功能,跳转到编辑页面
@@ -259,24 +387,30 @@ const copyProductUrl = async (id, url) => {
} }
} }
// 删除商品 // 下架商品
const deleteProduct = async (id) => { const offShelfProduct = async (id) => {
try { try {
await ElMessageBox.confirm('确定要删除该商品吗?', '提示', { await ElMessageBox.confirm(
confirmButtonText: '确定', '确定要下架该商品吗下架后商品所有SKU库存将改为0链接将失效无法再被访问。',
cancelButtonText: '取消', '提示',
type: 'warning' {
}) confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
// TODO: 实现删除商品API const response = await offShelfProductById(id)
ElMessage.info('删除功能待实现') if (response.code === '0000') {
// await request.delete(`/api/product/${id}`) ElMessage.success('商品下架成功')
// ElMessage.success('商品删除成功') loadProductList()
// loadProductList() } else {
ElMessage.error(response.message || '商品下架失败')
}
} catch (error) { } catch (error) {
if (error !== 'cancel') { if (error !== 'cancel') {
console.error('删除商品失败:', error) console.error('下架商品失败:', error)
ElMessage.error('删除商品失败') ElMessage.error('下架商品失败')
} }
} }
} }
@@ -367,5 +501,35 @@ onMounted(() => {
color: #c0c4cc; color: #c0c4cc;
font-size: 12px; font-size: 12px;
} }
/* 查询表单 */
.search-card {
margin-bottom: 20px;
}
.search-form {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.search-form .el-form-item {
margin-bottom: 0;
}
@media (max-width: 768px) {
.search-form {
flex-direction: column;
}
.search-form .el-form-item {
width: 100%;
}
.search-form .el-form-item .el-input,
.search-form .el-form-item .el-select {
width: 100% !important;
}
}
</style> </style>