flx:提交orc

This commit is contained in:
Rain_ 2025-07-24 18:32:02 +08:00
parent c05680fd5b
commit 199a50c6a2
12 changed files with 3064 additions and 16 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

View File

@ -0,0 +1,84 @@
#myCanvas {
width: 100%;
height: 100%;
background: #f6f6f6;
}
#sketchpad-upload {
display: none;
}
.tool-box {
position: absolute;
z-index: 10;
background: #d0d0d0;
display: flex;
justify-content: space-between;
}
.tool-box.tool-box--left {
top: 0;
left: 0;
width: 50px;
height: 100%;
flex-direction: column;
}
.tool-box.tool-box--top {
top: 0;
left: 0;
width: 100%;
height: 50px;
flex-direction: row;
}
.tool-box.tool-box--right {
top: 0;
right: 0;
width: 50px;
height: 100%;
flex-direction: column;
}
.tool-box.tool-box--bottom {
bottom: 0;
left: 0;
width: 100%;
height: 50px;
flex-direction: row;
}
.tool-box .tool-con {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
}
.tool-box .tool-con.active {
background: #333;
color: #fff;
}
.tool-box .tool-con label {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
}
.board-box {
width: 100%;
height: 100%;
position: relative;
}
.board-box .btn {
width: 80px;
height: 30px;
background: #f0f0f0;
margin: 0 5px;
}

View File

@ -0,0 +1 @@
#myCanvas{width:100%;height:100%;background:#f6f6f6}#sketchpad-upload{display:none}.tool-box{position:absolute;z-index:10;background:#d0d0d0;display:flex;justify-content:space-between}.tool-box.tool-box--left{top:0;left:0;width:50px;height:100%;flex-direction:column}.tool-box.tool-box--top{top:0;left:0;width:100%;height:50px;flex-direction:row}.tool-box.tool-box--right{top:0;right:0;width:50px;height:100%;flex-direction:column}.tool-box.tool-box--bottom{bottom:0;left:0;width:100%;height:50px;flex-direction:row}.tool-box .tool-con{width:50px;height:50px;display:flex;justify-content:center;align-items:center;font-size:30px}.tool-box .tool-con.active{background:#333;color:#fff}.tool-box .tool-con label{width:50px;height:50px;display:flex;justify-content:center;align-items:center}.board-box{width:100%;height:100%;position:relative}.board-box .btn{width:80px;height:30px;background:#f0f0f0;margin:0 5px}

View File

