myERP/src/views/commodity/combination.vue

340 lines
10 KiB
Vue
Raw Normal View History

2025-06-14 10:30:10 +08:00
<template>
<div class="pageBox">
<div class="searchBox">
<div class="row">
<span class="span">商品名称</span>
<div class="right"><el-input v-model="filter.title" class="wid100" clearable></el-input></div>
</div>
<div class="row">
<span class="span">组合编码</span>
<div class="right"><el-input v-model="filter.combination_goods_code" class="wid100" clearable></el-input></div>
</div>
<div class="row">
<span class="span">状态</span>
<div class="right">
<el-select v-model="filter.status" placeholder="请选择" clearable class="wid100">
<el-option label="启用" :value="1" />
<el-option label="不启用" :value="0" />
</el-select>
</div>
</div>
<div class="row">
<span class="span"></span>
<div class="right"><el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon>&nbsp;筛选</el-button></div>
</div>
</div>
<el-card shadow="never">
<div class="opaBox">
<el-button type="primary" @click="handleAdd"><el-icon><Plus /></el-icon>&nbsp;新增</el-button>
<!-- <el-button type="warning" @click="handleExport"><span class="iconfont icon-daochu"></span>&nbsp;导出</el-button> -->
</div>
<el-table :data="goodsList" style="width: 100%" border v-loading="loading">
<el-table-column prop="id" label="ID" width="80" align="center" />
<el-table-column prop="title" label="组合商品名称" align="center" />
<el-table-column prop="combination_goods_code" label="组合编码" align="center" />
<el-table-column prop="actual_inventory" label="实际库存" align="center" />
<el-table-column prop="lock_in_stock" label="锁定库存" align="center" />
<el-table-column prop="available_inventory" label="可售库存" align="center" />
<el-table-column label="状态" align="center">
<template #default="scope">
<span>{{ scope.row.status ? '启用' : '不启用' }}</span>
</template>
</el-table-column>
<el-table-column prop="admin_user.username" label="添加人" align="center" />
<el-table-column prop="created_at" label="添加时间" align="center" />
<el-table-column label="操作" align="center" width="150">
<template #default="scope">
<el-button type="primary" circle @click="handleEdit(scope.row)"><el-icon><Edit /></el-icon></el-button>
</template>
</el-table-column>
</el-table>
<div class="page-pagination">
<el-pagination
background
:current-page="page"
layout="prev, pager, next, sizes, total"
:total="total"
:page-sizes="[10, 50, 100]"
:page-size="pageSize"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
</el-card>
<el-dialog v-model="showDialog" width="900px" :title="opaType == 'add' ? '新增' : '编辑' ">
<el-form label-position="right" label-width="110px">
<el-form-item label="组合商品名称:">
<el-input v-model="itemInfo.title" clearable></el-input>
</el-form-item>
<el-form-item label="组合编码:">
<el-input v-model="itemInfo.combination_goods_code" clearable></el-input>
</el-form-item>
<el-form-item label="锁定库存:">
<el-input v-model="itemInfo.lock_in_stock" clearable></el-input>
</el-form-item>
<el-form-item label="状态:">
<el-radio-group v-model="itemInfo.status">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">不启用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注:">
<el-input v-model="itemInfo.note" type="textarea" :rows="4"></el-input>
</el-form-item>
<el-form-item label="排序:">
<el-input-number v-model="itemInfo.sort" :min="0" />
</el-form-item>
<el-form-item label=" ">
<b style="margin-top: 20px;">参与组合商品</b>
</el-form-item>
</el-form>
<div v-for="(item, i) in goodsSkus" :key="i" class="skuBox">
<el-form label-width="110px" :inline="true">
<el-form-item label="规格:">
<el-select v-model="item.sku_id" placeholder="请选择" clearable filterable style="width: 160px;">
<el-option v-for="it in skusList" :key="it.id" :label="it.goods && it.goods.title + '' + it.title + ''" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="数量:">
<el-input-number v-model="item.num" :min="0" />
</el-form-item>
<el-form-item label=" ">
<el-button type="danger" @click="handleSkuDelete(i)" size="small"><el-icon><Delete /></el-icon>&nbsp;删除</el-button>
</el-form-item>
</el-form>
</div>
<el-form label-position="right" label-width="110px">
<el-form-item label="">
<el-button type="success" @click="toAddSku()">新增</el-button>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="showDialog = false">取消</el-button>
<el-button type="primary" @click="commitOpa()" :loading="opa_loading">确定</el-button>
</span>
</template>
</el-dialog>
<!-- 预览图片 -->
<el-dialog v-model="picVisible" center width="800px">
<img :src="dialogImageUrl" style="max-width: 700px; margin: 0 auto;display: block;" />
</el-dialog>
</div>
</template>
<script>
import { onMounted, reactive, toRefs } from "vue"
import { get, post } from "@/api/request"
import { Search, Plus, Edit, ZoomIn, Delete } from '@element-plus/icons'
import { ElMessage, ElMessageBox } from 'element-plus'
import { parseErrors } from 'components/common'
export default {
components: {
Search, Plus, Edit, ZoomIn, Delete
},
setup() {
const data = reactive({
filter: {},
goodsList: [],
page: 1,
pageSize: 10,
total: 0,
loading: false,
opaType: '',
showDialog: false,
opa_loading: false,
itemInfo: {},
goodsSkus: [],
skusList: []
})
function handleSearch() {
data.page = 1
fetchData()
}
const fetchData = () => {
data.loading = true
let params = {
page: data.page,
pageSize: data.pageSize,
...data.filter
}
get(`/api/combination-goods-skus`, params).then((res) => {
data.goodsList = res.data
data.total = res.meta.total
data.loading = false
}).catch(() => {
data.loading = false
})
}
function handleCurrentChange(e) {
data.page = e
fetchData()
}
function handleSizeChange(e) {
data.page = 1
data.pageSize = e
fetchData()
}
function handleAdd() {
data.opaType = 'add'
data.fileList = []
data.goodsSkus = []
data.itemInfo = {
sort: 0,
status: 1
}
data.showDialog = true
}
function handleEdit(item) {
data.opaType = 'edit'
get(`/api/combination-goods-skus/${item.id}`).then((res) => {
data.itemInfo = res.data
data.goodsSkus = res.data.combination_goods_sku || []
data.showDialog = true
})
}
function commitOpa() {
data.opa_loading = true
let params = {
...data.itemInfo
}
params.goodsSkus = data.goodsSkus
if(data.opaType == 'add') {
post(`/api/combination-goods-skus`, params).then(() => {
data.page = 1
fetchData()
ElMessage({ type: 'success', message: '新增成功' })
data.showDialog = false
data.opa_loading = false
}).catch((err) => {
data.opa_loading = false
parseErrors(err.response.data.errors)
})
} else {
post(`/api/combination-goods-skus/${data.itemInfo.id}`, params, 'PUT').then(() => {
fetchData()
ElMessage({ type: 'success', message: '编辑成功' })
data.showDialog = false
data.opa_loading = false
}).catch((err) => {
data.opa_loading = false
parseErrors(err.response.data.errors)
})
}
}
function handleSkuDelete(index) {
data.goodsSkus.splice(index, 1)
}
function toAddSku() {
let sku = {
sku_id: '',
num: 1
}
data.goodsSkus.push(sku)
}
function getSkusList() {
get(`/api/all/goods-skus`).then((res) => {
data.skusList = res.data
})
}
onMounted(() => {
fetchData()
getSkusList()
})
return {
...toRefs(data),
handleSearch,
handleCurrentChange,
handleSizeChange,
fetchData,
handleAdd,
handleEdit,
commitOpa,
handleSkuDelete,
toAddSku,
getSkusList
}
}
}
</script>
<style lang="scss" scoped>
.searchBox{
display: flex;
flex-wrap: wrap;
background-color: #fff;
padding: 15px 0 0 0;
border-radius: 4px;
margin-bottom: 15px;
.row{
display: flex;
align-items: center;
width: 20%;
box-sizing: border-box;
margin-bottom: 15px;
&.row1{
width: 25%;
}
.span{
display: block;
width: 80px;
font-size: 14px;
text-align: right;
box-sizing: border-box;
}
.right{
width: calc(100% - 100px);
}
.wid100{
width: 100%;
}
}
}
.opaBox{
margin-bottom: 15px;
}
.imgBox{
display: flex;
flex-wrap: wrap;
.el-image{
width: 60px;
height: 60px;
border-radius: 4px;
margin-right: 10px;
}
}
.skuBox{
border: 1px solid #e5e5e5;
border-radius: 5px;
padding: 15px 0;
margin-bottom: 15px;
background-color: #f3f3f3;
.tit{
padding-left: 40px;
font-weight: 600;
font-size: 15px;
margin-bottom: 15px;
}
}
</style>