文章目录
- 需求背景
- 解决效果
- index.vue
- 视频效果
需求背景
需要在统一个列表下,实现商品和规格得管理和联动
解决效果
index.vue
<!--/*** @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" borderwidth="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-teleportedfit="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-switchv-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/><paginationv-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.bMallGoodsSpecificationsproxy.$message.success("新增成功")}})}})
}// 修改规格
const updateSpecification = (row) => {updateSpecifications(row).then((res) => {if (+res.code === 200) {row.specificationEdit = falseproxy.$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 = '无需库存'breakcase 1:str = '下单后减少'breakcase 2:str = '支付后减少'breakcase 3:str = '使用后减少'break}return str
}
</script>