This commit is contained in:
njdaoyehu 2025-01-08 11:28:29 +08:00
parent fd409ddc08
commit 10d52b2e3c
11 changed files with 636 additions and 281 deletions

View File

@ -85,6 +85,7 @@
"mockjs": "^1.1.0",
"nprogress": "^0.2.0",
"path-to-regexp": "^6.2.1",
"pdfjs-dist": "^4.10.38",
"pinia": "2.1.4",
"qrcode": "^1.5.3",
"qs": "^6.11.2",

View File

@ -19,50 +19,50 @@
margin: 10px 20px 2px 10px;
}
:deep(.ant-form-item-label > label.ant-form-item-no-colon) {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: white;
}
//:deep(.ant-form-item-label > label.ant-form-item-no-colon) {
// font-family: "Noto Sans SC", serif;
// font-size: 14px;
// color: white;
//}
//
//:deep(.vben-basic-table-form-container label) {
// color: transparent !important;
// width: 10px !important;
//}
:deep(.vben-basic-table-form-container label) {
color: transparent !important;
width: 10px !important;
}
:deep(.ant-input-affix-wrapper) {
border-radius: 6px;
background-color: rgba(45,119,243,0.2);
border: 1px solid rgba(45,119,243,0.3);
}
:deep(.ant-input-affix-wrapper >input.ant-input) {
height: 26px;
}
:deep(.ant-input-affix-wrapper:hover),
:deep(.ant-input-affix-wrapper:focus) {
background-color: rgba(45,119,243,0.3);
border: 1px solid rgba(45,119,243,0.4);
}
:deep(.ant-input-affix-wrapper > textarea) {
padding: 4px 11px;
border: 1px solid rgba(45,119,243,0.3);
}
:deep(.ant-input) {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background: transparent;
}
:deep(.ant-input::placeholder) {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #AAAAAA;
}
//:deep(.ant-input-affix-wrapper) {
// border-radius: 6px;
// background-color: rgba(45,119,243,0.2);
// border: 1px solid rgba(45,119,243,0.3);
//}
//
//:deep(.ant-input-affix-wrapper >input.ant-input) {
// height: 26px;
//}
//
//:deep(.ant-input-affix-wrapper:hover),
//:deep(.ant-input-affix-wrapper:focus) {
// background-color: rgba(45,119,243,0.3);
// border: 1px solid rgba(45,119,243,0.4);
//}
//
//:deep(.ant-input-affix-wrapper > textarea) {
// padding: 4px 11px;
// border: 1px solid rgba(45,119,243,0.3);
//}
//
//:deep(.ant-input) {
// font-family: "Noto Sans SC", serif;
// font-size: 14px;
// color: #FFFFFF;
// background: transparent;
//}
//
//:deep(.ant-input::placeholder) {
// font-family: "Noto Sans SC", serif;
// font-size: 14px;
// color: #AAAAAA;
//}
//:deep(.ant-btn-default) {
// font-family: "Noto Sans SC", serif;
@ -114,95 +114,95 @@
// border: none;
//}
:deep(.vben-basic-table) {
background: transparent;
}
//:deep(.vben-basic-table) {
// background: transparent;
//}
//
:deep(.ant-table-wrapper) {
background: transparent;
}
//
//:deep(.vben-basic-table .ant-table-wrapper) {
// background-color: transparent !important;
// padding: 0;
//}
:deep(.vben-basic-table .ant-table-wrapper) {
background-color: transparent !important;
padding: 0;
}
//:deep(.ant-spin-container) {
// margin: 0 5px;
//}
:deep(.ant-spin-container) {
margin: 0 5px;
}
//:deep(.ant-table.ant-table-middle) {
// border-radius: 0;
// background-color: transparent !important;
//}
:deep(.ant-table.ant-table-middle) {
border-radius: 0;
background-color: transparent !important;
}
//:deep(.vben-basic-table .ant-table-wrapper .ant-table.ant-table-bordered .ant-table-title) {
// padding-top: 8px !important;
// border-radius: 8px 8px 0 0;
// border-left: 1px solid #183171 !important;
// border-top: 1px solid #183171 !important;
// border-right: 1px solid #183171 !important;
// background-color: #13265a !important;
//}
:deep(.vben-basic-table .ant-table-wrapper .ant-table.ant-table-bordered .ant-table-title) {
padding-top: 8px !important;
border-radius: 8px 8px 0 0;
border-left: 1px solid #183171 !important;
border-top: 1px solid #183171 !important;
border-right: 1px solid #183171 !important;
background-color: #13265a !important;
}
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container) {
// border-inline-start: 1px solid rgba(45,119,243,0.3) !important;
//}
//
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table) {
// border-top: 1px solid rgba(45,119,243,0.3) !important;
//}
//
//:deep(.ant-table-cell) {
// background-color: #0d1540 !important;
//}
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container) {
border-inline-start: 1px solid rgba(45,119,243,0.3) !important;
}
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >thead>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >thead>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >thead>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >thead>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tbody>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tbody>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tbody>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tbody>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tfoot>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tfoot>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tfoot>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tfoot>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tfoot>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tfoot>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tfoot>tr>td),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tfoot>tr>td) {
// border-inline-end: 1px solid rgba(45,119,243,0.3) !important;
//}
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table) {
border-top: 1px solid rgba(45,119,243,0.3) !important;
}
//:deep(.ant-table-wrapper .ant-table-tbody >tr.ant-table-row:hover>td),
//:deep(.ant-table-wrapper .ant-table-tbody >tr >td.ant-table-cell-row-hover) {
// background: #273c62 !important;
//}
:deep(.ant-table-cell) {
background-color: #0d1540 !important;
}
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >thead>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >thead>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >thead>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >thead>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tbody>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tbody>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tbody>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tbody>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tfoot>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tfoot>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tfoot>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tfoot>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >tfoot>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table >tfoot>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >tfoot>tr>td),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-summary >table >tfoot>tr>td) {
border-inline-end: 1px solid rgba(45,119,243,0.3) !important;
}
:deep(.ant-table-wrapper .ant-table-tbody >tr.ant-table-row:hover>td),
:deep(.ant-table-wrapper .ant-table-tbody >tr >td.ant-table-cell-row-hover) {
background: #273c62 !important;
}
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >thead>tr>th),
:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >thead>tr>th) {
font-family: "Noto Sans SC", serif;
font-size: 14px;
font-weight: normal;
color: #ffffff;
border-bottom: none;
background: #13265a !important;
}
:deep(.ant-table-wrapper .ant-table-cell-ellipsis.ant-table-cell-fix-right-first) {
overflow: hidden !important;
border-left: 1px solid rgba(45,119,243,0.3) !important;
}
:deep(.ant-table-tbody >tr >td) {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #ffffff;
border-bottom: 1px solid rgba(45,119,243,0.3) !important;
}
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >thead>tr>th),
//:deep(.ant-table-wrapper .ant-table.ant-table-bordered >.ant-table-container >.ant-table-body >table >thead>tr>th) {
// font-family: "Noto Sans SC", serif;
// font-size: 14px;
// font-weight: normal;
// color: #ffffff;
// border-bottom: none;
// background: #13265a !important;
//}
//
//:deep(.ant-table-wrapper .ant-table-cell-ellipsis.ant-table-cell-fix-right-first) {
// overflow: hidden !important;
// border-left: 1px solid rgba(45,119,243,0.3) !important;
//}
//
//:deep(.ant-table-tbody >tr >td) {
// font-family: "Noto Sans SC", serif;
// font-size: 14px;
// color: #ffffff;
// border-bottom: 1px solid rgba(45,119,243,0.3) !important;
//}
:deep(.ant-pagination-total-text) {
font-family: "Noto Sans SC", serif;
@ -529,10 +529,10 @@
border-inline-end: 1px solid #183171 !important;
}
:deep(.ant-checkbox-inner) {
border: 1px solid rgba(45, 119, 243, 0.3) !important;
background-color: #13265a !important;
}
//:deep(.ant-checkbox-inner) {
// border: 1px solid rgba(45, 119, 243, 0.3) !important;
// background-color: #13265a !important;
//}
:deep(.CodeMirror) {
border-radius: 6px;

192
src/assets/style.css Normal file
View File

@ -0,0 +1,192 @@
.custom-modal .ant-modal-content {
background-color: #13265a;
}
.ant-modal-header {
background-color: #13265a !important;
}
.vben-basic-title {
font-family: "Noto Sans SC", serif;
font-size: 16px;
color: #ffffff !important;
}
.ant-btn-primary {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: #3793d4;
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-primary:hover {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(69,175,223,0.8);
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(58,98,203,0.8);
box-shadow: inset 0 0 20px 2px #3A62CB;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default:hover {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF !important;
background-color: rgba(58,98,203,0.8);
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default:disabled,
.ant-btn-default:disabled:hover,
.ant-btn-default:disabled svg {
color: #AAAAAA !important;
background-color: rgba(58,98,203,0.8);
box-shadow: inset 0 0 20px 2px #3A62CB;
}
.ant-spin-container {
margin: 0 5px;
}
.ant-spin-container .scroll-container {
padding-top: 10px;
}
.ant-tree-checkbox-inner,
.ant-checkbox-inner {
border: 1px solid rgba(45, 119, 243, 0.3) !important;
background-color: #13265a !important;
}
.ant-form-item-label > label {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF !important;
height: 36px !important;
}
.vben-basic-table-form-container label {
color: transparent !important;
width: 10px !important;
}
.ant-input-affix-wrapper {
border-radius: 6px;
background-color: rgba(45,119,243,0.2);
border: 1px solid rgba(45,119,243,0.3);
}
.ant-input-affix-wrapper >input.ant-input {
height: 26px;
}
.ant-input-affix-wrapper:hover,
.ant-input-affix-wrapper:focus {
background-color: rgba(45,119,243,0.3);
border: 1px solid rgba(45,119,243,0.4);
}
.ant-input-affix-wrapper > textarea {
padding: 4px 11px;
border: 1px solid rgba(45,119,243,0.3);
}
.ant-input {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background: transparent;
}
.ant-input::placeholder {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #AAAAAA;
}
.vben-basic-table {
background: transparent;
}
.vben-basic-table .ant-table-wrapper {
background-color: transparent;
padding: 0;
}
.ant-table.ant-table-middle {
border-radius: 0;
background-color: transparent !important;
}
.ant-table-title {
border-radius: 8px 8px 0 0;
border-left: 1px solid #183171 !important;
border-top: 1px solid #183171 !important;
border-right: 1px solid #183171 !important;
background-color: #13265a !important;
}
.ant-table-container {
border-inline-start: 1px solid rgba(45,119,243,0.3) !important;
}
.ant-table.ant-table-bordered >.ant-table-container {
border-inline-start: 1px solid rgba(45,119,243,0.3) !important;
}
.ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table,
.ant-table.ant-table-bordered >.ant-table-container >.ant-table-header >table {
border-top: 1px solid rgba(45,119,243,0.3) !important;
}
.ant-table-cell {
background-color: #0d1540 !important;
}
.ant-table.ant-table-bordered th,
.ant-table.ant-table-bordered td {
border-inline-end: 1px solid rgba(45, 119, 243, 0.3) !important;
}
.ant-table-tbody >tr.ant-table-row:hover>td,
.ant-table-tbody >tr >td.ant-table-cell-row-hover {
background: #273c62 !important;
}
.ant-table.ant-table-bordered >.ant-table-container >.ant-table-content >table >thead>tr>th {
border-bottom: none;
background: #13265a !important;
font-family: "Noto Sans SC", serif;
font-size: 14px;
font-weight: normal;
color: #ffffff;
}
.ant-table-cell-ellipsis.ant-table-cell-fix-right-first {
overflow: hidden !important;
border-left: 1px solid rgba(45,119,243,0.3) !important;
}
.ant-table-tbody >tr >td {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #ffffff;
border-bottom: 1px solid rgba(45,119,243,0.3) !important;
}

View File

@ -0,0 +1,222 @@
<template>
<div class="box" v-show="open">
<div
id="scroller"
class="pdf-viewer"
@mousedown="startSelection"
@mousemove="updateSelection"
@mouseup="endSelection"
@scroll="handleScroll"
>
<canvas ref="pdfCanvas" />
<canvas ref="tempCanvas" v-show="false" />
<div v-if="selection" class="selection-box" :style="selectionStyle"></div>
</div>
<a-button
type="primary"
class="btn"
v-show="captureButtonVisible"
:style="captureButtonStyle"
:icon="h(ScissorOutlined)"
@click="captureSelection"
> </a-button
>
<a-button
type="primary"
class="btn-close"
:style="closeButtonStyle"
:icon="h(CloseOutlined)"
@click="close"
> </a-button
>
</div>
</template>
<script>
import * as pdfjsLib from 'pdfjs-dist';
import {h} from "vue";
import {CloseOutlined, ScissorOutlined} from "@ant-design/icons-vue";
pdfjsLib.GlobalWorkerOptions.workerSrc = '../../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
export default {
name: 'PdfViewer',
data() {
return {
open: false,
start: false,
selection: null,
startPoint: null,
scrollPoint: null,
selectionStyle: null,
captureButtonStyle: null,
closeButtonStyle: null,
captureButtonVisible: false,
}
},
methods: {
CloseOutlined,
ScissorOutlined,
h,
async loadPdf(param) {
let loadingTask;
loadingTask = pdfjsLib.getDocument({data: param});
const pdf = await loadingTask.promise;
const page = await pdf.getPage(1); //
const viewport = page.getViewport({scale: 1.75});
const canvas = this.$refs.pdfCanvas;
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = {
canvasContext: context,
viewport: viewport,
};
await page.render(renderContext).promise;
},
show() {
this.open = true;
this.scrollPoint = {
x: 0,
y: 0
};
this.closeButtonStyle = {
top: '5px',
};
this.start = false;
this.selection = null;
this.startPoint = null;
this.selectionStyle = null;
this.captureButtonVisible = false;
},
close() {
document.getElementById("scroller").scrollTop = 0;
document.getElementById("scroller").scrollLeft = 0;
this.open = false;
},
startSelection(event) {
this.start = true;
this.startPoint = {
x: event.offsetX,
y: event.offsetY
};
this.selection = {
x: event.offsetX,
y: event.offsetY,
width: 0,
height: 0,
};
this.selectionStyle = null;
this.hideCaptureButton();
},
updateSelection(event) {
if (!this.start)
return;
if (this.startPoint) {
this.selection.width = Math.abs(event.offsetX - this.startPoint.x);
this.selection.height = Math.abs(event.offsetY - this.startPoint.y);
this.selection.x = Math.min(event.offsetX, this.startPoint.x);
this.selection.y = Math.min(event.offsetY, this.startPoint.y);
this.selectionStyle = {
left: `${this.selection.x}px`,
top: `${this.selection.y}px`,
width: `${this.selection.width}px`,
height: `${this.selection.height}px`,
position: 'absolute',
border: '1px dashed red',
};
}
},
endSelection() {
this.start = false;
this.showCaptureButton();
},
captureSelection() {
const canvas = this.$refs.pdfCanvas;
const context = canvas.getContext('2d');
const tempCanvas = this.$refs.tempCanvas;
tempCanvas.width = this.selection.width;
tempCanvas.height = this.selection.height;
const tempContext = tempCanvas.getContext('2d');
tempContext.drawImage(
canvas,
this.selection.x,
this.selection.y,
this.selection.width,
this.selection.height,
0,
0,
tempCanvas.width,
tempCanvas.height
);
const imageData = tempCanvas.toDataURL('image/png');
this.$emit("onCapture", imageData);
this.close();
},
handleScroll(event) {
this.scrollPoint = {
x: event.srcElement.scrollLeft,
y: event.srcElement.scrollTop,
}
this.showCaptureButton();
},
showCaptureButton() {
if (this.selection && this.selection.width > 50 && this.selection.height > 30) {
this.captureButtonStyle = {
left: `${this.startPoint.x - this.scrollPoint.x + 1}px`,
top: `${this.startPoint.y - this.scrollPoint.y + 1}px`,
position: 'absolute',
borderRadius: 0,
};
this.captureButtonVisible = true;
} else {
this.captureButtonVisible = false;
}
},
hideCaptureButton() {
this.captureButtonVisible = false;
}
},
};
</script>
<style scoped>
.box {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background-color: #0d1540;
z-index: 9999;
.pdf-viewer {
text-align: center;
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background-color: #0d1540;
overflow: auto;
.selection-box {
position: absolute;
border: 1px dashed red;
}
}
.btn {
position: absolute;
border-radius: 0;
left: 0;
top: 0;
}
.btn-close {
position: absolute;
border-radius: 0;
left: 50%;
top: 5px;
transform: translateX(-50%);
}
}
</style>

View File

@ -415,7 +415,7 @@
.ant-table-title {
min-height: 40px;
padding: 0 0 8px !important;
padding: 8px 0 8px !important;
}
.ant-table.ant-table-bordered .ant-table-title {

View File

@ -3,6 +3,8 @@ import '@/design/index.less';
import '@/components/VxeTable/src/css/index.scss';
import 'ant-design-vue/dist/reset.css';
import '@/design/font.css';
import "@/assets/style.css";
// Register icon sprite
import 'virtual:svg-icons-register';

View File

@ -1,21 +1,11 @@
<template>
<BasicDrawer v-bind="$attrs" @register="registerDrawer" showFooter :title="getTitle" width="900px" @ok="handleSubmit">
<BasicForm @register="registerForm">
<template #paramJson="{ model }">
<CodeEditor
style="height: 500px"
:auto-height="false"
v-model:value="model.paramJson"
@change="model.paramJson = $event;"
/>
</template>
</BasicForm>
<BasicForm @register="registerForm" />
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate" :icon="h(PlusOutlined)"> </a-button>
<div style="width: 5px" />
<a-button type="primary" :icon="h(EyeOutlined)" @click="handleOpenFileDialog">OCR识别</a-button>
<input type="file" ref="fileInput" aria-hidden="true" accept="image/bmp,image/jpeg,image/jpg,image/png" @change="handleFileChange" style="display: none;" />
<div style="width: 5px" />
</template>
<template #bodyCell="{ column, record }">
@ -52,7 +42,6 @@ import {defineEmits, ref, computed, unref, h} from 'vue';
import { BasicForm, useForm } from '@/components/Form/index';
import { formSchema } from './schema';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { CodeEditor } from "@/components/CodeEditor";
import * as TaskApi from '@/api/data/taskApi';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { EyeOutlined, PlusOutlined } from "@ant-design/icons-vue";
@ -99,11 +88,11 @@ const columns = [
const paramData = ref<any>([]);
const emit = defineEmits(['success', 'register']);
const emit = defineEmits(['success', 'register', 'ocrClick']);
const isUpdate = ref(true);
const entity = ref();
const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
const [registerForm, { resetFields, setFieldsValue, validate, getFieldsValue }] = useForm({
labelWidth: 120,
schemas: formSchema,
showActionButtonGroup: false,
@ -124,6 +113,13 @@ const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (
});
});
const setParamData = (items: any) => {
paramData.value = [];
items.forEach((d: any, index: number) => {
paramData.value.push({index, ...d});
});
};
const [registerTable] = useTable({
title: '预埋件列表',
columns,
@ -146,9 +142,8 @@ const [registerTable] = useTable({
const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
async function handleSubmit() {
try {
const values = await validate();
setDrawerProps({ confirmLoading: true });
setDrawerProps({confirmLoading: true});
const {
...rest
} = values;
@ -172,9 +167,7 @@ async function handleSubmit() {
await action(data);
closeDrawer();
emit('success');
} catch {} finally {
setDrawerProps({ confirmLoading: false });
}
setDrawerProps({confirmLoading: false});
}
const handleCreate = () => {
@ -189,35 +182,29 @@ const handleDelete = (record: Recordable) => {
paramData.value = paramData.value.filter(d => d.code !== record.code);
};
const fileInput = ref<HTMLInputElement>();
const handleOpenFileDialog = () => {
fileInput.value?.click();
};
const handleFileChange = (event: any) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
handleImport(e.target!.result);
fileInput.value!.value = '';
};
reader.readAsDataURL(file);
const rest = getFieldsValue();
const data = !unref(isUpdate)
? {
...rest,
}
: Object.assign({},
{
...unref(entity),
...rest,
},
);
emit("ocrClick", data);
};
const handleImport = (base64ImageString: any) => {
TaskApi.importImageOCR(base64ImageString).then((res: any) => {
WebViewService.setMessage("数据导入成功!", "success").then(() => {});
paramData.value = JSON.parse(res);
}).catch(() => {
WebViewService.setMessage("数据导入失败!", "error").then(() => {});
});
};
const updateParamData = (data: any) => {
const updateParamData = async (data: any) => {
paramData.value[data.index] = { ...data };
}
defineExpose({
setParamData
});
</script>
<style lang="scss" scoped>
@use '@/assets/custom.scss';

View File

@ -8,8 +8,8 @@
<template #toolbar>
<a-button type="primary" @click="handleCreate" :icon="h(PlusOutlined)"> </a-button>
<div style="width: 5px" />
<a-button type="default" :icon="h(ImportOutlined)" @click="handleOpenFileDialog">导入数据</a-button>
<input type="file" ref="fileInput" accept="image/bmp,image/jpeg,image/jpg,image/png" aria-hidden="true" @change="handleFileChange" style="display: none;" />
<a-button type="default" :icon="h(EyeOutlined)" @click="handleOpenFileDialog(null)">OCR识别</a-button>
<input type="file" ref="fileInput" accept="application/pdf" aria-hidden="true" @change="handleFileChange" style="display: none;" />
<div style="width: 5px" />
<a-button type="default" @click="handleDownload" :icon="h(DownloadOutlined)" :disabled="checkedKeys.length === 0">下发数据</a-button>
<a-button type="default" @click="handleSync" :icon="h(SyncOutlined)" :disabled="checkedKeys.length === 0">同步数据</a-button>
@ -63,7 +63,8 @@
</template>
</template>
</BasicTable>
<TaskDrawer @register="registerDrawer" @success="handleSuccess" />
<TaskDrawer ref="taskDrawer" @register="registerDrawer" @success="handleSuccess" @ocrClick="handleOpenFileDialog" />
<PdfViewer ref="pdfView" @onCapture="handleCapture" />
</div>
</template>
<script lang="ts" setup>
@ -81,10 +82,13 @@
import { onMounted, onUnmounted, computed } from "vue";
import {
DownloadOutlined,
ImportOutlined,
EyeOutlined,
PlusOutlined,
SyncOutlined
} from "@ant-design/icons-vue";
import PdfViewer from "@/components/PdfViewer/index.vue";
const taskDrawer = ref<typeof TaskDrawer>();
const { hasPermission } = usePermission();
const go = useGo();
const checkedKeys = ref<Array<string | number>>([]);
@ -178,8 +182,10 @@
go('/data/task/' + record.id);
};
let ocrData = null;
const fileInput = ref<HTMLInputElement>();
const handleOpenFileDialog = () => {
const handleOpenFileDialog = (data: any) => {
ocrData = data;
fileInput.value?.click();
};
@ -188,18 +194,25 @@
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
handleImport(e.target!.result);
openPdf(e.target!.result);
fileInput.value!.value = '';
};
reader.readAsDataURL(file);
reader.readAsArrayBuffer(file);
}
};
const handleImport = (base64ImageString: any) => {
const pdfView = ref<any>();
const openPdf = async (pdfData: any) => {
await pdfView.value.loadPdf(pdfData);
pdfView.value.show();
};
const handleCapture = (base64ImageString: any) => {
TaskApi.importImageOCR(base64ImageString).then((res: any) => {
WebViewService.setMessage("数据导入成功!", "success").then(() => {});
const data = JSON.parse(res);
if (data.length === 0) return;
if (ocrData === null) {
const record = {
name: '',
paramJson: JSON.stringify(data),
@ -209,6 +222,9 @@
record,
isUpdate: false,
});
} else {
taskDrawer.value?.setParamData(data);
}
}).catch(() => {
WebViewService.setMessage("数据导入失败!", "error").then(() => {});
});
@ -242,7 +258,6 @@
});
const timer = ref(0)
onMounted(()=> {
timer.value = setInterval(() => {
DeviceClientService.getDeviceConnected().then((d) => {
@ -258,7 +273,6 @@
onUnmounted(()=> {
clearInterval(timer.value);
});
</script>
<style lang="scss" scoped>
@use '@/assets/custom.scss';

View File

@ -129,66 +129,3 @@ async function handleSubmit() {
<style lang="scss" scoped>
@use '@/assets/custom.scss';
</style>
<style>
.custom-modal .ant-modal-content {
background-color: #13265a;
}
.ant-modal-header {
background-color: #13265a !important;
}
.vben-basic-title {
font-family: "Noto Sans SC", serif;
font-size: 16px;
color: #ffffff !important;
}
.ant-btn-primary {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: #3793d4;
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-primary:hover {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(69,175,223,0.8);
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(58,98,203,0.8);
box-shadow: inset 0 0 20px 2px #3A62CB;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default:hover {
font-family: "Noto Sans SC", serif;
font-size: 14px;
color: #FFFFFF;
background-color: rgba(58,98,203,0.8);
box-shadow: inset 0 0 20px 2px #006CC6;
height: 36px;
border-radius: 6px;
border: none;
}
.ant-btn-default:disabled,
.ant-btn-default:disabled:hover,
.ant-btn-default:disabled svg {
color: #AAAAAA;
}
</style>

View File

@ -233,7 +233,7 @@ export const schema = {
const queryFields = ['name','deviceSn','startTimeQuery','state'];
// const editFields = ['name','deviceSn','paramJson'];
const editFields = ['name','deviceSn'];
const editFields = ['name', 'deviceSn'];
const tableFields = ['name','deviceSn','startTime','endTime','state','createTime'];
const descriptionFields = ['name','deviceSn','paramJson','resultJson','startTime','endTime','state'];

View File

@ -6,7 +6,7 @@
</div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" @click="handleCreate" :icon="h(PlusOutlined)"></a-button>
<a-button type="primary" @click="handleCreate" :icon="h(PlusOutlined)"> </a-button>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
@ -103,9 +103,9 @@ import {defineComponent, h, onMounted} from 'vue';
reload();
}
onMounted(() => {
WebViewService.setIsLoading(false).then(() => {});
});
// onMounted(() => {
// WebViewService.setIsLoading(false).then(() => {});
// });
return {
registerTable,