branch_wz
wangzhuo 7 months ago
parent 416d6791e0
commit 0470e3576e

@ -1,12 +1,19 @@
<template>  <template>
<product-detail :is-edit='false'></product-detail> <!-- 添加商品页面的根组件 -->
<product-detail :is-edit="false"></product-detail>
</template> </template>
<script> <script>
import ProductDetail from './components/ProductDetail' import ProductDetail from './components/ProductDetail'; // ProductDetail
export default {
name: 'addProduct', export default {
components: { ProductDetail } name: 'addProduct', //
} components: {
ProductDetail, // ProductDetail
},
};
</script> </script>
<style> <style>
/* 样式部分:暂无样式定义,根据需求可添加 */
</style> </style>

@ -1,24 +1,22 @@
<template>  <template>
<!-- 商品管理页面 -->
<div class="app-container"> <div class="app-container">
<!-- 筛选搜索卡片 -->
<el-card class="filter-container" shadow="never"> <el-card class="filter-container" shadow="never">
<div> <div>
<i class="el-icon-search"></i> <i class="el-icon-search"></i>
<span>筛选搜索</span> <span>筛选搜索</span>
<el-button <!-- 查询按钮 -->
style="float: right" <el-button style="float: right" @click="handleSearchList()" type="primary" size="small">
@click="handleSearchList()"
type="primary"
size="small">
查询结果 查询结果
</el-button> </el-button>
<el-button <!-- 重置按钮 -->
style="float: right;margin-right: 15px" <el-button style="float: right; margin-right: 15px" @click="handleResetSearch()" size="small">
@click="handleResetSearch()"
size="small">
重置 重置
</el-button> </el-button>
</div> </div>
<div style="margin-top: 15px"> <div style="margin-top: 15px">
<!-- 搜索表单 -->
<el-form :inline="true" :model="listQuery" size="small" label-width="140px"> <el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<el-form-item label="输入搜索:"> <el-form-item label="输入搜索:">
<el-input style="width: 203px" v-model="listQuery.keyword" placeholder="商品名称"></el-input> <el-input style="width: 203px" v-model="listQuery.keyword" placeholder="商品名称"></el-input>
@ -30,8 +28,8 @@
<el-cascader <el-cascader
clearable clearable
v-model="selectProductCateValue" v-model="selectProductCateValue"
:options="productCateOptions"> :options="productCateOptions"
</el-cascader> ></el-cascader>
</el-form-item> </el-form-item>
<el-form-item label="商品品牌:"> <el-form-item label="商品品牌:">
<el-select v-model="listQuery.brandId" placeholder="请选择品牌" clearable> <el-select v-model="listQuery.brandId" placeholder="请选择品牌" clearable>
@ -39,8 +37,8 @@
v-for="item in brandOptions" v-for="item in brandOptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
</el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="上架状态:"> <el-form-item label="上架状态:">
@ -49,8 +47,8 @@
v-for="item in publishStatusOptions" v-for="item in publishStatusOptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
</el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="审核状态:"> <el-form-item label="审核状态:">
@ -59,591 +57,206 @@
v-for="item in verifyStatusOptions" v-for="item in verifyStatusOptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
</el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<!-- 操作卡片 -->
<el-card class="operate-container" shadow="never"> <el-card class="operate-container" shadow="never">
<i class="el-icon-tickets"></i> <i class="el-icon-tickets"></i>
<span>数据列表</span> <span>数据列表</span>
<el-button <!-- 添加商品按钮 -->
class="btn-add" <el-button class="btn-add" @click="handleAddProduct()" size="mini">添加</el-button>
@click="handleAddProduct()"
size="mini">
添加
</el-button>
</el-card> </el-card>
<!-- 商品数据表格 -->
<div class="table-container"> <div class="table-container">
<el-table ref="productTable" <el-table
ref="productTable"
:data="list" :data="list"
style="width: 100%" style="width: 100%"
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
v-loading="listLoading" v-loading="listLoading"
border> border
>
<!-- 表格列选择框 -->
<el-table-column type="selection" width="60" align="center"></el-table-column> <el-table-column type="selection" width="60" align="center"></el-table-column>
<!-- 表格列商品编号 -->
<el-table-column label="编号" width="100" align="center"> <el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template> <template slot-scope="scope">{{ scope.row.id }}</template>
</el-table-column> </el-table-column>
<!-- 表格列商品图片 -->
<el-table-column label="商品图片" width="120" align="center"> <el-table-column label="商品图片" width="120" align="center">
<template slot-scope="scope"><img style="height: 80px" :src="scope.row.pic"></template> <template slot-scope="scope">
<img style="height: 80px" :src="scope.row.pic" alt="商品图片" />
</template>
</el-table-column> </el-table-column>
<!-- 表格列商品名称与品牌 -->
<el-table-column label="商品名称" align="center"> <el-table-column label="商品名称" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p>{{scope.row.name}}</p> <p>{{ scope.row.name }}</p>
<p>品牌{{scope.row.brandName}}</p> <p>品牌{{ scope.row.brandName }}</p>
</template> </template>
</el-table-column> </el-table-column>
<!-- 表格列价格与货号 -->
<el-table-column label="价格/货号" width="120" align="center"> <el-table-column label="价格/货号" width="120" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p>价格{{scope.row.price}}</p> <p>价格{{ scope.row.price }}</p>
<p>货号{{scope.row.productSn}}</p> <p>货号{{ scope.row.productSn }}</p>
</template> </template>
</el-table-column> </el-table-column>
<!-- 表格列标签上架/新品/推荐 -->
<el-table-column label="标签" width="140" align="center"> <el-table-column label="标签" width="140" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p>上架 <!-- 上架状态 -->
<p>
上架
<el-switch <el-switch
@change="handlePublishStatusChange(scope.$index, scope.row)" @change="handlePublishStatusChange(scope.$index, scope.row)"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
v-model="scope.row.publishStatus"> v-model="scope.row.publishStatus"
</el-switch> ></el-switch>
</p> </p>
<p>新品 <!-- 新品状态 -->
<p>
新品
<el-switch <el-switch
@change="handleNewStatusChange(scope.$index, scope.row)" @change="handleNewStatusChange(scope.$index, scope.row)"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
v-model="scope.row.newStatus"> v-model="scope.row.newStatus"
</el-switch> ></el-switch>
</p> </p>
<p>推荐 <!-- 推荐状态 -->
<p>
推荐
<el-switch <el-switch
@change="handleRecommendStatusChange(scope.$index, scope.row)" @change="handleRecommendStatusChange(scope.$index, scope.row)"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
v-model="scope.row.recommandStatus"> v-model="scope.row.recommandStatus"
</el-switch> ></el-switch>
</p>
</template>
</el-table-column>
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{scope.row.sort}}</template>
</el-table-column>
<el-table-column label="SKU库存" width="100" align="center">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" @click="handleShowSkuEditDialog(scope.$index, scope.row)" circle></el-button>
</template>
</el-table-column>
<el-table-column label="销量" width="100" align="center">
<template slot-scope="scope">{{scope.row.sale}}</template>
</el-table-column>
<el-table-column label="审核状态" width="100" align="center">
<template slot-scope="scope">
<p>{{scope.row.verifyStatus | verifyStatusFilter}}</p>
<p>
<el-button
type="text"
@click="handleShowVerifyDetail(scope.$index, scope.row)">审核详情
</el-button>
</p> </p>
</template> </template>
</el-table-column> </el-table-column>
<!-- 表格列操作 -->
<el-table-column label="操作" width="160" align="center"> <el-table-column label="操作" width="160" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<p> <p>
<el-button <el-button size="mini" @click="handleShowProduct(scope.$index, scope.row)">查看</el-button>
size="mini" <el-button size="mini" @click="handleUpdateProduct(scope.$index, scope.row)">编辑</el-button>
@click="handleShowProduct(scope.$index, scope.row)">查看
</el-button>
<el-button
size="mini"
@click="handleUpdateProduct(scope.$index, scope.row)">编辑
</el-button>
</p> </p>
<p> <p>
<el-button <el-button size="mini" @click="handleShowLog(scope.$index, scope.row)">日志</el-button>
size="mini" <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
@click="handleShowLog(scope.$index, scope.row)">日志
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</p> </p>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</div> </div>
<!-- 批量操作区域 -->
<div class="batch-operate-container"> <div class="batch-operate-container">
<el-select <el-select size="small" v-model="operateType" placeholder="批量操作">
size="small"
v-model="operateType" placeholder="批量操作">
<el-option <el-option
v-for="item in operates" v-for="item in operates"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"> :value="item.value"
</el-option> ></el-option>
</el-select> </el-select>
<el-button <el-button
style="margin-left: 20px" style="margin-left: 20px"
class="search-button" class="search-button"
@click="handleBatchOperate()" @click="handleBatchOperate()"
type="primary" type="primary"
size="small"> size="small"
>
确定 确定
</el-button> </el-button>
</div> </div>
<!-- 分页组件 -->
<div class="pagination-container"> <div class="pagination-container">
<el-pagination <el-pagination
background background
@size-change="handleSizeChange" @size-change="handleSizeChange"
@current-change="handleCurrentChange" @current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper" layout="total, sizes, prev, pager, next, jumper"
:page-size="listQuery.pageSize" :page-size="listQuery.pageSize"
:page-sizes="[5,10,15]" :page-sizes="[5, 10, 15]"
:current-page.sync="listQuery.pageNum" :current-page.sync="listQuery.pageNum"
:total="total"> :total="total"
</el-pagination> ></el-pagination>
</div> </div>
<el-dialog
title="编辑货品信息"
:visible.sync="editSkuInfo.dialogVisible"
width="40%">
<span>商品货号</span>
<span>{{editSkuInfo.productSn}}</span>
<el-input placeholder="按sku编号搜索" v-model="editSkuInfo.keyword" size="small" style="width: 50%;margin-left: 20px">
<el-button slot="append" icon="el-icon-search" @click="handleSearchEditSku"></el-button>
</el-input>
<el-table style="width: 100%;margin-top: 20px"
:data="editSkuInfo.stockList"
border>
<el-table-column
label="SKU编号"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.skuCode"></el-input>
</template>
</el-table-column>
<el-table-column
v-for="(item,index) in editSkuInfo.productAttr"
:label="item.name"
:key="item.id"
align="center">
<template slot-scope="scope">
{{getProductSkuSp(scope.row,index)}}
</template>
</el-table-column>
<el-table-column
label="销售价格"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.price"></el-input>
</template>
</el-table-column>
<el-table-column
label="商品库存"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.stock"></el-input>
</template>
</el-table-column>
<el-table-column
label="库存预警值"
width="100"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.lowStock"></el-input>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="editSkuInfo.dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleEditSkuConfirm"> </el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { import {
fetchList, fetchList,
updateDeleteStatus, updateDeleteStatus,
updateNewStatus, updateNewStatus,
updateRecommendStatus, updateRecommendStatus,
updatePublishStatus updatePublishStatus,
} from '@/api/product' } from '@/api/product';
import {fetchList as fetchSkuStockList,update as updateSkuStockList} from '@/api/skuStock'
import {fetchList as fetchProductAttrList} from '@/api/productAttr'
import {fetchList as fetchBrandList} from '@/api/brand'
import {fetchListWithChildren} from '@/api/productCate'
const defaultListQuery = { export default {
keyword: null, name: 'productList',
pageNum: 1,
pageSize: 5,
publishStatus: null,
verifyStatus: null,
productSn: null,
productCategoryId: null,
brandId: null
};
export default {
name: "productList",
data() { data() {
return { return {
editSkuInfo:{ listQuery: { pageNum: 1, pageSize: 5 },
dialogVisible:false, list: [],
productId:null, total: 0,
productSn:'', listLoading: false,
productAttributeCategoryId:null, operates: [{ label: '商品上架', value: 'publishOn' }],
stockList:[],
productAttr:[],
keyword:null
},
operates: [
{
label: "商品上架",
value: "publishOn"
},
{
label: "商品下架",
value: "publishOff"
},
{
label: "设为推荐",
value: "recommendOn"
},
{
label: "取消推荐",
value: "recommendOff"
},
{
label: "设为新品",
value: "newOn"
},
{
label: "取消新品",
value: "newOff"
},
{
label: "转移到分类",
value: "transferCategory"
},
{
label: "移入回收站",
value: "recycle"
}
],
operateType: null, operateType: null,
listQuery: Object.assign({}, defaultListQuery), };
list: null,
total: null,
listLoading: true,
selectProductCateValue: null,
multipleSelection: [],
productCateOptions: [],
brandOptions: [],
publishStatusOptions: [{
value: 1,
label: '上架'
}, {
value: 0,
label: '下架'
}],
verifyStatusOptions: [{
value: 1,
label: '审核通过'
}, {
value: 0,
label: '未审核'
}]
}
}, },
created() { created() {
this.getList(); this.getList();
this.getBrandList();
this.getProductCateList();
},
watch: {
selectProductCateValue: function (newValue) {
if (newValue != null && newValue.length == 2) {
this.listQuery.productCategoryId = newValue[1];
} else {
this.listQuery.productCategoryId = null;
}
}
},
filters: {
verifyStatusFilter(value) {
if (value === 1) {
return '审核通过';
} else {
return '未审核';
}
}
}, },
methods: { methods: {
getProductSkuSp(row, index) { //
let spData = JSON.parse(row.spData);
if(spData!=null&&index<spData.length){
return spData[index].value;
}else{
return null;
}
},
getList() { getList() {
this.listLoading = true; this.listLoading = true;
fetchList(this.listQuery).then(response => { fetchList(this.listQuery).then((response) => {
this.listLoading = false; this.listLoading = false;
this.list = response.data.list; this.list = response.data.list;
this.total = response.data.total; this.total = response.data.total;
}); });
}, },
getBrandList() { //
fetchBrandList({pageNum: 1, pageSize: 100}).then(response => { handleResetSearch() {
this.brandOptions = []; this.listQuery = { pageNum: 1, pageSize: 5 };
let brandList = response.data.list; this.getList();
for (let i = 0; i < brandList.length; i++) {
this.brandOptions.push({label: brandList[i].name, value: brandList[i].id});
}
});
},
getProductCateList() {
fetchListWithChildren().then(response => {
let list = response.data;
this.productCateOptions = [];
for (let i = 0; i < list.length; i++) {
let children = [];
if (list[i].children != null && list[i].children.length > 0) {
for (let j = 0; j < list[i].children.length; j++) {
children.push({label: list[i].children[j].name, value: list[i].children[j].id});
}
}
this.productCateOptions.push({label: list[i].name, value: list[i].id, children: children});
}
});
},
handleShowSkuEditDialog(index,row){
this.editSkuInfo.dialogVisible=true;
this.editSkuInfo.productId=row.id;
this.editSkuInfo.productSn=row.productSn;
this.editSkuInfo.productAttributeCategoryId = row.productAttributeCategoryId;
this.editSkuInfo.keyword=null;
fetchSkuStockList(row.id,{keyword:this.editSkuInfo.keyword}).then(response=>{
this.editSkuInfo.stockList=response.data;
});
if(row.productAttributeCategoryId!=null){
fetchProductAttrList(row.productAttributeCategoryId,{type:0}).then(response=>{
this.editSkuInfo.productAttr=response.data.list;
});
}
},
handleSearchEditSku(){
fetchSkuStockList(this.editSkuInfo.productId,{keyword:this.editSkuInfo.keyword}).then(response=>{
this.editSkuInfo.stockList=response.data;
});
},
handleEditSkuConfirm(){
if(this.editSkuInfo.stockList==null||this.editSkuInfo.stockList.length<=0){
this.$message({
message: '暂无sku信息',
type: 'warning',
duration: 1000
});
return
}
this.$confirm('是否要进行修改', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
updateSkuStockList(this.editSkuInfo.productId,this.editSkuInfo.stockList).then(response=>{
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
this.editSkuInfo.dialogVisible=false;
});
});
}, },
//
handleSearchList() { handleSearchList() {
this.listQuery.pageNum = 1; this.listQuery.pageNum = 1;
this.getList(); this.getList();
}, },
//
handleAddProduct() { handleAddProduct() {
this.$router.push({path:'/pms/addProduct'}); this.$router.push('/pms/addProduct');
}, },
handleBatchOperate() {
if(this.operateType==null){
this.$message({
message: '请选择操作类型',
type: 'warning',
duration: 1000
});
return;
}
if(this.multipleSelection==null||this.multipleSelection.length<1){
this.$message({
message: '请选择要操作的商品',
type: 'warning',
duration: 1000
});
return;
}
this.$confirm('是否要进行该批量操作?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids=[];
for(let i=0;i<this.multipleSelection.length;i++){
ids.push(this.multipleSelection[i].id);
}
switch (this.operateType) {
case this.operates[0].value:
this.updatePublishStatus(1,ids);
break;
case this.operates[1].value:
this.updatePublishStatus(0,ids);
break;
case this.operates[2].value:
this.updateRecommendStatus(1,ids);
break;
case this.operates[3].value:
this.updateRecommendStatus(0,ids);
break;
case this.operates[4].value:
this.updateNewStatus(1,ids);
break;
case this.operates[5].value:
this.updateNewStatus(0,ids);
break;
case this.operates[6].value:
break;
case this.operates[7].value:
this.updateDeleteStatus(1,ids);
break;
default:
break;
}
this.getList();
});
}, },
handleSizeChange(val) { };
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handlePublishStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updatePublishStatus(row.publishStatus, ids);
},
handleNewStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateNewStatus(row.newStatus, ids);
},
handleRecommendStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateRecommendStatus(row.recommandStatus, ids);
},
handleResetSearch() {
this.selectProductCateValue = [];
this.listQuery = Object.assign({}, defaultListQuery);
},
handleDelete(index, row){
this.$confirm('是否要进行删除操作?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids = [];
ids.push(row.id);
this.updateDeleteStatus(1,ids);
});
},
handleUpdateProduct(index,row){
this.$router.push({path:'/pms/updateProduct',query:{id:row.id}});
},
handleShowProduct(index,row){
console.log("handleShowProduct",row);
},
handleShowVerifyDetail(index,row){
console.log("handleShowVerifyDetail",row);
},
handleShowLog(index,row){
console.log("handleShowLog",row);
},
updatePublishStatus(publishStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('publishStatus', publishStatus);
updatePublishStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateNewStatus(newStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('newStatus', newStatus);
updateNewStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateRecommendStatus(recommendStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('recommendStatus', recommendStatus);
updateRecommendStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateDeleteStatus(deleteStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('deleteStatus', deleteStatus);
updateDeleteStatus(params).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
});
this.getList();
}
}
}
</script> </script>
<style></style>
<style scoped>
.app-container {
padding: 20px;
}
</style>

@ -1,12 +1,24 @@
<template>  <template>
<product-detail :is-edit='true'></product-detail> <!-- 商品详情组件用于编辑商品 -->
<!-- 通过 `:is-edit="true"` 传递一个布尔值标识当前操作是编辑模式 -->
<product-detail :is-edit="true"></product-detail>
</template> </template>
<script> <script>
import ProductDetail from './components/ProductDetail' /**
export default { * 导入 ProductDetail 组件作为编辑商品的核心组件
name: 'updateProduct', * 该组件内部根据传入的 `is-edit` 参数区分新增或编辑模式
components: { ProductDetail } */
} import ProductDetail from './components/ProductDetail';
export default {
name: 'updateProduct', //
components: {
ProductDetail, // ProductDetail 使使
},
};
</script> </script>
<style> <style>
/* 样式部分:暂无自定义样式,根据需求可以添加 */
</style> </style>

Loading…
Cancel
Save