需要在统一个列表下,实现商品和规格得管理和联动
<!--/**
* @author: liuk
* @date: 2023/7/7
* @describe: 商品列表
*/-->
<template>
<div class="container">
<h1>商品列表</h1>
<div class="creatbtn" style="margin-bottom: 15px">
<div class="creatbtn1">
<el-button class="btn" @click="editShop('')">+ 新增商品</el-button>
</div>
</div>
<el-row justify="space-between" style="margin-bottom: 15px">
<el-col :span="12">
<el-radio-group v-model="fromData.putShelf" @change="getList" size="large">
<el-radio-button label="">全部</el-radio-button>
<el-radio-button label="1">已发布</el-radio-button>
<el-radio-button label="0">未发布</el-radio-button>
</el-radio-group>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input v-model="fromData.productName" style="width: 400px;marginRight:30px " placeholder="请输入内容"
@keyup.enter="getList">
<template #append>
<el-icon @click="getList">
<Search/>
</el-icon>
</template>
</el-input>
<el-button type="danger" @click="resetBtn">重置</el-button>
</el-form-item>
</el-col>
</el-row>
<el-table v-if="shopTableList.length" v-loading="loading" :data="shopTableList" class="cemetery-table" border
width="1200px"
@expand-change="expandChange" :row-key="(row) => row.id" :expand-row-keys="expands">
<el-table-column min-width="50" type="expand">
<template #default="props">
<div>
<el-table :data="props.row.bMallGoodsSpecifications" border>
<el-table-column width="80" type="index" label="序号" align="center"/>
<el-table-column label="图片" align="center" prop="image">
<template #default="scope">
<image-upload class="img-specif-box" v-model="scope.row.image" :limit="1"
:disabled="!scope.row.specificationEdit"
></image-upload>
</template>
</el-table-column>
<el-table-column label="规格描述" align="center" prop="specificationDescription">
<template #default="scope">
<el-input v-model="scope.row.specificationDescription"
:disabled="!scope.row.specificationEdit"
style="width: 60px"/>
</template>
</el-table-column>
<el-table-column label="规格" align="center" prop="specifications">
<template #default="scope">
<el-input v-model="scope.row.specifications"
:disabled="!scope.row.specificationEdit"
style="width: 60px"/>
</template>
</el-table-column>
<el-table-column label="价格" align="center" prop="price">
<template #header>
<span class="red">*</span>
<el-icon>
<Edit/>
</el-icon>
价格
</template>
<template #default="scope">
<el-input v-model="scope.row.price"
:disabled="!scope.row.specificationEdit"
style="width: 60px"/>
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="unitName">
<template #default="scope">
<el-select v-model="scope.row.unitId" :disabled="!scope.row.specificationEdit">
<el-option v-for="(item,i) in units" :key="i" :label="item.label" :value="item.value"/>
</el-select>
</template>
</el-table-column>
<el-table-column label="划线价" align="center" prop="crossedPrice">
<template #header>
<el-icon>
<Edit/>
</el-icon>
划线价
</template>
<template #default="scope">
<el-input v-model="scope.row.crossedPrice"
:disabled="!scope.row.specificationEdit"
style="width: 60px"/>
</template>
</el-table-column>
<el-table-column label="库存" align="center" prop="stock">
<template #default="scope">
<el-input v-model="scope.row.stock"
:disabled="!scope.row.specificationEdit"
style="width: 60px"/>
</template>
</el-table-column>
<el-table-column label="可否调价" align="center" prop="adjustThePrice">
<template #default="scope">
<el-switch v-model="scope.row.adjustThePrice" :active-value="1" :inactive-value="0"
:disabled="!scope.row.specificationEdit"
style="--el-switch-on-color: rgb(19, 206, 102); --el-switch-off-color: rgb(255, 73, 73)"/>
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width"
min-width="210">
<template #default="scope">
<el-button v-show="!scope.row.specificationEdit" type="success"
@click="editSpecifications(scope.row,props)">编辑
</el-button>
<el-button v-show="scope.row.specificationEdit" type="success"
@click="updateSpecification(scope.row)">
保存
</el-button>
<el-button v-show="scope.row.specificationEdit"
@click="scope.row.specificationEdit = false">取消
</el-button>
<el-button v-show="!scope.row.specificationEdit" type="danger"
@click="delSpecifica(scope.row,props)">删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column min-width="80" type="index" align="center" label="序号"/>
<el-table-column min-width="100" label="商品名称" align="center" prop="productName" sortable>
<template #header>
商品名称
<el-icon>
<QuestionFilled/>
</el-icon>
</template>
</el-table-column>
<el-table-column min-width="150" label="图片" align="center" prop="productImage">
<template #default="scope">
<el-image style="width: 40px; height: 40px"
:src="scope.row.productImage"
:zoom-rate="1.2"
:preview-src-list="[scope.row.productImage]"
:initial-index="4"
preview-teleported
fit="cover"/>
</template>
</el-table-column>
<el-table-column min-width="100" label="库存策略" align="center" prop="inventoryStrategy">
<template #default="scope">
{{ formatInventoryStrategy(scope.row.inventoryStrategy) }}
</template>
</el-table-column>
<el-table-column min-width="100" label="顺序" prop="sort" align="center" sortable>
<template #header>
顺序
<el-icon>
<QuestionFilled/>
</el-icon>
</template>
</el-table-column>
<el-table-column min-width="100" label="是否已发布" align="center" prop="putShelf">
<template #default="scope">
<el-switch
v-model="scope.row.putShelf" :active-value="1" :inactive-value="0"
style="--el-switch-on-color: rgb(19, 206, 102); --el-switch-off-color: rgb(255, 73, 73)"/>
</template>
</el-table-column>
<el-table-column min-width="100" label="是否静态" align="center" prop="staticState">
<template #default="scope">
<el-switch v-model="scope.row.staticState" :active-value="1" :inactive-value="0"
:before-change="staticStateChange.bind(null, scope.row)"
:disabled="scope.row.staticState == 1"
style="--el-switch-on-color: rgb(19, 206, 102); --el-switch-off-color: rgb(255, 73, 73)"/>
</template>
</el-table-column>
<el-table-column min-width="100" label="SKU数量" align="center" prop="productNum">
<template #default="scope">
<span :class="{red:scope.row.productNum == 0}">{{ scope.row.productNum }}</span>
</template>
</el-table-column>
<el-table-column min-width="100" label="价格" align="center" prop="productPrice"/>
<el-table-column label="操作" fixed="right" min-width="250" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button @click="addSpecif(scope.row,scope)">增加规格</el-button>
<el-button type="primary" @click="editShop(scope.row.id)">编辑</el-button>
<el-button type="danger" @click="delShop(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-empty description="暂无商品" v-else/>
<pagination
v-show="pages.total>0"
:total="pages.total"
v-model:page="pages.pageNum"
v-model:limit="pages.pageSize"
@pagination="getList"
/>
</div>
</template>
<script setup>
import {listGoods, delGoods, previewGoods} from "@/api/retailmall/goods";
import {updateSpecifications, addSpecifications, delSpecifications} from "@/api/retailmall/specifications";
import {listUnits,} from "@/api/mall/units";
import {useRoute, useRouter} from "vue-router";
import {onMounted} from "vue";
// Emit
const emit = defineEmits(['editShopOpen'])
// route
const route = useRoute()
// store
import useMallStore from '@/store/modules/mall'
const mallStore = useMallStore()
const router = useRouter()
const {proxy} = getCurrentInstance();
const model = reactive({
fromData: {},
pages: {
pageNum: 1,
pageSize: 10,
total: 0
},
expands: [],//表格展开行
shopTableList: [],//商品列表
loading: true,
units: [],//单位列表
});
const {fromData, expands, pages, shopTableList, loading, units} = toRefs(model);
// 编辑商品
const editShop = (id) => {
emit('editShopOpen')
mallStore.setCurGoodId(id)
}
// 增加规格
const addSpecif = (row, props) => {
let params = {
commodityId: row.id,
crossedPrice: 0,
stock: 0,
price: 0,
specifications: 0,
specificationDescription: ""
}
addSpecifications(params).then(res => {
if (+res.code === 200) {
previewGoods(props.row.id).then((res) => {
if (+res.code === 200) {
model.expands = [] // 展开行
model.expands.push(row.id)
props.row.bMallGoodsSpecifications = res.data.bMallGoodsSpecifications
proxy.$message.success("新增成功")
}
})
}
})
}
// 修改规格
const updateSpecification = (row) => {
updateSpecifications(row).then((res) => {
if (+res.code === 200) {
row.specificationEdit = false
proxy.$message.success("编辑成功")
}
})
}
// 表格展开变化 -- 只能展开一行
const expandChange = (row, expandedRows) => {
if (expandedRows.length) {
model.expands = []
if (row) {
model.expands.push(row.id)
}
} else {
model.expands = []
}
}
// 删除商品
const delShop = (row) => {
proxy.$modal.confirm(`确定要删除${row.productName}`).then(function () {
return delGoods(row.id)
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
}
// 是否静态开关变化
const staticStateChange = (item) => {
return new Promise((resolve, reject) => {
proxy.$modal.confirm('一旦商品开启静态,该商品不可进行任何操作(删除编辑发布隐藏),是否确定要 修改 商品 ?').then(() => {
resolve(true)
})
})
}
// 编辑规格
const editSpecifications = (row) => {
row.specificationEdit = true
}
// 删除规格
const delSpecifica = (row, props) => {
proxy.$modal.confirm(`确定要删除${row.productName}`).then(function () {
return delSpecifications(row.id)
}).then(() => {
previewGoods(props.row.id).then((res) => {
props.row.bMallGoodsSpecifications = res.data.bMallGoodsSpecifications
})
proxy.$modal.msgSuccess("删除成功");
})
}
// 获取商品列表
function getList() {
let params = {
...model.fromData,
...model.pages,
shopIds: [route.query.id],
total: undefined
}
model.loading = true;
listGoods(params).then(response => {
model.expands = [] // 不展开行
model.shopTableList = response.rows || {bMallGoodsSpecifications: []};
model.pages.total = response.total;
model.loading = false;
})
}
// 表单重置
function reset() {
form.value = {};
}
// 获取全部单位
const getlistUnits = () => {
let params = {
pageNum: 1,
pageSize: 999
}
listUnits(params).then(res => {
model.units = res.rows.map((item) => {
return {
label: item.name,
value: item.id
}
})
})
}
// 重置
const resetBtn = () => {
fromData.value = {}
getList()
}
onMounted(() => {
getList();
getlistUnits()
})
const formatInventoryStrategy = (val) => {
let str = ''
switch (val) {
case 0:
str = '无需库存'
break
case 1:
str = '下单后减少'
break
case 2:
str = '支付后减少'
break
case 3:
str = '使用后减少'
break
}
return str
}
</script>