devicesmgt/sgzb-ui/src/views/store/label/labelBinding.vue

935 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container" id="labelBinding">
<div style="z-index: 10000">
<div style="z-index: 10000">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
style="z-index: 10000"
>
<el-form-item label="关键字" prop="keyWord">
<el-input
v-model="queryParams.keyWord"
placeholder="请输入关键字"
clearable maxlength="50"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="设备类型" prop="typeId">
<el-select
v-model="queryParams.typeId"
placeholder="请选择设备类型"
clearable filterable
style="width: 240px"
@change="selectDevice"
>
<el-option
v-for="typeItem in typeList"
:key="typeItem.typeId"
:label="typeItem.typeName"
:value="typeItem.typeId"
/>
</el-select>
</el-form-item>
<el-form-item label="规格型号" prop="modelId">
<el-select
v-model="queryParams.modelId"
placeholder="请选择规格型号"
clearable filterable
style="width: 240px"
>
<el-option
v-for="model in modelList"
:key="model.typeId"
:label="model.typeName"
:value="model.typeId"
/>
</el-select>
</el-form-item>
<el-form-item label="绑定状态" prop="isBind">
<el-select
v-model="queryParams.isBind"
placeholder="请选择绑定状态"
clearable
style="width: 240px"
>
<el-option label="已绑定" value="1" />
<el-option label="未绑定" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleQuery"
>搜索</el-button
>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
>重置</el-button
>
</el-form-item>
</el-form>
</div>
<el-row :gutter="10" class="mb8">
<!-- -->
<el-col :span="1.5">
<el-button
type="primary"
icon="el-icon-plus"
size="mini"
@click="handleBind"
:disabled="single"
>绑定</el-button
>
</el-col>
<!-- :disabled="single" -->
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="createLabel"
>标签生成</el-button
>
</el-col>
<el-col :span="1.5">
<!-- 下载二维码地址Excel -->
<download-excel
class="export-excel-wrapper"
:data="checkboxModel"
:fields="json_fields"
name="二维码地址.xls"
>
<!-- 下载二维码图片 -->
<el-button
type="success"
plain
icon="el-icon-plus"
size="mini"
:disabled="multiple"
@click="labelUpload"
>标签下载</el-button>
</download-excel>
</el-col>
<!-- <el-col :span="1.5">
<download-excel
class="export-excel-wrapper"
:data="checkboxModel"
:fields="json_fields"
name="二维码地址.xls"
>
<el-button :disabled="multiple">导出地址</el-button>
</download-excel>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
>删除</el-button>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
>导出</el-button>
</el-col> -->
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="labelList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="序号" align="center" type="index" />
<el-table-column
label="标签类型"
align="center"
prop="name"
:show-overflow-tooltip="true"
/>
<el-table-column label="标签编号" align="center" prop="labelCode">
<template slot-scope="scope">
<span
style="color: blue; cursor: pointer"
@click="labelUploadCode(scope.row)"
>
{{ scope.row.labelCode }}</span
>
</template>
</el-table-column>
<el-table-column
label="物品种类"
align="center"
prop="kindName"
:show-overflow-tooltip="true"
/>
<el-table-column label="物品名称" align="center" prop="modelName" />
<el-table-column
label="规格型号"
align="center"
prop="typeName"
:show-overflow-tooltip="true"
/>
<el-table-column label="设备编码" align="center" prop="maCode" />
<el-table-column
label="绑定人员"
align="center"
prop="userName"
:show-overflow-tooltip="true"
/>
<el-table-column label="绑定时间" align="center" prop="bindTime" />
<el-table-column label="状态" align="center" prop="status">
<template slot-scope="scope">
<span>{{
scope.row.status == 0
? '未绑定'
: scope.row.status == 1
? '已绑定'
: scope.row.status == 2
? '已解绑'
: ''
}}</span>
<!-- <dict-tag
:options="dict.type.sys_normal_disable"
:value="scope.row.status"
/> -->
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template slot-scope="scope">
<!-- <el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
>编辑</el-button> -->
<!-- status 未绑定0 已绑定1 已解绑2 -->
<!-- isBind 不展示解绑0 展示解绑1 -->
<el-button
:disabled="
!(scope.row.status === '1' && scope.row.isBind === '1')
"
size="mini"
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>解绑</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 标签绑定对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="标签类型" prop="labelType">
<el-select
v-model="form.labelType"
placeholder="请选择标签类型"
style="width: 100%"
disabled
>
<el-option
v-for="item in labelTypeList"
:key="item.id"
:label="item.name"
:value="item.id"
v-if="item.status != '1'"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="标签编号" prop="labelCode">
<el-select
v-model="form.labelCode"
placeholder="请选择标签编号"
style="width: 100%"
disabled
>
<el-option
v-for="item in labelCodeList"
:key="item.labelCode"
:label="item.labelCode"
:value="item.labelCode"
v-if="item.status != '1'"
></el-option>
</el-select>
<!-- <el-input v-model="form.labelCode" placeholder="请输入标签编号" /> -->
</el-form-item>
<el-form-item label="规格型号" prop="typeId">
<treeselect
v-model="form.typeId"
:options="deptOptions"
placeholder="请选择规格型号"
default-expand-all
@select="selectType"
:disable-branch-nodes="true"
/>
</el-form-item>
<el-form-item label="设备编码" prop="maCode">
<el-input
v-model="form.maCode"
placeholder="请输入设备编码,如NSJJ+类型编码+规格编码"
:clearable="true" maxlength="50"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
<!-- 标签生成对话框 -->
<el-dialog
:title="title"
:visible.sync="createOpen"
width="500px"
append-to-body :close-on-click-modal="false"
>
<el-form ref="cform" :model="cform" :rules="crules" label-width="80px">
<el-form-item label="标签类型" prop="labelType">
<el-select
v-model="cform.labelType"
placeholder="请选择标签类型"
style="width: 100%"
>
<el-option
v-for="item in labelTypeList"
:key="item.id"
:label="item.name"
:value="item.id"
v-if="item.status != '1'"
></el-option>
</el-select>
<!-- <el-input v-model="cform.labelType" placeholder="请输入标签类型" /> -->
</el-form-item>
<el-form-item label="标签数量" prop="labelNum">
<el-input-number
style="width: 100%"
v-model="cform.labelNum"
controls-position="right"
:min="1"
:max="100"
placeholder="请输入标签数量"
></el-input-number>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitCreate">确 定</el-button>
<el-button @click="cancelCreate">取 消</el-button>
</div>
</el-dialog>
<!-- 标签下载对话框 -->
<el-dialog
:title="title"
:visible.sync="uploadOpen"
width="450px"
append-to-body :close-on-click-modal="false"
>
<div style="text-align: center" ref="codeBox">
<div class="uploadImg">
<div id="qrcode" class="qrcode" ref="codeItem"></div>
<!-- <img src="" alt="">-->
</div>
<div class="maCode">设备编号:{{ rowObj.maCode }}</div>
</div>
<div slot="footer" class="dialog-footer" style="text-align: center">
<el-button type="primary" @click="downloadCode">下 载</el-button>
</div>
</el-dialog>
<div style="background-color: transparent" ref="qrCodeAll">
<div
id="qrCode"
v-for="(codeItem, codeIndex) in checkboxModel"
:key="codeIndex"
class="captureId"
v-show="codeId"
ref="QrcodePage"
style="
z-index: -1111111;
position: absolute;
top: 10px;
left: -99999;
width: 450px;
height: 475px;
background-size: cover;
"
></div>
<!-- <center style="text-align: center; font-size: 1.5625rem">
{{ codeVal }}
</center> -->
</div>
</div>
</template>
<script>
import {addMachine, delMachine, getMachine, listMachine, updateMachine,supplierInfoList,getListByMaType} from "@/api/store/tools";
import { listType, getType, delType, addType, updateType, refreshCache, } from "@/api/system/dict/type";
import { listLabelBind, addLabelBind, delLabelBind } from "@/api/store/label";
import { getTypeList } from "@/api/store/warehousing";
import user from '../../../store/modules/user'
import { unitTypeList, getMaMachineLabelApi, addMaMachineLabelApi } from "@/api/base/base";
import { v4 as uuidv4 } from 'uuid';
import html2canvas from "html2canvas";
import QRCode from 'qrcodejs2'
import JSZip from 'jszip'
import FileSaver from "file-saver"
import { getDeviceTypeTree } from "@/api/claimAndRefund/receive";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
export default {
name: "LabelBinding",
dicts: ['sys_normal_disable'],
components: { Treeselect },
data() {
return {
deptOptions: undefined,
rowObj: {},
userInfo: user.state,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
typeList: [],
modelList: [],
// 字典表格数据
labelList: [],
//标签类型下拉
labelTypeList: [],
// 标签编号
labelCodeList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 日期范围
dateRange: [],
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
// labelType: undefined,
// labelCode: undefined,
// status: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {
// labelType: [
// { required: true, message: "标签类型不能为空", trigger: "blur" }
// ],
// labelCode: [
// { required: true, message: "标签编号不能为空", trigger: "blur" }
// ],
typeId: [
{ required: true, message: "规格型号不能为空", trigger: "blur" }
],
maCode: [
{ required: true, message: "设备编码不能为空", trigger: "blur" }
],
},
//标签生成
createOpen: false,
cform: {},
crules: {
labelType: [
{ required: true, message: "标签类型不能为空", trigger: "blur" }
],
labelNum: [
{ required: true, message: "标签数量不能为空", trigger: "blur" }
]
},
//标签下载
uploadOpen: false,
deviceId: '',
selectionList: [],
checkboxModel: [], // 列表复选框
checked: false,
qrcodeArr: [],
codeVal: "",
codeId: true,
isShowQrCode: -1,
labelmaCode: '',
qrUrl:'http://112.29.103.165:21626/qrCode/qrCodePage?qrCode=',
json_fields:{"二维码地址":'exportUrl',"标签编号":'labelCode',"设备编码":'maCode'},
};
},
created() {
console.log(this.userInfo.id)
this.getList();
this.getType()
this.getTypeList();
},
methods: {
/** 查询下拉 */
getTypeList() {
getTypeList({ level: '3' }).then(response => {
this.typeList = response.data;
}
);
getTypeList({ level: '4' }).then(response => {
this.modelList = response.data;
}
);
},
//获取单位类型
getType() {
unitTypeList({ id: "8" }).then(response => {
this.labelTypeList = response.rows;
})
// 获取标签编号
getMaMachineLabelApi().then(response => {
this.labelCodeList = response.rows;
})
},
//选择设备类型
selectDevice(id){
console.log(id)
getListByMaType({typeId:id}).then(response => {
this.modelList = response.data;
}
);
},
/** 查询字典类型列表 */
getList() {
this.loading = true;
listLabelBind(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.labelList = response.rows;
this.total = response.total;
this.loading = false;
}
);
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
typeId: undefined,
maId: undefined,
labelType: undefined,
labelCode: undefined,
remark: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = [];
this.resetForm("queryForm");
this.handleQuery();
},
/** 绑定按钮操作 */
handleBind() {
this.reset();
this.open = true;
this.title = "绑定";
this.form.id = this.ids[0].id;
// this.form.typeId = this.ids[0].typeId;
this.form.maId = this.ids[0].maId;
this.form.labelId = this.ids[0].labelId;
this.form.labelType = this.ids[0].labelType;
this.form.labelCode = this.ids[0].labelCode;
getDeviceTypeTree({ "level": "4" }).then(response => {
this.deptOptions = response.data;
});
},
/** 修改按钮操作 */
handleUpdate(row) {
// this.reset();
// const maId = row.maId || this.ids
// getType(maId).then(response => {
// this.form = response.data;
// this.open = true;
// this.title = "绑定";
// });
},
/** 提交按钮 */
submitForm: function () {
this.form.binder = this.userInfo.id + '';
// this.form.typeId
console.log(this.form);
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.level == '4') {
if (this.form.maCode.indexOf('null') > 0) {
this.$modal.msgError("请输入正确规则的设备编码!");
} else {
addLabelBind(this.form).then(response => {
this.$modal.msgSuccess("绑定成功");
this.open = false;
this.getList();
});
}
} else {
this.$modal.msgError("当前类型无法生成标签,请选择设备类型-规格型号!");
}
}
});
},
selectType(val) {
console.log(val)
if (!val.children) {
console.log(val)
let nTime = new Date();
let nYear = nTime.getFullYear() + '';
let nMonth = nTime.getMonth() + 1;
console.log(nYear)
console.log(nMonth)
this.form.level = '4';
// let arr = this.form.arrivalTime.split('-')
this.$set(this.form, 'maCode', 'NSJJ' + val.code + val.modelCode + nYear[2] + nYear[3] + nMonth)
} else {
this.form.level = '';
this.$set(this.form, 'maCode', '')
}
this.form.typeId = val.id
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id;
this.$modal.confirm('是否确认解绑数据项?').then(function () {
return delLabelBind(id);
}).then(() => {
this.getList();
this.$modal.msgSuccess("解绑成功");
}).catch(() => { });
},
// 标签生成按钮
createLabel() {
this.resetCreate();
this.createOpen = true;
this.title = "标签生成";
},
// 表单重置
resetCreate() {
this.cform = {
labelType: undefined,
labelNum: undefined,
};
this.resetForm("cform");
},
cancelCreate() {
this.createOpen = false;
this.resetCreate();
},
// 标签生成提交
submitCreate() {
this.$refs["cform"].validate(valid => {
if (valid) {
let uuidList = []
for (let i = 0; i < this.cform.labelNum; i++) {
uuidList.push(uuidv4())
// 索引,数组下标
}
let parmas = {
uuidList: uuidList.join(','),
labelType: this.cform.labelType,
labelNum: this.cform.labelNum,
}
addMaMachineLabelApi(parmas).then(res => {
if (res.code == 200) {
this.$modal.msgSuccess(res.msg);
this.createOpen = false;
this.getList();
}
})
// updateType(this.form).then(response => {
// this.open = false;
// this.getList();
// });
} else {
return false
}
});
},
//标签下载
async labelUpload() {
console.log('checkboxModel', this.checkboxModel);
const msg = this.$modal.loading("批量生成中,请稍候...");
try {
let that = this;
let captureId = document.getElementsByClassName("captureId");
for (let i = 0; i < this.checkboxModel.length; i++) {
const element = this.checkboxModel[i];
captureId[i].innerHTML = "";
let shareContent = that.$refs["QrcodePage"][i],
width = shareContent.offsetWidth,
height = shareContent.offsetHeight;
const maCodeText = document.createElement("div");
maCodeText.innerHTML = "设备编码:"+element.maCode;
maCodeText.style = "font-size=18px; width:100%;text-align:center;margin:10px;"
shareContent.appendChild(maCodeText);
new QRCode(captureId[i], {
width: width,
height: height,
text: this.qrUrl+ element.labelCode,
colorDark: "#000",
colorLight: "#fff"
});
let canvas = document.createElement("canvas"),
scale = 1;
canvas.width = width * scale;
canvas.height = height * scale;
canvas.style.width = (shareContent.clientWidth * scale) / 100 + "rem";
canvas.style.height = (shareContent.clientHeight * scale) / 100 + "rem";
canvas.getContext("2d").scale(scale, scale);
let opts = {
scale: scale,
canvas: canvas,
logging: false,
width: width,
height: height,
useCORS: true
};
await html2canvas(shareContent, opts)
.then(function (canvas) {
const qrContentImage = canvas.toDataURL("image/jpeg", 1.0);
if (i <= that.checkboxModel.length - 1) {
that.qrcodeArr.push({
url: qrContentImage,
name: element.labelCode
});
}
})
.catch(function (reason) {
console.log(reason);
that.getList();
that.$modal.closeLoading();
});
}
await new Promise(resolve => setTimeout(resolve, 1000));
that.packageImages();
setTimeout(msg, 1000);
that.$modal.closeLoading();
} catch (error) {
setTimeout(msg, 1000);
that.getList();
that.$modal.closeLoading();
}
},
//打包压缩
packageImages() {
let that = this;
const zip = new JSZip();
const cache = {};
let arr = that.qrcodeArr;
arr.forEach((item, index) => {
let fileName = item.name;
zip.file(fileName + ".png", item.url.substring(22), { base64: true });
cache[fileName] = item.url;
});
zip.generateAsync({ type: "blob" }).then(content => {
FileSaver.saveAs(content, "二维码.zip");
});
that.getList();
that.qrcodeArr = [];
},
//二维码查看
labelUploadCode(row) {
// if (row.maCode == null) {
// this.$message.error('当前设备没有设备编码');
// return
// }
this.labelCodeName = ''
this.rowObj = row
this.uploadOpen = true;
this.title = "二维码查看";
this.labelmaCode = row.labelCode
let str = this.qrUrl+row.labelCode
this.$nextTick(() => {
// this.selectionList.forEach((item, index) => {
this.$refs.codeItem.innerHTML = "";
var qrcode = new QRCode(this.$refs.codeItem, {
text: str, //二维码内容
width: 256,
height: 256,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H,
})
// });
}, 500)
},
downloadCode(e) {
if (document.getElementById('qrcode').childNodes[0]) {
let element = this.$refs.codeBox;
html2canvas(element).then((canvas) => {
// 将canvas转换为图片URL
const image = canvas.toDataURL('image/png');
const alink = document.createElement('a')
alink.href = image
alink.download = this.labelmaCode
alink.click()
});
}
},
CanvasToImage(canvas) {
// 新Image对象可以理解为DOM
var image = new Image()
// canvas.toDataURL 返回的是一串Base64编码的URL当然,浏览器自己肯定支持
// 指定格式PNG
image.src = canvas.toDataURL('image/png')
return image
},
// 分享二维码弹窗
popQrcode() {
this.qrcodeDialogVisible = true
const colorFore = '#4169E1'
const colorOut = '#CD5C5C'
const colorIn = '#191970'
this.qrcode = ''
this.$nextTick(() => {
this.qrcode = qrcanvas({
cellSize: 8,
data: location.href,
effect: { round: 0.4 },
correctLevel: 'M',
foreground: [
// 前景色
{ style: colorFore },
// 外方块位置
{ row: 0, rows: 7, col: 0, cols: 7, style: colorOut },
{ row: -7, rows: 7, col: 0, cols: 7, style: colorOut },
{ row: 0, rows: 7, col: -7, cols: 7, style: colorOut },
// 内方块位置
{ row: 2, rows: 3, col: 2, cols: 3, style: colorIn },
{ row: -5, rows: 3, col: 2, cols: 3, style: colorIn },
{ row: 2, rows: 3, col: -5, cols: 3, style: colorIn }
],
background: '#f5f5f5',
padding: 12
})
// 判断是否有子节点,如果已经有则删除原有的,然后再新增子节点
if (document.getElementById('qrcode').childNodes[0]) {
this.$refs.qrcode.removeChild(document.getElementById('qrcode').childNodes[0])
}
this.$refs.qrcode.appendChild(this.qrcode)
})
},
// downloadCode() { },
// 多选框选中数据
handleSelectionChange(selection) {
console.log('thhis,', selection);
this.selectionList = selection
this.checkboxModel = selection
this.checkboxModel.forEach(item=>{
item.exportUrl = this.qrUrl+item.labelCode;
})
this.ids = selection.map(item => item)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 导出按钮操作 */
handleExport() {
this.download('system/dict/type/export', {
...this.queryParams
}, `type_${new Date().getTime()}.xlsx`)
},
/** 刷新缓存按钮操作 */
handleRefreshCache() {
refreshCache().then(() => {
this.$modal.msgSuccess("刷新成功");
this.$store.dispatch('dict/cleanDict');
});
}
}
};
</script>
<style lang="scss" scoped>
// .qrcode{
// height: 300px;
// width: 300px;
// }
.uploadImg {
padding-top: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.maCode {
margin-top: 10px;
padding-bottom: 20px;
font-size: 18px;
}
::v-deep.el-table .fixed-width .el-button--mini {
width: 60px !important;
margin-bottom: 10px;
}
</style>