二维码画板

This commit is contained in:
2022-10-12 17:30:35 +08:00
parent f863413792
commit 0c5a34fbc7
2 changed files with 255 additions and 203 deletions

View File

@ -0,0 +1,42 @@
<template>
<div v-if="fontReady">
<v-stage :config="content" v-if="content" @mousedown="handleStageMouseDown">
<v-layer>
<v-rect v-if="content.background.type === 'color'" :config="content.background">
</v-rect>
<v-image v-if="content.background.type === 'image' && imageBgConfig" :config="imageBgConfig"></v-image>
</v-layer>
<v-layer>
<template v-for="(item, key) in content.blocks">
<v-text v-if="item.type === 'text'" :config="item"
@dragmove="onMove($event, item)"
@mousedown="handleStageMouseDown($event, item)"
@transform="handleTransformEnd"
@transformend="handleTransformEnd"></v-text>
<v-image v-else-if="item.type === 'image'" :config="item"
@dragmove="onMove($event, item)"
@mousedown="handleStageMouseDown($event, item)"
@transform="handleTransformEnd"
@transformend="handleTransformEnd"></v-image>
<v-image v-else-if="item.type === 'qrcode'" :config="item"
@dragmove="onMove($event, item)"
@mousedown="handleStageMouseDown($event, item)"
@transform="handleTransformEnd"
@transformend="handleTransformEnd"></v-image>
</template>
<v-transformer ref="transformer"/>
</v-layer>
</v-stage>
</div>
<div v-else>资源加载中...</div>
</template>
<script setup>
</script>
<style scoped>
</style>

View File

