492 lines
17 KiB
Vue
492 lines
17 KiB
Vue
<template>
|
||
<el-dialog
|
||
:title="title + ' - 商品'"
|
||
:visible.sync="visible"
|
||
width="900px"
|
||
append-to-body
|
||
:close-on-click-modal="false"
|
||
:destroy-on-close="true"
|
||
@close="handleClose"
|
||
@open="handelOpen"
|
||
>
|
||
<div style="width: 100%;height: 500px;overflow-y: auto;">
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="商品编号" prop="materialCode">
|
||
<el-input
|
||
v-model="form.materialCode"
|
||
placeholder="请输入商品编号"
|
||
maxlength="40"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="商品名称" prop="materialName">
|
||
<el-input
|
||
v-model="form.materialName"
|
||
placeholder="请输入商品名称"
|
||
maxlength="40"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="商品类别" prop="materialTypeId">
|
||
<el-cascader v-model="form.materialTypeId"
|
||
:options="treeTypeOptions" :filterable="true" style="width: 100%;" :show-all-levels="false"
|
||
:props="{
|
||
emitPath: false,// 若设置 false,则只返回该节点的值,只返回最后选择的id
|
||
checkStrictly: false,//来设置父子节点取消选中关联,从而达到选择任意一级选项的目的
|
||
value:'materialTypeId',label:'materialTypeName'
|
||
}" clearable >
|
||
</el-cascader>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="所属区域" prop="areaId">
|
||
<el-cascader v-model="form.areaId"
|
||
:options="treeAreaOptions" :filterable="true" style="width: 100%;" :show-all-levels="false"
|
||
:props="{
|
||
emitPath: false,// 若设置 false,则只返回该节点的值,只返回最后选择的id
|
||
checkStrictly: false,//来设置父子节点取消选中关联,从而达到选择任意一级选项的目的
|
||
value:'id',label:'label'
|
||
}" clearable @change="handleAreaChange">
|
||
</el-cascader>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="计重类型" prop="salesMode" >
|
||
<el-select v-model="form.salesMode" placeholder="请选择计量类型" style="width: 100%" @change="getDrpUnitList">
|
||
<el-option label="按份" value="1" />
|
||
<el-option label="称重" value="2" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="计量单位" prop="unitId">
|
||
<el-select v-model="form.unitId" placeholder="请选择商品单位" style="width: 100%">
|
||
<el-option v-for="item in this.unitOptions"
|
||
:key="item.unitId"
|
||
:label="item.unitName"
|
||
:value="item.unitId"
|
||
></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
|
||
<el-col :span="12">
|
||
<el-form-item label="商品进价" prop="unitPrice">
|
||
<el-input
|
||
v-model="form.unitPrice"
|
||
placeholder="请输入商品进价"
|
||
@input="handleNumericInput('unitPrice', $event)"
|
||
@blur="formatNumericValue('unitPrice')"
|
||
>
|
||
<template slot="append">元</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="零售价" prop="salePrice">
|
||
<el-input
|
||
v-model="form.salePrice"
|
||
placeholder="请输入零售价"
|
||
maxlength="20"
|
||
@input="handleNumericInput('salePrice', $event)"
|
||
@blur="formatNumericValue('salePrice')"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="条码" prop="barCode">
|
||
<el-input
|
||
v-model="form.barCode"
|
||
placeholder="请输入条码"
|
||
maxlength="20"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="12">
|
||
<el-form-item label="保质期" prop="qualityNum">
|
||
<el-select v-model="form.qualityType" style="width: 80px; margin-left: 10px">
|
||
<el-option label="按年" value="1" />
|
||
<el-option label="按月" value="2" />
|
||
<el-option label="按日" value="3" />
|
||
</el-select>
|
||
<el-input v-model="form.qualityNum" placeholder="请输入" style="width: 120px;margin-right: 10px;" @input="(v)=>(form.qualityNum=v.replace(/[^\d]/g,''))"/>
|
||
<span v-if="form.qualityType==1">年</span>
|
||
<span v-if="form.qualityType==2">月</span>
|
||
<span v-if="form.qualityType==3">日</span>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="供应资格证书" prop="supplyCertificate">
|
||
<el-select v-model="form.supplyCertificate" placeholder="请选择供应资格证书" style="width: 100%">
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col> -->
|
||
<el-col :span="12">
|
||
<el-form-item label="商品简介" prop="productRemark">
|
||
<el-input
|
||
type="textarea"
|
||
:rows="3"
|
||
placeholder="请输入商品简介"
|
||
v-model="form.productRemark">
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="图片" prop="imgUrl">
|
||
<el-upload
|
||
:http-request="(obj) => imgUpLoad(obj, 'fileUrl')"
|
||
action="#"
|
||
:limit="1"
|
||
:file-list="fileList"
|
||
:show-file-list="true"
|
||
list-type="picture-card"
|
||
accept=".png, .jpg, .jpeg"
|
||
:on-success="handleAvatarSuccess"
|
||
:class="{ disabled: uploadDisabled }"
|
||
:on-remove="handleRemove"
|
||
>
|
||
<i
|
||
class="el-icon-plus avatar-uploader-icon"
|
||
></i>
|
||
</el-upload>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</div>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitForm" :disabled="loading">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script>
|
||
import { systemAreaTreeApi } from "@/api/base/area";
|
||
import { shopMaterialTreeApi,getDrpUnitListApi } from "@/api/superStore/shopMaterial";
|
||
import { imgUpLoadTwo } from '@/api/system/upload'
|
||
export default {
|
||
name: "MaterialDialog",
|
||
props: {
|
||
title: {
|
||
type: String,
|
||
default: '新增'
|
||
},
|
||
visible: {
|
||
type: Boolean,
|
||
default: false
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
loading:false,
|
||
treeAreaOptions:[],//区域树
|
||
treeTypeOptions:[],//类型树
|
||
unitOptions:[],//单位下拉
|
||
form: {
|
||
materialName: '',//商品名称
|
||
areaId: null,//所属区域
|
||
materialTypeId: null,//商品类别
|
||
materialType: 2,
|
||
salesMode: '1',//计量类型
|
||
salePrice: '',//零售价(元)
|
||
unitId: '',//商品单位
|
||
unitPrice: '',//商品进价(元)
|
||
barCode: '',//条码
|
||
nutritionId:null,//营养信息
|
||
qualityType:"1",//保质期类型
|
||
qualityNum:"",//保质期
|
||
purPriceCeiling:'',//采购上限价格
|
||
size:'',//商品规格
|
||
taxRate:'',//商品税率
|
||
supplyCertificate: '',
|
||
productRemark:"",//简介
|
||
imgUrl:"",//图片
|
||
|
||
},
|
||
rules: {
|
||
materialCode: [{ required: true, message: '请输入商品编号', trigger: 'blur' }],
|
||
materialName: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
|
||
areaId: [{ required: true, message: '请选择所属区域', trigger: 'change' }],
|
||
salePrice: [{ required: true, message: '请输入零售价', trigger: 'change' }],
|
||
materialTypeId: [{ required: true, message: '请选择商品类别', trigger: 'change' }],
|
||
salesMode: [{ required: true, message: '请选择计量类型', trigger: 'change' }],
|
||
unitId: [{ required: true, message: '请选择商品单位', trigger: 'change' }],
|
||
},
|
||
fileList: [],//档口图片
|
||
checkUrlList: [],//档口图片
|
||
checkUrlNameList: [],//档口图片
|
||
dialogVisible:false,//图片弹窗
|
||
dialogImageUrl:"",//图片弹窗
|
||
};
|
||
},
|
||
computed: {
|
||
//图片上传1张后,隐藏上传框
|
||
uploadDisabled() {
|
||
return this.checkUrlList.length > 0
|
||
},
|
||
},
|
||
mounted() {
|
||
},
|
||
methods: {
|
||
handelOpen(){
|
||
this.getAreaTreeData();//获取区域树
|
||
this.getDrpUnitList();//获取单位类型下拉
|
||
},
|
||
handleClose() {
|
||
this.$emit('update:visible', false);
|
||
this.$nextTick(() => {
|
||
this.reset();
|
||
});
|
||
},
|
||
//区域树
|
||
getAreaTreeData() {
|
||
systemAreaTreeApi({}).then((response) => {
|
||
this.treeAreaOptions = response.data;
|
||
this.getTypeTreeData()
|
||
});
|
||
},
|
||
//基础设置-选择区域
|
||
handleAreaChange(val){
|
||
console.log(this.form)
|
||
this.getTypeTreeData()
|
||
this.getDrpUnitList()
|
||
},
|
||
//类型树
|
||
getTypeTreeData() {
|
||
shopMaterialTreeApi().then((response) => {
|
||
this.treeTypeOptions = this.handleTree(response.rows,'materialTypeId');
|
||
});
|
||
},
|
||
handleTree(data, idKey, parentIdKey = 'parentId', childrenKey = 'children') {
|
||
// 用于存储节点数据的Map,以idKey为键
|
||
const nodeMap = new Map();
|
||
// 用于存储根节点的数组
|
||
const rootNodes = [];
|
||
|
||
// 遍历数据,构建nodeMap并找到根节点
|
||
data.forEach(node => {
|
||
// 将节点添加到nodeMap中,并初始化children为空数组
|
||
if(node.parentId==0){
|
||
nodeMap.set(node[idKey], { ...node, [childrenKey]: [] });
|
||
}else{
|
||
nodeMap.set(node[idKey], { ...node });
|
||
}
|
||
// 如果parentId为null或父节点不存在于nodeMap中,则该节点为根节点
|
||
if (node[parentIdKey] === null || !nodeMap.has(node[parentIdKey])) {
|
||
// 将根节点添加到rootNodes数组中
|
||
rootNodes.push(nodeMap.get(node[idKey]));
|
||
} else {
|
||
// 否则,将当前节点添加到其父节点的children列表中
|
||
// 获取父节点
|
||
const parentNode = nodeMap.get(node[parentIdKey]);
|
||
// 将当前节点添加到父节点的children列表中
|
||
parentNode[childrenKey].push(nodeMap.get(node[idKey]));
|
||
}
|
||
});
|
||
|
||
// 返回根节点数组,它现在包含了完整的树形结构
|
||
return rootNodes;
|
||
},
|
||
//单位类型拉下选
|
||
getDrpUnitList() {
|
||
let param = {
|
||
"weighType":this.form.salesMode,
|
||
"pageNum": 1,
|
||
"pageSize": 100
|
||
}
|
||
this.form.unitId=null
|
||
getDrpUnitListApi(param).then((response) => {
|
||
this.unitOptions = response.rows;
|
||
// if(response.data.records.length>0){
|
||
// response.data.records.forEach(item => {
|
||
// if(item.weighType==this.form.salesMode){
|
||
// this.unitOptions.push(item)
|
||
// }
|
||
// });
|
||
// }
|
||
});
|
||
},
|
||
|
||
setFormData(row){
|
||
console.log(row)
|
||
// this.form = Object.assign({}, row)
|
||
this.$set(this.form,"areaId",row.areaId)
|
||
this.getTypeTreeData()
|
||
this.getDrpUnitList()
|
||
this.$set(this.form,"areaName",row.areaName)
|
||
this.$set(this.form,"materialTypeId",row.materialTypeId)
|
||
this.$set(this.form,"categoryName",row.categoryName)
|
||
this.$set(this.form,"materialCode",row.materialCode)
|
||
this.$set(this.form,"materialId",row.materialId)
|
||
this.$set(this.form,"materialName",row.materialName)
|
||
this.$set(this.form,"materialType",row.materialType)
|
||
this.$set(this.form,"salesMode",row.salesMode+'')
|
||
this.$set(this.form,"unitId",row.unitId)
|
||
this.$set(this.form,"salePrice",Number((row.salePrice/100).toFixed(2)))
|
||
this.$set(this.form,"unitPrice",Number((row.unitPrice/100).toFixed(2)))
|
||
this.$set(this.form,"barCode",row.barCode)
|
||
if(row.qualityType){
|
||
this.$set(this.form,"qualityType",row.qualityType+"")
|
||
}else{
|
||
this.$set(this.form,"qualityType","1")
|
||
}
|
||
this.$set(this.form,"qualityNum",row.qualityNum)
|
||
this.$set(this.form,"supplyCertificate","")
|
||
this.$set(this.form,"productRemark",row.productRemark)
|
||
this.$set(this.form,"imgUrl",row.imgUrl)
|
||
//图片反显
|
||
if(row.imgUrl){
|
||
this.fileList=[{url:row.imgUrl}]
|
||
this.checkUrlList=[row.imgUrl]
|
||
}else{
|
||
this.fileList=[]
|
||
this.checkUrlList=[]
|
||
}
|
||
},
|
||
|
||
submitForm() {
|
||
this.$refs.form.validate(valid => {
|
||
if (valid) {
|
||
this.loading=true
|
||
this.form.salePrice = Number(this.form.salePrice)*100;
|
||
this.form.unitPrice = Number(this.form.unitPrice)*100;
|
||
setTimeout(()=>{
|
||
this.$set(this.form,"salePrice",Number((this.form.salePrice/100).toFixed(2)))
|
||
this.$set(this.form,"unitPrice",Number((this.form.unitPrice/100).toFixed(2)))
|
||
this.loading=false
|
||
},500)
|
||
this.$emit('submit', this.form);
|
||
|
||
}
|
||
});
|
||
},
|
||
|
||
|
||
cancel() {
|
||
this.$emit('update:visible', false);
|
||
this.$nextTick(() => {
|
||
this.reset();
|
||
});
|
||
},
|
||
|
||
reset() {
|
||
this.form = {
|
||
materialName: '',//商品名称
|
||
areaId: null,//所属区域
|
||
materialTypeId: null,//商品类别
|
||
salesMode: '1',//计量类型
|
||
unitId: '',//商品单位
|
||
salePrice: '',//商品售价(元)
|
||
unitPrice: '',//商品进价(元)
|
||
barCode: '',//条码
|
||
str:[],//营养信息类型
|
||
nutritionId:null,//营养信息
|
||
qualityType:"1",//保质期类型
|
||
qualityNum:"",//保质期
|
||
supplyCertificate: '',
|
||
productRemark:"",//简介
|
||
imgUrl:""
|
||
};
|
||
},
|
||
|
||
// 图片上传
|
||
imgUpLoad(param, name, index) {
|
||
// console.log(param,'image')
|
||
param.type = 'stall'
|
||
imgUpLoadTwo(param).then((res) => {
|
||
if (res.code == 200) {
|
||
this.checkUrlList.push(res.data.url)
|
||
this.checkUrlNameList.push(res.data.name)
|
||
this.$set(this.form,"imgUrl",res.data.url)
|
||
} else {
|
||
this.$modal.msgError(res.msg)
|
||
this.$set(this.form,"imgUrl","")
|
||
}
|
||
})
|
||
.catch((error) => {
|
||
this.$modal.msgError(error)
|
||
})
|
||
},
|
||
handleAvatarSuccess(res, file) {
|
||
console.log('success')
|
||
},
|
||
handleExceed(files, fileList) {
|
||
this.$message.warning('最多只可以上传一张图片')
|
||
},
|
||
handleRemove(file, fileList) {
|
||
let sum = 0
|
||
this.checkUrlNameList.forEach((item, index) => {
|
||
if (item == file.name) {
|
||
sum = index
|
||
}
|
||
})
|
||
this.checkUrlNameList.splice(sum, 1)
|
||
this.checkUrlList.splice(sum, 1)
|
||
},
|
||
//数字输入
|
||
handleNumericInput(field, event) {
|
||
const value = event;
|
||
// 只允许输入数字和小数点
|
||
let newValue = value.replace(/[^\d.]/g, '');
|
||
|
||
// 确保只有一个小数点
|
||
const parts = newValue.split('.');
|
||
if (parts.length > 2) {
|
||
newValue = parts[0] + '.' + parts.slice(1).join('');
|
||
}
|
||
|
||
// 限制小数点后最多两位
|
||
if (parts.length === 2 && parts[1].length > 2) {
|
||
newValue = parts[0] + '.' + parts[1].substring(0, 2);
|
||
}
|
||
|
||
// 设置字段值
|
||
if (field.includes('.')) {
|
||
const [obj, prop] = field.split('.');
|
||
this.form[obj][prop] = newValue;
|
||
} else {
|
||
this.form[field] = newValue;
|
||
}
|
||
},
|
||
formatNumericValue(field) {
|
||
let value;
|
||
if (field.includes('.')) {
|
||
const [obj, prop] = field.split('.');
|
||
value = this.form[obj][prop];
|
||
} else {
|
||
value = this.form[field];
|
||
}
|
||
|
||
if (!value || value === '' || value === '.') {
|
||
value = '0.00';
|
||
} else {
|
||
value = parseFloat(value).toFixed(2);
|
||
}
|
||
|
||
if (field.includes('.')) {
|
||
const [obj, prop] = field.split('.');
|
||
this.form[obj][prop] = value;
|
||
} else {
|
||
this.form[field] = value;
|
||
}
|
||
},
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
//隐藏图片上传框的css
|
||
::v-deep.disabled {
|
||
.el-upload--picture-card {
|
||
display: none;
|
||
}
|
||
}
|
||
</style> |