@ -0,0 +1,77 @@
@import "~@/assets/font/iconfont.css";
#myCanvas {
width: 100%;
height: 100%;
background: #f6f6f6;
}
#sketchpad-upload {
display: none;
}
.tool-box {
position: absolute;
z-index: 10;
background: #d0d0d0;
display: flex;
justify-content: space-between;
&.tool-box--left {
top: 0;
left: 0;
width: 50px;
height: 100%;
flex-direction: column;
}
&.tool-box--top {
top: 0;
left: 0;
width: 100%;
height: 50px;
flex-direction: row;
}
&.tool-box--right {
top: 0;
right: 0;
width: 50px;
height: 100%;
flex-direction: column;
}
&.tool-box--bottom {
bottom: 0;
left: 0;
width: 100%;
height: 50px;
flex-direction: row;
}
.tool-con {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
font-size: 30px;
&.active {
background: #333;
color: #fff;
}
label {
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
}
}
}
.board-box {
width: 100%;
height: 100%;
position: relative;
.btn {
width: 80px;
height: 30px;
background: #f0f0f0;
margin: 0 5px;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,615 @@
<template>
<div
class="board-box"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
>
<!-- 上传图片 -->
<input
type="file"
accept="image/*"
id="sketchpad-upload"
ref="sketchpadUpload"
@change="uploadImg($event)"
/>
<!-- 工具列表 -->
<ul
class="tool-box"
:class="{
'tool-box--left': placement === 'left',
'tool-box--top': placement === 'top',
'tool-box--right': placement === 'right',
'tool-box--bottom': placement === 'bottom',
}"
>
<li class="tool-con">
<el-color-picker
v-model="strokeColor"
:predefine="predefineColors"
size="mini"
show-alpha
>
</el-color-picker>
</li>
<li
v-for="item in tools"
:key="item.type"
class="tool-con"
:class="{ active: toolType === item.type }"
@click="changeTool(item.type)"
>
<label for="sketchpad-upload" v-if="item.type === 'upload'">
<i class="iconfont" :class="item.icon"></i>
</label>
<i class="iconfont" v-else :class="item.icon"></i>
</li>
</ul>
<!-- 画布 -->
<canvas id="myCanvas" ref="myCanvas"></canvas>
</div>
</template>
<script>
import { fabric } from "fabric";
// import FileSaver from 'file-saver'
import "./index.scss";
console.log("fabric", fabric);
let defaultProps = {
canvasWidth: {
type: Number,
default: window.innerWidth,
},
canvasHeight: {
type: Number,
default: window.innerHeight,
},
canvasBgColor: {
type: String,
default: "#f6f6f6",
},
strokeColor: {
type: String,
default: "#f30",
},
strokeWidth: {
type: Number,
default: 2,
},
showTools: {
type: Boolean,
default: true,
},
placement: {
type: String,
default: "left",
},
};
console.log("defaultProps", defaultProps);
const TOOLS = [
{
name: "铅笔",
type: "pencil",
icon: "icon-pan_icon",
},
{
name: "实线",
type: "line",
icon: "icon-xian",
},
{
name: "虚线",
type: "dashedLine",
icon: "icon-xian1",
},
{
name: "箭头",
type: "arrow",
icon: "icon-jiantou",
},
{
name: "文字",
type: "text",
icon: "icon-wenzi",
},
{
name: "矩形",
type: "rect",
icon: "icon-juxing",
},
{
name: "圆形",
type: "cricle",
icon: "icon-yuanxing",
},
{
name: "椭圆形",
type: "ellipse",
icon: "icon-tuoyuanxing",
},
{
name: "三角形",
type: "equilateral",
icon: "icon-sanjiaoxing",
},
{
name: "上传图片",
type: "upload",
icon: "icon-seiyw41",
},
{
name: "橡皮",
type: "rubber",
icon: "icon-xiangpi",
},
{
name: "回退",
type: "undo",
icon: "icon-undo",
},
{
name: "向前",
type: "redo",
icon: "icon-redo",
},
// {
// name: '',
// type: 'clear',
// icon: 'icon-clear'
// },
{
name: "移动",
type: "move",
icon: "icon-yidong",
},
// {
// name: '',
// type: 'download',
// icon: 'icon-xiazai'
// }
];
export default {
name: "vue-fabric-sketchpad",
data() {
return {
boardObj: null, //
mouseFrom: {}, //
mouseTo: {}, //
toolType: "pencil", //
isDrawing: false, //
drawingObj: null, //
history: [], //
textObj: null, //
stage: 0,
currImg: "",
tools: TOOLS,
predefineColors: [
"#ff4500",
"#ff8c00",
"#ffd700",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgba(255, 69, 0, 0.68)",
"rgb(255, 120, 0)",
"hsv(51, 100, 98)",
"hsva(120, 40, 94, 0.5)",
"hsl(181, 100%, 37%)",
"hsla(209, 100%, 56%, 0.73)",
"#c7158577",
],
};
},
props: defaultProps,
mounted() {
this.boardObj = new fabric.Canvas("myCanvas", {
isDrawingMode: true, //
selectable: true, //
selection: true, //
devicePixelRatio: true,
backgroundVpt: false,
});
this.boardObj.freeDrawingBrush.color = this.strokeColor; //
this.boardObj.freeDrawingBrush.width = this.strokeWidth; //
this.boardObj.setWidth(this.canvasWidth);
this.boardObj.setHeight(this.canvasHeight);
this.initEvent();
},
methods: {
initEvent() {
this.boardObj.on({
"mouse:down": (e) => {
console.log("down", e);
let { x, y } = e.pointer;
this.mouseFrom = { x, y };
//
if (!this.boardObj.getActiveObject()) {
this.isDrawing = true;
}
if (this.toolType === "text") {
this.drawText();
}
},
"mouse:up": (e) => {
console.log("up", e);
let { x, y } = e.pointer;
this.mouseTo = { x, y };
this.isDrawing = false;
this.drawingObj = null;
this.addHistory();
},
"mouse:move": (e) => {
if (this.isDrawing) {
console.log("move", e);
let { x, y } = e.pointer;
this.mouseTo = { x, y };
this.drawing();
}
},
//
"object:moving": (e) => {
console.log("移动", e);
},
//
"object:scaling": (e) => {
console.log("放大缩小", e);
},
//
"object:rotating": (e) => {
console.log("旋转", e);
},
"selection:created": (e) => {
console.log("选中了");
if (this.toolType === "rubber") {
console.log(e.target);
if (e.target._objects) {
//
var etCount = e.target._objects.length;
for (var i = 0; i < etCount; i++) {
this.boardObj.remove(e.target._objects[i]);
}
} else {
//
this.boardObj.remove(e.target);
}
this.boardObj.discardActiveObject(); //
}
this.addHistory();
},
});
},
drawing() {
//
if (this.drawingObj) {
this.boardObj.remove(this.drawingObj);
}
this.boardObj.isDrawingMode = false;
this.boardObj.selectable = false;
this.boardObj.selection = false;
let drawObj = null;
switch (this.toolType) {
case "pencil":
this.boardObj.isDrawingMode = true;
break;
case "line":
drawObj = this.drawLine();
break;
case "dashedLine":
drawObj = this.drawDashedLine();
break;
case "arrow":
drawObj = this.drawArrow();
break;
case "rect":
drawObj = this.drawRect();
break;
case "cricle":
drawObj = this.drawCricle();
break;
case "ellipse":
drawObj = this.drawEllipse();
break;
case "equilateral":
drawObj = this.drawEquilateral();
break;
default:
drawObj = null;
this.boardObj.selection = true;
this.boardObj.skipTargetFind = false;
this.boardObj.selectable = true;
break;
}
if (drawObj) {
console.log(drawObj);
this.boardObj.add(drawObj);
this.drawingObj = drawObj;
}
},
//
changeTool(type) {
this.boardObj.isDrawingMode = false;
this.resetDrawObj();
//
if (this.boardObj.getActiveObject()) {
this.boardObj.discardActiveObject();
this.boardObj.renderAll();
}
if (type === "clear") {
return this.boardObj.clear();
}
if (type === "upload") {
return;
}
if (type === "undo") {
return this.undo();
}
if (type === "redo") {
return this.redo();
}
if (type === "download") {
return this.composeImg();
}
this.toolType = type;
if (type === "pencil") {
this.boardObj.isDrawingMode = true;
}
if (type === "rubber" || type === "move") {
this.boardObj.selection = true;
this.boardObj.skipTargetFind = false;
this.boardObj.selectable = true;
}
},
resetDrawObj() {
this.boardObj.selectable = true;
this.boardObj.selection = true;
this.boardObj.skipTargetFind = false;
if (this.textObj) {
this.textObj.exitEditing();
this.textObj = null;
}
},
// 线
drawLine() {
return new fabric.Line(
[this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y],
{
stroke: this.strokeColor,
strokeWidth: this.strokeWidth,
}
);
},
// 线
drawDashedLine() {
return new fabric.Line(
[this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y],
{
stroke: this.strokeColor,
strokeWidth: this.strokeWidth,
strokeDashArray: [10, 3],
}
);
},
//
drawRect() {
return new fabric.Rect({
left: this.mouseFrom.x,
top: this.mouseFrom.y,
height: Math.abs(this.mouseTo.y - this.mouseFrom.y),
width: Math.abs(this.mouseTo.x - this.mouseFrom.x),
stroke: this.strokeColor,
strokeWidth: this.strokeWidth,
fill: "rgba(255, 255, 255, 0)",
});
},
//
drawCricle() {
// a^2 + b^2 = c^2
let a = this.mouseTo.x - this.mouseFrom.x;
let b = this.mouseTo.y - this.mouseFrom.y;
let r = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)) / 2;
return new fabric.Circle({
left: this.mouseFrom.x,
top: this.mouseFrom.y,
stroke: this.strokeColor,
fill: "rgba(255, 255, 255, 0)",
radius: r,
strokeWidth: this.strokeWidth,
});
},
//
drawEllipse() {
let left = this.mouseFrom.x;
let top = this.mouseFrom.y;
return new fabric.Ellipse({
left: left,
top: top,
stroke: this.strokeColor,
fill: "rgba(255, 255, 255, 0)",
originX: "center",
originY: "center",
rx: Math.abs(left - this.mouseTo.x),
ry: Math.abs(top - this.mouseTo.y),
strokeWidth: this.strokeWidth,
});
},
//
drawEquilateral() {
let height = this.mouseTo.y - this.mouseFrom.y;
return new fabric.Triangle({
top: this.mouseFrom.y,
left: this.mouseFrom.x,
width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2, 2)),
height: height,
stroke: this.strokeColor,
strokeWidth: this.strokeWidth,
fill: "rgba(255,255,255,0)",
});
},
//
drawArrow() {
let [sx, sy] = [this.mouseFrom.x, this.mouseFrom.y];
let [ex, ey] = [this.mouseTo.x, this.mouseTo.y];
let disY = sy - ey;
let disX = sx - ex;
let theta = 30;
let headlen = 30;
var angle = (Math.atan2(disY, disX) * 180) / Math.PI;
var angle1 = ((angle + theta) * Math.PI) / 180;
var angle2 = ((angle - theta) * Math.PI) / 180;
var topX = headlen * Math.cos(angle1);
var topY = headlen * Math.sin(angle1);
var botX = headlen * Math.cos(angle2);
var botY = headlen * Math.sin(angle2);
var arrowX = sx - topX;
var arrowY = sy - topY;
var path = " M " + sx + " " + sy;
path += " L " + ex + " " + ey;
arrowX = ex + topX;
arrowY = ey + topY;
path += " M " + arrowX + " " + arrowY;
path += " L " + ex + " " + ey;
arrowX = ex + botX;
arrowY = ey + botY;
path += " L " + arrowX + " " + arrowY;
return new fabric.Path(path, {
stroke: this.strokeColor,
fill: "rgba(255,255,255,0)",
strokeWidth: this.strokeWidth,
});
},
drawText() {
let { x, y } = this.mouseFrom;
this.textObj = new fabric.Textbox("", {
left: x,
top: y,
width: "",
height: "",
fill: this.strokeColor,
hasControls: true,
});
this.boardObj.add(this.textObj);
this.textObj.enterEditing();
this.textObj.selectAll();
this.textObj.hiddenTextarea.focus();
this.addHistory();
},
//
addHistory() {
this.history.push(JSON.stringify(this.boardObj));
},
//
undo() {
let stack = this.history;
if (this.stage < stack.length) {
this.boardObj.clear().renderAll();
this.boardObj.loadFromJSON(stack[stack.length - 1 - this.stage - 1]);
this.boardObj.renderAll();
this.stage += 1;
}
},
//
redo() {
let stack = this.history;
if (this.stage > 0) {
this.boardObj.clear().renderAll();
this.boardObj.loadFromJSON(stack[stack.length - 1 - this.stage + 1]);
this.boardObj.renderAll();
this.stage -= 1;
}
},
//
composeImg() {
let base64Img = this.boardObj.toDataURL({
formart: "png",
width: this.boardObj.width,
height: this.boardObj.height,
});
// console.log(this.boardObj.getObjects())
// console.log(this.boardObj)
// console.log("base64Img", base64Img)
return base64Img;
// let bd = base64Img.split(',')
// let mime = bd[0].match(/:(.*?);/)[1]
// let bstr = atob(bd[1]); let l = bstr.length; let u8arr = new Uint8Array(l)
// while (l--) {
// u8arr[l] = bstr.charCodeAt(l)
// }
// let blobData = new Blob([u8arr], { type: mime })
// console.log('blob', blobData)
// FileSaver.saveAs(blobData, 'sketchpad.png')
},
//
getObjects() {
return this.boardObj.getObjects();
},
//
createImage(myImage) {
console.log("myImage", myImage);
// const bgImage = fabric.Image.fromURL(myImage, (img) => {
// img.set({
// // scale
// scaleX: this.boardObj.width / img.width,
// scaleY: this.boardObj.height / img.height,
// })
// this.boardObj.setBackgroundImage(img, this.boardObj.renderAll.bind(this.boardObj), {
// backgroundVpt: true,
// });
// });
let imgObj = new Image();
imgObj.src = myImage;
imgObj.hasControls = false;
let oImg = new fabric.Image(imgObj);
// oImg.scale(0.5)
console.log("oImg", this.boardObj);
this.boardObj.setBackgroundImage(oImg);
this.boardObj.renderAll();
// this.boardObj.setBackgroundImage(oImg, this.boardObj.renderAll.bind(this.boardObj), {
// backgroundVpt: false,
// }).add(oImg).renderAll()
// new fabric.createImage(myImage, {
// isDrawingMode: true,
// width: this.canvasWidth,
// height: this.canvasHeight,
// left: 0,
// top: 0,
// // scaleX: 0.5,
// // scaleY: 0.5,
// // cornerStrokeColor: "#000000",
// })
},
uploadImg(e) {
let imgData = e.target.files[0];
let reader = new FileReader();
reader.onload = (res) => {
let dataUrl = res.target.result;
let imgObj = new Image();
imgObj.src = dataUrl;
imgObj.onload = () => {
console.log("imgObj", imgObj);
var oImg = new fabric.Image(imgObj);
oImg.scale(0.5);
this.boardObj.centerObject(oImg).add(oImg).renderAll();
// onchange
this.$refs.sketchpadUpload.value = "";
};
};
reader.readAsDataURL(imgData);
},
},
watch: {
strokeColor: {
handler(newVal) {
this.boardObj.freeDrawingBrush.color = newVal; //
},
},
},
};
</script>
<style scoped lang="less">
.el-color-picker /deep/ .el-color-picker__trigger {
border: none !important;
}
</style>