@ -39,7 +39,8 @@
icon="Plus" icon="Plus"
@click="handleAdd" @click="handleAdd"
v-hasPermi="['shop:goodsInfo:add']" v-hasPermi="['shop:goodsInfo:add']"
>新增</el-button> >新增
</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -49,7 +50,8 @@
:disabled="single" :disabled="single"
@click="handleUpdate" @click="handleUpdate"
v-hasPermi="['shop:goodsInfo:edit']" v-hasPermi="['shop:goodsInfo:edit']"
>修改</el-button> >修改
</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -59,7 +61,8 @@
:disabled="multiple" :disabled="multiple"
@click="handleDelete" @click="handleDelete"
v-hasPermi="['shop:goodsInfo:remove']" v-hasPermi="['shop:goodsInfo:remove']"
>删除</el-button> >删除
</el-button>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
@ -68,25 +71,26 @@
icon="Download" icon="Download"
@click="handleExport" @click="handleExport"
v-hasPermi="['shop:goodsInfo:export']" v-hasPermi="['shop:goodsInfo:export']"
>导出</el-button> >导出
</el-button>
</el-col> </el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row> </el-row>
<el-table v-loading="loading" :data="goodsInfoList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="goodsInfoList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center"/>
<el-table-column label="商品ID" align="center" prop="goodsId" /> <el-table-column label="商品ID" align="center" prop="goodsId"/>
<el-table-column label="编码" align="center" prop="goodsNo" /> <el-table-column label="编码" align="center" prop="goodsNo"/>
<el-table-column label="名称" align="center" prop="goodsName" /> <el-table-column label="名称" align="center" prop="goodsName"/>
<el-table-column label="产地" align="center" prop="goodsPlace" /> <el-table-column label="产地" align="center" prop="goodsPlace"/>
<el-table-column label="品牌" align="center" prop="goodsBrand" /> <el-table-column label="品牌" align="center" prop="goodsBrand"/>
<el-table-column label="规格" align="center" prop="goodsSpec" /> <el-table-column label="规格" align="center" prop="goodsSpec"/>
<el-table-column label="单位" align="center" prop="goodsUnit" /> <el-table-column label="单位" align="center" prop="goodsUnit"/>
<el-table-column label="库存" align="center" prop="goodsStock" /> <el-table-column label="库存" align="center" prop="goodsStock"/>
<el-table-column label="价格" align="center" prop="goodsPrice" /> <el-table-column label="价格" align="center" prop="goodsPrice"/>
<el-table-column label="售价" align="center" prop="salePrice" /> <el-table-column label="售价" align="center" prop="salePrice"/>
<el-table-column label="二维码" align="center" prop="goodsQrcode" /> <el-table-column label="二维码" align="center" prop="goodsQrcode"/>
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="备注" align="center" prop="remark"/>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button <el-button
@ -94,13 +98,15 @@
icon="Edit" icon="Edit"
@click="handleUpdate(scope.row)" @click="handleUpdate(scope.row)"
v-hasPermi="['shop:goodsInfo:edit']" v-hasPermi="['shop:goodsInfo:edit']"
>修改</el-button> >修改
</el-button>
<el-button <el-button
type="text" type="text"
icon="Delete" icon="Delete"
@click="handleDelete(scope.row)" @click="handleDelete(scope.row)"
v-hasPermi="['shop:goodsInfo:remove']" v-hasPermi="['shop:goodsInfo:remove']"
>删除</el-button> >删除
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -117,12 +123,16 @@
<el-dialog :title="title" v-model="open" width="700px" append-to-body draggable> <el-dialog :title="title" v-model="open" width="700px" append-to-body draggable>
<el-form ref="goodsInfoRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="goodsInfoRef" :model="form" :rules="rules" label-width="80px">
<el-row> <el-row>
<el-col :span="12"><el-form-item label="编码" prop="goodsNo"> <el-col :span="12">
<el-input v-model="form.goodsNo" placeholder="请输入编码" /> <el-form-item label="编码" prop="goodsNo">
</el-form-item></el-col> <el-input v-model="form.goodsNo" placeholder="请输入编码"/>
<el-col :span="12"><el-form-item label="名称" prop="goodsName"> </el-form-item>
<el-input v-model="form.goodsName" placeholder="请输入名称" /> </el-col>
</el-form-item></el-col> <el-col :span="12">
<el-form-item label="名称" prop="goodsName">
<el-input v-model="form.goodsName" placeholder="请输入名称"/>
</el-form-item>
</el-col>
</el-row> </el-row>
<el-form-item label="产地" prop="goodsPlace"> <el-form-item label="产地" prop="goodsPlace">
<!-- <el-input v-model="form.goodsPlace" placeholder="请输入产地" />--> <!-- <el-input v-model="form.goodsPlace" placeholder="请输入产地" />-->
@ -136,19 +146,19 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="品牌" prop="goodsBrand"> <el-form-item label="品牌" prop="goodsBrand">
<el-input v-model="form.goodsBrand" placeholder="请输入品牌" /> <el-input v-model="form.goodsBrand" placeholder="请输入品牌"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="规格" prop="goodsSpec"> <el-form-item label="规格" prop="goodsSpec">
<el-input v-model="form.goodsSpec" placeholder="请输入规格" /> <el-input v-model="form.goodsSpec" placeholder="请输入规格"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="单位" prop="goodsUnit"> <el-form-item label="单位" prop="goodsUnit">
<!-- <el-input v-model="form.goodsUnit" placeholder="请输入单位" />--> <!-- <el-input v-model="form.goodsUnit" placeholder="请输入单位" />-->
<el-select <el-select
v-model="form.goodsUnit" v-model="form.goodsUnit"
filterable filterable
@ -170,26 +180,26 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="库存" prop="goodsStock"> <el-form-item label="库存" prop="goodsStock">
<el-input v-model="form.goodsStock" placeholder="请输入库存" /> <el-input v-model="form.goodsStock" placeholder="请输入库存"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="价格" prop="goodsPrice"> <el-form-item label="价格" prop="goodsPrice">
<el-input v-model="form.goodsPrice" placeholder="请输入价格" /> <el-input v-model="form.goodsPrice" placeholder="请输入价格"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="售价" prop="salePrice"> <el-form-item label="售价" prop="salePrice">
<el-input v-model="form.salePrice" placeholder="请输入售价" /> <el-input v-model="form.salePrice" placeholder="请输入售价"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="二维码" prop="goodsQrcode"> <el-form-item label="二维码" prop="goodsQrcode">
<el-input v-model="form.goodsQrcode" placeholder="请输入二维码" /> <el-input v-model="form.goodsQrcode" placeholder="请输入二维码"/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@ -197,7 +207,7 @@
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -211,10 +221,10 @@
</template> </template>
<script setup name="GoodsInfo"> <script setup name="GoodsInfo">
import { listGoodsInfo, getGoodsInfo, delGoodsInfo, addGoodsInfo, updateGoodsInfo } from "@/api/shop/goodsInfo"; import {listGoodsInfo, getGoodsInfo, delGoodsInfo, addGoodsInfo, updateGoodsInfo} from "@/api/shop/goodsInfo";
import { regionDataPlus , CodeToText } from 'element-china-area-data' import {regionDataPlus, CodeToText} from 'element-china-area-data'
const { proxy } = getCurrentInstance(); const {proxy} = getCurrentInstance();
const goodsInfoList = ref([]); const goodsInfoList = ref([]);
const open = ref(false); const open = ref(false);
@ -227,13 +237,13 @@ const total = ref(0);
const title = ref(""); const title = ref("");
//校验输入编码规则 //校验输入编码规则
const checkGoodsNo = (rule, value, callback)=>{ const checkGoodsNo = (rule, value, callback) => {
if (value !== '' && value !== null) { if (value !== '' && value !== null) {
if (!/^-?[1-9]\d*$/.test(value)) { if (!/^-?[1-9]\d*$/.test(value)) {
callback(new Error('编码必须为数字')) callback(new Error('编码必须为数字'))
} else if (!/^\d{6,9}$/.test(value)){ } else if (!/^\d{6,9}$/.test(value)) {
callback(new Error('编码必须为6-9位数字')) callback(new Error('编码必须为6-9位数字'))
}else { } else {
callback() callback()
} }
} else { } else {
@ -241,23 +251,23 @@ const checkGoodsNo = (rule, value, callback)=>{
} }
} }
//库存总量规则校验 //库存总量规则校验
const checkGoodsStock = (rules,value,callback)=>{ const checkGoodsStock = (rules, value, callback) => {
if (value !== '' && value !== null) { if (value !== '' && value !== null) {
console.log(form.goodsUnit) console.log(form.goodsUnit)
if(form.goodsUnit !== 'kg'){ if (form.goodsUnit !== 'kg') {
if (!/^-?[1-9]\d*$/.test(value)) { if (!/^-?[1-9]\d*$/.test(value)) {
callback(new Error('库存总量必须为整数')) callback(new Error('库存总量必须为整数'))
}else if(value < 0){ } else if (value < 0) {
callback(new Error('库存总量必须为正整数')) callback(new Error('库存总量必须为正整数'))
}else { } else {
callback() callback()
} }
}else { } else {
if (value < 0){ if (value < 0) {
callback(new Error('库存总量不能小于0')) callback(new Error('库存总量不能小于0'))
}else if (!/^((([^0][0-9]+|0)\.([0-9]{1,2}))$)|^(([1-9]+)\.([0-9]{1,3})$)/.test(value)){ } else if (!/^((([^0][0-9]+|0)\.([0-9]{1,2}))$)|^(([1-9]+)\.([0-9]{1,3})$)/.test(value)) {
callback(new Error('库存总量最多保留三位小数')) callback(new Error('库存总量最多保留三位小数'))
}else { } else {
callback() callback()
} }
} }
@ -266,24 +276,21 @@ const checkGoodsStock = (rules,value,callback)=>{
} }
} }
//商品价格规则校验 //商品价格规则校验
const checkGoodsPrice = (rules,value,callback)=>{ const checkGoodsPrice = (rules, value, callback) => {
console.log()
if (value !== '' && value !== null) { if (value !== '' && value !== null) {
if(value < 0){ if (value < 0) {
callback(new Error('商品价格不能为负数')) callback(new Error('商品价格不能为负数'))
}else{ } else {
if(value.indexOf(".") !==0) { //首位为小数点
if (!/^(([^0][0-9]+|0)\.([0-9])$)|^(([^0][0-9]+|0)$)|^(([1-9]+)\.([0-9]{1,3})$)|^(([1-9]+)$)/.test(value)) { if (value.substr(0, 1) === '.') {
callback(new Error('商品价格输入格式不正确'))
} else if (!/^(([^0][0-9]+|0)\.([0-9])$)|^(([^0][0-9]+|0)$)|^(([1-9]+)\.([0-9]{1,3})$)|^(([1-9]+)$)/.test(value)) {
callback(new Error('商品价格最多保留三位小数')) callback(new Error('商品价格最多保留三位小数'))
}else { } else {
callback() callback()
} }
}else {
if(value.substr(0,1) === '.'){
callback(new Error('商品价格输入格式不正确'))
} }
}
}
} else { } else {
callback(new Error('商品价格不能为空')) callback(new Error('商品价格不能为空'))
} }
@ -291,8 +298,10 @@ const checkGoodsPrice = (rules,value,callback)=>{
const options = regionDataPlus const options = regionDataPlus
const GoodsOptions = [ const GoodsOptions = [
{value: 'kg', {
label: '千克'}, value: 'kg',
label: '千克'
},
{ {
value: '袋', value: '袋',
label: '袋' label: '袋'
@ -335,42 +344,42 @@ const data = reactive({
// {type: 'number', message: "编码必须为数字", trigger: "blur"} // {type: 'number', message: "编码必须为数字", trigger: "blur"}
// ], // ],
goodsNo: [ goodsNo: [
{ validator: checkGoodsNo, trigger: "blur" } {validator: checkGoodsNo, trigger: "blur"}
], ],
goodsName: [ goodsName: [
{ required: true, message: "名称不能为空", trigger: "blur" } {required: true, message: "名称不能为空", trigger: "blur"}
], ],
goodsPlace: [ goodsPlace: [
{ required: true, message: "产地不能为空", trigger: "blur" } {required: true, message: "产地不能为空", trigger: "blur"}
], ],
goodsBrand: [ goodsBrand: [
{ required: true, message: "品牌不能为空", trigger: "blur" } {required: true, message: "品牌不能为空", trigger: "blur"}
], ],
goodsSpec: [ goodsSpec: [
{ required: true, message: "规格不能为空", trigger: "blur" } {required: true, message: "规格不能为空", trigger: "blur"}
], ],
goodsUnit: [ goodsUnit: [
{ required: true, message: "单位不能为空", trigger: "blur" } {required: true, message: "单位不能为空", trigger: "blur"}
], ],
goodsStock: [ goodsStock: [
{ validator: checkGoodsStock, trigger: "blur" } {validator: checkGoodsStock, trigger: "blur"}
// { required: true, message: "库存不能为空", trigger: "blur" } // { required: true, message: "库存不能为空", trigger: "blur" }
], ],
goodsPrice: [ goodsPrice: [
{ validator: checkGoodsPrice, trigger: "blur" } {validator: checkGoodsPrice, trigger: "blur"}
// { required: true, message: "价格不能为空", trigger: "blur" } // { required: true, message: "价格不能为空", trigger: "blur" }
], ],
salePrice: [ salePrice: [
{ validator: checkGoodsPrice, trigger: "blur" } {validator: checkGoodsPrice, trigger: "blur"}
// { required: true, message: "售价不能为空", trigger: "blur" } // { required: true, message: "售价不能为空", trigger: "blur" }
], ],
goodsQrcode: [ goodsQrcode: [
{ required: true, message: "二维码不能为空", trigger: "blur" } {required: true, message: "二维码不能为空", trigger: "blur"}
], ],
} }
}); });
const { queryParams, form, rules } = toRefs(data); const {queryParams, form, rules} = toRefs(data);
// 产地选择 // 产地选择
function getCodeToText(codeStr, codeArray) { function getCodeToText(codeStr, codeArray) {
@ -401,7 +410,7 @@ function getCodeToText(codeStr, codeArray) {
return area; return area;
} }
function handleGoodsPlace (value) { function handleGoodsPlace(value) {
console.log(value) console.log(value)
form.goodsPlace = getCodeToText(null, value) form.goodsPlace = getCodeToText(null, value)
} }
@ -513,12 +522,13 @@ function submitForm() {
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const _goodsIds = row.goodsId || ids.value; const _goodsIds = row.goodsId || ids.value;
proxy.$modal.confirm('是否确认删除商品信息编号为"' + _goodsIds + '"的数据项?').then(function() { proxy.$modal.confirm('是否确认删除商品信息编号为"' + _goodsIds + '"的数据项?').then(function () {
return delGoodsInfo(_goodsIds); return delGoodsInfo(_goodsIds);
}).then(() => { }).then(() => {
getList(); getList();
proxy.$modal.msgSuccess("删除成功"); proxy.$modal.msgSuccess("删除成功");
}).catch(() => {}); }).catch(() => {
});
} }
/** 导出按钮操作 */ /** 导出按钮操作 */