|
@ -0,0 +1,7 @@
|
||||||
|
Package: hanvonwebscan
|
||||||
|
Version: 4.2007.2022.07047
|
||||||
|
Architecture: amd64
|
||||||
|
Maintainer: hanvon
|
||||||
|
Section: libs
|
||||||
|
Priority: optional
|
||||||
|
Description: hanvon webscan server and application
|
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#RC_LOCAL="/etc/rc.local"
|
||||||
|
|
||||||
|
|
||||||
|
chmod 777 -R /opt/hanvonwebscan/bin/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "installed in the dir /opt/hanvonwebscan"
|
||||||
|
|
||||||
|
chmod 644 /etc/udev/rules.d/60-hanvon*
|
||||||
|
udevadm control --reload-rules
|
||||||
|
udevadm trigger
|
||||||
|
|
||||||
|
echo "enable hanvonwebscanserver.service "
|
||||||
|
systemctl enable hanvonwebscanserver.service
|
||||||
|
|
||||||
|
echo "reload daemoning "
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
echo "enable start.service "
|
||||||
|
systemctl start hanvonwebscanserver.service
|
||||||
|
sleep 10
|
||||||
|
echo "install hanvonwebserver finished"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
test -h /etc/systemd/system/multi-user.target.wants/hanvonwebscanserver.service
|
||||||
|
if [ $? -eq 0 ];then
|
||||||
|
rm -rf /etc/systemd/system/multi-user.target.wants/hanvonwebscanserver.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -h /etc/systemd/system/hanvonwebscanserver
|
||||||
|
if [ $? -eq 0 ];then
|
||||||
|
rm -rf /etc/systemd/system/hanvonwebscanserver
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -e /lib/systemd/system/hanvonwebscanserver.service
|
||||||
|
if [ $? -eq 0 ];then
|
||||||
|
rm -rf /lib/systemd/system/hanvonwebscanserver.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -d /opt/hanvonwebscan/
|
||||||
|
if [ $? -eq 0 ];then
|
||||||
|
rm -rf /opt/hanvonwebscan
|
||||||
|
fi
|
||||||
|
systemctl stop hanvonwebscanserver.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Load firmware for this printer.
|
||||||
|
|
||||||
|
#ACTION!="add", GOTO="mud_rules_end"
|
||||||
|
|
||||||
|
#HuaGao --->G100~G400
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0100", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0200", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0300", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0400", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0139", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0239", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0339", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="3072", ATTR{idProduct}=="0439", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
|
||||||
|
|
||||||
|
#Lanxum --->G100~G400
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8620", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8730", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8420", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8520", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8200", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8629", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8739", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8429", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="31c9", ATTR{idProduct}=="8529", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Hanvon --->G100~G400
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="7000", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="7039", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="1000", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="8000", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="9000", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="1002", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="7002", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="2903", ATTR{idProduct}=="7039", MODE="0666", OWNER="root", GROUP="lp", ENV{libsane_matched}="yes"
|
||||||
|
|
||||||
|
LABEL="mud_rules_end"
|
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=hanvon webscan service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
User=root
|
||||||
|
ExecStart=/opt/hanvonwebscan/bin/server.sh start
|
||||||
|
ExecStop=/opt/hanvonwebscan/bin/server.sh stop
|
||||||
|
ExecReload=/opt/hanvonwebscan/bin/server.sh restart
|
||||||
|
Restart=always
|
||||||
|
RestartSSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
Alias=hanvonwebscanserver
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/bash
|
||||||
|
service hanvonwebscanserver restart
|
|
@ -0,0 +1,89 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||||
|
echo "current dir $DIR"
|
||||||
|
BASE_DIR="$DIR"
|
||||||
|
export LD_LIBRARY_PATH="$DIR"
|
||||||
|
APP_NAME=HwWebService
|
||||||
|
|
||||||
|
APP_PATH="$BASE_DIR/HWWebService"
|
||||||
|
echo "APP_PATH = $APP_PATH"
|
||||||
|
LIB_PARH="$BASE_DIR/libhwdriver.so"
|
||||||
|
echo "LIB_PARH = $LIB_PARH"
|
||||||
|
|
||||||
|
#userage
|
||||||
|
usage() {
|
||||||
|
echo "Usage: sh script.sh [start|stop|restart|status]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
is_exist(){
|
||||||
|
if [ ! -f $BASE_DIR/HwWebService ]; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
pid=`ps -ef | grep "HWWebService" | grep -v grep | awk '{print $2}'`
|
||||||
|
echo "PID: $pid"
|
||||||
|
appNum=`ps -ef|awk '{print $2}'|grep -c -e "^${pid}\$"`
|
||||||
|
echo appNum $appNum
|
||||||
|
if [ ${appNum} -gt 0 ]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
rm -rf $BASE_DIR/HwWebService.pid >/dev/null 2>&1 &
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#start server
|
||||||
|
start(){
|
||||||
|
is_exist
|
||||||
|
if [ $? -eq "0" ]; then
|
||||||
|
echo "${APP_NAME} is already running. pid=${pid} ."
|
||||||
|
else
|
||||||
|
echo "APP_PATH: $APP_PATH"
|
||||||
|
echo "LIB_PATH: $LIB_PARH"
|
||||||
|
"$DIR"/HwWebService &
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#stop webserver
|
||||||
|
stop(){
|
||||||
|
is_exist
|
||||||
|
if [ $? -eq "0" ]; then
|
||||||
|
kill -9 $pid
|
||||||
|
rm -rf $BASE_DIR/application.pid >/dev/null 2>&1 &
|
||||||
|
else
|
||||||
|
echo "${APP_NAME} is not running"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#running status
|
||||||
|
status(){
|
||||||
|
is_exist
|
||||||
|
if [ $? -eq "0" ]; then
|
||||||
|
echo "${APP_NAME} is running. Pid is ${pid}"
|
||||||
|
else
|
||||||
|
echo "${APP_NAME} is NOT running."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#restart server
|
||||||
|
restart(){
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
"start")
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
"stop")
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
"status")
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
"restart")
|
||||||
|
restart
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,220 @@
|
||||||
|
html {
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
min-width: 1200px;
|
||||||
|
min-height: 900px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container {
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageListSelect {
|
||||||
|
/* border: 1px solid #909399; */
|
||||||
|
/*box-shadow: 0 2px 6px #ADADAD;*/
|
||||||
|
border: 2px solid #fa7857 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aside {
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
height: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.aside .header {
|
||||||
|
height: 40px;
|
||||||
|
background-color: #eaeaea;
|
||||||
|
line-height: 40px;
|
||||||
|
padding-left: 20px;
|
||||||
|
/* margin-top:10px; */
|
||||||
|
color: #09aaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置滚动条的滑轨 */
|
||||||
|
.scroll::-webkit-scrollbar-track {
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑块 */
|
||||||
|
.scroll::-webkit-scrollbar-thumb {
|
||||||
|
/* background-color: rgba(0, 0, 0, 0.6); */
|
||||||
|
background-color: #cdcdcd;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑轨两头的监听按钮 */
|
||||||
|
.scroll::-webkit-scrollbar-button {
|
||||||
|
/* background-color: #444; */
|
||||||
|
background-color: #cdcdcd;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .iconContainer {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
height: 35px
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menus {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menuContainer {
|
||||||
|
float: left;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menuContainer ul {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header ul li {
|
||||||
|
float: left;
|
||||||
|
padding-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menuRight {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menuRight ul li {
|
||||||
|
padding-right: 20px;
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-container .el-header .menuRight .iconContainer {
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main .opt {
|
||||||
|
width: 58px;
|
||||||
|
height: 100%;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
float: left;
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main .opt .active {
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
background-color: #cecece;
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
overflow: auto;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-main .opt ul li {
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 16px;
|
||||||
|
padding-top: 4px
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask .messageBox {
|
||||||
|
width: 500px;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 45%;
|
||||||
|
-webkit-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask .messageBox .title {
|
||||||
|
border-radius: 3px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask .messageBox .title .closeReport {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.canvas-container {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.el-dropdown-link {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #409EFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon-arrow-down {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-item {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.batch-item:hover {
|
||||||
|
background-color: #eaeaea;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.operaBg:hover {
|
||||||
|
background-color: #C0C4CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-style {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
width: 30%
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer
|
||||||
|
}
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 309 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 928 B |
After Width: | Height: | Size: 605 B |
After Width: | Height: | Size: 265 B |
After Width: | Height: | Size: 980 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 781 B |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 944 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 426 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 900 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 383 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 858 B |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 403 B |
After Width: | Height: | Size: 980 B |
After Width: | Height: | Size: 422 B |
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* FileSaver.js
|
||||||
|
* A saveAs() FileSaver implementation.
|
||||||
|
*
|
||||||
|
* By Eli Grey, http://eligrey.com
|
||||||
|
*
|
||||||
|
* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
|
||||||
|
* source : http://purl.eligrey.com/github/FileSaver.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
// The one and only way of getting global scope in all environments
|
||||||
|
// https://stackoverflow.com/q/3277182/1008999
|
||||||
|
var _global = typeof window === 'object' && window.window === window
|
||||||
|
? window : typeof self === 'object' && self.self === self
|
||||||
|
? self : typeof global === 'object' && global.global === global
|
||||||
|
? global
|
||||||
|
: this
|
||||||
|
|
||||||
|
function bom (blob, opts) {
|
||||||
|
if (typeof opts === 'undefined') opts = { autoBom: false }
|
||||||
|
else if (typeof opts !== 'object') {
|
||||||
|
console.warn('Deprecated: Expected third argument to be a object')
|
||||||
|
opts = { autoBom: !opts }
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepend BOM for UTF-8 XML and text/* types (including HTML)
|
||||||
|
// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
|
||||||
|
if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
||||||
|
return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })
|
||||||
|
}
|
||||||
|
return blob
|
||||||
|
}
|
||||||
|
|
||||||
|
function download (url, name, opts) {
|
||||||
|
var xhr = new XMLHttpRequest()
|
||||||
|
xhr.open('GET', url)
|
||||||
|
xhr.responseType = 'blob'
|
||||||
|
xhr.onload = function () {
|
||||||
|
saveAs(xhr.response, name, opts)
|
||||||
|
}
|
||||||
|
xhr.onerror = function () {
|
||||||
|
console.error('could not download file')
|
||||||
|
}
|
||||||
|
xhr.send()
|
||||||
|
}
|
||||||
|
|
||||||
|
function corsEnabled (url) {
|
||||||
|
var xhr = new XMLHttpRequest()
|
||||||
|
// use sync to avoid popup blocker
|
||||||
|
xhr.open('HEAD', url, false)
|
||||||
|
try {
|
||||||
|
xhr.send()
|
||||||
|
} catch (e) {}
|
||||||
|
return xhr.status >= 200 && xhr.status <= 299
|
||||||
|
}
|
||||||
|
|
||||||
|
// `a.click()` doesn't work for all browsers (#465)
|
||||||
|
function click (node) {
|
||||||
|
try {
|
||||||
|
node.dispatchEvent(new MouseEvent('click'))
|
||||||
|
} catch (e) {
|
||||||
|
var evt = document.createEvent('MouseEvents')
|
||||||
|
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,
|
||||||
|
20, false, false, false, false, 0, null)
|
||||||
|
node.dispatchEvent(evt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect WebView inside a native macOS app by ruling out all browsers
|
||||||
|
// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too
|
||||||
|
// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos
|
||||||
|
var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)
|
||||||
|
|
||||||
|
var saveAs = _global.saveAs || (
|
||||||
|
// probably in some web worker
|
||||||
|
(typeof window !== 'object' || window !== _global)
|
||||||
|
? function saveAs () { /* noop */ }
|
||||||
|
|
||||||
|
// Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView
|
||||||
|
: ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)
|
||||||
|
? function saveAs (blob, name, opts) {
|
||||||
|
var URL = _global.URL || _global.webkitURL
|
||||||
|
var a = document.createElement('a')
|
||||||
|
name = name || blob.name || 'download'
|
||||||
|
|
||||||
|
a.download = name
|
||||||
|
a.rel = 'noopener' // tabnabbing
|
||||||
|
|
||||||
|
// TODO: detect chrome extensions & packaged apps
|
||||||
|
// a.target = '_blank'
|
||||||
|
|
||||||
|
if (typeof blob === 'string') {
|
||||||
|
// Support regular links
|
||||||
|
a.href = blob
|
||||||
|
if (a.origin !== location.origin) {
|
||||||
|
corsEnabled(a.href)
|
||||||
|
? download(blob, name, opts)
|
||||||
|
: click(a, a.target = '_blank')
|
||||||
|
} else {
|
||||||
|
click(a)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Support blobs
|
||||||
|
a.href = URL.createObjectURL(blob)
|
||||||
|
setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s
|
||||||
|
setTimeout(function () { click(a) }, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use msSaveOrOpenBlob as a second approach
|
||||||
|
: 'msSaveOrOpenBlob' in navigator
|
||||||
|
? function saveAs (blob, name, opts) {
|
||||||
|
name = name || blob.name || 'download'
|
||||||
|
|
||||||
|
if (typeof blob === 'string') {
|
||||||
|
if (corsEnabled(blob)) {
|
||||||
|
download(blob, name, opts)
|
||||||
|
} else {
|
||||||
|
var a = document.createElement('a')
|
||||||
|
a.href = blob
|
||||||
|
a.target = '_blank'
|
||||||
|
setTimeout(function () { click(a) })
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
navigator.msSaveOrOpenBlob(bom(blob, opts), name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to using FileReader and a popup
|
||||||
|
: function saveAs (blob, name, opts, popup) {
|
||||||
|
// Open a popup immediately do go around popup blocker
|
||||||
|
// Mostly only available on user interaction and the fileReader is async so...
|
||||||
|
popup = popup || open('', '_blank')
|
||||||
|
if (popup) {
|
||||||
|
popup.document.title =
|
||||||
|
popup.document.body.innerText = 'downloading...'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof blob === 'string') return download(blob, name, opts)
|
||||||
|
|
||||||
|
var force = blob.type === 'application/octet-stream'
|
||||||
|
var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari
|
||||||
|
var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
|
||||||
|
|
||||||
|
if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') {
|
||||||
|
// Safari doesn't allow downloading of blob URLs
|
||||||
|
var reader = new FileReader()
|
||||||
|
reader.onloadend = function () {
|
||||||
|
var url = reader.result
|
||||||
|
url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
|
||||||
|
if (popup) popup.location.href = url
|
||||||
|
else location = url
|
||||||
|
popup = null // reverse-tabnabbing #460
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
} else {
|
||||||
|
var URL = _global.URL || _global.webkitURL
|
||||||
|
var url = URL.createObjectURL(blob)
|
||||||
|
if (popup) popup.location = url
|
||||||
|
else location.href = url
|
||||||
|
popup = null // reverse-tabnabbing #460
|
||||||
|
setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
_global.saveAs = saveAs.saveAs = saveAs
|
||||||
|
|
||||||
|
if (typeof module !== 'undefined') {
|
||||||
|
module.exports = saveAs;
|
||||||
|
}
|
|
@ -0,0 +1,656 @@
|
||||||
|
(function (window) {
|
||||||
|
const TAG = 'WebScanController:'
|
||||||
|
let Result = function (code, msg, data) {
|
||||||
|
this.code = code;
|
||||||
|
this.msg = msg;
|
||||||
|
this.data = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
function WebScanController(options) {
|
||||||
|
|
||||||
|
if (options.wsUrl == '' || options.wsUrl == null || options.wsUrl == undefined) {
|
||||||
|
WebScanController.prototype.wsUrl = "ws://localhost:38999";
|
||||||
|
} else {
|
||||||
|
WebScanController.prototype.wsUrl = options.wsUrl;
|
||||||
|
}
|
||||||
|
WebScanController.prototype.wslicence = options.wslicence;
|
||||||
|
return WebScanController.prototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebScanController.prototype = {
|
||||||
|
constructor: WebScanController,
|
||||||
|
|
||||||
|
/*****************************************扫描仪相关********************************************************************************/
|
||||||
|
initDevice: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "init_device",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
deinitDevices: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "deinit_device",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
getDeviceNameList: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_device_name_list",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
openDevice: function (device_name, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "open_device",
|
||||||
|
iden: that.wslicence,
|
||||||
|
device_name: device_name
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
closeDevice: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "close_device",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
setScanParams: function (appendParams, callBack) {
|
||||||
|
const that = this
|
||||||
|
let fixedParams = {
|
||||||
|
func: "set_device_param",
|
||||||
|
iden: that.wslicence
|
||||||
|
}
|
||||||
|
fixedParams.device_param = appendParams
|
||||||
|
console.log('final set scan params:' + JSON.stringify(fixedParams))
|
||||||
|
this.sendCommand(fixedParams, callBack)
|
||||||
|
},
|
||||||
|
getScanParams: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_device_param",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
resetScanParams: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "reset_device_param",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
getCurrDeviceName: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_curr_device_name",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//开始扫描
|
||||||
|
startScan: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "start_scan",
|
||||||
|
iden: that.wslicence,
|
||||||
|
get_base64: true
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
stopScan: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "stop_scan",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************基本接口********************************************************************************/
|
||||||
|
|
||||||
|
getLocalPic(path, callBack) {
|
||||||
|
let that = this
|
||||||
|
const cmd = {
|
||||||
|
func: "load_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: path
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(TAG, 'getLocalPic', JSON.parse(cmd))
|
||||||
|
this.sendCommand(cmd, callBack)
|
||||||
|
},
|
||||||
|
saveLocalPic(base64, callBack) {
|
||||||
|
const that = this
|
||||||
|
const cmd = {
|
||||||
|
func: "save_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_base64: base64
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(TAG, 'saveLocalPic', JSON.parse(cmd))
|
||||||
|
this.sendCommand(cmd, callBack)
|
||||||
|
},
|
||||||
|
//获取全局配置
|
||||||
|
getGlobalConfig: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_global_config",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//设置全局配置
|
||||||
|
setGlobalConfig: function (appendParams, callBack) {
|
||||||
|
const that = this
|
||||||
|
let fixedParams = {
|
||||||
|
func: "set_global_config",
|
||||||
|
iden: that.wslicence
|
||||||
|
}
|
||||||
|
const finalParams = Object.assign({}, appendParams, fixedParams)
|
||||||
|
console.log('final set global params:' + JSON.stringify(finalParams))
|
||||||
|
this.sendCommand(finalParams, callBack)
|
||||||
|
},
|
||||||
|
//加载本地图像
|
||||||
|
loadLocalImage: function (imagePath, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "load_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: imagePath
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//保存本地图像
|
||||||
|
saveLocalImage: function (imageBase64, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "save_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_base64: imageBase64
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//删除本地文件(为了安全,仅能删除后端生成的文件)
|
||||||
|
deleteLocalFile: function (filePath, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "delete_local_file",
|
||||||
|
iden: that.wslicence,
|
||||||
|
file_path: filePath
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//清理全局文件保存目录(为了安全,只会删除后端生成的文件)
|
||||||
|
clearGlobalFileSavePath: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "clear_global_file_save_path",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//合成本地图像
|
||||||
|
mergeLocalImage: function (imagePathList, mode, align, getBase64, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "merge_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path_list: imagePathList,
|
||||||
|
mode: mode,
|
||||||
|
align: align,
|
||||||
|
interval: 0,
|
||||||
|
get_base64: getBase64
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//本地合成多张图像
|
||||||
|
localMakeMultiImage: function (imagePathList, format, tiffCompression, tiffJpegQuality, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "local_make_multi_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path_list: imagePathList,
|
||||||
|
format: format,
|
||||||
|
tiff_compression: tiffCompression,
|
||||||
|
tiff_jpeg_quality: tiffJpegQuality
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//拆分本地图像
|
||||||
|
splitLocalImage: function (imagePath, mode, location, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "split_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: imagePath,
|
||||||
|
mode: mode,
|
||||||
|
location: location
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//本地生成压缩文件
|
||||||
|
localMakeZipFile: function (imagePathList, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "local_make_zip_file",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path_list: imagePathList
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//本地图像纠偏
|
||||||
|
localImageDeskew: function (imagePath, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "local_image_deskew",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: imagePath
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//上传本地文件
|
||||||
|
uploadLocalFile: function (filePath, uploadMode, remoteFilePath, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "upload_local_file",
|
||||||
|
iden: that.wslicence,
|
||||||
|
file_path: filePath,
|
||||||
|
upload_mode: uploadMode,
|
||||||
|
remote_file_path: remoteFilePath
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//本地图片添加水印
|
||||||
|
localImageAddWatermark: function (imagePath, text, textColor, textOpacity, textPos, marginRight,
|
||||||
|
marginBottom, locationX, locationY, fontName, fontSize, fontBold, fontUnderline,
|
||||||
|
fontItalic, fontStrikeout, getBase64,
|
||||||
|
callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "local_image_add_watermark",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: imagePath,
|
||||||
|
text: text,
|
||||||
|
text_color: textColor,
|
||||||
|
text_opacity: textOpacity,
|
||||||
|
text_pos: textPos,
|
||||||
|
margin_left: parseInt(marginLeft),
|
||||||
|
margin_top: parseInt(marginTop),
|
||||||
|
margin_right: parseInt(marginRight),
|
||||||
|
margin_bottom: parseInt(marginBottom),
|
||||||
|
location_x: parseInt(locationX),
|
||||||
|
location_y: parseInt(locationY),
|
||||||
|
font_name: fontName,
|
||||||
|
font_size: parseInt(fontSize),
|
||||||
|
font_bold: fontBold,
|
||||||
|
font_underline: fontUnderline,
|
||||||
|
font_italic: fontItalic,
|
||||||
|
font_strikeout: fontStrikeout,
|
||||||
|
get_base64: getBase64
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
/*****************************************文件管理相关********************************************************************************/
|
||||||
|
|
||||||
|
//获取批次号列表
|
||||||
|
getBatchIdList: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_batch_id_list",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//打开批次(后端启动后默认打开最近批次,没有最近批次则会新建default批次并打开)
|
||||||
|
openBatch: function (batchId, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "open_batch",
|
||||||
|
iden: that.wslicence,
|
||||||
|
batch_id: batchId + ""
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//删除批次
|
||||||
|
deleteBatch: function (batchId, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "delete_batch",
|
||||||
|
iden: that.wslicence,
|
||||||
|
batch_id: batchId + ""// 批次id,不能是当前批次
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//新建批次(新建批次到列表尾部并打开该批次)
|
||||||
|
createNewBatch: function (batchId, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "new_batch",
|
||||||
|
iden: that.wslicence,
|
||||||
|
batch_id: batchId + ""
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//获取当前批次号
|
||||||
|
getCurrBatchId: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_curr_batch_id",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//修改批次号
|
||||||
|
modifyBatchId: function (batchId, newBatchId, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "modify_batch_id",
|
||||||
|
iden: that.wslicence,
|
||||||
|
batch_id: batchId,
|
||||||
|
new_batch_id: newBatchId
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//加载图像缩略图列表
|
||||||
|
getImageThumbnailList: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_image_thumbnail_list",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//获取图像数量
|
||||||
|
getImageCount: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "get_image_count",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//绑定文件夹
|
||||||
|
bindFolder: function (folder, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "bind_folder",
|
||||||
|
iden: that.wslicence,
|
||||||
|
folder: folder,
|
||||||
|
name_mode: "order",
|
||||||
|
name_width: 4,
|
||||||
|
name_base: 0
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//停止绑定文件夹
|
||||||
|
stopBindFolder: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "stop_bind_folder",
|
||||||
|
iden: that.wslicence,
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//加载图像
|
||||||
|
loadImage: function (imageIndex, callBack) {
|
||||||
|
let that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "load_image",
|
||||||
|
iden: imageIndex + "",
|
||||||
|
image_index: imageIndex
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//保存图像
|
||||||
|
saveImage: function (imageIndex, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "save_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//插入本地图像(需返回成功后前端缩略图才能作相应的UI修改)
|
||||||
|
insertLocalImage: function (imagePath, insertIndex, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "insert_local_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_path: imagePath,
|
||||||
|
insert_pos: insertIndex,//插入位置,-1表示最后
|
||||||
|
image_tag: ''//标签名,可以为空
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//插入图像
|
||||||
|
insertImage: function (imageBase64, insertIndex, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "insert_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_base64: imageBase64,
|
||||||
|
insert_pos: insertIndex,//插入位置,-1表示最后
|
||||||
|
image_tag: ''//标签名,可以为空
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//修改图像标签
|
||||||
|
modifyImageTag: function (imageIndexList, imageTagList, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "modify_image_tag",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList,
|
||||||
|
image_tag_list: imageTagList
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//删除图像
|
||||||
|
deleteImage: function (imageIndexList, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "delete_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//清理图像列表
|
||||||
|
clearImageList: function (callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "clear_image_list",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//修改图像
|
||||||
|
modifyImage: function (imageIndex, imageBase64, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "modify_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex,
|
||||||
|
image_base64: imageBase64
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//使用本地图像修改图像
|
||||||
|
modifyImageByLocal: function (imageIndex, imagePath, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "modify_image_by_local",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex,
|
||||||
|
image_path: imagePath
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//移动图像
|
||||||
|
moveImage: function (imageIndexList, target, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "move_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList,
|
||||||
|
mode: 'index',
|
||||||
|
target: target
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
//图像书籍排序
|
||||||
|
imageBookSort: function (callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "image_book_sort",
|
||||||
|
iden: that.wslicence
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//合成图像
|
||||||
|
mergeImage: function (imageIndexList, mode, align, getBase64, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "merge_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList,
|
||||||
|
mode: mode,
|
||||||
|
align: align,
|
||||||
|
interval: 0,
|
||||||
|
get_base64: getBase64
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//合成多张图像
|
||||||
|
makeMultiImage: function (imageIndexList, format, callBack) {
|
||||||
|
const that = this
|
||||||
|
let msg = {
|
||||||
|
func: "make_multi_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList,
|
||||||
|
format: format,
|
||||||
|
tiff_compression: 'none',
|
||||||
|
tiff_jpeg_quality: 80,
|
||||||
|
get_base64: true
|
||||||
|
}
|
||||||
|
this.sendCommand(msg, callBack)
|
||||||
|
},
|
||||||
|
//交换图片
|
||||||
|
exchangeImage: function (index1, index2, callBack) {
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "exchange_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_1: index1,
|
||||||
|
image_index_2: index2
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//拆分图像
|
||||||
|
splitImage: function (imageIndex, mode, location, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "split_image",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex,
|
||||||
|
mode: mode,
|
||||||
|
location: location,
|
||||||
|
get_base64: true
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//压缩图像
|
||||||
|
makeZipFile: function (imageIndexList, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "make_zip_file",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index_list: imageIndexList,
|
||||||
|
get_base64: true
|
||||||
|
}, callBack)
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
//图像纠偏
|
||||||
|
imageDeskew: function (imageIndex, getBase64, callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
this.sendCommand({
|
||||||
|
func: "image_deskew",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex,
|
||||||
|
get_base64: getBase64
|
||||||
|
}, callBack)
|
||||||
|
},
|
||||||
|
//图片添加水印
|
||||||
|
imageAddWatermark: function (imageIndex, markInfo, getBase64,
|
||||||
|
callBack) {
|
||||||
|
|
||||||
|
const that = this
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
func: "image_add_watermark",
|
||||||
|
iden: that.wslicence,
|
||||||
|
image_index: imageIndex,
|
||||||
|
text: markInfo.text,
|
||||||
|
text_color: markInfo.text_color,
|
||||||
|
text_opacity: markInfo.text_opacity,
|
||||||
|
text_pos: markInfo.text_pos,
|
||||||
|
margin_left: parseInt(markInfo.margin_left),
|
||||||
|
margin_top: parseInt(markInfo.margin_top),
|
||||||
|
margin_right: parseInt(markInfo.margin_right),
|
||||||
|
margin_bottom: parseInt(markInfo.margin_bottom),
|
||||||
|
location_x: parseInt(markInfo.location_x),
|
||||||
|
location_y: parseInt(markInfo.location_y),
|
||||||
|
font_name: markInfo.font_name,
|
||||||
|
font_size: parseInt(markInfo.font_size),
|
||||||
|
font_bold: markInfo.font_bold,
|
||||||
|
font_underline: markInfo.font_underline,
|
||||||
|
font_italic: markInfo.font_italic,
|
||||||
|
font_strikeout: markInfo.font_strikeout,
|
||||||
|
get_base64: getBase64
|
||||||
|
}
|
||||||
|
console.log('添加水印:params===' + JSON.stringify(params))
|
||||||
|
|
||||||
|
this.sendCommand(params, callBack)
|
||||||
|
|
||||||
|
},
|
||||||
|
/*****************************************socket相关********************************************************************************/
|
||||||
|
callBackList: {}
|
||||||
|
,
|
||||||
|
addCallBack: function (key, listener) {
|
||||||
|
this.callBackList[key] = listener;
|
||||||
|
},
|
||||||
|
removeCallBack: function (key) {
|
||||||
|
delete this.callBackList[key];
|
||||||
|
},
|
||||||
|
getCallBack: function (key) {
|
||||||
|
return this.callBackList[key];
|
||||||
|
},
|
||||||
|
sendCommand: function (json, callBackListener) {
|
||||||
|
if (json.func && callBackListener) {
|
||||||
|
this.addCallBack(json.func, callBackListener)
|
||||||
|
}
|
||||||
|
this.SocketClient.send(JSON.stringify(json))
|
||||||
|
},
|
||||||
|
//初始化socketIO
|
||||||
|
initSocketIo: function (socketCallBack) {
|
||||||
|
this.socketCallBacks = socketCallBack
|
||||||
|
console.log(TAG, "initSocketIo ===============" + 'ws:' + this.wsUrl);
|
||||||
|
|
||||||
|
this.SocketClient = new WebSocket(this.wsUrl);
|
||||||
|
this.SocketClient.onopen = function (msg) {
|
||||||
|
console.log(TAG, "connect onopen")
|
||||||
|
socketCallBack(new Result(SOCKET_CONNECTED, "", null))
|
||||||
|
};
|
||||||
|
|
||||||
|
this.SocketClient.onmessage = function (event) {
|
||||||
|
console.log(TAG, "connect onmessage data:" + event.data)
|
||||||
|
if (event && event.data) {
|
||||||
|
socketCallBack(new Result(SOCKET_EVENT, "", event.data))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.SocketClient.onclose = function (msg) {
|
||||||
|
console.log(TAG, "connect onclose:" + JSON.stringify(msg))
|
||||||
|
socketCallBack(new Result(SOCKET_DISCONNECTED, "", msg))
|
||||||
|
};
|
||||||
|
},
|
||||||
|
disconnect: function () {
|
||||||
|
if (this.SocketClient) {
|
||||||
|
this.SocketClient.close()
|
||||||
|
this.SocketClient = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.WebScanController = WebScanController;
|
||||||
|
})(window);
|
|
@ -0,0 +1,121 @@
|
||||||
|
(function (window, debug, undefined) {
|
||||||
|
var loadding;
|
||||||
|
var ajaxDefault = {
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
loadding=window.eleLoadding();
|
||||||
|
},
|
||||||
|
complete: function (xhr) {
|
||||||
|
if(debug){
|
||||||
|
console.log(xhr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {},
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
if(debug){
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
if (data == undefined) {
|
||||||
|
eleAlert('返回结果异常','warning');
|
||||||
|
}else if(data.code==200){
|
||||||
|
msg = '调用成功,放回状态码为:' + data.code;
|
||||||
|
if(msg.code!=200){
|
||||||
|
msg+=';返回信息为:'+data.message;
|
||||||
|
}
|
||||||
|
// layer.alert(msg)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (xhr, error, exception) {
|
||||||
|
if(debug){
|
||||||
|
console.log(xhr);
|
||||||
|
console.log(error);
|
||||||
|
console.log(exception);
|
||||||
|
}
|
||||||
|
eleAlert('调用错误',"error");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function fnBeforeSend(xhr, callback) {
|
||||||
|
(callback || ajaxDefault.beforeSend)(xhr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fnAjaxSuccess(data, textStatus, jqXHR, callback) {
|
||||||
|
/* if(data!=undefined&&data.code!=undefined){
|
||||||
|
if(data.code===401){
|
||||||
|
layer.alert('请登陆',function(){
|
||||||
|
window.location.href = loginUrl;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}else if(data.code===403){
|
||||||
|
layer.alert(data.message);
|
||||||
|
return;
|
||||||
|
}else if(data.code===404){
|
||||||
|
layer.alert(data.message);
|
||||||
|
return;
|
||||||
|
}else if(data.code===500){
|
||||||
|
layer.alert(data.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
(callback || ajaxDefault.complete)(data, textStatus, jqXHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fnComplete(data, textStatus, callback) {
|
||||||
|
loadding.close();
|
||||||
|
(callback || ajaxDefault.complete)(data, textStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.utils = {
|
||||||
|
post: function (obj) {
|
||||||
|
var paramObj = {};
|
||||||
|
jQuery.extend(paramObj, obj)
|
||||||
|
if (window.jQuery == undefined) {
|
||||||
|
alert('请引入jQuery');
|
||||||
|
}
|
||||||
|
var finalData = {};
|
||||||
|
jQuery.extend(finalData, paramObj.data);
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: paramObj.url,
|
||||||
|
data: finalData,
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
fnBeforeSend(xhr, paramObj.beforeSend);
|
||||||
|
},
|
||||||
|
complete: function (xhr, textStatus) {
|
||||||
|
fnComplete(xhr, textStatus, paramObj.complete);
|
||||||
|
},
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
fnAjaxSuccess(data, textStatus, jqXHR, paramObj.success);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get: function (obj) {
|
||||||
|
var paramObj = {};
|
||||||
|
jQuery.extend(paramObj, obj)
|
||||||
|
if (window.jQuery == undefined) {
|
||||||
|
alert('请引入jQuery');
|
||||||
|
}
|
||||||
|
var finalData = {};
|
||||||
|
jQuery.extend(finalData, paramObj.data);
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: paramObj.url,
|
||||||
|
data: finalData,
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
fnBeforeSend(xhr, paramObj.beforeSend);
|
||||||
|
},
|
||||||
|
complete: function (xhr, textStatus) {
|
||||||
|
fnComplete(xhr, paramObj.complete);
|
||||||
|
},
|
||||||
|
dataType: paramObj.dataType || ajaxDefault.dataType,
|
||||||
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
fnAjaxSuccess(data, textStatus, jqXHR, paramObj.success);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(window, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,819 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title></title>
|
||||||
|
<link rel="Shortcut Icon" href="logo.png" type="image/x-icon"/>
|
||||||
|
<link rel="stylesheet" href="js/element-ui/index.css"/>
|
||||||
|
<link rel="stylesheet" href="css/scan.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<el-container id="container">
|
||||||
|
<el-aside width="195px" class="aside" v-loading.fullscreen.lock="fullscreenLoading"
|
||||||
|
element-loading-text="拼命加载中"
|
||||||
|
element-loading-spinner="el-icon-loading"
|
||||||
|
element-loading-background="rgba(0,0,0,0.7)">
|
||||||
|
<div class="header">
|
||||||
|
<i class="el-icon-document"></i>
|
||||||
|
图像预览
|
||||||
|
</div>
|
||||||
|
<div ref="imageArea" class="scroll" style="overflow: auto;height: calc(100% - 60px);">
|
||||||
|
<ul style="margin:auto;padding:0;margin-top:5px">
|
||||||
|
<li v-for="(image,index) in urls" :key="image"
|
||||||
|
style="padding:10px;padding-right:25px">
|
||||||
|
<div style="display:inline;position: relative;">
|
||||||
|
<span style="font-size:12px;position: absolute;left:0;width:25px;text-align:right">{{index +
|
||||||
|
1}}.</span>
|
||||||
|
<el-image
|
||||||
|
:class="{'imageListSelect': selectManyImages.indexOf(index)>=0}"
|
||||||
|
ref="imageList" :src="image.thumbnail" fit="contain"
|
||||||
|
imageIndex="{{index}}"
|
||||||
|
lazy
|
||||||
|
@dblclick="showBigImage(index)"
|
||||||
|
@click="!$event.ctrlKey && selectImage(image,index)"
|
||||||
|
@click.ctrl="selectManyImage(image,index)"
|
||||||
|
style="height:150px;margin-left:35px;width:80%;border:2px solid #dedede"
|
||||||
|
>
|
||||||
|
</el-image>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="position: fixed;background-color: #eaeaea;bottom: 0px;width:195px;height:25px;
|
||||||
|
line-height: 25px;padding-left:20px;color:#666">
|
||||||
|
总张数 {{urls.length}}
|
||||||
|
</div>
|
||||||
|
</el-aside>
|
||||||
|
|
||||||
|
<el-container>
|
||||||
|
<!-- <el-header>-->
|
||||||
|
<!-- <div style="height: 100px;width: 100%">-->
|
||||||
|
<!-- <el-radio-group style="margin: 10px auto" v-model="debugMode">-->
|
||||||
|
<!-- <el-radio-button :label="true">调试模式</el-radio-button>-->
|
||||||
|
<!-- <el-radio-button :label="false">开发模式</el-radio-button>-->
|
||||||
|
<!-- </el-radio-group>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </el-header>-->
|
||||||
|
<el-header height="auto" v-if="!debugMode">
|
||||||
|
<div class="menuContainer">
|
||||||
|
|
||||||
|
<div style="display: inline-block;float: left;margin: 14px 0px;cursor: pointer">
|
||||||
|
<div class="iconContainer" @click="openDeviceSetting">
|
||||||
|
<img src="images/icons/setup.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menus">扫描设定</div>
|
||||||
|
</div>
|
||||||
|
<ul v-show="deviceOpened" style="float: left;padding-left: 0px">
|
||||||
|
|
||||||
|
<li @click="startScan()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/scan.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">顺序扫描</div>
|
||||||
|
</li>
|
||||||
|
<li @click="stopScan()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/stop.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">停止扫描</div>
|
||||||
|
</li>
|
||||||
|
<li @click="insertScan()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/insert-scan.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">插入扫描</div>
|
||||||
|
</li>
|
||||||
|
<li @click="coverScan()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/cover-scan.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">覆盖扫描</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
width="360"
|
||||||
|
v-model="showBatchList">
|
||||||
|
<p style="font-weight: bold;font-size: 21px;color: black">批次选择</p>
|
||||||
|
|
||||||
|
<div @click="changeBatch(item)" class="batch-item" v-for="(item,index) in batchIdList" :key="index"
|
||||||
|
style="text-align: center;margin: 0;height: 45px;width: 100%;font-size: 21px">
|
||||||
|
|
||||||
|
<div style="display: inline-block;float: right;width: 120px;height: 100%">
|
||||||
|
<div class="operaBg" @click.stop="modifyBatchId(item,index)"
|
||||||
|
style="position:relative;line-height: 45px;float: left;display: inline;width: 60px;height:100%;">
|
||||||
|
<img style="position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);width: 28px;height: 28px"
|
||||||
|
src="images/icons/editor.png" title="编辑">
|
||||||
|
</div>
|
||||||
|
<div class="operaBg" @click.stop="deleteBatch(item,index)"
|
||||||
|
style="position:relative;float: left;display: inline;width: 50%;height:45px">
|
||||||
|
<img style="position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);height: 28px;width: 28px"
|
||||||
|
src="images/icons/delete.png" title="删除">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span style="line-height: 45px;text-align: center;overflow: hidden;display: inline-block;float: right;height: 100%;width: 240px">{{item}}</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<el-divider></el-divider>
|
||||||
|
<div @click="createNewBatch" class="batch-item"
|
||||||
|
style="font-weight: bold;text-align: center; margin: 0;width: 100%;font-size: 21px;height: 45px;line-height: 45px">
|
||||||
|
新建批次
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="reference">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/betch.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">选择批次</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</li>
|
||||||
|
<li @click="deleteSelectedImage()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/delImage.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">删除图片</div>
|
||||||
|
</li>
|
||||||
|
<li @click="exchangeImage()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/exchange.png" style="height:31px"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">图片互换</div>
|
||||||
|
</li>
|
||||||
|
<li @click="mergeHorizontal(true)">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/merge-horizontal.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">水平合并</div>
|
||||||
|
</li>
|
||||||
|
<li @click="mergeHorizontal(false)">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/merge-vertical.png" style="height:31px"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">垂直合并</div>
|
||||||
|
</li>
|
||||||
|
<li @click="bookSort()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/book_sort.png" style="height:31px"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">书籍自动排序</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li @click="showBatchMarkConfigure=true">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/add-watermark.png" style="height:31px"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">批量添加水印</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
width="160"
|
||||||
|
v-model="showExportType">
|
||||||
|
<p style="font-weight: bold;font-size: 21px;color: black">导出类型选择</p>
|
||||||
|
|
||||||
|
<div style="text-align: center;margin: 0;height: 60px;width: 100%;font-size: 21px">
|
||||||
|
<div class="batch-item" @click="exportFile('pdf')"
|
||||||
|
style="position:relative;line-height: 45px;float: left;display: inline;width: 50%;height:100%;">
|
||||||
|
<img style="position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);width: 40px;height: 40px"
|
||||||
|
src="images/icons/pdf.png" title="pdf">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="batch-item" @click="exportFile('ofd')"
|
||||||
|
style="position:relative;float: left;display: inline;width: 50%;height:100%">
|
||||||
|
<img style="height: 40px;width:40px;position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);"
|
||||||
|
src="images/icons/ofd.png" title="ofd">
|
||||||
|
</div>
|
||||||
|
<div class="batch-item" @click="exportFile('tif')"
|
||||||
|
style="position:relative;float: left;display: inline;width: 50%;height:100%">
|
||||||
|
<img style="position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);height: 40px;width: 40px"
|
||||||
|
src="images/icons/tiff.png" title="tiff">
|
||||||
|
</div>
|
||||||
|
<div class="batch-item" @click="exportFile('zip')"
|
||||||
|
style="position:relative;float: left;display: inline;width: 50%;height:100%">
|
||||||
|
<img style="position: absolute; left: 50%; top: 50%;transform: translate(-50%, -50%);height: 40px;width: 40px"
|
||||||
|
src="images/icons/zip.png" title="zip">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div slot="reference">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/export-file.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">文件导出</div>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</li>
|
||||||
|
<li @click="clearBatch()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/delAll.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">清空列表</div>
|
||||||
|
</li>
|
||||||
|
<li @click="clearGlobalFileSavePath()">
|
||||||
|
<div class="iconContainer">
|
||||||
|
<img src="images/icons/delete-all.png"/>
|
||||||
|
</div>
|
||||||
|
<div class="menu">清理全局文件保存目录</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<div style="width: 100%;height: 100%">
|
||||||
|
|
||||||
|
<div v-if="debugMode" style="height: 100%">
|
||||||
|
<div style="float: left;width: 60%;height: 100%;margin-top: 10px;margin-left: 10px;display: inline-block">
|
||||||
|
|
||||||
|
<el-input style="display: inline-block;width: 200px" v-model="serverIP" placeholder="请输入ip"></el-input>
|
||||||
|
<el-input style="display: inline-block;width: 200px" v-model="serverPort" placeholder="请输入端口号"></el-input>
|
||||||
|
|
||||||
|
<el-button :disabled="!connectEnable" type="primary" @click="initWebSocket()">连接</el-button>
|
||||||
|
<el-button :disabled="connectEnable" type="primary" @click="disconnectSocket()">断开</el-button>
|
||||||
|
<div style="margin-top: 30px">
|
||||||
|
|
||||||
|
<el-input style="display: inline-block;width: 400px" type="textarea"
|
||||||
|
:autosize="{ minRows: 5, maxRows: 10}" v-model="socketCommand"
|
||||||
|
:placeholder="jsonCommadnHolder"></el-input>
|
||||||
|
<el-button style="margin:auto 0px" type="primary" @click="sendSocketCommand()">发送socket命令</el-button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 30px">
|
||||||
|
|
||||||
|
<span style="margin-right: 30px">接收到的socket信息以及异常:</span>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="clearLog()">清空日志</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ref="logArea"
|
||||||
|
style="margin-top: 20px;height:400px;width: 100%;background-color: #e3e3e3;overflow: scroll;white-space: pre-wrap;line-height:1.5">
|
||||||
|
{{socketMsg}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="float: left;width: 1px;height: 100%;background-color:#e3e3e3;margin-right: 30px;margin-left: 30px;margin-top: 10px"></div>
|
||||||
|
<div style="float: left;width: 30%;height: 100%;margin-right: 30px;margin-top: 10px;display: inline-block">
|
||||||
|
<el-input type="textarea"
|
||||||
|
:autosize="{ minRows: 6, maxRows: 10}" v-model="originJson" style="display: inline-block;width: 400px;max-height: 400px"
|
||||||
|
placeholder="请输入数据源"></el-input>
|
||||||
|
|
||||||
|
<el-button style="margin-top: 10px" type="primary" @click="formatJson()">格式化json</el-button>
|
||||||
|
|
||||||
|
<div style="width:100%;height:60%;margin-top: 20px;background-color: #e3e3e3;overflow: scroll">
|
||||||
|
<pre id='preId' style="white-space: pre;line-height: 1.5">{{formatedJson}}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else style="height: 100%;width: 100%;position: relative">
|
||||||
|
|
||||||
|
<div class="opt">
|
||||||
|
<ul style="margin-left:-40px;line-height:24px">
|
||||||
|
<li @click="scaleMax($event)">
|
||||||
|
<img src="images/icons/amplify.png" title="放大"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="scaleMin($event)">
|
||||||
|
<img src="images/icons/narrow.png" title="缩小"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="ajustDimensions($event)">
|
||||||
|
<img src="images/icons/auto.png" title="自适应"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="realDimensions($event,true)">
|
||||||
|
<img src="images/icons/real.png" title="实际大小"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="addListenerToDiv($event)">
|
||||||
|
<img src="images/icons/drag.png" title="拖拽"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="rotate(-90,$event)">
|
||||||
|
<img src="images/icons/left-roate.png" title="左旋90度"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="rotate(90,$event)">
|
||||||
|
<img src="images/icons/right-roate.png" title="右旋90度"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="rotate(180,$event)">
|
||||||
|
<img src="images/icons/roate.png" title="旋转180度"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="innerErase($event)">
|
||||||
|
<img src="images/icons/erase-inner.png" title="内擦除"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="outerErase($event)">
|
||||||
|
<img src="images/icons/erase-outter.png" title="外擦除"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="rectification($event)" id="rectification">
|
||||||
|
<img src="images/icons/rectification.png" title="纠偏"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="undo($event)">
|
||||||
|
<img src="images/icons/undo.png" title="撤销" v-if="undoStack.length>0"></img>
|
||||||
|
<img src="images/icons/undogray.png" title="撤销"
|
||||||
|
v-if="undoStack.length<=0"></img>
|
||||||
|
</li>
|
||||||
|
<li @click="redo($event)">
|
||||||
|
<img src="images/icons/redo.png" title="前进" v-if="redoStack.length>0"/>
|
||||||
|
<img src="images/icons/redogray.png" title="前进"
|
||||||
|
v-if="redoStack.length<=0"/>
|
||||||
|
</li>
|
||||||
|
<li @click="split(true,$event)">
|
||||||
|
<img src="images/icons/split-horizontal.png" title="垂直拆分">
|
||||||
|
</li>
|
||||||
|
<li @click="split(false,$event)">
|
||||||
|
<img src="images/icons/split-vertical.png" title="水平拆分"/>
|
||||||
|
</li>
|
||||||
|
<li @click="showWaterMarkConfigure($event)">
|
||||||
|
<img src="images/icons/water-mark.png" title="添加水印"/>
|
||||||
|
</li>
|
||||||
|
<li @click="save()">
|
||||||
|
<img src="images/icons/save.png" title="保存"/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="image-container scroll" id="canvas-container" ref="canvasContainer"
|
||||||
|
@contextmenu.prevent>
|
||||||
|
<div v-show="showWaterMark" ref="water-mark-opt"
|
||||||
|
style="background-color: white;width: 300px;height: 300px;z-index:20;position: absolute;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);left: 80px;top: 450px;padding: 8px">
|
||||||
|
<div>
|
||||||
|
<span>输入文字</span>
|
||||||
|
<el-input v-model="waterMarkText" style="width: 220px" placeholder="请输入要添加的文字"></el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 8px"><span>选择字体</span>
|
||||||
|
<el-select v-model="markFontName" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in markFontNameList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px"><span>选择字号</span>
|
||||||
|
<el-select v-model="markFontSize" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in markFontSizeList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span>字体颜色</span>
|
||||||
|
<el-color-picker
|
||||||
|
v-model="markFontColor"
|
||||||
|
:predefine="markPredefineColors">
|
||||||
|
</el-color-picker>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="width: 100%;margin-top: 8px">
|
||||||
|
<div>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontBold">
|
||||||
|
粗体
|
||||||
|
</el-checkbox>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontUnderline">下划线</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontItalic">斜体</el-checkbox>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontStrikeout">删除线</el-checkbox>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 0 auto;display: inline-block;position: absolute;right: 8px;bottom:8px ">
|
||||||
|
<el-button @click="showWaterMark=false" type="info">取消</el-button>
|
||||||
|
<el-button @click="confirmMarkConfigure" type="primary">确定</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="showWaterMarkPosition" ref="water-mark-opt"
|
||||||
|
style="background-color: white;width: 160px;height: 40px;z-index:20;position: absolute;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);left: 80px;bottom: 120px;padding: 8px">
|
||||||
|
x:{{markPositionTipX}} y:{{markPositionTipY}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="position: absolute;z-index:20000;top:30px;right:32px"
|
||||||
|
v-if="rectificationDialog">
|
||||||
|
<div style="display: flex;">
|
||||||
|
<span style="margin-top:8px">拖动旋转</span>
|
||||||
|
<el-slider @change="sliderRotateChange" style="width:420px;margin-left:20px"
|
||||||
|
v-model="repSliderValue" :min=-360 :max=360 :step=1
|
||||||
|
show-input=true input-size="mini"></el-slider>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<canvas id="imageCanvas" height="100%" width="100%"></canvas>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="扫描设定"
|
||||||
|
:visible.sync="isSetup"
|
||||||
|
width="50%">
|
||||||
|
<div class="messageBox">
|
||||||
|
<el-form ref="form" :model="scanParams" label-width="120px"
|
||||||
|
style="padding-left:10px">
|
||||||
|
<el-tabs v-model="activeName">
|
||||||
|
<el-tab-pane style="margin: 18px" label="设备参数" name="1">
|
||||||
|
<el-form-item label="设备" required>
|
||||||
|
<el-select @change="onDeviceChanged" v-model="currDevice" placeholder="请选择扫描仪" filterable="true">
|
||||||
|
<el-option :label="device" :value="device"
|
||||||
|
v-for="(device, index) in devices" :key="device">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-tag class="cursor-pointer" style="margin-left: 30px" v-show="deviceOpened" @click="resetScanParams">参数重置
|
||||||
|
</el-tag>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div v-if="deviceOpened">
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane v-for="(groupParam,groupIndex) in scanParamsRange" :key="groupIndex"
|
||||||
|
:label="groupParam.group_name">
|
||||||
|
<el-form-item v-for="(singleParam,singleParamIndex) in groupParam.group_param" :key="singleParamIndex"
|
||||||
|
:label="singleParam.name" label-width="auto">
|
||||||
|
|
||||||
|
|
||||||
|
<el-switch v-if="singleParam.value_type==='bool'"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"></el-switch>
|
||||||
|
|
||||||
|
|
||||||
|
<el-select v-else-if="singleParam.value_type==='string'"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"
|
||||||
|
placeholder="请选择">
|
||||||
|
<el-option v-for="(paramRange,index) in singleParam.value_list" :label="paramRange"
|
||||||
|
:value="paramRange"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="singleParam.value_type==='double'&&singleParam.range_type==='min_max'"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"
|
||||||
|
:min="singleParam.value_min"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.01"
|
||||||
|
placeholder="请输入"
|
||||||
|
:max="singleParam.value_max"></el-input-number>
|
||||||
|
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="singleParam.value_type==='int'&&singleParam.range_type==='min_max'"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"
|
||||||
|
:min="singleParam.value_min" :step="1" :precision="0"
|
||||||
|
placeholder="请输入"
|
||||||
|
:max="singleParam.value_max"></el-input-number>
|
||||||
|
|
||||||
|
<el-select
|
||||||
|
v-else-if="singleParam.value_type=='int'&&singleParam.range_type==='list'"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"
|
||||||
|
placeholder="请选择">
|
||||||
|
<el-option v-for="(paramRange,index) in singleParam.value_list" :label="paramRange"
|
||||||
|
:value="paramRange"></el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="singleParam.value_type=='int'&&singleParam.range_type==undefined"
|
||||||
|
v-model="scanParams[groupIndex].group_param[singleParamIndex].value"
|
||||||
|
:min="1" :step="1" :precision="0"
|
||||||
|
placeholder="请输入"
|
||||||
|
:max="9999"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<el-form-item label="模式">
|
||||||
|
<el-radio-group v-model="scanParams.color_mode">
|
||||||
|
<el-radio v-for="(itemInfo,index) in scanParamsRange.color_mode_list" :label="itemInfo">
|
||||||
|
{{parameterTranslation(itemInfo)}}
|
||||||
|
</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="单双面">
|
||||||
|
<el-radio-group v-model="scanParams.page_mode">
|
||||||
|
<el-radio v-for="(itemInfo,index) in scanParamsRange.page_mode_list" :label="itemInfo">
|
||||||
|
{{parameterTranslation(itemInfo)}}
|
||||||
|
</el-radio>
|
||||||
|
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分辨率">
|
||||||
|
<el-select v-model="scanParams.resolution" placeholder="请选择分辨率">
|
||||||
|
<el-option v-for="(itemInfo,index) in scanParamsRange.resolution_list" :label="itemInfo"
|
||||||
|
:value="itemInfo"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="扫描幅面">
|
||||||
|
<el-select v-model="scanParams.paper_size" placeholder="请选择幅面">
|
||||||
|
<el-option v-for="(itemInfo,index) in scanParamsRange.paper_size_list"
|
||||||
|
:label="parameterTranslation(itemInfo)" :value="itemInfo"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否纠偏">
|
||||||
|
<el-switch v-model="scanParams.auto_crop"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="是否裁剪">
|
||||||
|
<el-switch v-model="scanParams.paper_cut_enabled"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div v-show="scanParams.paper_cut_enabled">
|
||||||
|
<el-form-item label="起始位置点坐标X">
|
||||||
|
<el-input v-model="scanParams.paper_cut_left"
|
||||||
|
placeholder="请输入坐标点X的值"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="起始位置点坐标Y">
|
||||||
|
<el-input v-model="scanParams.paper_cut_top"
|
||||||
|
placeholder="请输入坐标点Y的值"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="终点位置点坐标X">
|
||||||
|
<el-input v-model="scanParams.paper_cut_right"
|
||||||
|
placeholder="请输入坐标点X的值"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="终点位置点坐标Y">
|
||||||
|
<el-input v-model="scanParams.paper_cut_bottom"
|
||||||
|
placeholder="请输入坐标点Y的值"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-form-item label="亮度">
|
||||||
|
<el-slider v-model="scanParams.brightness" :min="1"
|
||||||
|
:max="255"></el-slider>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="对比度">
|
||||||
|
<el-slider v-model="scanParams.contrast" :min="1"
|
||||||
|
:max="7"></el-slider>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="伽马值">
|
||||||
|
<el-input-number v-model="scanParams.gamma" :precision="2" :min="0.01" :step="0.01"
|
||||||
|
:max="5.00"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<el-tab-pane style="margin: 18px" label="全局配置" name="2" :disabled="!deviceOpened">
|
||||||
|
<el-form-item label="文件保存目录">
|
||||||
|
<el-input v-model="globalConfig.file_save_path"
|
||||||
|
placeholder="请输入文件保存目录"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="文件绑定目录">
|
||||||
|
<el-input v-model="bindFolderPath"
|
||||||
|
placeholder="请输入文件绑定目录"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="文件名前缀">
|
||||||
|
<el-input v-model="globalConfig.file_name_prefix"
|
||||||
|
placeholder="请输入文件名前缀"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="文件命名规则">
|
||||||
|
<el-select v-model="globalConfig.file_name_mode" placeholder="请选择命名规则">
|
||||||
|
<el-option label="date_time" value="date_time"></el-option>
|
||||||
|
<el-option label="random" value="random"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="文件保存格式">
|
||||||
|
<el-select v-model="globalConfig.image_format" placeholder="请选择格式">
|
||||||
|
<el-option label="jpg" value="jpg"></el-option>
|
||||||
|
<el-option label="png" value="png"></el-option>
|
||||||
|
<el-option label="bmp" value="bmp"></el-option>
|
||||||
|
<el-option label="tif" value="tif"></el-option>
|
||||||
|
<el-option label="pdf" value="pdf"></el-option>
|
||||||
|
<el-option label="ofd" value="ofd"></el-option>
|
||||||
|
<el-option label="ocr-pdf" value="ocr-pdf"></el-option>
|
||||||
|
<el-option label="ocr-ofd" value="ocr-ofd"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="jpg图片质量" v-show='globalConfig.image_format=="jpg"'>
|
||||||
|
<el-slider v-model="globalConfig.image_jpeg_quality" :min="0"
|
||||||
|
:max="100"></el-slider>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
<el-form-item label="tiff压缩方式" v-show='globalConfig.image_format=="tif"'>
|
||||||
|
|
||||||
|
<el-select v-model="globalConfig.image_tiff_compression">
|
||||||
|
<el-option label="none" value="none"></el-option>
|
||||||
|
<el-option label="lzw" value="lzw"></el-option>
|
||||||
|
<el-option label="jpeg" value="jpeg"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="tiff压缩质量"
|
||||||
|
v-show='globalConfig.image_format=="tif"&&globalConfig.image_tiff_compression=="jpeg"'>
|
||||||
|
<el-slider v-model="globalConfig.image_tiff_jpeg_quality" :min="0"
|
||||||
|
:max="100"></el-slider>
|
||||||
|
</el-form-item>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
<el-divider content-position="center">HTTP上传配置</el-divider>
|
||||||
|
<el-form-item label="上传地址">
|
||||||
|
<el-input v-model="globalConfig.upload_http_host"
|
||||||
|
placeholder="请输入上传地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="端口">
|
||||||
|
<el-input v-model="globalConfig.upload_http_port"
|
||||||
|
placeholder="请输入端口号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="上传路径">
|
||||||
|
<el-input v-model="globalConfig.upload_http_path"
|
||||||
|
placeholder="请输入上传路径"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
<el-divider content-position="center">FTP上传配置</el-divider>
|
||||||
|
<el-form-item label="上传地址">
|
||||||
|
<el-input v-model="globalConfig.upload_ftp_host"
|
||||||
|
placeholder="请输入上传地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="端口号">
|
||||||
|
<el-input v-model="globalConfig.upload_ftp_port"
|
||||||
|
placeholder="请输入端口号"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户名">
|
||||||
|
<el-input v-model="globalConfig.upload_ftp_user"
|
||||||
|
placeholder="请输入用户名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="密码">
|
||||||
|
<el-input v-model="globalConfig.upload_ftp_password"
|
||||||
|
placeholder="请输入密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<el-row style="text-align:center" v-if="deviceOpened">
|
||||||
|
<el-button type="primary" @click="saveParams()">保存</el-button>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="批量添加水印"
|
||||||
|
:visible.sync="showBatchMarkConfigure"
|
||||||
|
width="30%">
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>插入值</span>
|
||||||
|
<el-input style="width: 70%;margin-left: 16px" v-model="waterMarkText" placeholder="请输入文字"></el-input>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>插入位置</span>
|
||||||
|
<el-select style="margin-left: 16px" v-model="markPosition" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="(item,index) in waterMarkPositionList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="waterMarkPositionSignList[index]">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="markPosition!='location'">
|
||||||
|
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>上边距</span>
|
||||||
|
<el-input style="width: 70%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markMarginTop" placeholder="请输入距离"></el-input>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>下边距</span>
|
||||||
|
<el-input style="width: 70%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markMarginBottom" placeholder="请输入距离"></el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>左边距</span>
|
||||||
|
<el-input style="width: 70%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markMarginLeft" placeholder="请输入距离"></el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>右边距</span>
|
||||||
|
<el-input style="width: 70%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markMarginRight" placeholder="请输入距离"></el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px" v-show="markPosition=='location'">
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>起始位置X坐标(像素)</span>
|
||||||
|
<el-input style="width: 50%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markAbsoluteX" placeholder="请输入X坐标"></el-input>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>起始位置Y坐标(像素)</span>
|
||||||
|
<el-input style="width: 50%;margin-left: 16px"
|
||||||
|
oninput="if(isNaN(value)) { value = ''}if(value.indexOf('.')>0){value=value.slice(0,value.indexOf('.'))}"
|
||||||
|
v-model="markAbsoluteY" placeholder="请输入Y坐标"></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>插入范围</span>
|
||||||
|
<el-slider
|
||||||
|
style="margin-left: 16px"
|
||||||
|
v-model="markInsertRange"
|
||||||
|
range
|
||||||
|
show-stops
|
||||||
|
:min="1"
|
||||||
|
:max="urls.length">
|
||||||
|
</el-slider>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin-top: 8px"><span>选择字体</span>
|
||||||
|
<el-select style="margin-left: 16px" v-model="markFontName" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in markFontNameList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px"><span>选择字号</span>
|
||||||
|
<el-select style="margin-left: 16px" v-model="markFontSize" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in markFontSizeList"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 8px">
|
||||||
|
<span>字体颜色</span>
|
||||||
|
<el-color-picker
|
||||||
|
style="margin-left: 16px"
|
||||||
|
v-model="markFontColor"
|
||||||
|
:predefine="markPredefineColors">
|
||||||
|
</el-color-picker>
|
||||||
|
</div>
|
||||||
|
<div style="width: 200px;margin-top: 8px;height: 60px">
|
||||||
|
<span>字体样式</span>
|
||||||
|
<div style="width: 100%">
|
||||||
|
<el-checkbox class="font-style" v-model="markFontBold">粗体</el-checkbox>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontUnderline">下划线</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div style="width: 100%">
|
||||||
|
<el-checkbox class="font-style" v-model="markFontItalic">斜体</el-checkbox>
|
||||||
|
<el-checkbox class="font-style" v-model="markFontStrikeout">删除线</el-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="width: 100%;height: 40px">
|
||||||
|
<el-button style="float: right" type="primary" @click="addWaterMarkWithBatch">确 定</el-button>
|
||||||
|
<el-button style="float: right;margin-right: 16px" @click="showBatchMarkConfigure = false">取 消</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
<div v-if="showBigImageDialog"
|
||||||
|
style="position: fixed;left: 0px;right: 0px;top: 0px;bottom: 0px;background-color: #000000">
|
||||||
|
<el-image @dblclick="showBigImageDialog=false"
|
||||||
|
ref="bigImage" :src="selectBigImage" fit="scale-down"
|
||||||
|
lazy
|
||||||
|
style="position:absolute;height:95%;width: 100%;left: 50%;top: 50%;transform: translate(-50%,-50%)">
|
||||||
|
</el-image>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
<script src="js/polyfill.min.js"></script>
|
||||||
|
<script src="js/vue.min.js"></script>
|
||||||
|
<script src="js/element-ui/index.js"></script>
|
||||||
|
<script src="js/jquery-1.11.1.min.js"></script>
|
||||||
|
<script src="js/fabric.js"></script>
|
||||||
|
<script src="js/ScanEvent.js"></script>
|
||||||
|
<script src="js/WebScanController.js"></script>
|
||||||
|
<script src="js/util.js"></script>
|
||||||
|
<script src="js/FileSaver.js"></script>
|
||||||
|
<script src="js/colorpicker.js"></script>
|
||||||
|
<script src="js/scanWeb.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Type=Application
|
||||||
|
Name=HanvonScan
|
||||||
|
Name[zh_CN]=汉王扫描仪网页服务器重启
|
||||||
|
Exec=sh /opt/hanvonwebscan/bin/restart.sh
|
||||||
|
Icon=/opt/hanvonwebscan/static/hanvon_logo.png
|
||||||
|
Categories=Application;
|