View File

@ -0,0 +1,860 @@
<template>
<div class="container_main">
<div class="changeVideoTypeBox whiteBlock">
<div class="ocrType">
<el-button
@click="sendValue"
size="medium"
icon="el-icon-back"
type="primary"
plain
>返回</el-button
>
<p>OCR类型</p>
<p
v-for="item in videoTypeList"
:key="item.id"
@click="beforeCut(item)"
>
<span>{{ item.title }}</span>
<img
v-show="ocrType != item.id"
src="@/assets/images/switch.png"
class="switch"
/>
<img
v-show="ocrType == item.id"
src="@/assets/images/switch_active.png"
class="switch"
/>
</p>
</div>
<div>
<p class="tips">
(以下OCR类型同时只可开启一种如果当前有配置好的OCR环境用户又重新开启其他环境配置时当前配置不可用)
</p>
<el-button @click="dealAdd(1)" size="medium" type="primary"
>环境配置</el-button
>
</div>
</div>
<div class="content-main">
<div class="content-box">
<div class="content-box_header">
<div>识别位置</div>
<el-button @click="dealAdd(2)" size="medium" type="primary"
>新增</el-button
>
</div>
<ul
class="infinite-list"
v-infinite-scroll="ocrModulePlaceLoad"
:infinite-scroll-immediate="true"
:infinite-scroll-distance="20"
:infinite-scroll-delay="500"
style="overflow: auto"
>
<li
v-for="item in ocrModulePlaceList"
:key="item.id"
class="infinite-list-item"
:class="{ 'active-item': item.id == modulePlaceId }"
@click="selectModulePlace(item)"
>
<div>{{ item.placeName }}</div>
<div>
<img
@click="dealAdd(3, item)"
src="@/assets/images/icon-edit.png"
/>
<img
@click="deleteBtn(item, 1)"
src="@/assets/images/icon-delete.png"
/>
</div>
</li>
</ul>
</div>
<div class="content-box ml-20">
<div class="content-box_header">
<div>识别区域设置</div>
<el-button @click="dealAdd(4)" size="medium" type="primary"
>新增</el-button
>
</div>
<ul
class="infinite-list"
v-infinite-scroll="ocrZonePlaceLoad"
:infinite-scroll-immediate="true"
:infinite-scroll-distance="20"
:infinite-scroll-delay="500"
style="overflow: auto"
>
<li
v-for="item in ocrZonePlaceList"
:key="item.id"
class="infinite-list-item"
:class="{ 'active-item': item.id == zonePlaceInfo.id }"
@click="selectZonePlace(item)"
>
<div>{{ item.zoneName }}</div>
<div>
<img
@click="dealAdd(5, item)"
src="@/assets/images/icon-edit.png"
/>
<img
@click="deleteBtn(item, 2)"
src="@/assets/images/icon-delete.png"
/>
</div>
</li>
</ul>
</div>
<div class="content-box1">
<div class="content-box1-top">
<el-button size="medium" icon="el-icon-circle-close"> </el-button>
<el-button
@click="saveFabric"
type="primary"
size="medium"
icon="el-icon-circle-check"
> </el-button
>
</div>
<MyPictode
class="mypictode"
ref="canvasfabric"
:canvasWidth="width"
:canvasHeight="height"
:configJson="zonePlaceInfo.configJson"
></MyPictode>
</div>
</div>
<!--切换其它平台之前的提示-->
<el-dialog
:modal-append-to-body="false"
:title="$t('message.videoManage.switch_platforms.title')"
:visible.sync="Popup.platforms"
width="667px"
>
<div class="dialog_content">
<div class="platforms-title">确认更换OCR类型为"{{ Popup.name }}"</div>
<div class="platforms-msg">
更换后原有的OCR类型配置及设备信息将全部清零请谨慎更换
</div>
<div class="dialog-footer">
<el-button
class="zdy-btn"
@click="Popup.platforms = false"
size="medium"
>
<div>
<img src="../../../assets/images/cancel.png" alt="" />
<span>{{ $t("message.videoManage.btn_cancel") }}</span>
</div>
</el-button>
<el-button
type="primary"
icon="el-icon-circle-check"
@click="cut"
size="medium"
>{{ $t("message.videoManage.btn_determine") }}
</el-button>
</div>
</div>
</el-dialog>
<!-- 新增 -->
<el-dialog
:visible.sync="dealShow"
width="668px"
append-to-body
:title="dealTitle"
>
<el-form
ref="dealForm"
:model="dealForm"
:rules="dealFormRules"
size="medium"
label-width="210px"
class="dealForm"
>
<template v-if="dealType == 1">
<el-form-item label="ocr类型" prop="ocrType">
<el-select
v-model="dealForm.ocrType"
placeholder="请选择"
filterable
>
<el-option
v-for="(item, index) in videoTypeList"
:key="item.id"
:label="item.title"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="apiKey" prop="apiKey">
<el-input v-model="dealForm.apiKey" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="secretKey" prop="secretKey">
<el-input
v-model="dealForm.secretKey"
placeholder="请输入"
></el-input>
</el-form-item>
</template>
<template v-if="dealType == 2 || dealType == 3">
<el-form-item label="位置名称" prop="placeName">
<el-input
v-model="dealForm.placeName"
placeholder="请输入"
></el-input>
</el-form-item>
<el-form-item label="位置编码" prop="placeCode">
<el-input
v-model="dealForm.placeCode"
placeholder="请输入"
></el-input>
</el-form-item>
<!-- <el-form-item label="关联模块" prop="moduleId">
<el-select
v-model="dealForm.moduleId"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="(item, index) in videoTypeList"
:key="item.id"
:label="item.title"
:value="item.id"
></el-option>
</el-select>
</el-form-item> -->
</template>
<template v-if="dealType == 4 || dealType == 5">
<el-form-item label="区域名称" prop="zoneName">
<el-input
v-model="dealForm.zoneName"
placeholder="请输入"
></el-input>
</el-form-item>
<el-form-item label="区域编码" prop="zoneCode">
<el-input
v-model="dealForm.zoneCode"
placeholder="请输入"
></el-input>
</el-form-item>
<!-- <el-form-item label="关联模块" prop="moduleId">
<el-select
v-model="dealForm.moduleId"
placeholder="请选择"
clearable
filterable
>
<el-option
v-for="(item, index) in videoTypeList"
:key="item.id"
:label="item.title"
:value="item.id"
></el-option>
</el-select>
</el-form-item> -->
</template>
</el-form>
<div slot="footer" style="text-align: center">
<el-button type="primary" @click="submitDealForm">确认</el-button>
<el-button @click="dealFormCancel">取消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
enableConfigOcrConfigApi,
getEnableConfigOcrConfigApi,
editOcrConfigApi,
getOcrModulePlacePageApi,
addOcrModulePlaceApi,
editOcrModulePlaceApi,
deleteOcrModulePlaceApi,
saveConfigOcrConfigApi,
getOcrZonePlacePageApi,
addOcrZonePlaceApi,
editOcrZonePlaceApi,
deleteOcrZonePlaceApi,
} from "@/assets/js/api/equipmentCenter/cameraList";
// import MyFabric from "./components/myfabric.vue";
import MyPictode from "./components/myPictode.vue";
import { isJSON } from '@/util/nowDate';
export default {
components: {
// MyFabric,
MyPictode,
},
name: "ocrRecognitionArea",
data() {
return {
width: 0,
height: 0,
projectSn: "",
videoTypeList: [
{
id: 1,
title: "百度智能云",
},
],
ocrType: 1, //1?
Popup: {
platforms: false,
name: "",
ocrType: "",
},
count: 10,
dealType: 2,
dealShow: false,
dealTitle: "",
enableConfig: {},
dealForm: {
hardwareId: "",
alarmType: "",
location: "",
createTime: "",
},
dealFormRules: {
ocrType: [
{
required: true,
message: "请选择ocr类型",
trigger: "change",
},
],
apiKey: [
{
required: true,
message: "请输入apiKey",
trigger: "blur",
},
],
secretKey: [
{
required: true,
message: "请输入secretKey",
trigger: "blur",
},
],
placeCode: [
{
required: true,
message: "请输入位置编码",
trigger: "blur",
},
],
placeName: [
{
required: true,
message: "请输入位置名称",
trigger: "blur",
},
],
zoneName: [
{
required: true,
message: "请输入区域编码",
trigger: "blur",
},
],
zoneCode: [
{
required: true,
message: "请输入区域位置",
trigger: "blur",
},
],
},
ocrModulePlaceInfo: {
pageNo: 1,
pageSize: 20,
total: 0,
},
ocrModulePlaceList: [],
ocrZonePlaceInfo: {
pageNo: 1,
pageSize: 20,
total: 0,
},
ocrZonePlaceList: [],
modulePlaceId: "",
zonePlaceInfo: {
id: "",
configJson: "",
},
};
},
created() {
this.projectSn = this.$store.state.userInfo.sn;
this.getOcrModulePlacePage();
this.getEnableConfigOcrConfig();
},
mounted() {},
methods: {
saveFabric() {
const boardObjRef = this.$refs.canvasfabric.boardObjRef();
// JSON
const configJson = boardObjRef.toJSON();
// JSON 便
console.log('画布内容转换后的 JSON 数据:', configJson);
let params = {
...this.zonePlaceInfo,
configJson: JSON.stringify(configJson),
};
editOcrZonePlaceApi(params).then((result) => {
if (result.success) {
this.$message.success(result.message);
this.refreshOcrZonePlace();
}
});
},
selectZonePlace(row) {
this.zonePlaceInfo = {
...row,
};
},
ocrZonePlaceLoad() {
if (this.ocrZonePlaceInfo.pageNo > 0 && this.ocrZonePlaceInfo.total == 0)
return;
if (
this.ocrZonePlaceInfo.pageNo * this.ocrZonePlaceInfo.pageSize >
this.ocrZonePlaceInfo.total
)
return; // this.$message.warning("");
this.ocrZonePlaceInfo.pageNo += 1;
this.getOcrZonePlacePage();
},
getOcrZonePlacePage() {
getOcrZonePlacePageApi({
projectSn: this.$store.state.projectSn,
pageNo: this.ocrZonePlaceInfo.pageNo,
pageSize: this.ocrZonePlaceInfo.pageSize,
modulePlaceId: this.modulePlaceId,
}).then((res) => {
if (res.code == 200) {
this.ocrZonePlaceList = res.result.records;
this.ocrZonePlaceInfo.total = res.result.total;
if (!this.zonePlaceInfo.id && this.ocrZonePlaceList.length > 0) {
this.selectZonePlace(this.ocrZonePlaceList[0])
}
}
});
},
selectModulePlace(row) {
this.modulePlaceId = row.id;
this.refreshOcrZonePlace();
},
ocrModulePlaceLoad() {
if (
this.ocrModulePlaceInfo.pageNo > 0 &&
this.ocrModulePlaceInfo.total == 0
)
return;
if (
this.ocrModulePlaceInfo.pageNo * this.ocrModulePlaceInfo.pageSize >
this.ocrModulePlaceInfo.total
)
return; // this.$message.warning("");
this.ocrModulePlaceInfo.pageNo += 1;
this.getOcrModulePlacePage();
},
getOcrModulePlacePage() {
getOcrModulePlacePageApi({
projectSn: this.$store.state.projectSn,
pageNo: this.ocrModulePlaceInfo.pageNo,
pageSize: this.ocrModulePlaceInfo.pageSize,
}).then((res) => {
if (res.code == 200) {
this.ocrModulePlaceList = res.result.records;
this.ocrModulePlaceInfo.total = res.result.total;
if (!this.modulePlaceId && this.ocrModulePlaceList.length > 0) {
this.modulePlaceId = this.ocrModulePlaceList[0].id;
this.getOcrZonePlacePage();
}
}
});
},
//
dealAdd(type, row) {
this.dealType = type;
if (type == 1) {
this.dealTitle = "环境配置";
if (this.enableConfig && this.enableConfig.ocrType) {
this.dealForm = {
...this.enableConfig,
};
} else {
this.initDealForm();
}
} else if (type == 2) {
this.dealTitle = "新增识别位置";
this.initDealForm();
} else if (type == 3) {
this.dealTitle = "编辑识别位置";
this.dealForm = {
...row,
};
} else if (type == 4) {
this.dealTitle = "新增识别区域设置";
this.initDealForm();
} else if (type == 5) {
this.dealTitle = "编辑识别区域设置";
this.dealForm = {
...row,
};
}
this.$nextTick(() => {
this.$refs["dealForm"].clearValidate();
});
this.dealShow = true;
},
initDealForm() {
if (this.dealType == 1) {
this.dealForm = {
ocrType: "",
apiKey: "",
secretKey: "",
};
} else if (this.dealType == 2) {
this.dealForm = {
placeName: "",
placeCode: "",
moduleId: "",
configId: this.enableConfig.id,
};
} else if (this.dealType == 4) {
this.dealForm = {
zoneName: "",
zoneCode: "",
configJson: "",
modulePlaceId: this.modulePlaceId,
};
}
},
submitDealForm() {
this.$refs["dealForm"].validate((valid) => {
if (valid) {
if (this.dealType == 1) {
saveConfigOcrConfigApi({
...this.dealForm,
headquartersSn: this.$store.state.userInfo.sn,
}).then((res) => {
if (res.code == 200) {
this.$message.success("修改成功");
this.dealShow = false;
this.ocrType = res.result.ocrType;
this.enableConfig = res.result;
this.saveVideoConfigFn();
}
});
} else if (this.dealType == 2) {
let params = {
...this.dealForm,
projectSn: this.projectSn,
};
addOcrModulePlaceApi(params).then((result) => {
if (result.success) {
this.$message.success(result.message);
this.refreshOcrModulePlace();
this.dealShow = false;
}
});
} else if (this.dealType == 3) {
let params = {
...this.dealForm,
projectSn: this.projectSn,
};
editOcrModulePlaceApi(params).then((result) => {
if (result.success) {
this.$message.success(result.message);
this.refreshOcrModulePlace();
this.dealShow = false;
}
});
} else if (this.dealType == 4) {
let params = {
...this.dealForm,
projectSn: this.projectSn,
};
addOcrZonePlaceApi(params).then((result) => {
if (result.success) {
this.$message.success(result.message);
this.refreshOcrZonePlace();
this.dealShow = false;
}
});
} else if (this.dealType == 5) {
let params = {
...this.dealForm,
projectSn: this.projectSn,
};
editOcrZonePlaceApi(params).then((result) => {
if (result.success) {
this.$message.success(result.message);
this.refreshOcrZonePlace();
this.dealShow = false;
}
});
}
}
});
},
dealFormCancel() {
this.initDealForm();
this.$refs["dealForm"].clearValidate();
this.dealShow = false;
},
//
refreshOcrModulePlace() {
this.ocrModulePlaceInfo.pageNo = 1;
this.getOcrModulePlacePage();
},
//
refreshOcrZonePlace() {
this.ocrZonePlaceInfo.pageNo = 1;
this.getOcrZonePlacePage();
},
deleteBtn(val, type) {
this.$confirm("确认删除吗?, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
const obj = {
1: deleteOcrModulePlaceApi,
2: deleteOcrZonePlaceApi,
};
obj[type]({ id: val.id }).then((res) => {
if (res.code == 200) {
this.$message({
type: "success",
message: "删除成功!",
});
if (type == 1) {
this.modulePlaceId = "";
this.refreshOcrModulePlace();
} else if (type == 2) {
this.refreshOcrZonePlace();
}
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
beforeCut(item) {
if (item.id !== this.ocrType) {
this.Popup.platforms = true;
this.Popup.name = item.title;
this.Popup.ocrType = item.id;
}
},
cut() {
this.ocrType = this.Popup.ocrType;
this.Popup.platforms = false;
console.log("当前videoType", this.ocrType);
this.saveVideoConfigFn();
},
saveVideoConfigFn() {
enableConfigOcrConfigApi({
headquartersSn: this.$store.state.userInfo.sn,
ocrType: this.ocrType,
}).then((res) => {
if (res.code) {
this.configDialog = false;
this.getEnableConfigOcrConfig();
}
});
},
//
getEnableConfigOcrConfig() {
getEnableConfigOcrConfigApi({
headquartersSn: this.$store.state.userInfo.sn,
}).then((res) => {
if (res.code == 200) {
this.ocrType = res.result && res.result.ocrType;
this.enableConfig = res.result;
}
});
},
sendValue() {
this.$emit("updateValue", 0);
},
},
};
</script>
<style lang="less" scoped>
.dealForm {
.el-input,
.el-select {
width: 320px;
}
}
.content-main {
display: flex;
height: calc(100% - 118px - 20px);
margin-top: 20px;
.content-box1 {
width: 1188px;
margin-left: 20px;
background: #000000;
position: relative;
.content-box1-top {
position: absolute;
top: 20px;
right: 20px;
}
}
.ml-20 {
margin-left: 20px;
}
.content-box {
width: calc(326px - 26px);
height: calc(100% - 40px);
padding: 20px 13px;
background-color: white;
.infinite-list {
margin-top: 20px;
padding: 15px 0;
height: calc(100% - 30px - 20px - 34px);
background: #f7f7f7;
.infinite-list-item:hover {
background: rgba(81, 129, 246, 0.2);
color: #5181f6;
}
.infinite-list-item {
padding: 0 15px 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
color: #4d4d4d;
> div:last-child {
display: flex;
> img:not(:first-child) {
margin-left: 16px;
}
> img {
width: 15px;
height: 15px;
}
}
> div:first-child {
font-size: 14px;
}
}
.active-item {
background: rgba(81, 129, 246, 0.2);
color: #5181f6;
}
}
.content-box_header {
display: flex;
justify-content: space-between;
> div:first-child {
font-size: 16px;
color: #272d45;
position: relative;
padding-left: 20px;
height: 20px;
}
> div:first-child::before {
content: "";
position: absolute;
left: 7px;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 15px;
background: #4181fe;
}
}
}
}
.zdy-btn {
div {
display: flex;
align-items: center;
img {
width: 14px;
height: 14px;
margin-right: 6px;
}
}
}
.platforms-title {
color: rgba(42, 46, 63, 1);
font-size: 17px;
}
.platforms-msg {
color: rgba(230, 69, 69, 1);
font-size: 14px;
margin-top: 16px;
}
.changeVideoTypeBox {
padding: 20px;
> div:last-child {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
> p {
font-size: 12px;
color: #b2b8c2;
}
}
.ocrType {
// margin-top: 5px;
font-size: 14px;
color: #1d1d1d;
display: flex;
align-items: center;
.el-button {
margin-right: 1rem /* 16/16 */;
}
> p > img {
cursor: pointer;
}
p {
display: flex;
align-items: center;
margin-right: 50px;
.switch {
margin-left: 15px;
// width: 65px;
// height: 32px;
}
}
}
}
.container_main {
width: calc(100%);
height: calc(100%);
// padding: 15px;
overflow-y: auto;
overflow-x: hidden;
.el-form-item {
margin-bottom: 10px;
}
}
</style>

View File

@ -1,27 +1,45 @@
<template>
<div class="fullHeight">
<div class="rightPanel whiteBlock" v-if="!safetyRiskDetailShow">
<div class="sidebar_btn">
<p class="pageTitle">风险管控设置</p>
<div class="rightPanel whiteBlock" v-if="safetyRiskDetailShow == 0">
<div>
<div class="sidebar_btn">
<p class="pageTitle">风险管控设置</p>
</div>
<div class="tables-box">
<div class="table_box" @click="onDetail(1)">
<div>安全风险评估计算</div>
<i class="el-icon-arrow-right"></i>
</div>
</div>
</div>
<div class="tables">
<div class="table_box" @click="onDetail">
<div>安全风险评估计算</div>
<i class="el-icon-arrow-right"></i>
</div>
<div>
<div class="sidebar_btn">
<p class="pageTitle">施工日志设置</p>
</div>
<div class="tables-box">
<div class="table_box" @click="onDetail(2)">
<div>OCR识别区域模版</div>
<i class="el-icon-arrow-right"></i>
</div>
</div>
</div>
</div>
<div class="whiteBlock fullHeight" v-else>
<div class="whiteBlock fullHeight" v-else-if="safetyRiskDetailShow == 1">
<SafetyRiskListSetDetail @updateValue="handleValue"></SafetyRiskListSetDetail>
</div>
<div class="fullHeight" v-else-if="safetyRiskDetailShow == 2">
<OcrRecognitionArea @updateValue="handleValue"></OcrRecognitionArea>
</div>
</div>
</template>
<script>
import { getDictionaryItemApi } from "@/assets/js/api/companyDiagram";
import SafetyRiskListSetDetail from '@/views/companyAdmin/qualityAndSafety/safetyRiskListSetDetail.vue'
import OcrRecognitionArea from '@/views/companyAdmin/qualityAndSafety/ocrRecognitionArea.vue'
export default {
components: {
SafetyRiskListSetDetail,
OcrRecognitionArea,
},
data() {
return {
@ -47,7 +65,7 @@ export default {
riskDialogFormRules: {
nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
},
safetyRiskDetailShow: false,
safetyRiskDetailShow: 2,
};
},
created() {
@ -59,8 +77,8 @@ export default {
handleValue(val) {
this.safetyRiskDetailShow = val;
},
onDetail() {
this.safetyRiskDetailShow = true;
onDetail(type) {
this.safetyRiskDetailShow = type;
},
//
getDicProjectTypeList() {
@ -87,7 +105,7 @@ export default {
};
</script>
<style lang="less" scoped>
.tables {
.tables-box {
.table_box:nth-child(odd) {
background-color: #f5f7fa;
}
@ -127,6 +145,7 @@ export default {
align-items: center;
padding-bottom: 8px;
padding-left: 15px;
padding-top: 20px;
.el-button + .el-button {
margin-left: 8px;
}
@ -310,8 +329,8 @@ export default {
.rightPanel {
float: left;
width: calc(100%);
padding: 20px 0;
height: calc(100% - 40px);
padding: 0 0 20px;
height: calc(100% - 20px);
.tabs-content {
height: calc(100% - 95px);
/deep/.el-tabs__content {

View File

@ -1047,7 +1047,7 @@ export default {
},
sendValue() {
// this.safetyRiskDetailShow = true;
this.$emit('updateValue', false);
this.$emit('updateValue', 0);
},
//
getDicProjectTypeList() {