Commit 70226210 authored by 赵啸非's avatar 赵啸非

Initial commit

parents
Pipeline #2816 failed with stages
*.iml
node_modules/
.idea/
*.class
target/
\ No newline at end of file
# 国产化中间件
国产化系统中间件,提供BS与硬件对接,调用方式为HTTP API方式,常驻后台,实现语言为JAVA。
\ No newline at end of file
{"cutType":0,"roteAngle":0,"cameraIndex":0,"maxPhoto":0,"ratio":"640x480"}
\ No newline at end of file
本中间件方案中采用什么组件或方式实现HTTPAPI服务,参考来源或简单代码
\ No newline at end of file
采用什么组件或方式实现HTTPAPI服务,参考来源或简单代码
成熟方式:
springMVC+sping boot+tomcat
spring系列是目前java基本通用的http服务框架模式,大多网络应用服务都采用ssm框架模式。
优点:
框架帮你完成了路由控制,业务数据转换,调度等等功能,使用会比较简单。
缺点:
体积较大,打包部署大概在70M~100M,针对小型应用有点过重。
样列:略
轻量化:
java servelt + tomcat
比较老旧的java http server 实现方案
优点:
轻量化,只需要加载几个jar包。运行tomcat容器即可。
缺点:
实现都比较老旧,开发方式会比较麻烦,需要重启熟悉路由规则配置等。
样列:https://www.jianshu.com/p/b3bad015020e
轻量化:
httpServer内部服务
优点:
简单,不需要依赖第三方框架,通过java内部实现即可。
缺点:
异常,session,路由控制等等及其它服务器稳定性功能需求都需自己实现。
样列:略
轻量化:
netty异步服务
优点:
速度快,体积小,可异步进行通信。
缺点:
开发难度高,http api也会在内部已异步handle方式进行流转
轻量化:
httpServer内部服务
优点:
简单,不需要依赖第三方框架,通过java内部实现即可。
缺点:
异常,session,路由控制等等及其它服务器稳定性功能需求都需自己实现。
样列:略
样列:
/**
* 根据Java提供的API实现Http服务器
*/
public class MyHttpServer {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// 创建HttpServer服务器,
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 10);
//将请求交给MyHandler处理器处理
httpServer.createContext("/", new MyHandler());
httpServer.start();
}
}
class MyHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
String content = "hello";
//设置响应头属性及响应信息的长度
httpExchange.sendResponseHeaders(200, content.length());
//获得输出流
OutputStream os = httpExchange.getResponseBody();
os.write(content.getBytes());
os.close();
}
}
本中间件方案中JAVA调用打印机的实现确定(来源或简单代码):
1、JAVA调用打印机方式(如:java1.4以上的awt.print)
2、JAVA打印机状态检测方式(如:snmp检测方式)
\ No newline at end of file
以下代码实现java调用打印服务遍历打印机(采用java1.4版本开始的原生打印服务),已经通过测试。
===========================================================================
--------------------------------------MyPrint.java-------------------------
import java.awt.print.*;
import javax.print.*;
class MyPrint{
public static void main(String[] args){
System.out.println("Hello World!");
//获得本台电脑连接的所有打印机
PrintService[] printServices = PrinterJob.lookupPrintServices();
if(printServices == null || printServices.length == 0) {
System.out.print("打印失败,未找到可用打印机,请检查。");
return ;
}
PrintService printService = null;
String printerName = "xx打印机";
//遍历打印机
for (int i = 0;i < printServices.length; i++) {
System.out.println(printServices[i].getName());
if (printServices[i].getName().contains(printerName)) {
printService = printServices[i];
break;
}
}
}
}
--------------------------------------MyPrint.java-------------------------
javac MyPrint.java
java MyPrint
===========================================================================
以下为网上的JAVA打印资料:
https://www.jianshu.com/p/be0456f5265d
java实现打印功能
https://blog.csdn.net/weixin_39818264/article/details/114032503?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5-114032503-blog-114158354.pc_relevant_3mothn_strategy_recovery&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5-114032503-blog-114158354.pc_relevant_3mothn_strategy_recovery&utm_relevant_index=6
java 打印图片_java打印程序——打印图片(不带对话框)
https://blog.csdn.net/weixin_29266007/article/details/114158354?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-114158354-blog-79748598.pc_relevant_multi_platform_whitelistv3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-114158354-blog-79748598.pc_relevant_multi_platform_whitelistv3&utm_relevant_index=8
java打印图片_java如何调用本地打印机进行图片打印
https://blog.csdn.net/baidu_37366055/article/details/105427208?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-105427208-blog-51754068.pc_relevant_aa2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-105427208-blog-51754068.pc_relevant_aa2&utm_relevant_index=2
JAVA调用打印机
https://blog.csdn.net/dailuwen/article/details/51754068#:~:text=PrintService%20%E4%BD%BF%E7%94%A8%20java%20x.%20print%20%E5%8C%85%E4%B8%8B%E7%9A%84%E7%B1%BB%E6%9D%A5%20%E6%89%93%E5%8D%B0%20%EF%BC%8C%E5%8F%AF%E4%BB%A5,print.pdf%22%29%2C%20DocFlavor.BYTE_ARRAY.PDF%2C%20null%29%3B%20PrintService%20ps%20%3D%20Print%20S
JAVA 本地打印 DocFlavor、DocPrintJob job、PrintService
https://blog.csdn.net/m0_46267097/article/details/112609095
Java调用打印机打印(远程、本地皆可用)
中间件安装部署方式:
1、打包方式(如:DEB)
2、开机启动
3、安装
4、卸载
\ No newline at end of file
https://blog.csdn.net/slf_123/article/details/109466720
linux-deb安装包打包
https://blog.csdn.net/wf19930209/article/details/79277091
linux的程序打包deb
https://www.cnblogs.com/wjg123/p/14216803.html
linux软件deb打包及开机管理员自启动
https://cloud.tencent.com/developer/article/1625609
Linux设置开机启动的三种方式
-----------------------------------------------------------------------------
非deb包安装部署:
安装包(deploy.sh+xxxx.tar)
1.复制到任意目录,执行deploy.sh脚本服务部署文件。
2.脚本自动安装jdk环境,与中间件服务自启service。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mortals</groupId>
<artifactId>mortals-common</artifactId>
<version>1.1.7-SNAPSHOT</version>
<relativePath/>
</parent>
<groupId>com.mortals.xhx</groupId>
<artifactId>tts-platform</artifactId>
<version>1.0.0-SNAPSHOT</version>
<profiles>
<profile>
<id>develop</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profiles.active>develop</profiles.active>
<profiles.filepath>/mortals/data</profiles.filepath>
<profiles.log.level>INFO</profiles.log.level>
<profiles.log.path>/logs</profiles.log.path>
<profiles.data.path>/data</profiles.data.path>
<profiles.server.port>9000</profiles.server.port>
<profiles.siteconfig.filepath>F:\\mid.prop</profiles.siteconfig.filepath>
<profiles.siteconfig.configpath>F:\\config.prop</profiles.siteconfig.configpath>
<profiles.siteconfig.url>http://192.168.0.98:8090</profiles.siteconfig.url>
<profiles.javacpp.platform>windows-x86_64</profiles.javacpp.platform>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
<profiles.filepath>/tmp</profiles.filepath>
<profiles.log.level>INFO</profiles.log.level>
<profiles.log.path>/root/logs</profiles.log.path>
<profiles.server.port>9000</profiles.server.port>
<profiles.siteconfig.filepath>/root/mid.prop</profiles.siteconfig.filepath>
<profiles.siteconfig.configpath>/root/config.prop</profiles.siteconfig.configpath>
<profiles.siteconfig.url>http://192.168.0.98:8090</profiles.siteconfig.url>
<profiles.javacpp.platform>linux-x86_64</profiles.javacpp.platform>
<!-- <profiles.javacpp.platform>linux-arm64</profiles.javacpp.platform>-->
</properties>
</profile>
<profile>
<id>reg</id>
<properties>
<profiles.active>reg</profiles.active>
<profiles.filepath>/tmp</profiles.filepath>
<profiles.log.level>INFO</profiles.log.level>
<profiles.log.path>/mortals/app/logs</profiles.log.path>
<profiles.server.port>9000</profiles.server.port>
<profiles.siteconfig.filepath>/root/mid.prop</profiles.siteconfig.filepath>
<profiles.siteconfig.configpath>/root/config.prop</profiles.siteconfig.configpath>
<profiles.siteconfig.url>http://10.207.153.67:8090</profiles.siteconfig.url>
<profiles.javacpp.platform>linux-arm64</profiles.javacpp.platform>
</properties>
</profile>
</profiles>
<properties>
<common-lib.version>0.0.1-SNAPSHOT</common-lib.version>
<pcap4j.version>1.8.2</pcap4j.version>
<zxing.version>3.4.1</zxing.version>
<javacpp.platform.linux-armhf>linux-armhf</javacpp.platform.linux-armhf>
<javacpp.platform.linux-arm64>linux-arm64</javacpp.platform.linux-arm64>
<javacpp.platform.linux-ppc64le>linux-ppc64le</javacpp.platform.linux-ppc64le>
<javacpp.platform.linux-x86>linux-x86</javacpp.platform.linux-x86>
<javacpp.platform.linux-x86_64>linux-x86_64</javacpp.platform.linux-x86_64>
<javacpp.platform.windows-x86>windows-x86</javacpp.platform.windows-x86>
<javacpp.platform.windows-x86_64>windows-x86_64</javacpp.platform.windows-x86_64>
</properties>
<dependencies>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacpp</artifactId>
<version>1.5.5</version>
<classifier>${profiles.javacpp.platform}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>openblas</artifactId>
<version>0.3.13-1.5.5</version>
<classifier>${profiles.javacpp.platform}</classifier>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.5.1-1.5.5</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>opencv</artifactId>
<version>4.5.1-1.5.5</version>
<classifier>${profiles.javacpp.platform}</classifier>
</dependency>
<dependency>
<groupId>com.mortals.framework</groupId>
<artifactId>mortals-framework-springcloud</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- 引入 SpringMVC 相关依赖,并实现对其的自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--抓取网络包-->
<dependency>
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-core</artifactId>
<version>${pcap4j.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.pcap4j</groupId>
<artifactId>pcap4j-packetfactory-static</artifactId>
<version>${pcap4j.version}</version>
</dependency>
<!--Zxing 条形码二维码生成和解析工具-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing.version}</version>
</dependency>
<!-- &lt;!&ndash;opencv配置&ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.opencv</groupId>-->
<!-- <artifactId>opencv</artifactId>-->
<!-- <version>3.4.16</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/src/main/resources/lib/opencv-3416.jar</systemPath>-->
<!-- </dependency>-->
<!--第三方调用摄像头-->
<dependency>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture</artifactId>
<version>0.3.12</version>
</dependency>
<!-- Gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.dorkbox</groupId>
<artifactId>Notify</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>3.0.9</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<skipTests>true</skipTests> <!--默认关掉单元测试 -->
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<outputDirectory>dist/${project.artifactId}/conf</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>etlsql/**</include>
<include>sqlmap/**</include>
<include>config/**</include>
<include>*.yml</include>
<include>*.xml</include>
<include>*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-bin</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<outputDirectory>dist/${project.artifactId}/bin</outputDirectory>
<resources>
<resource>
<directory>src/main/bin/</directory>
<filtering>true</filtering>
<includes>
<include>*.sh</include>
<include>*.png</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-boot</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<encoding>UTF-8</encoding>
<outputDirectory>dist/${project.artifactId}/boot</outputDirectory>
<resources>
<resource>
<directory>target</directory>
<includes>
<include>${project.artifactId}-${version}.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
{"siteId":21,"windowId":348,"siteName":"四川兴文经济开发区","windowName":"综合窗口(出件)"}
\ No newline at end of file
#! /bin/sh
PORT="8037"
BASEDIR=$(dirname $0)
BASEDIR=$( (
cd "$BASEDIR"
pwd
))
PROJECT_NAME="mid-platform"
MAIN_CLASS="$PROJECT_NAME"
if [ ! -n "$PORT" ]; then
echo $"Usage: $0 {port}"
exit $FAIL
fi
pid=$(ps ax | grep -i "$MAIN_CLASS" | grep java | grep -v grep | awk '{print $1}')
if [ -z "$pid" ]; then
echo "No Server running."
exit 1
fi
echo "stoping application $PROJECT_NAME......"
kill -15 ${pid}
echo "Send shutdown request to Server $PROJECT_NAME OK"
echo off
if not exist "%JAVA_HOME%\bin\java.exe" echo Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! & EXIT /B 1
set "JAVA=%JAVA_HOME%\bin\java.exe"
set BASEDIR=%~dp0
set BASEDIR="%BASEDIR:~0,-5%"
set PROJECT_NAME=@project.artifactId@
set APP_NAME=%PROJECT_NAME%-@project.version@.jar
set LOG_PATH="%BASEDIR%@profiles.log.path@/%PROJECT_NAME%"
if not exist "%LOG_PATH%" md "%LOG_PATH%"
set GC_PATH=%LOG_PATH%/gc.log
set HS_ERR_PATH=%LOG_PATH%PORT%-hs_err.log
set HEAP_DUMP_PATH=%LOG_PATH%/heap_dump.hprof
set TEMP_PATH=%LOG_PATH%/temp/
if not exist "%TEMP_PATH%" md "%TEMP_PATH%"
rem jvm启动参数
set JAVA_OPTS=-Xms512M -Xmx512M -Xss256K -XX:+UseAdaptiveSizePolicy -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:GCTimeRatio=39 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError
set JAVA_OPTS=%JAVA_OPTS% -XX:+PrintGCDateStamps -Xloggc:%GC_PATH%
set JAVA_OPTS=%JAVA_OPTS% -XX:ErrorFile=%HS_ERR_PATH%
set JAVA_OPTS=%JAVA_OPTS% -XX:HeapDumpPath=%HEAP_DUMP_PATH%
rem jvm config
set JVM_CONFIG=%JVM_CONFIG% -Dapp.name=%PROJECT_NAME%
set JVM_CONFIG=%JVM_CONFIG% -Dapp.port=%PORT%
set JVM_CONFIG=%JVM_CONFIG% -Djava.io.tmpdir=%TEMP_PATH%
set JVM_CONFIG=%JVM_CONFIG% -Dbasedir=%BASEDIR%
set DEBUG_OPTS=
if ""%1"" == ""debug"" (
set DEBUG_OPTS= -Xloggc:../logs/gc.log -verbose:gc -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=../logs
goto debug
)
set JMX_OPTS=
if ""%1"" == ""jmx"" (
set JMX_OPTS= -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9888 -Dcom.sun.management.jmxremote.ssl=FALSE -Dcom.sun.management.jmxremote.authenticate=FALSE
goto jmx
)
set "LOG_OPTS=--logging.config=%BASEDIR%/conf/logback-spring.xml"
echo "Starting the %APP_NAME%"
"%JAVA%" %JAVA_OPTS% -server %JVM_CONFIG% -jar %BASEDIR%/boot/%APP_NAME%
echo ""%JAVA%" %JAVA_OPTS% -server %JVM_CONFIG% -jar %BASEDIR%/boot/%APP_NAME% "
goto end
:debug
echo "debug"
"%JAVA%" -Xms512m -Xmx512m -server %DEBUG_OPTS% %JVM_CONFIG% -jar ../boot/%APP_NAME%
goto end
:jmx
"%JAVA%" -Xms512m -Xmx512m -server %JMX_OPTS% %JVM_CONFIG% -jar ../boot/%APP_NAME%
goto end
:end
pause
#!/bin/sh
PORT="8037"
BASEDIR=`dirname $0`/..
BASEDIR=`(cd "$BASEDIR"; pwd)`
PROJECT_NAME="mid-platform";
MAIN_CLASS="$PROJECT_NAME-1.0.0-SNAPSHOT.jar";
LOG_PATH="/opt/apps/mid-platform/logs/$PROJECT_NAME"
GC_PATH=$LOG_PATH/PROJECT_NAME"-gc.log"
HS_ERR_PATH=$LOG_PATH/PROJECT_NAME"-hs_err.log"
HEAP_DUMP_PATH=$LOG_PATH/PROJECT_NAME"-heap_dump.hprof"
TEMP_PATH=$LOG_PATH/temp/
SUCCESS=0
FAIL=9
if [ ! -n "$PORT" ]; then
echo $"Usage: $0 {port}"
exit $FAIL
fi
if [ ! -d $LOG_PATH ];
then
mkdir -p $LOG_PATH;
fi
if [ ! -d $TEMP_PATH ];
then
mkdir -p $TEMP_PATH;
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD=`which java > /dev/null 2>&1`
echo "Error: JAVA_HOME is not defined correctly."
exit $ERR_NO_JAVA
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "We cannot execute $JAVACMD"
exit $ERR_NO_JAVA
fi
if [ -e "$BASEDIR" ]
then
JAVA_OPTS="-Xms512M -Xmx1024M -Xss256K -XX:+UseAdaptiveSizePolicy -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:GCTimeRatio=39 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$GC_PATH -XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=$HS_ERR_PATH -XX:HeapDumpPath=$HEAP_DUMP_PATH"
fi
CLASSPATH=$CLASSPATH_PREFIX:
EXTRA_JVM_ARGUMENTS=""
cd "$BASEDIR/boot";
echo "starting application $PROJECT_NAME......"
exec "$JAVACMD" $JAVA_OPTS \
$EXTRA_JVM_ARGUMENTS \
-Dapp.name="$PROJECT_NAME" \
-Dapp.port="$PORT" \
-Dbasedir="$BASEDIR" \
-Djava.io.tmpdir=$TEMP_PATH \
-Dloader.path="file://$BASEDIR/conf,file://$BASEDIR/lib" \
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5514 \
-jar $MAIN_CLASS \
> /dev/null &
for i in {1..60}
do
jcpid=`ps -ef | grep -v "grep" | grep "$MAIN_CLASS" | grep "app.port=$PORT" | sed -n '1P' | awk '{print $2}'`
if [ $jcpid ]; then
echo "The $PROJECT_NAME start finished, PID is $jcpid"
exit $SUCCESS
else
echo "starting the application .. $i"
sleep 1
fi
done
echo "$PROJECT_NAME start failure!"
package com.mortals.xhx;
import com.mortals.framework.springcloud.boot.BaseWebApplication;
import com.mortals.xhx.swing.SwingArea;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;
//@SpringBootApplication(scanBasePackages = {"com.mortals"},exclude= {DataSourceAutoConfiguration.class})
@SpringBootApplication(scanBasePackages = {"com.mortals"},exclude={DataSourceAutoConfiguration.class})
@ServletComponentScan("com.mortals")
//@ImportResource(locations = {"classpath:config/spring-config.xml"})
public class ManagerApplication extends BaseWebApplication {
public static void main(String[] args) {
/* SpringApplication.run(ManagerApplication.class, args);*/
/* SpringApplication.run(ManagerApplication.class, args);*/
ApplicationContext ctx = new SpringApplicationBuilder(ManagerApplication.class)
.headless(false).run(args);
}
}
package com.mortals.xhx.base.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Operlog {
String msg() default "";
String params() default "";
}
package com.mortals.xhx.base.framework.aspect;
import cn.hutool.extra.servlet.ServletUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.ContentCachingRequestWrapper;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 打印每个请求的入参、出参等信息
*
* @author: zxfei
* @date: 2022/4/20 9:24
*/
//@Aspect
//@Component
@Slf4j
@Order(1)
//@Profile({"default", "develop", "test"})
public class WebLogAspect {
@Pointcut("execution(public * com.mortals..*Controller.*(..))")
public void webLog() {
}
@Pointcut("execution(public * com.mortals.xhx.base.framework.exception.ExceptionHandle.*(..))")
public void exceptions() {
}
/**
* 只在进入controller时记录请求信息
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// log.debug("请求路径 {} ,进入方法 {}", request.getRequestURI(), joinPoint.getSignature().getDeclaringTypeName() + ":" + joinPoint.getSignature().getName());
MDC.put("req", getRequestInfo(request).toJSONString());
MDC.put("startTime", String.valueOf(System.currentTimeMillis()));
}
/**
* 打印请求日志
*/
@AfterReturning(pointcut = "webLog()|| exceptions()", returning = "result")
public void afterReturning(Object result) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Map<String, String> map = MDC.getCopyOfContextMap();
if (map != null&&result!=null) {
String startTime = map.getOrDefault("startTime", String.valueOf(System.currentTimeMillis()));
long takeTime = (System.currentTimeMillis() - Long.parseLong(startTime));
String req = map.getOrDefault("req", "");
if (result instanceof String) {
log.info(" \n 请求路径:{} 耗时:{}ms 客户端IP:{} \n 请求报文:{} \n 响应报文:{}\n cookies:{} "
, request.getRequestURI(), takeTime,ServletUtil.getClientIP(request), req, result);
} else {
log.info(" \n 请求路径:{} 耗时:{}ms 客户端IP:{}\n 请求报文:{} \n 响应报文:{}\n cookies:{}"
, request.getRequestURI(), takeTime,ServletUtil.getClientIP(request), req, JSON.toJSONString(result));
}
}
}
/**
* 读取请求信息,如果是表单则转换为json
*/
private JSONObject getRequestInfo(HttpServletRequest req) {
JSONObject requestInfo = new JSONObject();
try {
StringBuffer requestURL = req.getRequestURL();
requestInfo.put("requestURL", requestURL);
String method = req.getMethod();
requestInfo.put("method", method);
if (req.getQueryString() != null) {
requestInfo.put("queryString", URLDecoder.decode(req.getQueryString(), "UTF-8"));
}
String remoteAddr = req.getRemoteAddr();
requestInfo.put("remoteAddr", remoteAddr);
if (req instanceof ContentCachingRequestWrapper) {
ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) req;
String bodyStr = new String(wrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
if (bodyStr.startsWith("{")) {
JSONObject jsonObject = JSON.parseObject(bodyStr);
requestInfo.put("requestBody", jsonObject);
}
String cookieStr = Arrays.asList(wrapper.getCookies()).stream().map(item -> JSON.toJSONString(item)).collect(Collectors.joining("|"));
requestInfo.put("cookieStr", cookieStr);
}
} catch (Exception e) {
log.error("解析请求失败", e);
requestInfo.put("parseError", e.getMessage());
}
return requestInfo;
}
}
package com.mortals.xhx.base.framework.config;
import com.mortals.framework.springcloud.config.mybatis.AbstractMybatisConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
//@Configuration
//@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisConfiguration extends AbstractMybatisConfiguration {
private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
// 配置类型别名
@Value("${spring.application.name:}")
private String name;
// 配置类型别名
@Value("${mybatis.root-path:}")
private String rootPath;
// 配置类型别名
@Value("${mybatis.type-aliases-package:}")
private String typeAliasesPackage;
// 配置mapper的扫描,找到所有的mapper.xml映射文件
@Value("${mybatis.mapper-locations:}")
private String mapperLocations;
// 加载全局的配置文件
@Value("${mybatis.config-location:}")
private String configLocation;
// 提供SqlSeesion
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("dataSource") DataSource dataSource) {
return super.getSqlSessionFactoryBean(dataSource);
}
@Override
public SqlSessionFactory getSqlSessionFactoryBean(DataSource dataSource) {
return null;
}
@Override
public String getTypeAliasesRootPackage() {
return rootPath;
}
@Override
public String getSqlMappers() {
return mapperLocations;
}
@Override
public String getMybatisConfig() {
return configLocation;
}
@Override
public String getTypeAliasesPackage() {
logger.info("typeAliasesPackage:"+typeAliasesPackage);
return typeAliasesPackage;
}
}
\ No newline at end of file
package com.mortals.xhx.base.framework.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
/**
* 统一异常处理
*/
@ControllerAdvice
public class ExceptionHandle {
private final static Logger log = LoggerFactory.getLogger(ExceptionHandle.class);
public static final String KEY_RESULT_CODE = "code";
public static final String KEY_RESULT_MSG = "msg";
public static final String KEY_RESULT_DATA = "data";
public static final int VALUE_RESULT_FAILURE = -1;
@ExceptionHandler(value = Exception.class)
@ResponseBody
public String handle(Exception e) {
JSONObject ret = new JSONObject();
ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
if (e instanceof AppException) {
StackTraceElement stack = e.getStackTrace()[0];
log.error("[business error]=========stack message[{}],[{},method:{},line{}][{}]", e.getMessage(),
stack.getClassName(), stack.getMethodName(), stack.getLineNumber(), e.getClass().getName());
AppException ex = (AppException) e;
ret.put(KEY_RESULT_MSG, ex.getMessage());
} else {
log.error("[system error]", e);
ret.put(KEY_RESULT_MSG, "unknown exception!");
}
return ret.toJSONString();
}
}
package com.mortals.xhx.busiz.handler;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.req.ApiReqPdu;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.ApiRespPdu;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
/**
* 骨架类
* @author:
* @date: 2023/1/6 15:38
*/
@Slf4j
public abstract class BaseReqHandler<T, K> implements ReqHandler {
/**
* 处理请求
*
* @param request
* @return
*/
public ApiResp<K> process(T request) {
try {
validData(request);
return handle(request);
} catch (Throwable t) {
log.error("异常:", t);
return null;
}
}
/**
* 业务处理
*
* @param request
* @return
* @throws AppException
*/
protected abstract ApiResp<K> handle(T request) throws AppException;
private ApiRespPdu<K> getApiResponsePdu(ApiRespCodeEnum result, K data, Throwable t) {
ApiRespPdu<K> response = new ApiRespPdu<>();
response.setCode(result.getValue());
response.setMsg(ObjectUtils.isEmpty(t) ? result.getLabel() : t.getMessage());
response.setData(data);
return response;
}
/**
* 校验数据
*
* @param request
* @return
* @throws Exception
*/
protected abstract void validData(T request) throws IllegalArgumentException;
}
package com.mortals.xhx.busiz.handler;
public interface ReqHandler {
}
package com.mortals.xhx.busiz.handler.impl;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* p
*/
@Service
@Slf4j
public class BusizAssessmentReqHandler extends BaseReqHandler<String, Object> {
@Override
protected ApiResp<Object> handle(String request) throws AppException {
//todo
return null;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.CaptureResp;
import com.mortals.xhx.busiz.rsp.PrintListResp;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.capture.model.File;
import com.mortals.xhx.module.capture.service.CaptureService;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 高拍仪
*
* @author: zxfei
* @date: 2024/1/2 9:51
*/
@Service
@Slf4j
public class BusizCaptureReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private CaptureService captureService;
@Override
protected ApiResp<Void> handle(String waitTime) throws AppException {
Rest<List<File>> rest = captureService.getCapture(waitTime);
CaptureResp captureResp = new CaptureResp();
if (rest.getCode() == YesNoEnum.YES.getValue()) {
captureResp.setStatus(CaptureResp.SUCCESS);
captureResp.setCode(YesNoEnum.YES.getValue());
captureResp.setMessage(rest.getMsg());
captureResp.setData(rest.getData());
//captureResp.setFilelist(rest.getData());
} else {
captureResp.setCode(YesNoEnum.NO.getValue());
captureResp.setStatus(CaptureResp.FAIL);
captureResp.setMessage("高拍仪获取照片失败!");
}
log.info("【高拍仪】【执行响应】-->{}", JSON.toJSONString(captureResp));
return captureResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.busiz.rsp.PrintListResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 身份证识别
*
* @author:
* @date: 2023/1/5 22:25
*/
@Service
@Slf4j
public class BusizIdcardRecognitionReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private IdCardService idCardService;
@Override
protected ApiResp<Void> handle(String printReq) throws AppException {
IdCardCons idCardCons = new IdCardCons();
IdCardResp idCardResp = idCardService.readIdCardMessage(idCardCons);
log.info("【身份识别】【执行响应】-->{}", JSON.toJSONString(idCardResp));
return idCardResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.PrintListResp;
import com.mortals.xhx.busiz.rsp.PrintQueueResp;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 打印机列表
*
* @author:
* @date: 2023/1/5 22:25
*/
@Service
@Slf4j
public class BusizPrintListReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private PrintService printService;
@Override
protected ApiResp<Void> handle(String printerName) throws AppException {
log.info("【打印机队列查询】【请求体】-->{}", printerName);
Rest<List<PrinterQueue>> rest = printService.getPrintQueue(printerName);
PrintQueueResp printQueueResp = new PrintQueueResp();
printQueueResp.setStatus(PrintListResp.SUCCESS);
printQueueResp.setMessage("success");
printQueueResp.setQueueList(rest.getData());
printQueueResp.setQueueNum(rest.getData().size() + "");
log.info("【打印列表】【执行响应】-->{}", JSON.toJSONString(printQueueResp));
return printQueueResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.PrintListResp;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 打印机打印队列
*
* @author:
* @date: 2023/1/5 22:25
*/
@Service
@Slf4j
public class BusizPrintQueueReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private PrintService printService;
@Override
protected ApiResp<Void> handle(String printReq) throws AppException {
Rest<List<Printer>> rest = printService.getPrintList();
PrintListResp printListResp = new PrintListResp();
printListResp.setStatus(PrintListResp.SUCCESS);
printListResp.setMessage("success");
printListResp.setPrinterList(rest.getData());
log.info("【打印列表】【执行响应】-->{}", JSON.toJSONString(printListResp));
return printListResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.req.ApiReqPdu;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.PrintQueueResp;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.apachecommons.CommonsLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 打印handler
*
* @author:
* @date: 2023/1/5 22:25
*/
@Service
@Slf4j
public class BusizPrintReqHandler extends BaseReqHandler<PrintReq, Void> {
@Autowired
private PrintService printService;
@Override
protected ApiResp<Void> handle(PrintReq printReq) throws AppException {
log.info("【打印】【请求体】-->{}", JSON.toJSONString(printReq));
Rest<Void> rest = printService.executePrint(printReq);
log.info("【打印】【执行响应】-->{}", JSON.toJSONString(rest));
if (rest.getCode() == Rest.SUCCESS) {
return ApiResp.ok(rest.getMsg());
} else {
return ApiResp.fail(rest.getMsg());
}
}
@Override
protected void validData(PrintReq request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.CaptureResp;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.capture.service.CaptureService;
import com.mortals.xhx.module.sign.modle.File;
import com.mortals.xhx.module.sign.service.SignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 签名板
*
* @author: zhou
* @date: 2024/7/8 9:51
*/
@Service
@Slf4j
public class BusizSignReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private SignService signService;
@Override
protected ApiResp<Void> handle(String waitTime) throws AppException {
SignResp signResp = signService.getSign(waitTime);
log.info("【签名板】【执行响应】-->{}", JSON.toJSONString(signResp));
return signResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.handler.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.busiz.rsp.SocialResp;
import com.mortals.xhx.module.sign.service.SignService;
import com.mortals.xhx.module.social.service.SocialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 社保卡 T10三合一
*
* @author: zhou
* @date: 2024/7/15 9:51
*/
@Service
@Slf4j
public class BusizSocialReqHandler extends BaseReqHandler<String, Void> {
@Autowired
private SocialService socialService;
@Override
protected ApiResp<Void> handle(String socialType) throws AppException {
SocialResp socialResp = socialService.getSocial(socialType);
log.info("【社保卡T10三合一】【执行响应】-->{}", JSON.toJSONString(socialResp));
return socialResp;
}
@Override
protected void validData(String request) throws IllegalArgumentException {
}
}
package com.mortals.xhx.busiz.req;
import lombok.Data;
@Data
public class ApiReqPdu<T> {
/**
* 透传数据
*/
private T transmission;
}
package com.mortals.xhx.busiz.req;
import com.mortals.xhx.module.print.model.PrintContent;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 打印请求
* @author:
* @date: 2022/12/26 10:24
*/
@Data
public class PrintReq implements Serializable {
/**
* PrinterJson中增加papertype参数,为空则按以前逻辑处理
* ,为ticket、A3、A4则分别设置PrinterJson中打印机名称和宽度(按照中间件的配置来)
* papertype为空则忽略,为ticket则将printername设为小票打印机名称,
* 为a3则将printername设为A3打印机名称,
* 为a4则将printername设为A4打印机名称
*/
private String papertype;
/**
* 打印机名称,为空则为默认打印机
*/
private String printername;
/**
* 打印机纸张宽度
*/
private String printerpaperwidth;
/**
* 打印类型,url/base64/normal,
* url为网络文件打印,base64为串文件打印,normal为普通行打印
*/
private String printertype;
/**
* 打印文件网络地址,当printertype为url时有效,其它参数时可省略,网络文件地址,
* 支持doc、docx、xls、xlsx、pdf、图片文件等,但依靠windows默认对文件的打印支持
*/
private String url;
/**
* 打印base64字符串,当printertype为base64时有效,其它参数时可省略,base64串打印支持,
* 必须依靠【data:application/msword;base64,】前缀指明,支持doc、docx、xls、xlsx、pdf、txt几种格式,
* 对应前缀:【application/msword】、【application/vnd.openxmlformats-officedocument.wordprocessingml.document】、
* 【application/vnd.ms-excel】、【application/vnd.openxmlformats-officedocument.spreadsheetml.sheet】、【application/pdf】
* 、【text/plain】 增加对图片格式的支持 2021-03-09【image/gif】、【image/png】、【image/jpeg】、【image/jpg】、【image/bmp】
*/
private String base64;
/**
* 打印行集合,当printertype为normal时有效,其它参数时可省略
*/
private List<PrintContent> contents;
}
package com.mortals.xhx.busiz.req;
import com.mortals.xhx.module.print.model.PrintContent;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 签名板请求
* @author:
* @date: 2022/12/26 10:24
*/
@Data
public class SignReq implements Serializable {
/**
* HWInitialize 开始签名
* HWFinalize 结束签名
* HWClearSign 清除签名
* HWGetSign 获取签名图片
*/
private String HWPenSign;
/**
* 签名版固定设置参数
*/
private String key = "F7B040A43D80063BEBC1A8C8DC9351D5";
private String title = "请签名";
private int nOrgX = 400;
private int nOrgY = 350;
private int nWidth = 500;
private int nHeight = 300;
private int nImageWidth =250;
private int nImageHeight = 150;
private int nImageType = 3;
private int nFingerCap = 0;
private int nConfirmTimeout = 60;
}
package com.mortals.xhx.busiz.req;
import lombok.Data;
import java.io.Serializable;
/**
* 社保卡请求
* @author:
* @date: 2022/12/26 10:24
*/
@Data
public class SocialReq implements Serializable {
String function;
String pchPhotoAddr;
String iType;
}
package com.mortals.xhx.busiz.rsp;
import lombok.Data;
@Data
public class ApiResp<T> {
/**
* 成功
*/
public static final String SUCCESS = "1";
/**
* 失败
*/
public static final String FAIL = "-1";
/**
* 结果编码
*/
private String status;
/**
* 结果描述
*/
private String message;
private Integer code;
/**
* 响应数据
*/
private T data;
public static <T> ApiResp<T> ok() {
return ApiRespResult(null, SUCCESS, "操作成功");
}
public static <T> ApiResp<T> ok(T data) {
return ApiRespResult(data, SUCCESS, "操作成功");
}
public static <T> ApiResp<T> ok(String msg) {
return ApiRespResult(null, SUCCESS, msg);
}
public static <T> ApiResp<T> ok(String msg, T data) {
return ApiRespResult(data, SUCCESS, msg);
}
public static <T> ApiResp<T> fail() {
return ApiRespResult(null, FAIL, "操作失败");
}
public static <T> ApiResp<T> fail(String msg) {
return ApiRespResult(null, FAIL, msg);
}
public static <T> ApiResp<T> fail(T data) {
return ApiRespResult(data, FAIL, "操作失败");
}
public static <T> ApiResp<T> fail(String msg, T data) {
return ApiRespResult(data, FAIL, msg);
}
public static <T> ApiResp<T> fail(String code, String msg) {
return ApiRespResult(null, code, msg);
}
private static <T> ApiResp<T> ApiRespResult(T data, String code, String msg) {
ApiResp<T> ApiResp = new ApiResp<>();
ApiResp.setStatus(code);
ApiResp.setData(data);
ApiResp.setMessage(msg);
return ApiResp;
}
}
package com.mortals.xhx.busiz.rsp;
import lombok.Data;
/**
* @author karlhoo
*/
@Data
public class ApiRespPdu<T> {
/**
* 结果编码
*/
private int code;
/**
* 结果描述
*/
private String msg;
/**
* 响应数据
*/
private T data;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.mortals.xhx.module.capture.model.File;
import com.mortals.xhx.module.print.model.Printer;
import lombok.Data;
import java.util.List;
/**
* 高拍仪响应
* @author: zxfei
* @date: 2024/1/2 9:57
*/
@Data
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)
public class CaptureResp extends ApiResp {
/**
* 附件列表
*/
private List<File> filelist;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.mortals.xhx.module.print.model.Printer;
import lombok.Data;
import java.util.List;
@Data
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)
public class IdCardResp extends ApiResp {
private String username;
private String idcardno;
private String sex;
private String address;
private String Born;
private String GrantDept;
private String Nation;
private String UserLifeBegin;
private String UserLifeEnd;
private String PhotoFileName;
private String PhotoBase64String;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.mortals.xhx.module.print.model.Printer;
import lombok.Data;
import java.util.List;
@Data
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)
public class PrintListResp extends ApiResp {
private List<Printer> PrinterList;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.mortals.xhx.module.print.model.PrinterQueue;
import lombok.Data;
import java.util.List;
@Data
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)
public class PrintQueueResp extends ApiResp {
private List<PrinterQueue> QueueList;
private String QueueNum;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.mortals.xhx.module.sign.modle.File;
import lombok.Data;
import java.util.List;
/**
* 签名板响应
* @author: zhou
* @date: 2024/7/10 9:57
*/
@Data
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)
public class SignResp extends ApiResp {
/**
* 操作类型
*/
private String HWPenSign;
/**
* 错误代码
*/
private int msgID;
/**
* 错误信息
*/
private String message;
}
package com.mortals.xhx.busiz.rsp;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import lombok.Data;
/**
* 社保卡响应
* @author: zhou
* @date: 2024/7/10 9:57
*/
@Data
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)
public class SocialResp extends ApiResp {
/**
* 错误信息
*/
private String message;
}
package com.mortals.xhx.busiz.web;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.busiz.req.ApiReqPdu;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.busiz.rsp.PrintListResp;
import com.mortals.xhx.busiz.rsp.PrintQueueResp;
import com.mortals.xhx.common.code.BusizTypeEnum;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* api controller
*
* @author: zxfei
* @date: 2022/12/26 10:21
*/
@RestController
@Slf4j
public class ApiController extends BaseAbstractApiController {
@Autowired
private PrintService printService;
@Autowired
private IdCardService idCardService;
@RequestMapping(value = "GetHardWareInfo", method = {RequestMethod.POST, RequestMethod.GET})
public Object GetHardWareInfo(@RequestParam Map<String, Object> reqMap) {
String getType = (String) reqMap.getOrDefault("GetType", "");
String reqJson = (String) reqMap.getOrDefault("PrinterJson", "");
String printerName = (String) reqMap.getOrDefault("printerName", "");
String waitTime = (String) reqMap.getOrDefault("waitTime", "120");
String signType = (String) reqMap.getOrDefault("signType", "");
String socialType = (String) reqMap.getOrDefault("socialType", "");
log.info("getType:" + getType);
try {
switch (BusizTypeEnum.getByValue(getType)) {
case BUSIZ_CAPTURE: //高拍仪
ApiResp<Object> captureResp = handle(waitTime, "busizCaptureReqHandler");
return captureResp;
case BUSIZ_ASSESSMENT: //评价
ApiResp<Object> assessResp = handle(JSON.parseObject(reqJson, new TypeReference<PrintReq>() {
}), "busizAssessmentReqHandler");
return assessResp;
case BUSIZ_PRINT: //打印
ApiResp<Object> rest = handle(JSON.parseObject(reqJson, new TypeReference<PrintReq>() {
}), "busizPrintReqHandler");
return rest;
case BUSIZ_PRINTLIST: //打印机列表
//获取打印机列表
ApiResp<Object> printListResp = handle("", "busizPrintListReqHandler");
return printListResp;
case BUSIZ_PRINT_QUEUE: //查看指定打印机打印队列
ApiResp<Object> printQueueResp = handle(printerName, "busizPrintQueueReqHandler");
return printQueueResp;
case BUSIZ_IDCARD_RECOGNITION: //身份证读取
ApiResp<Object> idCardResp = handle("", "busizIdcardRecognitionReqHandler");
return idCardResp;
case BUSIZ_CAMERA: //双目摄像头
log.info("双目摄像头");
return null;
case BUSIZ_SIGN: //签名板
ApiResp<Object> signResp = handle(signType, "busizSignReqHandler");
return signResp;
case BUSIZ_SOCIAL: //社保卡 德卡T10三合一
ApiResp<Object> socialResp = handle(socialType, "busizSocialReqHandler");
return socialResp;
case BUSIZ_FINGER: //指纹
log.info("指纹");
return null;
}
} catch (Exception e) {
log.error("接收数据失败", e);
return ApiResp.fail(e.getMessage());
}
return ApiResp.ok();
}
}
package com.mortals.xhx.busiz.web;
import com.mortals.xhx.busiz.handler.BaseReqHandler;
import com.mortals.xhx.busiz.rsp.ApiResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import java.util.Map;
@Slf4j
public class BaseAbstractApiController {
private Map<String, BaseReqHandler> handlers;
@Autowired
private ApplicationContext context;
@SuppressWarnings("unchecked")
protected <T, K> ApiResp<K> handle(T apiReq, String handleName) {
BaseReqHandler reqHandler = handlers.get(handleName);
if (!ObjectUtils.isEmpty(reqHandler)) {
return reqHandler.process(apiReq);
} else {
log.warn(String.format("没有找到业务处理类 handleName:%s", handleName));
return null;
}
}
@PostConstruct
private void init() {
handlers = context.getBeansOfType(BaseReqHandler.class);
}
}
package com.mortals.xhx.common.code;
/**
* @author karlhoo
*/
public enum ApiRespCodeEnum {
/** 接收成功 */
SUCCESS(1, "接收成功"),
/** 执行失败 */
FAILED(2,"执行失败"),
;
private final Integer value;
private final String label;
ApiRespCodeEnum(Integer value, String label) {
this.value = value;
this.label = label;
}
public int getValue() {
return this.value;
}
public String getLabel() {
return this.label;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
public enum Base64TypeEnum {
// 文件类型
BASE64_FILETYPE_DOC("doc", "data:application/msword;base64"),
BASE64_FILETYPE_DOCX("docx", "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64"),
BASE64_FILETYPE_XLS("xls", "data:application/vnd.ms-excel;base64,"),
BASE64_FILETYPE_XLSX("xlsx", "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64"),
BASE64_FILETYPE_PDF("pdf", "data:application/pdf;base64"),
BASE64_FILETYPE_PPT("ppt", "data:application/vnd.ms-powerpoint;base64"),
BASE64_FILETYPE_PPTX("pptx", "data:application/vnd.openxmlformats-officedocument.presentationml.presentation;base64"),
BASE64_FILETYPE_TXT("txt", "data:text/plain;base64"),
// 图片类型
BASE64_FILETYPE_PNG("png", "data:image/png;base64"),
BASE64_FILETYPE_JPG("jpg", "data:image/jpeg;base64"),
BASE64_FILETYPE_JPEG("jpeg", "data:image/jpeg;base64"),
BASE64_FILETYPE_GIF("gif", "data:image/gif;base64"),
BASE64_FILETYPE_SVG("svg", "data:image/svg+xml;base64"),
BASE64_FILETYPE_ICO("ico", "data:image/x-icon;base64"),
BASE64_FILETYPE_BMP("bmp", "data:image/bmp;base64"),
// 二进制流
BASE64_FILETYPE_OCTET_STREAM("octet-stream", "data:application/octet-stream;base64"),
;
private String value;
private String desc;
Base64TypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static Base64TypeEnum getByValue(String value) {
for (Base64TypeEnum BusizTypeEnum : Base64TypeEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (Base64TypeEnum item : Base64TypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 接收业务方法类
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum BusizTypeEnum {
BUSIZ_ASSESSMENT("1", "评价"),
BUSIZ_IDCARD_RECOGNITION("2", "身份证读取"),
BUSIZ_PRINT("71", "打印"),
BUSIZ_PRINTLIST("73", "打印机列表"),
BUSIZ_CAPTURE("3", "高拍仪"),
BUSIZ_PRINT_QUEUE("74", "查看指定打印机打印队列"),
BUSIZ_SIGN("61", "签名板"),
BUSIZ_CAMERA("51", "双目摄像头"),
BUSIZ_FINGER("41", "指纹"),
BUSIZ_SOCIAL("31", "社保卡"),
;
private String value;
private String desc;
BusizTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static BusizTypeEnum getByValue(String value) {
for (BusizTypeEnum BusizTypeEnum : BusizTypeEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (BusizTypeEnum item : BusizTypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.HashMap;
import java.util.Map;
/**
* Created by chendilin on 2018/3/7.
*/
public enum OperTypeEnum {
SAVE(0,"添加"),
UPDATE(1,"更新"),
DELETE(2,"删除"),
OTHER(-1,"其它");
private int value;
private String msg;
private OperTypeEnum(int value,String msg) {
this.value = value;
this.msg = msg;
}
public int getValue() {
return this.value;
}
public static Map<String,String> getEnumMap(){
Map<String,String> resultMap = new HashMap<>();
OperTypeEnum[] operTypeEnum = OperTypeEnum.values();
for (OperTypeEnum typeEnum : operTypeEnum) {
resultMap.put(String.valueOf(typeEnum.value),typeEnum.msg);
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印纸张类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PaperTypeEnum {
PAPER_TICKET("ticket", "小票"),
PAPER_A3("A3", "A3"),
PAPER_A4("A4", "A4"),
;
private String value;
private String desc;
PaperTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PaperTypeEnum getByValue(String value) {
for (PaperTypeEnum BusizTypeEnum : PaperTypeEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PaperTypeEnum item : PaperTypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印内容类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PrintAlignStyleEnum {
PRINT_LEFT("left", "居左"),
PRINT_CENTER("center", "居中"),
PRINT_RIGHT("right", "居右"),
;
private String value;
private String desc;
PrintAlignStyleEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PrintAlignStyleEnum getByValue(String value) {
for (PrintAlignStyleEnum BusizTypeEnum : PrintAlignStyleEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PrintAlignStyleEnum item : PrintAlignStyleEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印内容类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PrintContentTypeEnum {
PRINT_TEXT("text", "文本"),
PRINT_PAGEING("pageing", "分页"),
PRINT_IMG("img", "图片"),
PRINT_BARCODE("barcode", "条形码"),
PRINT_QRCODE("qrcode", "二维码"),
PRINT_SEPARATE("separate", "分隔符"),
;
private String value;
private String desc;
PrintContentTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PrintContentTypeEnum getByValue(String value) {
for (PrintContentTypeEnum BusizTypeEnum : PrintContentTypeEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PrintContentTypeEnum item : PrintContentTypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印内容类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PrintFontStyleEnum {
PRINT_REGULAR("regular", "正常"),
PRINT_BOLD("bold", "粗体"),
PRINT_UNDERLINE("underline", "下划线"),
PRINT_ITALIC("italic", "斜体"),
PRINT_STRIKEOUT("strikeout", "二维码"),
;
private String value;
private String desc;
PrintFontStyleEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PrintFontStyleEnum getByValue(String value) {
for (PrintFontStyleEnum BusizTypeEnum : PrintFontStyleEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PrintFontStyleEnum item : PrintFontStyleEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印字体单位
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PrintFontUnitEnum {
PRINT_WORLD("world", "world"),
PRINT_DISPLAY("display", "display"),
PRINT_PIXEL("pixel", "pixel"),
PRINT_POINT("point", "point"),
PRINT_INCH("inch", "inch"),
PRINT_DOCUMENT("document", "document"),
PRINT_MILLIMETER("millimeter", "millimeter"),
;
private String value;
private String desc;
PrintFontUnitEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PrintFontUnitEnum getByValue(String value) {
for (PrintFontUnitEnum BusizTypeEnum : PrintFontUnitEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PrintFontUnitEnum item : PrintFontUnitEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum PrintTypeEnum {
PRINT_URL("url", "网络文件打印"),
PRINT_BASE64("base64", "串文件打印"),
PRINT_NORMAL("normal", "普通行打印"),
;
private String value;
private String desc;
PrintTypeEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static PrintTypeEnum getByValue(String value) {
for (PrintTypeEnum BusizTypeEnum : PrintTypeEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (PrintTypeEnum item : PrintTypeEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
public enum PublishStatusEnum implements IBaseEnum{
PRODUCT_PENDING(0, "待发布"),
PRODUCT_AUDITING(1, "审核中"),
PRODUCT_SUCESS(2, "审核通过"),
PRODUCT_REJECT(3, "审核拒绝");
private int value;
private String desc;
PublishStatusEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static PublishStatusEnum getByValue(int value) {
for (PublishStatusEnum YesNoEnum : PublishStatusEnum.values()) {
if (YesNoEnum.getValue() == value) {
return YesNoEnum;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (PublishStatusEnum item : PublishStatusEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
/**
* 业务统一返回码
* @author linlc
*
*/
public enum ResultCodeEnum {
CODE_001(156001,"参数类型错误"),
CODE_002(156002,"部分参数为空"),
CODE_003(156003,"参数长度超过限制"),
CODE_004(156004,"日期格式错误"),
CODE_005(156005,"时间区间不合法"),
CODE_006(156006,"远端服务不可用"),
CODE_007(156007,"无效的签名"),
CODE_008(156008,"不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写"),
CODE_009(156009,"请求来源地址不合法"),
CODE_010(156010,"没有相应的用户"),
CODE_011(156011,"不合法的文件类型"),
CODE_012(156012,"不合法的文件大小"),
CODE_013(156013,"上传文件缺失"),
CODE_014(156014,"不支持的图片格式"),
CODE_015(156015,"无效的url"),
CODE_016(156016,"设备编号不合法"),
CODE_017(356017,"设备编号不存在"),
CODE_018(356018,"设备当前在线状态为“离线”,无法使用!"),
CODE_019(356019,"设备当前投放状态为“待重投”,无法使用!"),
CODE_020(356020,"设备当前投放状态为“已报废”,无法使用!"),
CODE_021(356021,"设备当前投放状态为“初始化”,无法使用!"),
CODE_022(356022,"此设备当前启用状态为“禁用”,无法使用!"),
CODE_023(356023,"API 调用太频繁,请稍候再试"),
CODE_024(256024,"用户未授权该 api"),
CODE_025(156025,"解析 JSON/XML 内容错误"),
CODE_FAILUER(-1,"失败");
private int value;
private String desc;
ResultCodeEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
package com.mortals.xhx.common.code;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 角色类型
* @author
*
*/
public enum RoleType implements IBaseEnum {
/** 系统内置角色 */
BUILT_IN(0, "系统内置角色", SysConstains.STYLE_DEFAULT),
/** 默认系统角色 */
SYSTEM_DEFAULT(1, "默认系统角色", SysConstains.STYLE_INFO),
/** 企业用户角色 */
CUSTOMER_DEFAULT(2, "企业用户角色", SysConstains.STYLE_PRIMARY),
/** 普通角色 */
NORMAL(4, "普通角色 ", SysConstains.STYLE_SUCCESS),;
//0:系统内置角色(不可删除),1:默认系统角色,2:默认新闻用户角色,3:默认资讯用户角色,4:普通角色,默认4
private int value;
private String desc;
private String style;
RoleType(int value, String desc, String style) {
this.value = value;
this.desc = desc;
this.style = style;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public String getStyle()
{
return style;
}
public static RoleType getByValue(int value) {
for (RoleType examStatus : RoleType.values()) {
if (examStatus.getValue() == value) {
return examStatus;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (RoleType item : RoleType.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 站点状态
* @author
*
*/
public enum SiteSatusEnum {
DISENABLE(0, "禁用"),
ENABLE(1, "启用");
private int value;
private String desc;
SiteSatusEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static SiteSatusEnum getByValue(int value) {
for (SiteSatusEnum examStatus : SiteSatusEnum.values()) {
if (examStatus.getValue() == value) {
return examStatus;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (SiteSatusEnum item : SiteSatusEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 资源类型
* @author
*
*/
public enum SourceType implements IBaseEnum {
/** 系统资源 */
SYSTEM(0, "系统资源", SysConstains.STYLE_DEFAULT),
/** 开放资源 */
OPEN(1, "开放资源", SysConstains.STYLE_PRIMARY);
private int value;
private String desc;
private String style;
SourceType(int value, String desc, String style) {
this.value = value;
this.desc = desc;
this.style = style;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public String getStyle()
{
return style;
}
public static SourceType getByValue(int value) {
for (SourceType examStatus : SourceType.values()) {
if (examStatus.getValue() == value) {
return examStatus;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (SourceType item : SourceType.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author
* @create 2018/01/12
*/
public enum TaskExcuteStatusEnum {
WAIT_RUN(0, "待执行"),
RUNNING(1, "执行中"),
SUCCESS_RUN(2, "执行成功"),
FAIL_RUN(3, "执行失败"),
CANCEL(4, "取消");
private int value;
private String desc;
TaskExcuteStatusEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static TaskExcuteStatusEnum getByValue(int value) {
for (TaskExcuteStatusEnum taskExcuteStatusEnum : TaskExcuteStatusEnum.values()) {
if (taskExcuteStatusEnum.getValue() == value) {
return taskExcuteStatusEnum;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (TaskExcuteStatusEnum item : TaskExcuteStatusEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
public enum TaskExcuteStrategyEnum{
/** 按日 */
DAY(1, "按日"),
/** 按周 */
WEEK(2, "按周"),
/** 按月 */
MONTH(3, "按月"),
/** 按间隔时间 */
INTERVAL(4, "按间隔时间");
private int value;
private String desc;
TaskExcuteStrategyEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static TaskExcuteStrategyEnum getByValue(int value) {
for (TaskExcuteStrategyEnum taskExcuteStrategy : TaskExcuteStrategyEnum.values()) {
if (taskExcuteStrategy.getValue() == value) {
return taskExcuteStrategy;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (TaskExcuteStrategyEnum item : TaskExcuteStrategyEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
public enum TaskInterimExcuteStatusEnum{
/** 未启用 */
UNUSE(0, "未启用"),
/** 立即执行并保留 */
IMMEDIATE_EXECUTION(1, "立即执行并保留"),
/** 立即执行并删除 */
IMMEDIATE_EXECUTION_BEFORE_DELETE(2, "立即执行并删除");
private int value;
private String desc;
TaskInterimExcuteStatusEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static TaskInterimExcuteStatusEnum getByValue(int value) {
for (TaskInterimExcuteStatusEnum taskInterimExcuteStatus : TaskInterimExcuteStatusEnum.values()) {
if (taskInterimExcuteStatus.getValue() == value) {
return taskInterimExcuteStatus;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (TaskInterimExcuteStatusEnum item : TaskInterimExcuteStatusEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 打印内容类型
*
* @author:
* @date: 2022/12/26 11:11
*/
public enum TicketTypeWidthEnum {
TYPE_SMALL("1", "164"),
TYPE_LARGER("2", "227");
private String value;
private String desc;
TicketTypeWidthEnum(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static TicketTypeWidthEnum getByValue(String value) {
for (TicketTypeWidthEnum BusizTypeEnum : TicketTypeWidthEnum.values()) {
if (BusizTypeEnum.getValue().equals(value)) {
return BusizTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(String... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (TicketTypeWidthEnum item : TicketTypeWidthEnum.values()) {
try {
boolean hasE = false;
for (String e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author: finegirl
* @date: 2021/7/16 11:50
* @description: //TODO 请完善注释信息
**/
public enum TopicalTypeEnum {
PERSONAL(1, "个人服务"),
ENTERPRISE(2, "企业服务");
private int value;
private String desc;
private TopicalTypeEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static TopicalTypeEnum getByValue(int value) {
TopicalTypeEnum[] var1 = values();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
TopicalTypeEnum examStatus = var1[var3];
if (examStatus.getValue() == value) {
return examStatus;
}
}
return null;
}
public static Map<String, String> getEnumMap(int... eItem) {
Map<String, String> resultMap = new LinkedHashMap();
TopicalTypeEnum[] var2 = values();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
TopicalTypeEnum item = var2[var4];
try {
boolean hasE = false;
int[] var7 = eItem;
int var8 = eItem.length;
for(int var9 = 0; var9 < var8; ++var9) {
int e = var7[var9];
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception var11) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
public enum TreeTypeEnum implements IBaseEnum{
TOPIC(0, "el-icon-folder"),
CLASSIFY (1, "el-icon-document"),
CLASSIFYOPTION(2, "el-icon-s-tools");
private int value;
private String desc;
TreeTypeEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static TreeTypeEnum getByValue(int value) {
for (TreeTypeEnum YesNoEnum : TreeTypeEnum.values()) {
if (YesNoEnum.getValue() == value) {
return YesNoEnum;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (TreeTypeEnum item : TreeTypeEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import com.mortals.framework.common.IBaseEnum;
/**
* 上传文件类型枚举
*
* @author pengziyuan
*/
public enum UploadFileType implements IBaseEnum {
/** 表格 */
EXCEL(1, "表格", 1024 * 1023 * 100),
/** 图片 */
IMG(2, "图片", 1024 * 1024 * 10),
/** 压缩文件 */
ZIP(3, "压缩文件", 1024 * 1024 * 100),
/** PDF */
PDF(4, "PDF", 1024 * 1024 * 100),
/** 其他 */
OTHER(99, "其他", 1024 * 1024 * 100);
private int value;
private String desc;
private int maxSize;
UploadFileType(int value, String desc, int maxSize) {
this.value = value;
this.desc = desc;
this.maxSize = maxSize;
}
@Override
public int getValue() {
return this.value;
}
@Override
public String getDesc() {
return desc;
}
public int getMaxSize() {
return maxSize;
}
public static UploadFileType getFileType(String extension) {
if ("xls".equalsIgnoreCase(extension) || "xlsx".equalsIgnoreCase(extension)) {
return EXCEL;
}
if ("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension) || "png".equalsIgnoreCase(extension)
|| "gif".equalsIgnoreCase(extension)) {
return IMG;
}
if ("zip".equalsIgnoreCase(extension)) {
return ZIP;
}
if ("pdf".equalsIgnoreCase(extension)) {
return PDF;
}
return OTHER;
}
}
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author: finegirl
* @date: 2021/7/16 11:50
* @description: //TODO 请完善注释信息
**/
public enum UserStatus {
DISABLE(0, "停用"),
NORMAL(1, "正常"),
FROZEN(2, "冻结"),
CACCOUNT(3, "销户"),
QUIT(4, "离职");
private int value;
private String desc;
private UserStatus(int value, String desc) {
this.value = value;
this.desc = desc;
}
public int getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static UserStatus getByValue(int value) {
UserStatus[] var1 = values();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
UserStatus examStatus = var1[var3];
if (examStatus.getValue() == value) {
return examStatus;
}
}
return null;
}
public static Map<String, String> getEnumMap(int... eItem) {
Map<String, String> resultMap = new LinkedHashMap();
UserStatus[] var2 = values();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
UserStatus item = var2[var4];
try {
boolean hasE = false;
int[] var7 = eItem;
int var8 = eItem.length;
for(int var9 = 0; var9 < var8; ++var9) {
int e = var7[var9];
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception var11) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.common.code;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
public enum ValidCodeType implements IBaseEnum{
IMAGE(0, "图片校验", SysConstains.STYLE_DEFAULT),
MOBILE(1, "手机校验", SysConstains.STYLE_DEFAULT),
EMAIL(2, "邮箱校验", SysConstains.STYLE_DEFAULT);
private int value;
private String desc;
private String style;
ValidCodeType(int value, String desc, String style) {
this.value = value;
this.desc = desc;
this.style = style;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public String getStyle()
{
return style;
}
public static ValidCodeType getByValue(int value) {
for (ValidCodeType validCodeType : ValidCodeType.values()) {
if (validCodeType.getValue() == value) {
return validCodeType;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (ValidCodeType item : ValidCodeType.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.code;
import com.mortals.framework.common.IBaseEnum;
import java.util.LinkedHashMap;
import java.util.Map;
public enum YesNoEnum implements IBaseEnum{
NO(0, "否"),
YES(1, "是");
private int value;
private String desc;
YesNoEnum(int value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public int getValue() {
return this.value;
}
public String getDesc() {
return desc;
}
public static YesNoEnum getByValue(int value) {
for (YesNoEnum YesNoEnum : YesNoEnum.values()) {
if (YesNoEnum.getValue() == value) {
return YesNoEnum;
}
}
return null;
}
/**
* 获取Map集合
* @param eItem 不包含项
* @return
*/
public static Map<String,String> getEnumMap(int... eItem) {
Map<String,String> resultMap= new LinkedHashMap<String,String>();
for (YesNoEnum item : YesNoEnum.values()) {
try{
boolean hasE = false;
for (int e : eItem){
if(item.getValue()==e){
hasE = true;
break;
}
}
if(!hasE){
resultMap.put(item.getValue()+"", item.getDesc());
}
}catch(Exception ex){
}
}
return resultMap;
}
}
package com.mortals.xhx.common.key;
public final class Constant {
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* http请求
*/
public static final String HTTP = "http://";
}
package com.mortals.xhx.common.key;
/**
* 参数表对应key定义对应
* @author linlc
*
*/
public class ParamKey {
/** 文件访问的地址 */
public static final String FILE_URL = "iot:base:param:fileUrl";
/** 物料编码长度,默认6 */
public static final String MATERIA_CODE_LENGTH = "iot:base:param:materia:length";
}
package com.mortals.xhx.common;
public class osSelect {
public static boolean isLinux() {
return System.getProperty("os.name").toLowerCase().contains("linux");
}
public static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().contains("windows");
}
}
package com.mortals.xhx.common.utils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import org.apache.commons.codec.binary.Base64;
import com.mortals.xhx.common.code.Base64TypeEnum;
import java.io.*;
public class Base64Util {
// 获取文件转换之后的base64内容
public static String encodeBase64File(String prefix, File file) {
try {
if (file == null || !file.exists() || prefix == null) {
return null;
}
long beginTime = System.currentTimeMillis();
// base64文件前缀
String base64Format = Base64TypeEnum.getByValue(prefix.toLowerCase()).getDesc();
if (base64Format == null || "".equals(base64Format)) {
return null;
}
// 获取文件流
InputStream in = new FileInputStream(file);
BufferedInputStream bufInput = new BufferedInputStream(in); // 缓存流
// 先把二进制流写入到ByteArrayOutputStream中
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
byte[] bt = new byte[4096];
int len;
while ((len = bufInput.read(bt)) != -1) {
byteArray.write(bt, 0, len);
}
byteArray.flush();
long endTime = System.currentTimeMillis();
System.out.println("==>encodeBase64File, 把文件转换成base64编码, 总耗时: " + (endTime - beginTime) + "ms");
// 返回
return base64Format+"," + Base64.encodeBase64String(byteArray.toByteArray());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 把base64文件解码
public static void decodeBase64(String destFile, String base64String) {
try {
long beginTime = System.currentTimeMillis();
// 把base64字符串转换成字节
byte[] bytes = Base64.decodeBase64(base64String);
FileUtil.writeBytes(bytes,destFile);
/*
// 转换成字节输入流
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
OutputStream out = new FileOutputStream(destFile);
// 写文件
byte[] buffer = new byte[4096];
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len); // 文件写操作
}
*/
long endTime = System.currentTimeMillis();
System.out.println("==>decodeBase64String, 解析base64编码文件, 总耗时: " + (endTime - beginTime) + "ms");
} catch (IORuntimeException e) {
e.printStackTrace();
}
}
// 把base64文件解码
public static String decodeBase64String(String prefix, String base64String) {
try {
if (prefix == null || base64String == null) {
return null;
}
long beginTime = System.currentTimeMillis();
// 把base64前缀截取掉
// base64文件前缀
String value = Base64TypeEnum.getByValue(prefix.toLowerCase()).getDesc();
if (value == null || "".equals(value)) {
return null;
}
// 替换
String tempBase64String = base64String.replace(value, "");
// 把base64字符串转换成字节
byte[] bytes = Base64.decodeBase64(tempBase64String);
// 转换成字节输入流
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
// 把base64编码文件还原, 并存放到指定磁盘路径中
OutputStream out = new FileOutputStream(new File("D:\\new_test." + prefix));
// 写文件
byte[] buffer = new byte[4096];
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len); // 文件写操作
}
long endTime = System.currentTimeMillis();
System.out.println("==>decodeBase64String, 解析base64编码文件, 总耗时: " + (endTime - beginTime) + "ms");
return "success";
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
// 获取文件, 对文件base64编码
File file = new File("F:\\test.txt");
String prefix = "txt";
// base64文件内容
String base64String = Base64Util.encodeBase64File(prefix, file);
System.out.println("文件base64加密之后的内容(太长, 控制台可能打印不出来): \n" + base64String);
// 获取base64文件, 进行解码
Base64Util.decodeBase64String(prefix, base64String);
}
}
package com.mortals.xhx.common.utils;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
public class BeanUtil {
protected static Logger log = LoggerFactory.getLogger(BeanUtil.class);
public static <SOURCE, TARGET> List<TARGET> covertList(List<SOURCE> srcList, Class<TARGET> clazz) {
List<TARGET> retList = new ArrayList<>();
if (srcList == null || srcList.isEmpty()) {
return retList;
}
for (SOURCE source : srcList) {
TARGET target;
try {
target = clazz.newInstance();
if (source == null) {
continue;
}
BeanUtils.copyProperties(source, target);
retList.add(target);
} catch (InstantiationException | IllegalAccessException e) {
log.error("", e);
}
}
return retList;
}
public static <SOURCE, TARGET> TARGET covert(SOURCE source, Class<TARGET> clazz) {
TARGET target = null;
if (source == null) {
return target;
}
try {
target = clazz.newInstance();
BeanUtils.copyProperties(source, target);
} catch (InstantiationException | IllegalAccessException e) {
log.error("", e);
}
return target;
}
@SuppressWarnings({ "rawtypes", "unused", "unchecked" })
public static final Map entityToMap(Object entity) {
Map map = new HashMap<>();
try {
Class cls = entity.getClass();
BeanInfo beanInfo = Introspector.getBeanInfo(cls);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (!propertyName.equals("class") && !propertyName.equals("orderCols")
&& !propertyName.equals("notSelectCols") && !propertyName.equals("symbolCols")
&& !propertyName.equals("vague")) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(entity, new Object[0]);
if (result != null) {
String className = result.getClass().getSimpleName();
map.put(propertyName, result);
/*
* if(result instanceof String){
* if(((String)result).trim().length() > 0){
* map.put(propertyName, result); } }else{
* map.put(propertyName, result); }
*/
}
}
}
} catch (Exception e) {
log.warn("将对象转换成Map异常-->" + entity + "-->" + e.getMessage());
}
return map;
}
public static final <T> T mapToEntity(Map<?, ?> map, Class<T> clz) {
T target = null;
try {
target = clz.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(clz);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (map.containsKey(propertyName)) {
Object value = map.get(propertyName);
Object[] args = new Object[1];
args[0] = value;
descriptor.getWriteMethod().invoke(target, args);
}
}
} catch (Exception e) {
log.warn("将Map转换成对象异常-->" + clz + "-->" + e.getMessage());
}
return target;
}
/**
*
* @Title: getNullPropertyNames
* @Description: 获取一个对象中属性值为null的属性名字符串数组
* @param source
* @return
*/
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
/**
*      * 校验特殊字符
*      * @param str
*      * @return
*      
*/
public static boolean isConSpeChar(String str) {
String regEx = "[`~'\"?~?]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.find();
}
public static void main(String[] args) {
String str="'";
System.out.println(BeanUtil.isConSpeChar(str));
ObjectMapper mapper = new ObjectMapper();
//Map<String, String> map = mapper.readValue(json, Map.class);
}
}
package com.mortals.xhx.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
/**
* 自定义编码、解码
*/
//加密过程:原文->base64->aes(1234567812345678)->des(12345678)->倒序(9位)->base64
//解密:base64->倒序(9位)->des(12345678)->aes(1234567812345678)->base64->原文
@Slf4j
public class EncryptUtil {
public static final String ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* 字符串转换为Base64
*
* @param text
* @return
*/
public static String toBase64(String text) {
Base64 base64 = new Base64();
try {
return base64.encodeToString(text.getBytes("utf-8")).trim().replace("\n", "");
} catch (UnsupportedEncodingException e) {
log.error("字符串转换为Base64[{}]异常", e);
}
return null;
}
/**
* Base64转换为字符串
*
* @param text
* @return
*/
private static String base64ToString(String text) {
Base64 base64 = new Base64();
try {
return new String(base64.decode(text.getBytes("utf-8")), "UTF-8").trim().replace("\n", "");
} catch (UnsupportedEncodingException e) {
log.error("Base64转换为字符串[{}]异常", e);
}
return null;
}
/**
* AES加密+Base64转码
*
* @param data 明文(16进制)
* @param key 密钥
* @return
*/
public static String encrypt(String data, String key) {
try {
byte[] keys = key.getBytes("utf-8");
// 明文
SecretKeySpec sKeySpec = new SecretKeySpec(keys, "AES");
//Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
byte[] bjiamihou = cipher.doFinal(data.getBytes("utf-8"));
// byte加密后,密文用base64加密;
String miKey = Base64.encodeBase64String(bjiamihou);
return miKey;
} catch (Exception e) {
e.printStackTrace();
log.error("AES加密[{}]异常", e);
}
return null;
}
/**
* Base64解码 + AES解码
*
* @param data 密文 (16进制)
* @param key 密钥
* @return
*/
public static String decrypt(String data, String key) {
try {
byte[] keys = key.getBytes("utf-8");
byte[] datas = Base64.decodeBase64(data);
SecretKeySpec sKeySpec = new SecretKeySpec(keys, "AES");
//Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, sKeySpec);
byte[] bjiemihou = cipher.doFinal(datas);
// byte加密后
String miKey = new String(bjiemihou, "utf-8");
return miKey;
} catch (Exception e) {
log.error("AES解码[{}]异常", e);
}
return null;
}
/**
* 转化为String
*
* @param buf
* @return
*/
private static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
private static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* DES加密(使用DES算法)
*
* @param message 需要加密的文本
* @param key 密钥
* @return 成功加密的文本
*/
public static String toDesString(String key, String message) throws Exception {
try {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return parseByte2HexStr(cipher.doFinal(message.getBytes("UTF-8")));
} catch (Exception e) {
log.error("DES加密[{}]异常", e);
}
return null;
}
/**
* DES解密(使用DES算法)
*
* @param message 需要解密的文本
* @param key 密钥
* @return 成功加密的文本
*/
public static String desToString(String key, String message) throws Exception {
try {
byte[] bytesrc = parseHexStr2Byte(message);//convertHexString(message);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] retByte = cipher.doFinal(bytesrc);
return new String(retByte);
} catch (Exception e) {
log.error("DES解密[{}]异常", e);
}
return null;
}
public static byte[] convertHexString(String ss) {
byte digest[] = new byte[ss.length() / 2];
for (int i = 0; i < digest.length; i++) {
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte) byteValue;
}
return digest;
}
public static String toHexString(byte b[]) {
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < b.length; i++) {
String plainText = Integer.toHexString(0xff & b[i]);
if (plainText.length() < 2)
plainText = "0" + plainText;
hexString.append(plainText);
}
return hexString.toString();
}
/**
* 倒序处理,每orderNum位进行倒序排列
*
* @param sourceString 为需要加密的串
* @param orderNum 为每x位进行倒序排列
* @return
*/
public static String toReverseString(int orderNum, String sourceString) {
String csFive = "", encrypted2 = "";
for (int i = 0; i < sourceString.length(); i++) {
csFive = csFive + sourceString.charAt(i);
if ((i + 1) % orderNum == 0 || (i + 1) >= sourceString.length()) {
String csFive2 = "";
for (int j = 0; j < csFive.length(); j++) {
csFive2 = csFive2 + csFive.charAt(csFive.length() - 1 - j);
}
encrypted2 += csFive2;
csFive = "";
}
}
return encrypted2;
}
/**
* 加密
*
* @return
*/
public static String myEnscrt(String sourceString, int orderNum, String desKey, String aesKey) throws Exception {
//加密过程:原文->base64->aes(1234567812345678)->des(12345678)->倒序(9位)->base64
String base64String = toBase64(sourceString);
String aesString = encrypt(base64String, aesKey);
//System.out.println("aseString==="+aesString);
String desString = toDesString(desKey, aesString);
String reverseString = toReverseString(orderNum, desString);
String result = toBase64(reverseString);
return result;
}
/**
* 解密
*
* @return
*/
public static String myReEnscrt(String targetString, int orderNum, String desKey, String aesKey) throws Exception {
//解密:base64->倒序(9位)->des(12345678)->aes(1234567812345678)->base64->原文
String reverseString = base64ToString(targetString);
//System.out.println("reverseString"+reverseString);
String desString = toReverseString(orderNum, reverseString);
//System.out.println("desString"+desString);
String aesString = desToString(desKey, desString);
// System.out.println("aesString"+aesString);
String base64String = decrypt(aesString, aesKey);
// System.out.println("base64String"+base64String);
String result = base64ToString(base64String);
return result;
}
public static void main(String[] args) {
try {
String s = EncryptUtil.myEnscrt("7E:20:F5:32:60:6A", 9, "FZV1D&tr", "w4*KbUamPdZDnDpG");
System.out.println("a===="+ s);
String sa = EncryptUtil.myReEnscrt(s, 9, "FZV1D&tr", "w4*KbUamPdZDnDpG");
System.out.println("sa===="+sa);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.mortals.xhx.common.utils;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class GetRequestJsonUtils {
public static JSONObject getRequestJsonObject(HttpServletRequest request) throws IOException {
String json = getRequestJsonString(request);
return JSONObject.parseObject(json);
}
/***
* 获取 request 中 json 字符串的内容
*
* @param request
* @return : <code>byte[]</code>
* @throws IOException
*/
public static String getRequestJsonString(HttpServletRequest request)
throws IOException {
String submitMehtod = request.getMethod();
// GET
if (submitMehtod.equals("GET")) {
return new String(request.getQueryString().getBytes("iso-8859-1"), "utf-8").replaceAll("%22", "\"");
// POST
} else {
return getRequestPostStr(request);
}
}
/**
* 描述:获取 post 请求的 byte[] 数组
* <pre>
* 举例:
* </pre>
*
* @param request
* @return
* @throws IOException
*/
public static byte[] getRequestPostBytes(HttpServletRequest request)
throws IOException {
int contentLength = request.getContentLength();
if (contentLength < 0) {
return null;
}
byte buffer[] = new byte[contentLength];
for (int i = 0; i < contentLength; ) {
int readlen = request.getInputStream().read(buffer, i,
contentLength - i);
if (readlen == -1) {
break;
}
i += readlen;
}
return buffer;
}
/**
* 描述:获取 post 请求内容
* <pre>
* 举例:
* </pre>
*
* @param request
* @return
* @throws IOException
*/
public static String getRequestPostStr(HttpServletRequest request)
throws IOException {
byte buffer[] = getRequestPostBytes(request);
String charEncoding = request.getCharacterEncoding();
if (charEncoding == null) {
charEncoding = "UTF-8";
}
return new String(buffer, charEncoding);
}
}
package com.mortals.xhx.common.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImgUtils {
public static void removeBackground(String imgUrl, String resUrl){
//定义一个临界阈值
int threshold = 300;
try{
BufferedImage img = ImageIO.read(new File(imgUrl));
int width = img.getWidth();
int height = img.getHeight();
for(int i = 1;i < width;i++){
for (int x = 0; x < width; x++){
for (int y = 0; y < height; y++){
Color color = new Color(img.getRGB(x, y));
System.out.println("red:"+color.getRed()+" | green:"+color.getGreen()+" | blue:"+color.getBlue());
int num = color.getRed()+color.getGreen()+color.getBlue();
if(num >= threshold){
img.setRGB(x, y, Color.WHITE.getRGB());
}
}
}
}
for(int i = 1;i<width;i++){
Color color1 = new Color(img.getRGB(i, 1));
int num1 = color1.getRed()+color1.getGreen()+color1.getBlue();
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Color color = new Color(img.getRGB(x, y));
int num = color.getRed()+color.getGreen()+color.getBlue();
if(num==num1){
img.setRGB(x, y, Color.BLACK.getRGB());
}else{
img.setRGB(x, y, Color.WHITE.getRGB());
}
}
}
}
File file = new File(resUrl);
if (!file.exists())
{
File dir = file.getParentFile();
if (!dir.exists())
{
dir.mkdirs();
}
try
{
file.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}
ImageIO.write(img, "jpg", file);
}catch (Exception e){
e.printStackTrace();
}
}
public static void cuttingImg(String imgUrl){
try{
File newfile=new File(imgUrl);
BufferedImage bufferedimage=ImageIO.read(newfile);
int width = bufferedimage.getWidth();
int height = bufferedimage.getHeight();
if (width > 52) {
bufferedimage=ImgUtils.cropImage(bufferedimage,(int) ((width - 52) / 2),0,(int) (width - (width-52) / 2),(int) (height));
if (height > 16) {
bufferedimage=ImgUtils.cropImage(bufferedimage,0,(int) ((height - 16) / 2),52,(int) (height - (height - 16) / 2));
}
}else{
if (height > 16) {
bufferedimage=ImgUtils.cropImage(bufferedimage,0,(int) ((height - 16) / 2),(int) (width),(int) (height - (height - 16) / 2));
}
}
ImageIO.write(bufferedimage, "jpg", new File(imgUrl));
}catch (IOException e){
e.printStackTrace();
}
}
public static BufferedImage cropImage(BufferedImage bufferedImage, int startX, int startY, int endX, int endY) {
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if (startX == -1) {
startX = 0;
}
if (startY == -1) {
startY = 0;
}
if (endX == -1) {
endX = width - 1;
}
if (endY == -1) {
endY = height - 1;
}
BufferedImage result = new BufferedImage(endX - startX, endY - startY, 4);
for (int x = startX; x < endX; ++x) {
for (int y = startY; y < endY; ++y) {
int rgb = bufferedImage.getRGB(x, y);
result.setRGB(x - startX, y - startY, rgb);
}
}
return result;
}
}
\ No newline at end of file
package com.mortals.xhx.common.utils;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.mortals.framework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
/**
* @author:
* @date: 2022/12/27 20:26
*/
@Slf4j
public class QrCodeUtil {
/**
* 默认宽度
*/
private static final int WIDTH = 300;
/**
* 默认高度
*/
private static final int HEIGHT = 300;
/**
* 默认文件格式
*/
private static final String FORMAT = "png";
/**
* 条形码宽度
*/
private static final int QR_WIDTH = 106;
/**
* 条形码高度
*/
private static final int QR_HEIGHT = 75;
/**
* 加文字 条形码
*/
private static final int WORDHEIGHT = 240;
/**
* 一些默认参数
*/
private static final Map<EncodeHintType, Object> HINTS = new HashMap();
static {
// 字符编码
HINTS.put(EncodeHintType.CHARACTER_SET, "utf-8");
// 容错等级 L、M、Q、H 其中 L 为最低, H 为最高
HINTS.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 二维码与图片边距
HINTS.put(EncodeHintType.MARGIN, 2);
}
/**
* 生成 图片缓冲
*
* @param vaNumber VA 码
* @return 返回BufferedImage
* @author fxbin
*/
public static BufferedImage getBarCode(String vaNumber) {
Code128Writer writer = new Code128Writer();
//为了无边距,需设置宽度为条码自动生成规则的宽度
int width = writer.encode(vaNumber).length;
//条码放大倍数
int codeMultiples = 1;
//获取条码内容的宽,不含两边距,当EncodeHintType.MARGIN为0时即为条码宽度
int codeWidth = width * codeMultiples;
int height = (int) (width * 0.7);
try {
// 编码内容, 编码类型, 宽度, 高度, 设置参数
BitMatrix bitMatrix = writer.encode(vaNumber, BarcodeFormat.CODE_128, codeWidth, height, HINTS);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 生成图片的条形码
*
* @param content 内容
* @param paths 路径
*/
public static void generateBarCodeFile(String content, String paths) {
Code128Writer writer = new Code128Writer();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.CODE_128, WIDTH, QR_HEIGHT, HINTS);
Path path = Paths.get(paths);
if (!StrUtil.isEmpty(content)) {
try {
MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, path);
} catch (IOException e) {
log.error("生成条形码失败:{}", e.getMessage());
}
}
}
/**
* 生成文件流的条形码
*
* @param content 内容
* @param response 响应体
* @return 流
*/
public static OutputStream generateBarCodeStream(String content, HttpServletResponse response) {
Code128Writer writer = new Code128Writer();
OutputStream outputStream = null;
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.CODE_128, WIDTH, QR_HEIGHT, HINTS);
if (!StrUtil.isEmpty(content)) {
try {
// 字节输出流
outputStream = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, FORMAT, outputStream);
return outputStream;
} catch (IOException e) {
log.error("生成条形码失败:{}", e.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error("流关闭失败:{}", e.getMessage());
}
}
}
}
return null;
}
/**
* 把带logo的二维码下面加上文字
*
* @param image 条形码图片
* @param words 文字
* @return 返回BufferedImage
* @author fxbin
*/
public static BufferedImage insertWords(BufferedImage image, String words) {
// 新的图片,把带logo的二维码下面加上文字
if (StringUtils.isNotEmpty(words)) {
int width=image.getWidth();
int height = (int) (width * 0.7);
Map<TextAttribute, Object> hm = new HashMap<>();
hm.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); // 定义加粗
hm.put(TextAttribute.SIZE, 12); // 定义字号
hm.put(TextAttribute.FAMILY, "微软雅黑"); // 定义字体名
Font font = new Font(hm);
Graphics2D graphics = image.createGraphics();
graphics.setFont(font);
int fontHeight = graphics.getFontMetrics().getHeight();
int totalHeight=height+fontHeight;
graphics.dispose();
BufferedImage outImage = new BufferedImage(width, totalHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = outImage.createGraphics();
// 抗锯齿
setGraphics2D(g2d);
// 设置白色
setColorWhite(g2d);
// 画条形码到新的面板
g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
// 画文字到新的面板
Color color = new Color(0, 0, 0);
g2d.setColor(color);
// 字体、字型、字号
g2d.setFont(font);
//todo 文字换行显示,需要重新计算高度
/* FontMetrics fontMetrics = g2d.getFontMetrics();
int strWidth = fontMetrics.stringWidth(words);
//测量是否需要换行
StringBuilder sb = new StringBuilder();
int textLength = words.length();
int totalWidth = fontMetrics.stringWidth(words); //文本的总长度,用于判断是否超出了范围
if (totalWidth > width) {
int nowWidth = 0; //目前一行写的长度
//遍历当前文本行
for (int i = 0; i < textLength; i++) {
sb.append(words.charAt(i));
int oneWordWidth = fontMetrics.charWidth(words.charAt(i)); //获取单个字符的长度
int tempWidth = oneWordWidth + nowWidth; //判断目前的一行加上这个字符的长度是否超出了总长度
if (tempWidth > width) {
//如果超出了一行的总长度,则要换成下一行 并画当前行
//int writeY = y + alreadyWriteLine * (textHeight + heightSpace);
y = drawAlignString(graphics2D, sb.toString(), align, x, y, lineWidth, lineHeight, tempWidth);
sb = new StringBuilder();
nowWidth = 0;
} else {
nowWidth = tempWidth;
}
}
}*/
//文字长度
int strWidth = g2d.getFontMetrics().stringWidth(words);
//总长度减去文字长度的一半 (居中显示)
int wordStartX = (width - strWidth) / 2;
//height + (outImage.getHeight() - height) / 2 + 12
int wordStartY = height + 15;
// 画文字
g2d.drawString(words, wordStartX, wordStartY);
g2d.dispose();
outImage.flush();
return outImage;
}
return null;
}
/**
* 设置 Graphics2D 属性 (抗锯齿)
*
* @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制
*/
private static void setGraphics2D(Graphics2D g2d) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
g2d.setStroke(s);
}
/**
* 设置背景为白色
*
* @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制
*/
private static void setColorWhite(Graphics2D g2d) {
g2d.setColor(Color.white);
g2d.fillRect(0,0,600,600);
//g2d.setBackground(new Color(255, 255, 255));
//设置笔刷
g2d.setColor(Color.BLACK);
}
/**
* 生成base64的二维码
*
* @param content 内容
* @return base64二维码
*/
public static String generateBarCodeBase64(String content) {
String base64;
ByteArrayOutputStream os = new ByteArrayOutputStream();
Code128Writer writer = new Code128Writer();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.CODE_128, WIDTH, HEIGHT, HINTS);
if (!StrUtil.isEmpty(content)) {
try {
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, FORMAT, os);
base64 = Base64.encode(os.toByteArray());
return base64;
} catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage());
} finally {
try {
os.flush();
os.close();
} catch (IOException e) {
log.error("流关闭失败:{}", e.getMessage());
}
}
}
return null;
}
/**
* 生成图片的二维码
*
* @param content 内容
*/
public static BufferedImage generateQrCode(String content, int width) {
MultiFormatWriter writer = new MultiFormatWriter();
if (!StrUtil.isEmpty(content)) {
try {
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, width, HINTS);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
} catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage());
}
}
return null;
}
/**
* 生成图片的二维码
*
* @param content 内容
* @param paths 路径
*/
public static void generateQrCodeFile(String content, String paths) {
MultiFormatWriter writer = new MultiFormatWriter();
if (!StrUtil.isEmpty(content)) {
try {
// 字节输出流
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, HINTS);
Path path = Paths.get(paths);
MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, path);
} catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage());
}
}
}
/**
* 生成文件流的二维码
*
* @param content 内容
* @param response 响应体
* @return 流
*/
public static OutputStream generateQrCodeStream(String content, HttpServletResponse response) {
MultiFormatWriter writer = new MultiFormatWriter();
OutputStream outputStream = null;
if (!StrUtil.isEmpty(content)) {
try {
// 字节输出流
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, HINTS);
outputStream = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, FORMAT, outputStream);
return outputStream;
} catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error("流关闭失败:{}", e.getMessage());
}
}
}
}
return null;
}
/**
* 生成base64的二维码
*
* @param content 内容
* @return base64二维码
*/
public static String generateQrCodeBase64(String content) {
String base64;
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (!StrUtil.isEmpty(content)) {
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, HINTS);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, FORMAT, os);
base64 = Base64.encode(os.toByteArray());
return base64;
} catch (Exception e) {
log.error("生成二维码失败:{}", e.getMessage());
} finally {
try {
os.flush();
os.close();
} catch (IOException e) {
log.error("流关闭失败:{}", e.getMessage());
}
}
}
return null;
}
public static void main(String[] args) throws IOException {
//QrCodeUtil.generateBarCodeFile("2004171839281004aadddfffffddffgfggf", "E:\\pic\\jpg\\1.png");
BufferedImage barCode = QrCodeUtil.getBarCode("123456789123456789");
BufferedImage bufferedImage = QrCodeUtil.insertWords(barCode, "123456789123456789");
ImageIO.write(bufferedImage,"png",new File("E:\\pic\\jpg\\test.png"));
}
}
\ No newline at end of file
package com.mortals.xhx.daemon.applicationservice;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.net.NetUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.daemon.applicationservice.model.DestInfo;
import lombok.extern.slf4j.Slf4j;
import org.pcap4j.core.PcapAddress;
import org.pcap4j.core.PcapNetworkInterface;
import org.pcap4j.core.Pcaps;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
//@Component
@Slf4j
public class CaptureStartedService implements IApplicationStartedService {
@Override
public void start() {
log.info("启动抓取网卡数据服务..");
ThreadPool.getInstance().init(20);
List<PcapNetworkInterface> allDevs = null;
try {
allDevs = Pcaps.findAllDevs();
for (final PcapNetworkInterface device : allDevs) {
String localHost = "127.0.0.1";
List<PcapAddress> addresses = device.getAddresses();
Boolean bool=false;
for (PcapAddress pcapAddress : addresses) {
// 获取网卡IP地址
String ip = pcapAddress.getAddress().getHostAddress();
// log.info("device"+JSON.toJSONString(device) + " ip:" + ip+" is local ipw:"+ JSON.toJSONString( NetUtil.localIps()));
//非本地网卡
boolean ipv4 = Validator.isIpv4(ip);
// log.info("deviceName:{},ip:{}, is ipv4:{}",device.getName(),ip ,ipv4);
if (ip != null && ip.contains(localHost)) {
bool=true;
break;
// 返回指定的设备对象
//return networkInterface;
}
if(!ipv4){
bool=true;
break;
}
}
if ("any".indexOf(device.getName()) != -1) {
continue;
}
if(!bool){
log.info("excloud device:{}",device.getName());
continue;
}
//log.info("deviceName:{},ip:{}, is ipv4:{}",device.getName(),ip ,ipv4);
Map<String, Set<String>> filterMap = DestInfo.build();
String redirectUrl = "";
CaptureThread captureThread = new CaptureThread(device, redirectUrl, filterMap);
ThreadPool.getInstance().execute(captureThread);
}
} catch (Exception e) {
log.error("启动抓取网卡服务异常:", e);
}
}
@Override
public void stop() {
log.info("停止服务..");
}
@Override
public int getOrder() {
return 10;
}
}
package com.mortals.xhx.daemon.applicationservice;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.mortals.xhx.daemon.applicationservice.model.Request;
import dorkbox.notify.Notify;
import dorkbox.notify.Pos;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pcap4j.core.BpfProgram;
import org.pcap4j.core.PcapHandle;
import org.pcap4j.core.PcapNetworkInterface;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.TcpPacket;
import java.io.EOFException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeoutException;
/**
* 持续获取本地网卡数据
*
* @author:
* @date: 2023/1/7 11:25
*/
@AllArgsConstructor
@Slf4j
public class CaptureThread implements Runnable {
public static final String AFFAIR_CODE = "affairCode";
private PcapNetworkInterface device;
private String redirectUrl;
private Map<String, Set<String>> filterMap;
@Override
public void run() {
int snapshotLength = 65536; // in bytes
int readTimeout = 50; // in milliseconds
PcapHandle handle = null;
try {
log.info("device:{} desc:{} address:{}",device.getName(),device.getDescription(),device.getAddresses());
handle = device.openLive(snapshotLength, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, readTimeout);
String filter = "tcp";
handle.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
while (true) {
try {
//过滤目标地址,端口
Packet packet = handle.getNextPacketEx();
//log.info("packet:{}",packet.length());
if (checkIpv4Packet(filterMap, packet)) continue;
TcpPacket tcp = packet.get(TcpPacket.class);
if (checkTcpPacket(filterMap, tcp)) continue;
if (checkHttpPacket(tcp)) continue;
//判断head信息
try {
String payLoad = new String(tcp.getPayload().getRawData(), "utf-8");
//解析httpHead协议
//解析http协议,获取下个包内容大小。通过内容大小判断区域内容
Request request = new Request();
// log.info("payLoad:{}",payLoad);
//分割协议头
List<String> vals = StrUtil.split(payLoad, "\r\n\r\n");
if (vals.size() < 2) {
continue;
}
List<String> split = StrUtil.split(vals.get(0), "\r\n", true, true);
for (String value : split) {
Request.parser(value, request);
}
//校验uripath
if (checkRequestUri(filterMap, request)) continue;
if (request.getContentType() == null) {
//设置默认类型
request.setContentType("application/json");
}
if (vals.get(1).length() == 0) {
//无内容区
continue;
}
//判断是application/x-www-form-urlencoded;charset=UTF-8 还是json
if (request.getContentType() != null && request.getContentType().indexOf("x-www-form-urlencoded") != -1) {
if (vals.get(1).length() == request.getContentLength()) {
String[] pairs = vals.get(1).split("\\&");
Map<String, String> formData = new HashMap<>();
for (int i = 0; i < pairs.length; i++) {
String[] fields = pairs[i].split("=");
if (fields.length > 1) {
String name = URLDecoder.decode(fields[0], "UTF-8");
String value = URLDecoder.decode(fields[1], "UTF-8");
formData.put(name, value);
}
}
//如果有则发送请求
if (formData.containsKey(AFFAIR_CODE)) {
//抓取到affairCode后发送到远端,并且成功后提示信息
String affairCode = formData.get(AFFAIR_CODE);
log.info("网卡:" + device.getName() + "affairCode:" + affairCode);
sendHttpMessage(redirectUrl, affairCode);
}
} else {
//内容分包,获取下一个包再resamble
}
//表单形式
} else if (request.getContentType() != null && request.getContentType().indexOf("json") != -1) {
if (vals.get(1).length() == request.getContentLength()) {
Map<String, String> formData = new JSONObject(vals.get(1)).toBean(Map.class);
//如果有则发送请求
if (formData.containsKey(AFFAIR_CODE)) {
//抓取到affairCode后发送到远端,并且成功后提示信息
String affairCode = formData.get(AFFAIR_CODE);
log.info("网卡:" + device.getName() + "ip:" + device.getAddresses() + "affairCode:" + affairCode);
sendHttpMessage(redirectUrl, affairCode);
}
} else {
//内容分包,获取下一个包再resamble
byte[] source = vals.get(1).getBytes();
//读取下个tcp包,如果长度大小相同 则是body 默认最多10个包
int num = 0;
while (num < 10) {
Packet nextPacket = handle.getNextPacket();
TcpPacket nextTcpPacket = nextPacket.get(TcpPacket.class);
if (checkTcpPacket(filterMap, nextTcpPacket)) continue;
byte[] target = nextTcpPacket.getPayload().getRawData();
source = doReassemble(source, target);
if (source.length == request.getContentLength()) {
//处理解析数据
Map<String, String> formData = new JSONObject(new String(source, "utf-8")).toBean(Map.class);
//如果有则发送请求
if (formData.containsKey(AFFAIR_CODE)) {
//抓取到affairCode后发送到远端,并且成功后提示信息
String affairCode = formData.get(AFFAIR_CODE);
log.info("网卡:" + device.getName() + "affairCode:" + affairCode);
sendHttpMessage(redirectUrl, affairCode);
}
break;
} else if (source.length < request.getContentLength()) {
num++;
continue;
} else {
//拼接包异常不做处理
break;
}
}
}
} else {
log.info("contenType error!");
}
} catch (UnsupportedEncodingException e) {
log.error("异常", e);
}
} catch (TimeoutException e) {
//log.info("超时异常:device {} ip:{} isLocal:{}",device.getName(),device.getAddresses(),device.isLocal());
//log.error("超时异常", e.getMessage());
} catch (EOFException e) {
log.error("异常EOFException", e.getMessage());
}
}
} catch (Exception e) {
log.error("异常", e);
}
}
private boolean checkRequestUri(Map<String, Set<String>> filterMap, Request request) {
return !filterMap.get("SendServerPath").contains(request.getRequestURI());
}
private boolean checkHttpPacket(TcpPacket tcp) throws UnsupportedEncodingException {
String payLoad = new String(tcp.getPayload().getRawData(), "utf-8");
if (payLoad.indexOf("HTTP") == -1) return true;
//System.out.println("payLoad:"+payLoad);
return false;
}
private boolean checkTcpPacket(Map<String, Set<String>> filterMap, TcpPacket tcp) {
String dstPort = tcp.getHeader().getDstPort().valueAsString();
// System.out.println("destPort before:"+dstPort);
if (!filterMap.get("SendServerPort").contains(dstPort)) {
return true;
}
if (tcp.getPayload() == null) {
return true;
}
//System.out.println("destPort:"+dstPort);
return false;
}
private boolean checkIpv4Packet(Map<String, Set<String>> filterMap, Packet packet) {
IpV4Packet ipV4Packet = packet.get(IpV4Packet.class);
if (ipV4Packet == null) {
return true;
}
String dest = ipV4Packet.getHeader().getDstAddr().getHostAddress();
if (!filterMap.get("SendServerIp").contains(dest)) {
return true;
}
//System.out.println("dest:"+dest);
return false;
}
private void sendHttpMessage(String url, String affairCode) {
if (url == null) {
log.info("发送地址为空!");
return;
}
String body = "";
String response = HttpUtil.post(url, body);
log.info("response :" + response);
if ("200".equals(response)) {
System.out.println("创建提示框!");
//创建提示框
Notify.create()
.title("aaaaa")
.text("这是什么")
.hideAfter(10000)
.position(Pos.BOTTOM_LEFT)
.darkStyle()
.showInformation();
}
}
//合并多个数据包
private byte[] doReassemble(byte[] source, byte[] target) {
//合并所需数组大小=原始包+新包
byte[] buffer = new byte[source.length + target.length];
System.arraycopy(source, 0, buffer, 0, source.length);
System.arraycopy(target, 0, buffer, source.length, target.length);
return buffer;
}
}
package com.mortals.xhx.daemon.applicationservice;
import com.mortals.framework.springcloud.service.IApplicationStartedService;
import com.mortals.xhx.opencv.UI.SetWindow;
import com.mortals.xhx.swing.MyTray;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DemoStartedService implements IApplicationStartedService {
@Value("${siteconfig.filepath:/root/mid.prop}")
String filePath;
@Value("${siteconfig.url:http://192.168.0.98:8090}")
String siteUrl;
@Override
public void start() {
log.info("开始服务..");
String path = System.getProperty("user.dir");
log.info("当前路径:{}", path);
String display = System.getenv("DISPLAY");
log.info("display:{}",display);
String osName = System.getProperty("os.name");
log.info("osName:{}",osName);
//MyTray.getInstance().SystemTrayInitial(filePath,siteUrl);
log.info("filePath:{}",filePath);
log.info("siteUrl:{}",siteUrl);
SetWindow.getInstance().initWindow(filePath,siteUrl);
log.info("初始化托盘完成!");
// Rest<ArrayList<PhotoBean>> rest = CameraOprationByOpenCV.initWindow(300);
//
// log.info("高拍仪照片:"+rest.getData().toString());
// SetWindow.initWindow(300);
/*
boolean headless = GraphicsEnvironment.isHeadless();
log.info("headless:{}",headless);*/
/* Demo demo = new Demo();
demo.test();*/
// new MySystemTray();
//加载so
//String strPath = System.getProperty("user.dir") + "\\lib\\tmz\\libSDTReader.so";
/* boolean sdkInstance = TMZMain.createSDKInstance();
log.info("skdInstance:" + sdkInstance);
int closeDev = TMZMain.tmzSDK._SDT_CloseDev();
log.info("close:0x{}", Integer.toHexString(closeDev));
int openret = TMZMain.tmzSDK._SDT_OpenUsbByFD(0);
log.info("打卡usb:{}", Integer.toHexString(openret));
if (Integer.toHexString(openret).equals("90")) {
log.info("打卡设备成功!");
//寻卡
byte[] pucManaInfo = new byte[4];
int ret = TMZMain.tmzSDK._SDT_StartFindIDCard(pucManaInfo);
log.info("寻卡:0x{},pucManaInfo:{}", Integer.toHexString(ret), pucManaInfo);
*//* if (!Integer.toHexString(ret).equals("9f")) {
log.info("寻卡失败");
return;
}*//*
//选卡
byte[] pucManaInfo1 = new byte[4];
int selectret = TMZMain.tmzSDK._SDT_SelectIDCard(pucManaInfo);
log.info("选卡:0x{}", Integer.toHexString(selectret));
//读卡
byte[] pucCHMsg = new byte[512];
byte[] pucPHMsg = new byte[2048];
byte[] pucFPMsg = new byte[2048];
// int puiCHMsgLen = 0, puiPHMsgLen = 0, puiFHMsgLen = 0;
IntByReference puiCHMsgLen = new IntByReference();
IntByReference puiPHMsgLen = new IntByReference();
IntByReference puiFHMsgLen = new IntByReference();
log.info("读卡开始");
// int[] ints = new int[8];
//int readret = TMZMain._SDT_ReadBaseMsg(pucCHMsg, ints, pucPHMsg, ints);
// int readret = JniTest._SDT_ReadBaseFPMsg(pucCHMsg, 0, pucPHMsg, 0,pucFPMsg,0);
int readret = TMZMain.tmzSDK._SDT_ReadBaseFPMsg(pucCHMsg, puiCHMsgLen, pucPHMsg, puiPHMsgLen,pucFPMsg,puiFHMsgLen);
//int readret = TMZMain.tmzParseSDK._SDT_ReadBaseMsg(pucCHMsg, puiCHMsgLen, pucPHMsg, puiPHMsgLen);
log.info("读卡:0x{},pucCHMsg:{}", Integer.toHexString(readret),pucCHMsg);
IntByReference iType = new IntByReference();
byte[] pSFZInfo = new byte[260];
int parseret = TMZMain.tmzSDK._SDT_ParseIDCardTextInfo(pucCHMsg, puiCHMsgLen.getValue(), iType, pSFZInfo);
String sfzStr = new String(pSFZInfo, StandardCharsets.UTF_8);
String[] split = sfzStr.split("|");
log.info("parseret:{},pSFZInfo:{}", parseret, sfzStr);
// byte[] pBmpFile = new byte[255];
byte[] pBmpFile ="/tmp/sfz.jpg".getBytes(StandardCharsets.UTF_8);
int photoRet = TMZMain.tmzSDK._SDT_ParsePhotoInfo(pucPHMsg, puiPHMsgLen.getValue(), 4, pBmpFile);
log.info("photoRet:0x{},pucCHMsg lens:{}", Integer.toHexString(photoRet),pucCHMsg.length);
}
*/
/*
String[] base64Text = CameraOpration.getInstance().initWindow();
log.info("base64Text:{}", base64Text);*/
/* Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
try {
String resp = HttpUtil.get("http://localhost:8092/app/account/imageCode");
if(!ObjectUtils.isEmpty(resp)){
log.info("http web is ok");
}
HttpClient http = null;
CookieStore httpCookieStore = new BasicCookieStore();
http = HttpClientBuilder.create().setDefaultCookieStore(httpCookieStore).build();
*//* do stuff *//*
HttpGet httpRequest = new HttpGet("http://localhost:8092/app/account/imageCode");
HttpResponse httpResponse = null;
try {
httpResponse = http.execute(httpRequest);
//String content = EntityUtils.toString(entity, charset);
//httpResponse.getEntity()
//httpResponse.toString()
} catch (Exception e) {
log.error("异常",e);
}
*//* check cookies *//*
String cookieStr = Arrays.asList(httpCookieStore.getCookies()).stream().map(item -> JSON.toJSONString(item)).collect(Collectors.joining("|"));
log.info("cookies:{}", cookieStr);
TimeUnit.MINUTES.sleep(2);
} catch (Exception e) {
log.error("异常", e);
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();*/
}
@Override
public void stop() {
log.info("停止服务..");
}
@Override
public int getOrder() {
return 10;
}
}
package com.mortals.xhx.daemon.applicationservice.model;
import cn.hutool.core.util.XmlUtil;
import lombok.Data;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import java.io.InputStream;
import java.util.*;
/**
* 目标服务信息
*
* @author: zxfei
* @date: 2021/11/2 20:12
* @description:
**/
@Data
public class DestInfo {
private String SendServerIp;
private Integer SendServerPort;
private String SendServerPath;
public static Map<String, Set<String>> build() {
Map<String, Set<String>> filterMap = new HashMap<>();
List<DestInfo> destInfos = new ArrayList<>();
ClassLoader classLoader = DestInfo.class.getClassLoader();
InputStream in = classLoader.getResourceAsStream("capture.xml");
//解析
Document document = XmlUtil.readXML(in);
NodeList nodeListByXPath = XmlUtil.getNodeListByXPath("/Captures//Capture//SendServerIp", document);
NodeList nodeListByXPath1 = XmlUtil.getNodeListByXPath("/Captures//Capture//SendServerPort", document);
NodeList nodeListByXPath2 = XmlUtil.getNodeListByXPath("/Captures//Capture//SendServerPath", document);
Set<String> set = new HashSet<>();
Set<String> set1 = new HashSet<>();
Set<String> set2 = new HashSet<>();
for (int i = 0; i < nodeListByXPath.getLength(); i++) {
set.add(nodeListByXPath.item(i).getTextContent());
set1.add(nodeListByXPath1.item(i).getTextContent());
set2.add(nodeListByXPath2.item(i).getTextContent());
}
filterMap.put("SendServerIp", set);
filterMap.put("SendServerPort", set1);
filterMap.put("SendServerPath", set2);
return filterMap;
}
}
package com.mortals.xhx.daemon.applicationservice.model;
import lombok.Data;
/**
* @author: zxfei
* @date: 2021/11/2 10:35
* @description:
**/
@Data
public class Request {
private String method;// 请求方法
private String protocol;// 协议版本
private String requestURL;
private String requestURI;//请求的URI地址 在HTTP请求的第一行的请求方法后面
private String host;//请求的主机信息
private String Connection;//Http请求连接状态信息 对应HTTP请求中的Connection
private String agent;// 代理,用来标识代理的浏览器信息 ,对应HTTP请求中的User-Agent:
private String language;//对应Accept-Language
private String encoding;//请求的编码方式 对应HTTP请求中的Accept-Encoding
private String charset;//请求的字符编码 对应HTTP请求中的Accept-Charset
private String accept;// 对应HTTP请求中的Accept;
private String contentType;//内容形式
private Integer contentLength;// 请求体长度
/**
* 传入HTTP请求中需要解析的某一句 解析该句,并请放入对应的Request对象中
*
* @param s
*/
public static void parser(String s, Request request) {
if (s.startsWith("GET")) {
String method = "Get";
request.setMethod(method);
int index = s.indexOf("HTTP");
//System.out.println("index--->" + index);
String uri = s.substring(3 + 1, index - 1).trim();// 用index-1可以去掉连接中的空格
// System.out.println("uri--->" + uri);
request.setRequestURI(uri);
String protocol = s.substring(index);
// System.out.println("protocol---->" + protocol);
request.setProtocol(protocol);
} else if (s.startsWith("POST")) {
String method = "POST";
request.setMethod(method);
int index = s.indexOf("HTTP");
String uri = s.substring(3 + 1, index - 1).trim();// 用index-1可以去掉连接中的空格
System.out.println("uri--->" + uri);
request.setRequestURI(uri);
String protocol = s.substring(index);
System.out.println("protocol---->" + protocol);
request.setProtocol(protocol);
} else if (s.startsWith("Accept:")) {
String accept = s.substring("Accept:".length() + 1);
System.out.println("accept--->" + accept);
request.setAccept(accept);
} else if (s.startsWith("User-Agent:")) {
String agent = s.substring("User-Agent:".length() + 1);
System.out.println("agent--->" + agent);
request.setAgent(agent);
} else if (s.startsWith("Host:")) {
String host = s.substring("Host:".length() + 1);
System.out.println("host--->" + host);
request.setHost(host);
} else if (s.startsWith("Accept-Language:")) {
String language = s.substring("Accept-Language:".length() + 1);
System.out.println("language--->" + language);
request.setLanguage(language);
} else if (s.startsWith("Accept-Charset:")) {
String charset = s.substring("Accept-Charset:".length() + 1);
System.out.println("charset--->" + charset);
request.setCharset(charset);
} else if (s.startsWith("Accept-Encoding:")) {
String encoding = s.substring("Accept-Encoding:".length() + 1);
System.out.println("encoding--->" + encoding);
request.setEncoding(encoding);
} else if (s.startsWith("Connection:")) {
String connection = s.substring("Connection:".length() + 1);
System.out.println("connection--->" + connection);
request.setConnection(connection);
} else if (s.startsWith("Content-Length:")) {
String lens = s.substring("Content-Length:".length() + 1);
System.out.println("Content-Length--->" + lens);
request.setContentLength(Integer.parseInt(lens));
}else if (s.startsWith("Content-Type:")) {
String contentType = s.substring("Content-Type:".length() + 1);
System.out.println("Content-Type--->" + contentType);
request.setContentType(contentType);
}
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getRequestURL() {
return requestURL;
}
public void setRequestURL(String requestURL) {
this.requestURL = requestURL;
}
public String getRequestURI() {
return requestURI;
}
public void setRequestURI(String requestURI) {
this.requestURI = requestURI;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getConnection() {
return Connection;
}
public void setConnection(String connection) {
Connection = connection;
}
public String getAgent() {
return agent;
}
public void setAgent(String agent) {
this.agent = agent;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getAccept() {
return accept;
}
public void setAccept(String accept) {
this.accept = accept;
}
public Integer getContentLength() {
return contentLength;
}
public void setContentLength(Integer contentLength) {
this.contentLength = contentLength;
}
}
package com.mortals.xhx.module.capture;
import com.mortals.xhx.common.osSelect;
import com.mortals.xhx.module.idCard.service.TMZParseSDK;
import com.mortals.xhx.module.idCard.service.TMZSDK;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
/**
* 高拍仪初始化
*
* @author: ZYW
* @date: 2024/01/24 09:59
*/
@Slf4j
public class CaptureMain {
}
package com.mortals.xhx.module.capture.model;
import lombok.Data;
/**
* 照片信息
* @author: zxfei
* @date: 2024/1/2 9:54
*/
@Data
public class File {
/**
* 文件名
* 1.jpg
*/
private String filename;
/**
* 文件类型 base64
* data:image/jpg;base64,/8j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ//2Q==
*/
private String Base64String;
}
package com.mortals.xhx.module.capture.service;
import com.sun.jna.Library;
/**
* 高拍仪so dell库
*
* @author: ZYW
* @date: 2024/01/24 09:59
*/
public interface CaptureSDK extends Library {
static int SXT_OK = 0; //成功
static int SXT_NOT_INIT_ERROR = -1; //SDK未初始化
static int SXT_NOT_DEVICE_ERROR = -2; //设备不存在
static int SXT_OPEN_DEVICE_ERROR = -3; //设备打开失败
static int SXT_PHOTOGRAPH_ERROR = -4; //拍照失败,摄像头未打开
static int SXT_RESOLUTION_ERROR = -5; //分辨率切换失败
static int SXT_MEMORY_ERROR = -6; //传入空间不够
static int SXT_FILE_ERROR = -7; //文件打开失败
static int SXT_FILE_DELETE_ERROR = -8; //文件删除失败
static int SXT_BARCODE_ERROR = -9; //条码识别失败
static int SXT_THREAD_ERROR = -10; //高拍仪线程初始化失败
static int SXT_ERROR_1 = -11; //参数错误
static int SXT_ERROR_2 = -12; //文件不存在
static int SXT_ERROR_3 = -13; //不支持的指令
static int SXT_ERROR_4 = -14; //摄像头数据读取出错
static int SXT_ERROR_5 = -15; //图片转PDF失败
static int SXT_ERROR_6 = -16; //身份证信息获取失败
static int SXT_ERROR_7 = -17; //没有这个功能
/*********************************
* 功能:
* 初始化高拍仪(必须先调用)
* 参数:
* 无
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_Init();
/*********************************
* 功能:
* 释放高拍仪(关闭高拍仪时必须调用)
* 参数:
* 无
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_Release();
/*********************************
* 功能:
* 视频流回调
* 参数:
* imgData - 图片二进制数据
* len - 图片长度
* 返回值:
* 参见: 错误代码
**********************************/
void DoSXT_VideoStreaming_Callback(String imgData, int len);
/*********************************
* 功能:
* 获取摄像头名称列表
* 参数:
* 无
* 返回值:
* 参见: 返回json字符串[{"index":1,"name":"video1"},
* {"index":2,"name":"video2"}]
* 如果没有找到返回空
**********************************/
String SXT_GetVideoInfos();
/*********************************
* 功能:
* 打开主头(副头打开时自动关闭副头)
* 参数:
* width - 分辨率宽度
* height - 分辨率高度
* 返回值:
* 参见: 错误代码
**********************************/
// int SXT_OpenHostDevice(int width, int height, DoSXT_VideoStreaming_Callback callback);
/*********************************
* 功能:
* 打开副头(主头打开时自动关闭主头)
* 参数:
* width - 分辨率宽度
* height - 分辨率高度
* 返回值:
* 参见: 错误代码
**********************************/
// int SXT_OpenDeputyDevice(int width,int height, DoSXT_VideoStreaming_Callback callback);
/*********************************
* 功能:
* 关闭摄像头
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_CloseDevice();
/*********************************
* 功能:
* 获取指定摄像头分辨率json列表
* 参数:
* index - 1 主头 2 副头(不是这个两个直接报错)
* 返回值:
* 参见: 返回json字符串 [{"index":1,"name":"640x480"},
* {"index":2,"name":"800x600"}]
* 如果没有找到返回空
**********************************/
String SXT_GetResolution(int index);
/*********************************
* 功能:
* 是否裁边拍照(只支持主头, 副头没有功能, 默认开启)
* 参数:
* type - 0 不裁边 1 裁边
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_SetCutType(int type);
/*********************************
* 功能:
* 设置视频画面模式
* 参数:
* type - 设置颜色 1 彩色 2 灰度 3 黑白
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_SetColorType(int type);
/*********************************
* 功能:
* 视频画面旋转
* 参数:
* direction - 旋转方向(左边 0 右边 1)
* rotate - 旋转角度(默认90)
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_SetRotate(int direction, int rotate);
/*********************************
* 功能:
* 拍照
* 参数:
* index - 1 文件拍照 2 base64 拍照
* path - 文件路径(可选)
* 回调:
* index - 拍照方式 1 文件拍照 2 base64 拍照
* imgData - 文件拍照或拍照失败时为空字符串
* len - 文件拍照或拍照失败时为-1
* isOk - 0 拍照成功 其他拍照失败
* isDelete - 如果是pdf会删除原图片此时返回1,否则返回0(默认)
* 返回值:
* 参见: 错误代码
**********************************/
void DoSXT_Photograph_Callback(int index, String imgData, int len, int isOk, int isDelete);
// int SXT_Photograph(int index, String path, DoSXT_Photograph_Callback callback);
/*********************************
* 功能:
* 设置分辨率
* 参数:
* resolutionIndex - 分辨率编号 0开始
* 返回值:
* 参见: 错误代码
**********************************/
int SXT_SetResolution(int resolutionIndex);
int SXT_SetResolution2(int w,int h);
/*********************************
* 功能:
* 图形拆分
* 参数:
* imgPath - 需要拆分的文件绝对路径
* dir - 保存文件夹
* type - 1 左右 2 上下
* 返回值:
* 成功返回json字符串, 失败返回空字符串 {"path1":"/tmp/1.jpg","path1":"/tmp/2.jpg"}
**********************************/
String SXT_SplitImage(String imgPath, String dir, int type);
/*********************************
* 功能:
* 图形合并
* 参数:
* imgPath1 - 需要合并的文件1绝对路径
* imgPath2 - 需要合并的文件2绝对路径
* path - 保存路径
* type - 1 左右 2 上下
* 返回值:
* 成功返回json字符串, 失败返回空字符串 {"path":"/tmp/1.jpg"}
**********************************/
String SXT_CombineImage(String imgPath1, String imgPath2, String savePath, int type);
/*********************************
* 功能:
* 文件转Base64
* 参数:
* file - 文件路径
* 返回值:
* 参见: 成功返回base64数据 失败返回 空
**********************************/
String SXT_FileToBase64(String path);
/*********************************
* 功能:
* 一维码识别
* 参数:
* file - 一维码图片
* 返回值:
* 参见: 成功返回扫码到的数据 失败返回 空
**********************************/
String SXT_DecodeBarcodeImage(String path);
}
\ No newline at end of file
package com.mortals.xhx.module.capture.service;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.module.capture.model.File;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import java.util.List;
/**
* 高拍仪 业务接口
*
* @author: zxfei
* @date: 2024/1/2 9:58
*/
public interface CaptureService {
Rest<List<File>> getCapture(String waitTime);
}
package com.mortals.xhx.module.capture.service.impl;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.capture.model.File;
import com.mortals.xhx.module.capture.service.CaptureService;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import com.mortals.xhx.module.print.service.PrintComponent.BasePrintComponent;
import com.mortals.xhx.module.print.service.PrintComponent.ComponentCons;
import com.mortals.xhx.module.print.service.PrintService;
import com.mortals.xhx.opencv.UI.CameraOprationByOpenCV;
import com.mortals.xhx.opencv.UI.CaptureUI;
import com.mortals.xhx.opencv.bean.PhotoBean;
import com.mortals.xhx.swing.SwingArea;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 高拍仪实现类
*
* @author: zxfei
* @date: 2024/1/2 10:00
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "capture", havingValue = "default")
public class CaptureServiceImpl implements CaptureService {
@Value("${siteconfig.configpath:'/root/config.prop'}")
String configPath;
@Value("${active.active:'reg'}")
String active;
@Value("${config.captureUrl:ws://localhost:1818/}")
private String url;
@Override
public Rest<List<File>> getCapture(String waitTime) {
Rest<ArrayList<PhotoBean>> rest = null;
log.info("active:{}",active);
if(active.equals("reg")){ //若尔盖是老版本opencv打开高拍仪
rest = CameraOprationByOpenCV.getInstance().initWindow(DataUtil.converStr2Int(waitTime, 120),configPath);
}else { //后续对接用汉腾提供的api开发
rest = CaptureUI.getInstance().initWindow(DataUtil.converStr2Int(waitTime, 120),configPath,url);
}
if (rest.getCode() == YesNoEnum.YES.getValue()) {
log.info("fileData:{}", JSON.toJSONString(rest.getData()));
List<File> fileList = rest.getData().stream().map(item -> {
File file = new File();
file.setFilename(item.getFilename());
file.setBase64String(item.getBase64String());
return file;
}).collect(Collectors.toList());
return Rest.ok("获取拍照列表成功!", fileList);
} else {
return Rest.fail(rest.getMsg());
}
}
public static void main(String[] args) {
PhotoBean photoBean = new PhotoBean("111","222");
System.out.println(JSON.toJSONString(photoBean));
}
}
package com.mortals.xhx.module.demo;
public interface BackCategoryRepository {
String getBackCategoryDetail(long backCategoryId);
}
package com.mortals.xhx.module.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(prefix="config",name = "data", havingValue = "one")
public class BackCategoryRepositoryImpl implements BackCategoryRepository {
@Override
public String getBackCategoryDetail(long backCategoryId) {
return "one";
}
}
package com.mortals.xhx.module.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(prefix="config",name = "data", havingValue = "two")
public class BackCategoryRepositoryTwoImpl implements BackCategoryRepository {
@Override
public String getBackCategoryDetail(long backCategoryId) {
return "two";
}
}
package com.mortals.xhx.module.demo.desktop;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class MySystemTray extends JFrame{
public MySystemTray() {
init();
}
public void init() {
this.setSize(300, 200);
this.setLocationRelativeTo(null);
this.setTray();
this.setVisible(true);
}
//添加托盘显示:1.先判断当前平台是否支持托盘显示
public void setTray() {
if(SystemTray.isSupported()){//判断当前平台是否支持托盘功能
//创建托盘实例
SystemTray tray = SystemTray.getSystemTray();
//创建托盘图标:1.显示图标Image 2.停留提示text 3.弹出菜单popupMenu 4.创建托盘图标实例
//1.创建Image图像
Image image = Toolkit.getDefaultToolkit().getImage("E:\\pic\\1.png");
//2.停留提示text
String text = "MySystemTray";
//3.弹出菜单popupMenu
PopupMenu popMenu = new PopupMenu();
MenuItem itmOpen = new MenuItem("打开");
itmOpen.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Show();
}
});
MenuItem itmHide = new MenuItem("隐藏");
itmHide.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
UnVisible();
}
});
MenuItem itmExit = new MenuItem("退出");
itmExit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
Exit();
}
});
popMenu.add(itmOpen);
popMenu.add(itmHide);
popMenu.add(itmExit);
//创建托盘图标
TrayIcon trayIcon = new TrayIcon(image,text,popMenu);
//将托盘图标加到托盘上
try {
tray.add(trayIcon);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
//内部类中不方便直接调用外部类的实例(this不能指向)
public void UnVisible() {
this.setVisible(false);
}
public void Show() {
this.setVisible(true);
}
public void Exit() {
System.exit(0);
}
public static void main(String[] args) {
new MySystemTray();
}
}
\ No newline at end of file
package com.mortals.xhx.module.demo.print;
import com.mortals.xhx.common.utils.QrCodeUtil;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class Main extends JFrame {
public Main() {
setTitle("绘制几何图形");
setBounds(100, 200, 500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
MyCanvas canvas = new MyCanvas();
c.add(canvas);
}
private class MyCanvas extends Canvas {
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;//新绘图类
//Image img = new ImageIcon("src/a.png").getImage();//获取图片来源
//g2.drawImage(img, 50, 0, this);a
BufferedImage barCode = QrCodeUtil.getBarCode("1231313123123131312aaaaaaaaaaa");
//g2.drawImage(barCode,null,20,100);
//居右
FontMetrics fontMetrics = g2.getFontMetrics();
String str="1231313123123131312aaaaaaaaaaa";
g2.drawImage(barCode,null,480 - barCode.getWidth(),100);
Color c = Color.RED;//设置颜色属性
Stroke stroke = new BasicStroke(8);//设置画笔属性
Font font = new Font("隶书", Font.BOLD, 16);
g2.setFont(font);//加载字体
g2.drawString("#################################################################################", 0, 30);//
g2.drawString("==================================================================", 0, 50);//
g2.drawString("..................................................................", 0, 70);//
//居右
fontMetrics = g2.getFontMetrics();
str="a lot of apple";
g2.drawString(str, 480 - fontMetrics.stringWidth(str), 90);//
//居中
fontMetrics = g2.getFontMetrics();
String str1="two lot of apple";
g2.drawString(str, (480 - fontMetrics.stringWidth(str1))/2, 220);//
float[] dash1 = {2.0f};
//设置打印线的属性。
//1.线宽 2、3、不知道,4、空白的宽度,5、虚线的宽度,6、偏移量
//g2.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 2.0f, dash1, 0.0f));
g2.drawLine(10,10,200,10);
// g2.setStroke(stroke);//加载画笔
/*BasicStroke.CAP_ROUND : 圆角末端
*BasicStroke.CAP_BUTT :无修饰末端
*BasicStroke.CAP_SQUARE :正方形末端
*
*BasicStroke.JOIN_BEVEL :平角
*BasicStroke.JOIN_MITER :尖角(默认)
*BasicStroke.JOIN_ROUND :圆角
* */
stroke = new BasicStroke(12, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);//加载画笔
// g2.setColor(c);
// g2.setColor(Color.BLUE);
// g2.drawOval(60, 20, 30, 30);// 画了一个圆
// g2.setColor(c);
// g2.fillRect(60, 20, 20, 20);// 画矩形
// g2.setColor(Color.BLUE);
//
// Shape shape1 = new Rectangle2D.Double(110, 5, 100, 100);// 矩形圆形对象
// g2.fill(shape1);// 画这个图形
//
// Shape shape2 = new Rectangle2D.Double(220, 15, 80, 80);// 矩形圆形对象
// g2.fill(shape2);// 画这个图形
//
// g2.drawArc(320, 25, 100, 50, 270, 200);// 弧形
//
// g2.drawLine(5, 120, 100, 120);//横线
// g2.drawLine(50, 120, 50, 200);//垂直线
//
// g2.drawRoundRect(120, 120, 100, 50, 10, 10);// 圆角矩形
//
// int x[] = { 250, 300, 250, 300 };
// int y[] = { 130, 130, 200, 200 };
//// g2.drawPolygon(x, y, 4);// 多边形
//
// g2.drawPolyline(x, y, 4);// 多边线
}
}
/**
* Graphic2D文本绘制换行,多行绘制
*
* @param graphics2D Graphics2D画笔实例
* @param text 需要绘制的文本内容
* @param maxWidth 一行的总宽度(像素)
* @param startX X坐标起始点(像素)
* @param startY Y坐标起始点(像素)
* @param heightSpace 每行间距(像素)
*/
public static void drawStringWithMultiLine(Graphics2D graphics2D, String text, int maxWidth, int startX, int startY, int heightSpace) {
// INFO: Dechert: 2021/1/7 获取画笔的字体
Font font = graphics2D.getFont();
// INFO: Dechert: 2021/1/7 通过JLabel获取文本的总长度和总高度
JLabel jLabel = new JLabel(text);
jLabel.setFont(font);
FontMetrics fontMetrics = jLabel.getFontMetrics(font);
int textLength = text.length();
int totalWidth = fontMetrics.stringWidth(text); //一行的总长度,用于判断是否超出了范围
int textHeight = fontMetrics.getHeight(); //计算一行的高度
if (totalWidth > maxWidth) {
// INFO: Dechert: 2021/1/7 总长度超过了整个长度限制
int alreadyWriteLine = 0; //已经写了多少行
int nowWidth = 0; //目前一行写的长度
for (int i = 0; i < textLength; i++) {
int oneWordWidth = fontMetrics.charWidth(text.charAt(i)); //获取单个字符的长度
int tempWidth = oneWordWidth + nowWidth; //判断目前的一行加上这个字符的长度是否超出了总长度
if (tempWidth > maxWidth) {
// INFO: Dechert: 2021/1/7 如果超出了一行的总长度,则要换成下一行
nowWidth = 0;
alreadyWriteLine++;
int writeY = startY + alreadyWriteLine * (textHeight + heightSpace);
graphics2D.drawString(text.charAt(i) + "", startX + nowWidth, writeY);
nowWidth = oneWordWidth;
} else {
// INFO: Dechert: 2021/1/7 当前行长度足够,可以直接画
int writeY = startY + alreadyWriteLine * (textHeight + heightSpace);
graphics2D.drawString(text.charAt(i) + "", startX + nowWidth, writeY);
nowWidth = tempWidth;
}
}
} else {
// INFO: Dechert: 2021/1/7 没有超过限制,直接画
graphics2D.drawString(text, startX, startY);
}
}
public static void main(String args[]) {
Main m = new Main();
}
}
\ No newline at end of file
package com.mortals.xhx.module.demo.print;
import java.awt.event.*;
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;
import java.awt.geom.*;
public class PrintPreviewDialog extends JDialog
implements ActionListener {
private JButton nextButton = new JButton("Next");
private JButton previousButton = new JButton("Previous");
private JButton closeButton = new JButton("Close");
private JPanel buttonPanel = new JPanel();
private PreviewCanvas canvas;
public PrintPreviewDialog(Frame parent, String title, boolean modal, PrintTest pt, String str) {
super(parent, title, modal);
canvas = new PreviewCanvas(pt, str);
setLayout();
}
private void setLayout() {
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(canvas, BorderLayout.CENTER);
nextButton.setMnemonic('N');
nextButton.addActionListener(this);
buttonPanel.add(nextButton);
previousButton.setMnemonic('N');
previousButton.addActionListener(this);
buttonPanel.add(previousButton);
closeButton.setMnemonic('N');
closeButton.addActionListener(this);
buttonPanel.add(closeButton);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
this.setBounds((int) ((SystemProperties.SCREEN_WIDTH - 400) / 2), (int) ((SystemProperties.SCREEN_HEIGHT - 400) / 2), 400, 400);
}
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == nextButton)
nextAction();
else if (src == previousButton)
previousAction();
else if (src == closeButton)
closeAction();
}
private void closeAction() {
this.setVisible(false);
this.dispose();
}
private void nextAction() {
canvas.viewPage(1);
}
private void previousAction() {
canvas.viewPage(-1);
}
class PreviewCanvas extends JPanel {
private String printStr;
private int currentPage = 0;
private PrintTest preview;
public PreviewCanvas(PrintTest pt, String str) {
printStr = str;
preview = pt;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
double xoff;
double yoff;
double scale;
double px = pf.getWidth();
double py = pf.getHeight();
double sx = getWidth() - 1;
double sy = getHeight() - 1;
if (px / py < sx / sy) {
scale = sy / py;
xoff = 0.5 * (sx - scale * px);
yoff = 0;
} else {
scale = sx / px;
xoff = 0;
yoff = 0.5 * (sy - scale * py);
}
g2.translate((float) xoff, (float) yoff);
g2.scale((float) scale, (float) scale);
Rectangle2D page = new Rectangle2D.Double(0, 0, px, py);
g2.setPaint(Color.white);
g2.fill(page);
g2.setPaint(Color.black);
g2.draw(page);
try {
preview.print(g2, pf, currentPage);
} catch (PrinterException pe) {
g2.draw(new Line2D.Double(0, 0, px, py));
g2.draw(new Line2D.Double(0, px, 0, py));
}
}
public void viewPage(int pos) {
int newPage = currentPage + pos;
if (0 <= newPage && newPage < preview.getPagesCount(printStr)) {
currentPage = newPage;
repaint();
}
}
}
}
\ No newline at end of file
package com.mortals.xhx.module.demo.print;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.util.Properties;
import java.awt.font.FontRenderContext;
import java.awt.print.*;
import javax.print.*;
import javax.print.attribute.*;
import java.io.*;
public class PrintTest extends JFrame
implements ActionListener, Printable {
private JButton printTextButton = new JButton("Print Text");
private JButton previewButton = new JButton("Print Preview");
private JButton printText2Button = new JButton("Print Text2");
private JButton printText3Button = new JButton("Print Text3");
private JButton printFileButton = new JButton("Print File");
private JButton printFrameButton = new JButton("Print Frame");
private JButton exitButton = new JButton("Exit");
private JLabel tipLabel = new JLabel("");
private JTextArea area = new JTextArea();
private JScrollPane scroll = new JScrollPane(area);
private JPanel buttonPanel = new JPanel();
private int PAGES = 0;
private String printStr;
public PrintTest() {
this.setTitle("Print Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds((int) ((SystemProperties.SCREEN_WIDTH - 800) / 2), (int) ((SystemProperties.SCREEN_HEIGHT - 600) / 2), 800, 600);
initLayout();
}
private void initLayout() {
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(scroll, BorderLayout.CENTER);
printTextButton.setMnemonic('P');
printTextButton.addActionListener(this);
buttonPanel.add(printTextButton);
previewButton.setMnemonic('v');
previewButton.addActionListener(this);
buttonPanel.add(previewButton);
printText2Button.setMnemonic('e');
printText2Button.addActionListener(this);
buttonPanel.add(printText2Button);
printText3Button.setMnemonic('g');
printText3Button.addActionListener(this);
buttonPanel.add(printText3Button);
printFileButton.setMnemonic('i');
printFileButton.addActionListener(this);
buttonPanel.add(printFileButton);
printFrameButton.setMnemonic('F');
printFrameButton.addActionListener(this);
buttonPanel.add(printFrameButton);
exitButton.setMnemonic('x');
exitButton.addActionListener(this);
buttonPanel.add(exitButton);
this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == printTextButton)
printTextAction();
else if (src == previewButton)
previewAction();
else if (src == printText2Button)
printText2Action();
else if (src == printText3Button)
printText3Action();
else if (src == printFileButton)
printFileAction();
else if (src == printFrameButton)
printFrameAction();
else if (src == exitButton)
exitApp();
}
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.black);
if (page >= PAGES)
return Printable.NO_SUCH_PAGE;
g2.translate(pf.getImageableX(), pf.getImageableY());
drawCurrentPageText(g2, pf, page);
return Printable.PAGE_EXISTS;
}
private void drawCurrentPageText(Graphics2D g2, PageFormat pf, int page) {
Font f = area.getFont();
String s = getDrawText(printStr)[page];
String drawText;
float ascent = 16;
int k, i = f.getSize(), lines = 0;
while (s.length() > 0 && lines < 54) {
k = s.indexOf('\n');
if (k != -1) {
lines += 1;
drawText = s.substring(0, k);
g2.drawString(drawText, 0, ascent);
if (s.substring(k + 1).length() > 0) {
s = s.substring(k + 1);
ascent += i;
}
} else {
lines += 1;
drawText = s;
g2.drawString(drawText, 0, ascent);
s = "";
}
}
}
public String[] getDrawText(String s) {
String[] drawText = new String[PAGES];
for (int i = 0; i < PAGES; i++)
drawText[i] = "";
int k, suffix = 0, lines = 0;
while (s.length() > 0) {
if (lines < 54) {
k = s.indexOf('\n');
if (k != -1) {
lines += 1;
drawText[suffix] = drawText[suffix] + s.substring(0, k + 1);
if (s.substring(k + 1).length() > 0)
s = s.substring(k + 1);
} else {
lines += 1;
drawText[suffix] = drawText[suffix] + s;
s = "";
}
} else {
lines = 0;
suffix++;
}
}
return drawText;
}
public int getPagesCount(String curStr) {
int page = 0;
int position, count = 0;
String str = curStr;
while (str.length() > 0) {
position = str.indexOf('\n');
count += 1;
if (position != -1)
str = str.substring(position + 1);
else
str = "";
}
if (count > 0)
page = count / 54 + 1;
return page;
}
private void printTextAction() {
printStr = area.getText().trim();
if (printStr != null && printStr.length() > 0) {
PAGES = getPagesCount(printStr);
PrinterJob myPrtJob = PrinterJob.getPrinterJob();
PageFormat pageFormat = myPrtJob.defaultPage();
myPrtJob.setPrintable(this, pageFormat);
if (myPrtJob.printDialog()) {
try {
myPrtJob.print();
} catch (PrinterException pe) {
pe.printStackTrace();
}
}
} else {
JOptionPane.showConfirmDialog(null, "Sorry, Printer Job is Empty, Print Cancelled!", "Empty"
, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);
}
}
private void previewAction() {
printStr = area.getText().trim();
PAGES = getPagesCount(printStr);
(new PrintPreviewDialog(this, "Print Preview", true, this, printStr)).setVisible(true);
}
private void printText2Action() {
printStr = area.getText().trim();
if (printStr != null && printStr.length() > 0) {
PAGES = getPagesCount(printStr);
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = printService.createPrintJob();
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(this, flavor, das);
try {
job.print(doc, pras);
} catch (PrintException pe) {
pe.printStackTrace();
}
} else {
JOptionPane.showConfirmDialog(null, "Sorry, Printer Job is Empty, Print Cancelled!", "Empty"
, JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE);
}
}
private void printText3Action() {
try {
String code = "test";
DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG;
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
//job
DocPrintJob job = printService.createPrintJob();
//document
//已输出流进行打印
BufferedImage img = new BufferedImage(400, 300, BufferedImage.TYPE_USHORT_555_RGB);
Graphics g = img.getGraphics();
g.drawString(code, 100, 100);
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", outstream);
byte[] buf = outstream.toByteArray();
InputStream stream = new ByteArrayInputStream(buf);
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(stream, flavor, das);
job.print(doc, pras);
} catch (Exception pe) {
pe.printStackTrace();
}
}
private void printFileAction() {
JFileChooser fileChooser = new JFileChooser(SystemProperties.USER_DIR);
//fileChooser.setFileFilter(new com.szallcom.file.JavaFilter());
int state = fileChooser.showOpenDialog(this);
if (state == fileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
PrintService service = ServiceUI.printDialog(null, 200, 200, printService
, defaultService, flavor, pras);
if (service != null) {
try {
DocPrintJob job = service.createPrintJob();
FileInputStream fis = new FileInputStream(file);
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(fis, flavor, das);
job.print(doc, pras);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void printFrameAction() {
Toolkit kit = Toolkit.getDefaultToolkit();
Properties props = new Properties();
props.put("awt.print.printer", "durango");
props.put("awt.print.numCopies", "2");
if (kit != null) {
PrintJob printJob = kit.getPrintJob(this, "Print Frame", props);
if (printJob != null) {
Graphics pg = printJob.getGraphics();
if (pg != null) {
try {
this.printAll(pg);
} finally {
pg.dispose();
}
}
printJob.end();
}
}
}
private void exitApp() {
this.setVisible(false);
this.dispose();
System.exit(0);
}
public static void main(String[] args) {
(new PrintTest()).setVisible(true);
}
}
package com.mortals.xhx.module.demo.print;
import java.awt.*;
public final class SystemProperties {
public static final double SCREEN_WIDTH = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
public static final double SCREEN_HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().getHeight();
public static final String USER_DIR = System.getProperty("user.dir");
public static final String USER_HOME = System.getProperty("user.home");
public static final String USER_NAME = System.getProperty("user.name");
public static final String FILE_SEPARATOR = System.getProperty("file.separator");
public static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static final String PATH_SEPARATOR = System.getProperty("path.separator");
public static final String JAVA_HOME = System.getProperty("java.home");
public static final String JAVA_VENDOR = System.getProperty("java.vendor");
public static final String JAVA_VENDOR_URL = System.getProperty("java.vendor.url");
public static final String JAVA_VERSION = System.getProperty("java.version");
public static final String JAVA_CLASS_PATH = System.getProperty("java.class.path");
public static final String JAVA_CLASS_VERSION = System.getProperty("java.class.version");
public static final String OS_NAME = System.getProperty("os.name");
public static final String OS_ARCH = System.getProperty("os.arch");
public static final String OS_VERSION = System.getProperty("os.version");
public static final String[] FONT_NAME_LIST = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
public static final Font[] FONT_LIST = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
public SystemProperties() {
}
}
package com.mortals.xhx.module.demo.print;
import java.awt.*;
import java.awt.print.*;
public class Test {
public static void main(String[] args) {
if (PrinterJob.lookupPrintServices().length > 0) {
//打印格式
PageFormat pageFormat = new PageFormat();
//设置打印起点从左上角开始,从左到右,从上到下打印
pageFormat.setOrientation(PageFormat.PORTRAIT);
//打印页面格式设置
Paper paper = new Paper();
//设置打印宽度(固定,和具体的打印机有关)和高度(跟实际打印内容的多少有关)
paper.setSize(140, 450);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, 135, 450);
pageFormat.setPaper(paper);
//创建打印文档
Book book = new Book();
book.append(new Printable() {
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
if (pageIndex > 0) {
return NO_SUCH_PAGE;
}
Graphics2D graphics2D = (Graphics2D) graphics;
Font font = new Font("宋体", Font.PLAIN, 5);
graphics2D.setFont(font);
drawString(graphics2D, "//", 10, 17, 119, 8);
font = new Font("宋体", Font.PLAIN, 7);
graphics2D.setFont(font);
int yIndex = 30;
int lineHeight = 10;
int lineWidth = 120;
Color defaultColor = graphics2D.getColor();
Color grey = new Color(145, 145, 145);
//收货信息
yIndex = drawString(graphics2D, "收货人:路人甲", 10, yIndex, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "收货地址:北京市海淀区上地十街10号百度大厦", 10, yIndex + lineHeight, lineWidth, lineHeight);
//收货信息边框
Stroke stroke = new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{4, 4}, 0);
graphics2D.setStroke(stroke);
graphics2D.drawRect(5, 10, 129, yIndex);
//药店名称
lineWidth = 129;
lineHeight = 8;
graphics2D.setFont(new Font("宋体", Font.BOLD, 8));
graphics2D.setColor(defaultColor);
yIndex = drawString(graphics2D, "北京药店零售小票", 5, yIndex + lineHeight + 20, lineWidth, 12);
graphics2D.setFont(new Font("宋体", Font.PLAIN, 6));
graphics2D.setColor(grey);
yIndex = drawString(graphics2D, "操作员:小清新", 5, yIndex + lineHeight + 2, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "日期:2017-01-05", 5 + lineWidth / 2, yIndex, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "品名", 5, yIndex + lineHeight * 2 - 5, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "规格", (lineWidth / 10) * 4, yIndex, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "单价", (lineWidth / 10) * 8, yIndex, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "数量", (lineWidth / 10) * 10, yIndex, lineWidth, lineHeight);
for (int i = 0; i < 5; i++) {
graphics2D.setFont(new Font("宋体", Font.PLAIN, 7));
yIndex = drawString(graphics2D, "E复合维生素B片100片E复合维生素B片100片", 5, yIndex + 15, (lineWidth / 10) * 7, 10);
graphics2D.setFont(new Font("宋体", Font.PLAIN, 6));
graphics2D.setColor(grey);
yIndex = drawString(graphics2D, "100片/盒", 5, yIndex + 11, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "14.50", (lineWidth / 10) * 8, yIndex, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "2", (lineWidth / 10) * 10, yIndex, lineWidth, lineHeight);
graphics2D.setFont(new Font("宋体", Font.PLAIN, 7));
yIndex = yIndex + 2;
graphics2D.drawLine(5, yIndex, 5 + lineWidth, yIndex);
}
graphics2D.setColor(defaultColor);
yIndex = drawString(graphics2D, "会员名称:小清新", 5, yIndex + lineHeight * 2, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "总 数:6", 5, yIndex + lineHeight, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "总 计:55.30", 5, yIndex + lineHeight, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "收 款:100.00", 5, yIndex + lineHeight, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "找 零:44.70", 5, yIndex + lineHeight, lineWidth, lineHeight);
graphics2D.setFont(new Font("宋体", Font.PLAIN, 6));
graphics2D.setColor(grey);
yIndex = drawString(graphics2D, "电话:020-123456", 5, yIndex + lineHeight * 2, lineWidth, lineHeight);
yIndex = drawString(graphics2D, "地址:北京市海淀区上地十街10号百度大厦", 5, yIndex + lineHeight, lineWidth, lineHeight);
yIndex = yIndex + 20;
graphics2D.drawLine(0, yIndex, 140, yIndex);
return PAGE_EXISTS;
}
}
, pageFormat);
//获取默认打印机
PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setPageable(book);
try {
printerJob.print();
} catch (PrinterException e) {
e.printStackTrace();
System.out.println("打印异常");
}
} else {
System.out.println("没法发现打印机服务");
}
}
/**
* 字符串输出
*
* @param graphics2D 画笔
* @param text 打印文本
* @param x 打印起点 x 坐标
* @param y 打印起点 y 坐标
* @param lineWidth 行宽
* @param lineHeight 行高
* @return 返回终点 y 坐标
*/
private static int drawString(Graphics2D graphics2D, String text, int x, int y, int lineWidth, int lineHeight) {
FontMetrics fontMetrics = graphics2D.getFontMetrics();
if (fontMetrics.stringWidth(text) > 0) {
graphics2D.drawString(text, x, y);
return y;
} else {
char[] chars = text.toCharArray();
int charsWidth = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
if ((charsWidth + fontMetrics.charWidth(chars[i])) > lineWidth) {
graphics2D.drawString(sb.toString(), x, y);
sb.setLength(0);
y = y + lineHeight;
charsWidth = fontMetrics.charWidth(chars[i]);
sb.append(chars[i]);
} else {
charsWidth = charsWidth + fontMetrics.charWidth(chars[i]);
sb.append(chars[i]);
}
}
if (sb.length() > 0) {
graphics2D.drawString(sb.toString(), x, y);
y = y + lineHeight;
}
return y - lineHeight;
}
}
}
package com.mortals.xhx.module.demo.print;
import com.mortals.framework.util.StringUtils;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import java.awt.*;
import java.awt.print.*;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class ThermalPrinter implements Printable {
private YcCustSale custSale;
private List<YcCustSaleDetail> custSaleDetailList;
private YcStore ycStore;
private YcUser ycUser;
/**
* 页面布局
*/
@Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (page > 0) {
return NO_SUCH_PAGE;
}
AtomicInteger flag = null;
Graphics2D g2d = (Graphics2D) g;
g2d.setFont(new Font("Tahoma", Font.PLAIN, 9));
if (this.ycStore != null && ycUser != null && custSale != null) {
g2d.drawString("欢迎光临" + this.ycStore.getStoreName(), 14, 10);
try {
g2d.drawString("机台名称:" + InetAddress.getLocalHost().getHostName().toString(), 14, 20);
} catch (UnknownHostException e) {
e.printStackTrace();
}
g2d.drawString("收银员:" + ycUser.getLoginName(), 14, 30);
int wordWrap = wordWrap(g2d, "流水号:" + custSale.getId(), new AtomicInteger(40), 24);
flag = new AtomicInteger(wordWrap);
}
g2d.drawString("------------------销-----售-----------------------", 7, flag.getAndAdd(20));
g2d.drawString("货号 品名 单价 数量 金额", 14, flag.getAndAdd(10));
if (custSaleDetailList != null && custSaleDetailList.size() > 0) {
for (int i = 0; i < custSaleDetailList.size(); i++) {
if (custSaleDetailList.get(i) != null
&& StringUtils.isNotBlank(custSaleDetailList.get(i).getGoodsCode())) {
String data = custSaleDetailList.get(i).getSalePrice() + " "
+ custSaleDetailList.get(i).getNum() + " " + custSaleDetailList.get(i).getTotalPrice();
g2d.drawString(custSaleDetailList.get(i).getGoodsCode(), 13, flag.getAndAdd(10));//商品条码
int wordWrap2 = wordWrap(g2d, " " + custSaleDetailList.get(i).getGoodsName(), flag, 17);//商品名称
flag = new AtomicInteger(wordWrap2 + 10);
//设置价格对齐
if (data.length() > 28) {
int wordWrap = wordWrap(g2d, data, flag, 28);
flag = new AtomicInteger(wordWrap);
} else {
g2d.drawString("" + custSaleDetailList.get(i).getSalePrice(), 55, flag.get());
g2d.drawString("" + custSaleDetailList.get(i).getNum(), 85, flag.get());
g2d.drawString("" + custSaleDetailList.get(i).getTotalPrice(), 110, flag.get());
flag.getAndAdd(10);
}
}
}
}
g2d.drawString("------------------------------------------------", 7, flag.getAndAdd(20));
if (custSale != null && ycStore != null) {
g2d.drawString(custSale.getTotalPrice() == null ? "合计 0.00" : "合计 " + custSale.getTotalPrice(), 13, flag.getAndAdd(10));
g2d.drawString(custSale.getNum() == null ? "总数 0" : "总数 " + custSale.getNum(), 13, flag.getAndAdd(10));
g2d.drawString(custSale.getSsPrice() == null ? "应付 0.00" : "应付 " + custSale.getYsPrice(), 13, flag.getAndAdd(10));
g2d.drawString(custSale.getYhPrice() == null ? "实收 0.00" : "实收 " + custSale.getSsPrice(), 13, flag.getAndAdd(10));
g2d.drawString(custSale.getYhPrice() == null ? "优惠 0.00" : "优惠 " + custSale.getYhPrice(), 13, flag.getAndAdd(10));
g2d.drawString(StringUtils.isNotBlank(custSale.getMemberPhone()) ? "会员 " + custSale.getMemberPhone() : "会员 ", 13, flag.getAndAdd(10));
g2d.drawString("积分 " + custSale.getMemberScore(), 13, flag.getAndAdd(10));
g2d.drawString(custSale.getZlPrice() == null ? "找零 0.00" : "找零 " + custSale.getZlPrice(), 13, flag.getAndAdd(10));
g2d.drawString("------------------------------------------------", 7, flag.getAndAdd(20));
//g2d.drawString("支付方式 " + PayTypeEnum.getValue(custSale.getPayType()), 13, flag.getAndAdd(10));
g2d.drawString("交易时间 " + sdf.format(custSale.getCreateDate()), 13, flag.getAndAdd(10));
g2d.drawString("送货电话 " + ycStore.getPhone(), 13, flag.getAndAdd(10));
int rowFlag = wordWrap(g2d, "地址 " + ycStore.getAddress(), new AtomicInteger(flag.get()), 17);
g2d.drawString(" 谢谢惠顾!欢迎再次光临本店!", 13, rowFlag);
}
return PAGE_EXISTS;
}
/**
* 开启打印
*/
public void printData() {
int height = 200 + 3 * 15 + 60;
if (custSaleDetailList != null && custSaleDetailList.size() > 0) {
height = 200 + custSaleDetailList.size() * 40 + 60;
}
// 通俗理解就是书、文档
Book book = new Book();
// 打印格式
PageFormat pf = new PageFormat();
pf.setOrientation(PageFormat.PORTRAIT);
// 通过Paper设置页面的空白边距和可打印区域。必须与实际打印纸张大小相符。
Paper p = new Paper();
p.setSize(230, height);
p.setImageableArea(5, -20, 230, height + 20);
pf.setPaper(p);
// 把 PageFormat 和 Printable 添加到书中,组成一个页面
book.append(this, pf);
// 获取打印服务对象
PrintService[] printServices = PrinterJob.lookupPrintServices();
for (int i = 0; i < printServices.length; i++) {
PrintService printService = printServices[i];
DocPrintJob printJob = printService.createPrintJob();
}
PrinterJob job = PrinterJob.getPrinterJob();
job.setPageable(book);
try {
job.print();
} catch (PrinterException e) {
System.out.println("================打印出现异常");
}
}
/**
* 自动换行
*
* @param g2d 构图对象
* @param data 打印的数据
* @param rowNum 当前行数
* @param characterNum 字符换行数
* @return
*/
public int wordWrap(Graphics2D g2d, String data, AtomicInteger rowNum, Integer characterNum) {
if (data.length() < 15) {
int andAdd = rowNum.getAndAdd(10);
g2d.drawString(data, 14, andAdd);
return andAdd;
} else {
int num = rowNum.get();
// 将字符串转变为指定长度的字符串集合
List<String> strList = getStrList(data, characterNum);
if (strList != null && strList.size() > 0) {
for (String wrapData : strList) {
g2d.drawString(wrapData, 14, rowNum.getAndAdd(10));
num += 10;
}
}
return num;
}
}
/**
* 把原始字符串分割成指定长度的字符串列表
*
* @param inputString 原始字符串
* @param length 指定长度
* @return
*/
public List<String> getStrList(String inputString, int length) {
int size = inputString.length() / length;
if (inputString.length() % length != 0) {
size += 1;
}
return getStrList(inputString, length, size);
}
/**
* 把原始字符串分割成指定长度的字符串列表
*
* @param inputString 原始字符串
* @param length 指定长度
* @param size 指定列表大小
* @return
*/
public List<String> getStrList(String inputString, int length, int size) {
List<String> list = new ArrayList<String>();
for (int index = 0; index < size; index++) {
String childStr = substring(inputString, index * length, (index + 1) * length);
list.add(childStr);
}
return list;
}
/**
* 分割字符串,如果开始位置大于字符串长度,返回空
*
* @param str 原始字符串
* @param f 开始位置
* @param t 结束位置
* @return
*/
public String substring(String str, int f, int t) {
if (f > str.length())
return null;
if (t > str.length()) {
return str.substring(f, str.length());
} else {
return str.substring(f, t);
}
}
@SuppressWarnings({"unused", "resource"})
public boolean printTest(String ip, int port, String str, String code, int skip) throws Exception {
Socket client = new java.net.Socket();
PrintWriter socketWriter;
client.connect(new InetSocketAddress(ip, port), 1000); // 创建一个 socket
socketWriter = new PrintWriter(client.getOutputStream());// 创建输入输出数据流
/* 纵向放大一倍 */
socketWriter.write(0x1c);
socketWriter.write(0x21);
socketWriter.write(8);
socketWriter.write(0x1b);
socketWriter.write(0x21);
socketWriter.write(8);
socketWriter.println(str);
// 打印条形码
socketWriter.write(0x1d);
socketWriter.write(0x68);
socketWriter.write(120);
socketWriter.write(0x1d);
socketWriter.write(0x48);
socketWriter.write(0x01);
socketWriter.write(0x1d);
socketWriter.write(0x6B);
socketWriter.write(0x02);
socketWriter.println(code);
socketWriter.write(0x00);
for (int i = 0; i < skip; i++) {
socketWriter.println(" ");// 打印完毕自动走纸
}
return true;
}
public YcCustSale getCustSale() {
return custSale;
}
public void setCustSale(YcCustSale custSale) {
this.custSale = custSale;
}
public List<YcCustSaleDetail> getCustSaleDetailList() {
return custSaleDetailList;
}
public void setCustSaleDetailList(List<YcCustSaleDetail> custSaleDetailList) {
this.custSaleDetailList = custSaleDetailList;
}
public YcStore getYcStore() {
return ycStore;
}
public void setYcStore(YcStore ycStore) {
this.ycStore = ycStore;
}
public YcUser getYcUser() {
return ycUser;
}
public void setYcUser(YcUser ycUser) {
this.ycUser = ycUser;
}
}
\ No newline at end of file
package com.mortals.xhx.module.demo.print;
import lombok.Data;
import java.util.Date;
@Data
public class YcCustSale {
private Integer id;
private String totalPrice;
private String num;
private String ssPrice;
private String ysPrice;
private String yhPrice;
private String memberPhone;
private String memberScore;
private String zlPrice;
private String payType;
private Date createDate;
}
package com.mortals.xhx.module.demo.print;
import lombok.Data;
@Data
public class YcCustSaleDetail {
private String salePrice;
private Integer num;
private String goodsCode;
private String goodsName;
private String totalPrice;
}
package com.mortals.xhx.module.demo.print;
import lombok.Data;
@Data
public class YcStore {
private String storeName;
private String phone;
private String address;
}
package com.mortals.xhx.module.demo.print;
import lombok.Data;
@Data
public class YcUser {
private String loginName;
}
package com.mortals.xhx.module.idCard;
import com.mortals.xhx.common.osSelect;
import com.mortals.xhx.module.idCard.service.TMZParseSDK;
import com.mortals.xhx.module.idCard.service.TMZSDK;
import com.sun.jna.Native;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TMZMain {
public static TMZSDK tmzSDK = null;
public static TMZParseSDK tmzParseSDK = null;
/**
* 根据不同操作系统选择不同的库文件和库路径
*
* @return
*/
public static boolean createSDKInstance() {
if (tmzSDK == null) {
synchronized (TMZSDK.class) {
String strDllPath = "";
try {
//System.setProperty("jna.debug_load", "true");
/* if (osSelect.isWindows())
//win系统加载库路径
strDllPath = System.getProperty("user.dir") + "\\lib\\tmz\\libSDTReader.so";
else if (osSelect.isLinux())*/
//Linux系统加载库路径
strDllPath = System.getProperty("user.dir") + "/lib/tmz/libSDTReader.so";
tmzSDK = Native.loadLibrary(strDllPath, TMZSDK.class);
strDllPath = System.getProperty("user.dir") + "/lib/tmz/libwlt.so";
tmzParseSDK = Native.loadLibrary(strDllPath, TMZParseSDK.class);
} catch (Exception ex) {
log.error("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
return false;
}
}
}
return true;
}
public static void main(String[] args) {
if (tmzSDK == null) {
if (!createSDKInstance()) {
System.out.println("Load SDK fail");
return;
}
}
//linux系统建议调用以下接口加载组件库
if (osSelect.isLinux()) {
TMZSDK.BYTE_ARRAY ptrByteArray1 = new TMZSDK.BYTE_ARRAY(256);
TMZSDK.BYTE_ARRAY ptrByteArray2 = new TMZSDK.BYTE_ARRAY(256);
//这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
/*
System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
ptrByteArray1.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArray1.getPointer());
System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
ptrByteArray2.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArray2.getPointer());
String strPathCom = System.getProperty("user.dir")+"/lib/";
HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
struComPath.write();
hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());*/
}
}
}
package com.mortals.xhx.module.idCard.model;
import lombok.Data;
@Data
public class IdCardCons {
/**
* 设置不解码身份证头像照片,返回的photobase64将为空(目前仅支持amd64平台解码,其他平台暂不支持)
*/
private String NoPhoto;
/**
* 同一张身份证只读第一次。
*/
private String readOnce;
/**
* 读卡超时单位秒 最长60秒
*/
private String waitTime;
/**
* 以JSONP方式返回数据
*/
private String callback;
}
package com.mortals.xhx.module.idCard.model;
import lombok.Data;
@Data
public class XzxIdCard {
private String code;
private String nation;
private String fpDescribe;
private Object fpData;
private String fpFeature1;
private String fpFeature2;
private String retmsg;
private String userlifee;
private String backImg;
private String userlifeb;
private String cardType;
private String fpFingerName1;
private String passID;
private String fpFingerName2;
private String address;
private String sex;
private String born;
private String errmsg;
private String cardno;
private String fpRegResult1;
private String fpRegResult2;
private String photobase64;
private String police;
private String issuesTimes;
private String frontImg;
private String name;
private String certVol;
private String fpQuality2;
private String engName;
private String fpQuality1;
private String retcode;
}
\ No newline at end of file
package com.mortals.xhx.module.idCard.service;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
/**
* 身份证业务接口
*
* @author:
* @date: 2022/12/26 13:26
*/
public interface IdCardService {
IdCardResp readIdCardMessage(IdCardCons cons);
}
package com.mortals.xhx.module.idCard.service;
import com.sun.jna.Library;
import com.sun.jna.Structure;
/**
* 身份证解析
*
* @author: zxfei
* @date: 2023/12/11 13:42
*/
public interface TMZParseSDK extends Library {
public static int success=0x90; //操作成功
int _SDT_OpenUsbByFD(int fd);//打开设备
int _SDT_CloseDev();//关闭设备
int _SDT_GetSAMID(byte[] pucSAMID);
/**
* @return 成功等于0x90,失败返回其他
* @brief 对 SAM_A 复位。
**/
int _SDT_ResetSAM();
/**
* @return 成功等于0,失败返回其他
* @brief 寻卡
* @param[OUT] pucManaInfo: 返回4字节0x00
**/
int _SDT_StartFindIDCard(byte[] pucManaInfo);
/**
* @return 成功等于0,失败返回其他
* @brief 选卡
* @param[OUT] pucManaMsg: 返回8字节0x00
**/
int _SDT_SelectIDCard(byte[] pucManaInfo);
/**
* @return 成功等于0x90,失败返回其他
* @brief 读取居民身份证机读文字信息和相片信息
* @param[OUT] pucCHMsg: 身份证文字信息
* @param[OUT] puiCHMsgLen: 身份证文字信息长度不少于256字节
* @param[OUT] pucPHMsg: 身份照片信息
* @param[OUT] puiPHMsgLen: 身份证照片信息长度不少于1024字节
**/
int _SDT_ReadBaseMsg(byte[] pucCHMsg, int puiCHMsgLen, byte[] pucPHMsg, int puiPHMsgLen);
/**
* @return 成功等于0x90,失败返回其他
* @brief 读取居民身份证机读文字信息、相片信息和指纹信息
* @param[OUT] pucCHMsg: 身份证文字信息
* @param[OUT] puiCHMsgLen: 身份证文字信息长度不少于256字节
* @param[OUT] pucPHMsg: 身份照片信息
* @param[OUT] puiPHMsgLen: 身份证照片信息长度不少于1024字节
* @param[OUT] pucFPMsg: 身份证指纹信息
* @param[OUT] puiFPMsgLen: 身份证指纹信息长度不少于1024字节
**/
int _SDT_ReadBaseFPMsg(byte[] pucCHMsg, int puiCHMsgLen, byte[] pucPHMsg, int puiPHMsgLen, byte[] pucFPMsg, int puiFPMsgLen);
/**
*@brief 解析身份证信息
**/
int _SDT_ParseIDCardTextInfo(byte[] pTextInfo, int iTextInfoLen, int iType, byte[] pWordInfo);
// int _SDT_ParseIDCardTextInfo(String pucCHMsg,int puiCHMsgLen,int iType,String pSFZInfo);
public static class BYTE_ARRAY extends Structure {
public byte[] byValue;
public BYTE_ARRAY(int iLen) {
byValue = new byte[iLen];
}
}
}
\ No newline at end of file
package com.mortals.xhx.module.idCard.service;
import com.sun.jna.Library;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
/**
* 身份证阅读器so dell库
*
* @author: zxfei
* @date: 2023/12/11 13:42
*/
public interface TMZSDK extends Library {
static int success = 0x90; //操作成功
int _SDT_OpenUsbByFD(int fd);//打开设备
int _SDT_CloseDev();//关闭设备
int _SDT_GetSAMID(byte[] pucSAMID);
/**
* @return 成功等于0x90,失败返回其他
* @brief 对 SAM_A 复位。
**/
int _SDT_ResetSAM();
/**
* @return 成功等于0,失败返回其他
* @brief 寻卡
* @param[OUT] pucManaInfo: 返回4字节0x00
**/
int _SDT_StartFindIDCard(byte[] pucManaInfo);
/**
* @return 成功等于0,失败返回其他
* @brief 选卡
* @param[OUT] pucManaMsg: 返回8字节0x00
**/
int _SDT_SelectIDCard(byte[] pucManaInfo);
/**
* @return 成功等于0x90,失败返回其他
* @brief 读取居民身份证机读文字信息和相片信息
* @param[OUT] pucCHMsg: 身份证文字信息
* @param[OUT] puiCHMsgLen: 身份证文字信息长度不少于256字节
* @param[OUT] pucPHMsg: 身份照片信息
* @param[OUT] puiPHMsgLen: 身份证照片信息长度不少于1024字节
**/
int _SDT_ReadBaseMsg(byte[] pucCHMsg, IntByReference puiCHMsgLen, byte[] pucPHMsg, IntByReference puiPHMsgLen);
/**
* @return 成功等于0x90,失败返回其他
* @brief 读取居民身份证机读文字信息、相片信息和指纹信息
* @param[OUT] pucCHMsg: 身份证文字信息
* @param[OUT] puiCHMsgLen: 身份证文字信息长度不少于256字节
* @param[OUT] pucPHMsg: 身份照片信息
* @param[OUT] puiPHMsgLen: 身份证照片信息长度不少于1024字节
* @param[OUT] pucFPMsg: 身份证指纹信息
* @param[OUT] puiFPMsgLen: 身份证指纹信息长度不少于1024字节
**/
int _SDT_ReadBaseFPMsg(byte[] pucCHMsg, IntByReference puiCHMsgLen, byte[] pucPHMsg, IntByReference puiPHMsgLen, byte[] pucFPMsg, IntByReference puiFPMsgLen);
/**
* @brief 解析身份证信息
**/
int _SDT_ParseIDCardTextInfo(byte[] pTextInfo, int iTextInfoLen, IntByReference iType, byte[] pWordInfo);
int _SDT_ParsePhotoInfo(byte[] pPhotoInfo, int iPhotoInfoLen, int iBmpFormat, byte[] pBmpFile);
// int _SDT_ParseIDCardTextInfo(String pucCHMsg,int puiCHMsgLen,int iType,String pSFZInfo);
static class BYTE_ARRAY extends Structure {
public byte[] byValue;
public BYTE_ARRAY(int iLen) {
byValue = new byte[iLen];
}
}
}
\ No newline at end of file
package com.mortals.xhx.module.idCard.service.impl;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* 德卡身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "dk")
public class DKIdCardServiceImpl implements IdCardService {
@Value("${config.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
//todo 德卡身份证识别待实现
IdCardResp idCardResp = new IdCardResp();
return idCardResp;
}
}
package com.mortals.xhx.module.idCard.service.impl;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* 国腾身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "gt")
public class GTIdCardServiceImpl implements IdCardService {
@Value("${config.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
//todo 国腾身份证识别待实现
IdCardResp idCardResp = new IdCardResp();
return idCardResp;
}
}
package com.mortals.xhx.module.idCard.service.impl;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* 华视身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "hs")
public class HSIdCardServiceImpl implements IdCardService {
@Value("${config.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
//todo 华视身份证识别待实现
IdCardResp idCardResp = new IdCardResp();
return idCardResp;
}
}
package com.mortals.xhx.module.idCard.service.impl;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* 精伦身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "jl")
public class JLIdCardServiceImpl implements IdCardService {
@Value("${config.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
//todo 精伦身份证识别待实现
IdCardResp idCardResp = new IdCardResp();
return idCardResp;
}
}
package com.mortals.xhx.module.idCard.service.impl;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* 神思身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "ss")
public class SSIdCardServiceImpl implements IdCardService {
@Value("${config.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
//todo 神思身份证识别待实现
IdCardResp idCardResp = new IdCardResp();
return idCardResp;
}
}
package com.mortals.xhx.module.idCard.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.utils.Base64Util;
import com.mortals.xhx.module.idCard.TMZMain;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.model.XzxIdCard;
import com.mortals.xhx.module.idCard.service.IdCardService;
import com.mortals.xhx.module.idCard.service.TMZSDK;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
/**
* TMZ身份证实现类
* <p>
* 加载so 调用so方法 完成身份证阅读
*
* @author: zxfei
* @date: 2023/12/12 15:04
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "tmz")
public class TMZIdCardServiceImpl implements IdCardService {
private Boolean DevOpen = false;
private Integer waitTime = 60;//单位秒
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
if (cons.getWaitTime() != null) {
DataUtil.converStr2Int(cons.getWaitTime(), 60);
}
IdCardResp idCardResp = new IdCardResp();
idCardResp.setStatus(YesNoEnum.NO.getValue() + "");
boolean sdkInstance = TMZMain.createSDKInstance();
if (!sdkInstance) {
idCardResp.setMessage("身份证阅读器初始化sdk失败!");
return idCardResp;
}
if (DevOpen) {
//关闭设备
TMZMain.tmzSDK._SDT_CloseDev();
}
int openret = TMZMain.tmzSDK._SDT_OpenUsbByFD(0);
log.info("打卡usb:{}", Integer.toHexString(openret));
if (Integer.toHexString(openret).equals("90")) {
ReadIDCardCycle(idCardResp);
}
return idCardResp;
}
/**
* 循环读卡
*
* @param idCardResp
* @return
*/
private IdCardResp ReadIDCardCycle(IdCardResp idCardResp) {
//等待时间 判断退出
DateTime endTime = DateUtil.offsetSecond(new Date(), waitTime);
while (true) {
int compare = DateUtil.compare(new Date(), endTime);
if (compare > 0) {
//超过读取时间,跳出循环,返回超时读取错误
idCardResp.setStatus(YesNoEnum.NO.getValue() + "");
idCardResp.setMessage("读取超时!");
break;
}
Boolean readIDCard = this.ReadIDCard(idCardResp);
if (readIDCard) {
log.info("读取成功!");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
log.error(e.getMessage());
}
}
return idCardResp;
}
private Boolean ReadIDCard(IdCardResp idCardResp) {
//寻卡
byte[] pucManaInfo = new byte[4];
int ret = TMZMain.tmzSDK._SDT_StartFindIDCard(pucManaInfo);
log.info("寻卡:0x{},pucManaInfo:{}", Integer.toHexString(ret), pucManaInfo);
//选卡
int selectret = TMZMain.tmzSDK._SDT_SelectIDCard(pucManaInfo);
log.info("选卡:0x{}", Integer.toHexString(selectret));
//读卡
byte[] pucCHMsg = new byte[512];
byte[] pucPHMsg = new byte[2048];
byte[] pucFPMsg = new byte[2048];
IntByReference puiCHMsgLen = new IntByReference();
IntByReference puiPHMsgLen = new IntByReference();
IntByReference puiFHMsgLen = new IntByReference();
int readret = TMZMain.tmzSDK._SDT_ReadBaseFPMsg(pucCHMsg, puiCHMsgLen, pucPHMsg, puiPHMsgLen, pucFPMsg, puiFHMsgLen);
log.info("读卡:0x{}", Integer.toHexString(readret));
IntByReference iType = new IntByReference();
byte[] pSFZInfo = new byte[260];
int parseret = TMZMain.tmzSDK._SDT_ParseIDCardTextInfo(pucCHMsg, puiCHMsgLen.getValue(), iType, pSFZInfo);
String sfzStr = new String(pSFZInfo, StandardCharsets.UTF_8);
List<String> splitList = StrUtil.split(sfzStr, "|");
//String[] split = sfzStr.split("|");
log.info("parseret:0x{},sfzStr:{}", Integer.toHexString(parseret), sfzStr);
//身份证信息封装
if (splitList.size() > 7) {
if (ObjectUtils.isEmpty(splitList.get(0))) {
log.info("身份证号码为空!");
return false;
}
idCardResp.setUsername(splitList.get(0));
idCardResp.setSex(splitList.get(1));
idCardResp.setNation(splitList.get(2));
idCardResp.setBorn(splitList.get(3));
idCardResp.setAddress(splitList.get(4));
idCardResp.setIdcardno(splitList.get(5));
idCardResp.setGrantDept(splitList.get(6));
idCardResp.setUserLifeBegin(splitList.get(7));
idCardResp.setUserLifeEnd(splitList.get(8));
String fileName = "/tmp/sfz_" + new Date().getTime() + ".jpg";
byte[] pBmpFile = fileName.getBytes(StandardCharsets.UTF_8);
int photoRet = TMZMain.tmzSDK._SDT_ParsePhotoInfo(pucPHMsg, puiPHMsgLen.getValue(), 4, pBmpFile);
log.info("photoRet:0x{},pucPHMsg lens:{}", Integer.toHexString(photoRet), pucPHMsg.length);
boolean exist = FileUtil.exist(fileName);
if(exist){
byte[] bytes = FileUtil.readBytes(fileName);
String photoBase64 = Base64.encode(bytes);
idCardResp.setPhotoBase64String("data:image/jpg;base64," + photoBase64);
}
idCardResp.setStatus(YesNoEnum.YES.getValue() + "");
idCardResp.setMessage("获取身份证成功");
return true;
}
return false;
}
public static void main(String[] args) {
/* byte[] bytes = FileUtil.readBytes("E:\\pic\\1.png");
String s = Base64.encode(bytes);
System.out.println(s);
*/
String str = "||||||||||";
// String[] split = str.split("|");
List<String> split = StrUtil.split(str, "|");
System.out.println(split.get(0));
}
}
package com.mortals.xhx.module.idCard.service.impl;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.xhx.busiz.rsp.IdCardResp;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.idCard.model.IdCardCons;
import com.mortals.xhx.module.idCard.model.XzxIdCard;
import com.mortals.xhx.module.idCard.service.IdCardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
/**
* 新中新身份证实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
@ConditionalOnProperty(prefix = "config", name = "idcard", havingValue = "xzx")
public class XZXIdCardServiceImpl implements IdCardService {
@Value("${config.idcard.xzxUrl:http://localhost:8989/api/ReadMsg}")
private String url;
@Override
public IdCardResp readIdCardMessage(IdCardCons cons) {
HashMap<String, String> params = new HashMap<>();
if (cons.getNoPhoto() != null) {
params.put("NoPhoto", cons.getNoPhoto());
}
if (cons.getReadOnce() != null) {
params.put("readOnce", cons.getReadOnce());
}
if (cons.getWaitTime() != null) {
params.put("waitTime", cons.getWaitTime());
}
if (cons.getCallback() != null) {
params.put("callback ", cons.getCallback());
}
String queryParams = HttpUtil.toParams(params);
String readUrl = url;
if (!ObjectUtils.isEmpty(readUrl)) {
readUrl = url + "?" + queryParams;
}
log.info("readUrl={}", readUrl);
String resp = HttpUtil.get(readUrl);
XzxIdCard idCard = JSON.parseObject(resp, XzxIdCard.class);
IdCardResp idCardResp = new IdCardResp();
if ("0".equals(idCard.getCode())) {
//映射
idCardResp.setUsername(idCard.getName());
idCardResp.setIdcardno(idCard.getCardno());
idCardResp.setSex(idCard.getSex());
idCardResp.setAddress(idCard.getAddress());
idCardResp.setBorn(idCard.getBorn());
idCardResp.setGrantDept(idCard.getPolice());
idCardResp.setNation(idCard.getNation());
idCardResp.setUserLifeBegin(idCard.getUserlifeb());
idCardResp.setUserLifeEnd(idCard.getUserlifee());
//idCardResp.setPhotoFileName();
idCardResp.setPhotoBase64String("data:image/jpg;base64," + idCard.getPhotobase64());
idCardResp.setStatus(YesNoEnum.YES.getValue() + "");
idCardResp.setMessage(idCard.getRetmsg());
} else {
idCardResp.setStatus(YesNoEnum.NO.getValue() + "");
idCardResp.setMessage(idCard.getErrmsg());
}
return idCardResp;
}
}
package com.mortals.xhx.module.print.model;
import lombok.Data;
@Data
public class PrintContent {
private String imgwidth;
private String fontstyle;
private String printtype;
private String fontsize;
private String fontunit;
private String title;
private String fontname;
private String align;
private String content;
public void initAttrValue() {
this.imgwidth = "100";
this.printtype = "text";
this.fontstyle = "regular";
this.fontsize = "12";
this.fontunit = "point";
this.title = "xxx";
this.fontname = "微软雅黑";
this.align = "left";
this.content = "目前正卡在这里寸步难行,请问我现在往哪里发展,应该怎么做,开了个大月。";
}
}
\ No newline at end of file
package com.mortals.xhx.module.print.model;
import lombok.Data;
@Data
public class Printer {
private String pinter;
}
\ No newline at end of file
package com.mortals.xhx.module.print.model;
import lombok.Data;
@Data
public class PrinterQueue {
private String queueName;
}
\ No newline at end of file
package com.mortals.xhx.module.print.service.PrintComponent;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.common.code.Base64TypeEnum;
import com.mortals.xhx.common.code.PrintTypeEnum;
import org.apache.commons.codec.binary.Base64;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.Copies;
import java.io.File;
import java.util.Date;
import java.util.List;
public class Base64PrintComponent extends BasePrintComponent {
public Base64PrintComponent(String type) {
super(type);
}
@Override
public void print(ComponentCons cons) {
PrintService printService = getPrintService(cons);
//base64 转换成图片 等其它 data:image/jpg;base64,/9j/4AAQSkZJRgA
String base64 = cons.getBase64();
String filePath = SpringUtil.getProperty("upload.path");
List<String> split = StrUtil.split(base64, ",");
if(split.size()<2){
throw new AppException("base64格式不正确!");
}
String head = split.get(0);
String base64Content = split.get(1);
if(Base64TypeEnum.BASE64_FILETYPE_JPG.getDesc().equalsIgnoreCase(head)){
}else if(Base64TypeEnum.BASE64_FILETYPE_TXT.getDesc().equalsIgnoreCase(head)){
String destFile = filePath + File.separator + new Date().getTime() + "." + Base64TypeEnum.BASE64_FILETYPE_TXT.getValue();
//Base64Util.decodeBase64(destFile,base64Content);
byte[] bytes = Base64.decodeBase64(base64Content);
//打印文件
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
DocPrintJob job = printService.createPrintJob();
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
DocAttributeSet das = new HashDocAttributeSet();
pras.add(new Copies(1));
Doc doc = new SimpleDoc(bytes, flavor, das);
try {
job.print(doc, pras);
} catch (PrintException e) {
throw new RuntimeException(e);
}
//Base64Util.decodeBase64String()
}
//String type = StrUtil.subBetween(head, "data:", ";");
//判断base64文件类型 生成不同类型文件
}
@Override
public String getType() {
return PrintTypeEnum.PRINT_BASE64.getValue();
}
}
package com.mortals.xhx.module.print.service.PrintComponent;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.common.code.PrintTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import java.awt.print.PrinterJob;
@Slf4j
public abstract class BasePrintComponent {
private String type;
public BasePrintComponent(String type) {
this.type = type;
}
public abstract void print(ComponentCons cons);
protected PrintService getPrintService(ComponentCons cons) {
PrintService printService = null;
if (ObjectUtils.isEmpty(cons.getPrintername())) {
printService = PrintServiceLookup.lookupDefaultPrintService();
if(printService==null){
PrintService[] printServices = PrinterJob.lookupPrintServices();
if(printServices.length>0){
printService=printServices[0];
}
}
} else {
// 匹配指定打印机
// 获得本台电脑连接的所有打印机
PrintService[] printServices = PrinterJob.lookupPrintServices();
if (printServices == null || printServices.length == 0) {
log.info("打印失败,未找到可用打印机,请检查!");
throw new AppException("打印失败,未找到可用打印机,请检查!");
}
for (int i = 0; i < printServices.length; i++) {
log.info(printServices[i].getName());
if (printServices[i].getName().contains(cons.getPrintername())) {
printService = printServices[i];
break;
}
}
if(printService==null){
printService = PrintServiceLookup.lookupDefaultPrintService();
}
}
return printService;
}
public static BasePrintComponent createType(String type) {
if (type.equals(PrintTypeEnum.PRINT_URL.getValue())) {
return new UrlPrintComponent(type);
} else if (type.equals(PrintTypeEnum.PRINT_BASE64.getValue())) {
return new Base64PrintComponent(type);
} else if (type.equals(PrintTypeEnum.PRINT_NORMAL.getValue())) {
return new NormalPrintComponent(type);
} else {
throw new AppException(String.format("不支持当前组件类型,Type:%s", type));
}
}
public abstract String getType();
}
package com.mortals.xhx.module.print.service.PrintComponent;
import com.mortals.xhx.module.print.model.PrintContent;
import lombok.Data;
import java.util.List;
@Data
public class ComponentCons {
private String papertype;
/**
* 打印机纸张宽度
*/
private String printerpaperwidth;
/**
* 打印机名称,为空则为默认打印机
*/
private String printername;
/**
* 网络附件下载连接
*/
private String url;
private String base64;
private List<PrintContent> contents;
}
package com.mortals.xhx.module.print.service.PrintComponent;
import cn.hutool.extra.spring.SpringUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.common.code.PaperTypeEnum;
import com.mortals.xhx.common.code.PrintTypeEnum;
import com.mortals.xhx.common.code.TicketTypeWidthEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import java.awt.print.*;
/**
* 普通行打印
*
* @author:
* @date: 2022/12/27 9:37
*/
@Slf4j
public class NormalPrintComponent extends BasePrintComponent {
Integer ticketMarginWidth = 30;
Integer marginTop = 20;
Integer marginBottom = 10;
public NormalPrintComponent(String type) {
super(type);
}
@Override
public void print(ComponentCons cons) {
String ticketType = SpringUtil.getProperty("print.ticket");
//创建打印文档
Book book = new Book();
//设置
TicketPrinter ticketPrinter = new TicketPrinter();
ticketPrinter.setMarginWidth(ticketMarginWidth);
ticketPrinter.setMarginTop(marginTop);
ticketPrinter.setPrintContentList(cons.getContents());
Integer ticketWidth = Integer.parseInt(TicketTypeWidthEnum.TYPE_LARGER.getDesc());
if (TicketTypeWidthEnum.TYPE_LARGER.getValue().equals(ticketType)) {
ticketWidth = Integer.parseInt(TicketTypeWidthEnum.TYPE_LARGER.getDesc());
} else if (TicketTypeWidthEnum.TYPE_SMALL.getValue().equals(ticketType)) {
ticketWidth = Integer.parseInt(TicketTypeWidthEnum.TYPE_SMALL.getDesc());
ticketMarginWidth = 22;
}
//打印格式
PageFormat pageFormat = new PageFormat();
//设置打印起点从左上角开始,从左到右,从上到下打印
pageFormat.setOrientation(PageFormat.PORTRAIT);
//打印页面格式设置
Paper paper = new Paper();
//设置打印宽度(固定,和具体的打印机有关)和高度(跟实际打印内容的多少有关)
if (cons.getPapertype().equals(PaperTypeEnum.PAPER_A3.getValue())) {
paper.setSize(841, 1190);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, 841, 1190);
} else if (cons.getPapertype().equals(PaperTypeEnum.PAPER_A4.getValue())) {
paper.setSize(595, 842);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, 595, 842);
} else if (cons.getPapertype().equals(PaperTypeEnum.PAPER_TICKET.getValue())) {
paper.setSize(ticketWidth, 576);
paper.setImageableArea(0, 0, ticketWidth, 566);
pageFormat.setPaper(paper);
int actualHeight = ticketPrinter.getActualHeight(pageFormat);
actualHeight += marginBottom;
log.info("ticketWidth:{} actualHeight:{}", ticketWidth, actualHeight);
//actualHeight=1500;
paper.setSize(ticketWidth, actualHeight);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, ticketWidth, actualHeight);
pageFormat.setPaper(paper);
/* paper.setSize(ticketWidth, 1314);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, ticketWidth, 1314);*/
} else {
//默认小票高宽 两种纸张宽度宽度 1.164 页边距11 2.227 页边距14
int actualHeight = ticketPrinter.getActualHeight(pageFormat);
//actualHeight += marginBottom;
//actualHeight=1500;
paper.setSize(ticketWidth, actualHeight);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, ticketWidth, actualHeight);
log.info("ticketWidth:{} actualHeight:{}", ticketWidth, actualHeight);
/* paper.setSize(ticketWidth, 566);
//设置打印区域 打印起点坐标、打印的宽度和高度
paper.setImageableArea(0, 0, ticketWidth, 566);*/
}
pageFormat.setPaper(paper);
book.append(ticketPrinter, pageFormat);
//获取默认打印机
PrintService printService = getPrintService(cons);
PrinterJob printerJob = PrinterJob.getPrinterJob();
log.info("page:" + book.getNumberOfPages());
printerJob.setPageable(book);
printerJob.setCopies(1);// 设置打印份数
try {
if (printService != null) {
printerJob.setPrintService(printService);
HashPrintRequestAttributeSet pars = new HashPrintRequestAttributeSet();
pars.add(Sides.ONE_SIDED); // 设置单双页
printerJob.print(pars);
} else {
log.info("打印失败,未找到名称为" + cons.getPrintername() + "的打印机,请检查。");
throw new AppException("打印失败,未找到名称为" + cons.getPrintername() + "的打印机,请检查。");
}
} catch (PrinterException e) {
log.error("打印异常", e);
throw new AppException(e.getMessage());
}
}
@Override
public String getType() {
return PrintTypeEnum.PRINT_NORMAL.getValue();
}
}
package com.mortals.xhx.module.print.service.PrintComponent;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.common.code.PrintAlignStyleEnum;
import com.mortals.xhx.common.code.PrintContentTypeEnum;
import com.mortals.xhx.common.code.PrintFontStyleEnum;
import com.mortals.xhx.common.utils.QrCodeUtil;
import com.mortals.xhx.module.print.model.PrintContent;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 文本小票打印
*
* @author:
* @date: 2022/12/27 16:15
*/
@Slf4j
public class TicketPrinter implements Printable {
// 每行的空闲高度
static final int lineHeight = 3;
// 页边距宽度
@Setter
@Getter
private Integer marginWidth;
@Setter
@Getter
private Integer marginTop;
@Setter
@Getter
private List<PrintContent> printContentList;
public int getActualHeight(PageFormat pageFormat) {
int xIndex = (int) pageFormat.getImageableX();
int yIndex = (int) pageFormat.getImageableY() + marginTop;
double imageableWidth = pageFormat.getPaper().getImageableWidth();
int charPerLine = (int) imageableWidth - marginWidth;
BufferedImage dimg = new BufferedImage((int) imageableWidth, (int) pageFormat.getPaper().getImageableWidth(), BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = dimg.createGraphics();
for (int i = 0; i < printContentList.size(); i++) {
//设置每行打印属性
PrintContent printContent = printContentList.get(i);
Map<TextAttribute, Object> hm = new HashMap<>();
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_UNDERLINE.getValue())) {
hm.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); // 定义是否有下划线
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_BOLD.getValue())) {
hm.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); // 定义加粗
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_ITALIC.getValue())) {
hm.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); // 是否斜体
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_REGULAR.getValue())) {
hm.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR); // 正常
}
hm.put(TextAttribute.SIZE, Integer.parseInt(printContent.getFontsize())); // 定义字号
hm.put(TextAttribute.FAMILY, printContent.getFontname()); // 定义字体名
Font font = new Font(hm); // 生成字号为12,字体为宋体,字形带有下划线的字体
graphics2D.setFont(font);
//设置打印颜色为黑色
graphics2D.setColor(Color.black);
// 背景色白色
graphics2D.setBackground(new Color(255, 255, 255));
//判断行内容是否为文本
if (PrintContentTypeEnum.PRINT_TEXT.getValue().equals(printContent.getPrinttype())) {
//文本输出
yIndex = drawString(graphics2D, printContent.getContent(), printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
} else if (PrintContentTypeEnum.PRINT_SEPARATE.getValue().equals(printContent.getPrinttype())) {
//分隔符
//测算分隔符宽度
FontMetrics fontMetrics = graphics2D.getFontMetrics();
int sepWidth = fontMetrics.stringWidth(printContent.getContent());
int count = charPerLine / sepWidth;
String repeatStr = StrUtil.repeat(printContent.getContent(), count);
yIndex = drawString(graphics2D, repeatStr, printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
} else if (PrintContentTypeEnum.PRINT_BARCODE.getValue().equals(printContent.getPrinttype())) {
//条形码
BufferedImage bufferedImage = QrCodeUtil.getBarCode(printContent.getContent());
bufferedImage= QrCodeUtil.insertWords(bufferedImage,printContent.getContent());
if(bufferedImage==null){
continue;
}
yIndex = drawBarCode(graphics2D, bufferedImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} else if (printContent.getPrinttype().equals(PrintContentTypeEnum.PRINT_QRCODE.getValue())) {
//二维码
int imgWidth = printContent.getImgwidth() == null ? 100 : DataUtil.converStr2Int(printContent.getImgwidth(), 100);
BufferedImage bufferedImage = QrCodeUtil.generateQrCode(printContent.getContent(), imgWidth);
yIndex = drawQrCode(graphics2D, bufferedImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} else if (printContent.getPrinttype().equals(PrintContentTypeEnum.PRINT_IMG.getValue())) {
//图片
byte[] bytes = HttpUtil.downloadBytes(printContent.getContent());
if (bytes.length > 0) {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
try {
BufferedImage image = ImageIO.read(in);
BufferedImage resizeBufferdImage = resize(image, DataUtil.converStr2Int(printContent.getImgwidth(), 0));
yIndex = drawImage(graphics2D, resizeBufferdImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} else {
//默认文本
yIndex = drawString(graphics2D, printContent.getContent(), printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
}
}
graphics2D.dispose();
return yIndex;
}
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
// 当打印页号大于需要打印的总页数时,打印工作结束
// 绘制打印内容
Graphics2D graphics2D = (Graphics2D) graphics;
if (pageIndex > 0) {
return NO_SUCH_PAGE;
}
log.info("字体高度:"+graphics2D.getFontMetrics().getHeight());
// 获取设定的纸张高度
// int height = (int) pageFormat.getPaper().getHeight();
// 计算每张图片有多少行文字
//int lineCount = height / lineHeight;
// 获取设置的纸张宽度
double imageableWidth = pageFormat.getPaper().getImageableWidth();
// 计算每行最大字符数
//int charPerLine = (int) imageableWidth / stringWidth;
int charPerLine = (int) imageableWidth - marginWidth;
// 获取打印的起点坐标
int xIndex = (int) pageFormat.getImageableX();
int yIndex = (int) pageFormat.getImageableY() + marginTop;
for (int i = 0; i < printContentList.size(); i++) {
//设置每行打印属性
PrintContent printContent = printContentList.get(i);
Map<TextAttribute, Object> hm = new HashMap<>();
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_UNDERLINE.getValue())) {
hm.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); // 定义是否有下划线
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_BOLD.getValue())) {
hm.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); // 定义加粗
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_ITALIC.getValue())) {
hm.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); // 是否斜体
}
if (printContent.getFontstyle().equals(PrintFontStyleEnum.PRINT_REGULAR.getValue())) {
hm.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR); // 正常
}
hm.put(TextAttribute.SIZE, Integer.parseInt(printContent.getFontsize())); // 定义字号
hm.put(TextAttribute.FAMILY, printContent.getFontname()); // 定义字体名
Font font = new Font(hm); // 生成字号为12,字体为宋体,字形带有下划线的字体
graphics2D.setFont(font);
//设置打印颜色为黑色
graphics2D.setColor(Color.black);
// 背景色白色
graphics2D.setBackground(new Color(255, 255, 255));
//判断行内容是否为文本
if (PrintContentTypeEnum.PRINT_TEXT.getValue().equals(printContent.getPrinttype())) {
//文本输出
yIndex = drawString(graphics2D, printContent.getContent(), printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
} else if (PrintContentTypeEnum.PRINT_SEPARATE.getValue().equals(printContent.getPrinttype())) {
//分隔符
//测算分隔符宽度
FontMetrics fontMetrics = graphics2D.getFontMetrics();
int sepWidth = fontMetrics.stringWidth(printContent.getContent());
int count = charPerLine / sepWidth;
String repeatStr = StrUtil.repeat(printContent.getContent(), count);
yIndex = drawString(graphics2D, repeatStr, printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
} else if (PrintContentTypeEnum.PRINT_BARCODE.getValue().equals(printContent.getPrinttype())) {
//条形码
BufferedImage bufferedImage = QrCodeUtil.getBarCode(printContent.getContent());
bufferedImage= QrCodeUtil.insertWords(bufferedImage,printContent.getContent());
if(bufferedImage==null){
continue;
}
yIndex = drawBarCode(graphics2D, bufferedImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} else if (printContent.getPrinttype().equals(PrintContentTypeEnum.PRINT_QRCODE.getValue())) {
//二维码
int imgWidth = printContent.getImgwidth() == null ? 100 : DataUtil.converStr2Int(printContent.getImgwidth(), 100);
BufferedImage bufferedImage = QrCodeUtil.generateQrCode(printContent.getContent(), imgWidth);
yIndex = drawQrCode(graphics2D, bufferedImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} else if (printContent.getPrinttype().equals(PrintContentTypeEnum.PRINT_IMG.getValue())) {
//图片
byte[] bytes = HttpUtil.downloadBytes(printContent.getContent());
if (bytes.length > 0) {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
try {
BufferedImage image = ImageIO.read(in);
BufferedImage resizeBufferdImage = resize(image, DataUtil.converStr2Int(printContent.getImgwidth(), 0));
yIndex = drawImage(graphics2D, resizeBufferdImage, printContent.getAlign(), xIndex, yIndex, charPerLine);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} else {
//默认文本
yIndex = drawString(graphics2D, printContent.getContent(), printContent.getAlign(), xIndex, yIndex, charPerLine, lineHeight);
}
}
graphics2D.dispose();
return PAGE_EXISTS;
}
private static int drawString(Graphics2D graphics2D, String text, String align, int x, int y, int lineWidth, int lineHeight) {
//计算文本宽度
FontMetrics fontMetrics = graphics2D.getFontMetrics();
int strWidth = fontMetrics.stringWidth(text);
//测量是否需要换行
StringBuilder sb = new StringBuilder();
int textLength = text.length();
int totalWidth = fontMetrics.stringWidth(text); //文本的总长度,用于判断是否超出了范围
if (totalWidth > lineWidth) {
int nowWidth = 0; //目前一行写的长度
//遍历当前文本行
for (int i = 0; i < textLength; i++) {
sb.append(text.charAt(i));
int oneWordWidth = fontMetrics.charWidth(text.charAt(i)); //获取单个字符的长度
int tempWidth = oneWordWidth + nowWidth; //判断目前的一行加上这个字符的长度是否超出了总长度
if (tempWidth > lineWidth) {
//如果超出了一行的总长度,则要换成下一行 并画当前行
//int writeY = y + alreadyWriteLine * (textHeight + heightSpace);
y = drawAlignString(graphics2D, sb.toString(), align, x, y, lineWidth, lineHeight, tempWidth);
sb = new StringBuilder();
nowWidth = 0;
} else {
nowWidth = tempWidth;
}
}
if (sb.toString().length() > 0) {
y = drawAlignString(graphics2D, sb.toString(), align, x, y, lineWidth, lineHeight, fontMetrics.stringWidth(sb.toString()));
}
} else {
// 没有超过限制,直接画
y = drawAlignString(graphics2D, text, align, x, y, lineWidth, lineHeight, strWidth);
}
return y;
}
private static int drawAlignString(Graphics2D graphics2D, String text, String align, int x, int y, int lineWidth, int lineHeight, int strWidth) {
//int heightSpace=0;
int fontHeight = graphics2D.getFontMetrics().getHeight();
lineHeight = fontHeight + lineHeight;
//布局方式
if (PrintAlignStyleEnum.PRINT_CENTER.getValue().equals(align)) {
//居中
graphics2D.drawString(text, (lineWidth - strWidth) / 2, y);
return y + lineHeight;
} else if (PrintAlignStyleEnum.PRINT_RIGHT.getValue().equals(align)) {
//居右
graphics2D.drawString(text, lineWidth - strWidth, y);
return y + lineHeight;
} else {
//默认靠左
graphics2D.drawString(text, x, y);
return y + lineHeight;
}
}
public static BufferedImage resize(BufferedImage img, int newW) {
//根据比例
BigDecimal radio = new BigDecimal(img.getWidth()).divide(new BigDecimal(img.getHeight()), 2, BigDecimal.ROUND_CEILING);
int newH = new BigDecimal(newW).divide(radio, 2, BigDecimal.ROUND_CEILING).intValue();
Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}
private static int drawBarCode(Graphics2D graphics2D, BufferedImage bufferedImage, String align, int x, int y, int lineWidth) {
//布局方式
if (PrintAlignStyleEnum.PRINT_CENTER.getValue().equals(align)) {
//居中
graphics2D.drawImage(bufferedImage, null, (lineWidth - bufferedImage.getWidth()) / 2, y);
return y + bufferedImage.getHeight() + lineHeight;
} else if (PrintAlignStyleEnum.PRINT_RIGHT.getValue().equals(align)) {
//居右
graphics2D.drawImage(bufferedImage, null, lineWidth - bufferedImage.getWidth(), y);
return y + bufferedImage.getHeight() + lineHeight;
} else {
//默认靠左
graphics2D.drawImage(bufferedImage, null, x, y);
return y + bufferedImage.getHeight() + lineHeight;
}
}
private static int drawQrCode(Graphics2D graphics2D, BufferedImage bufferedImage, String align, int x, int y, int lineWidth) {
//布局方式
if (PrintAlignStyleEnum.PRINT_CENTER.getValue().equals(align)) {
//居中
graphics2D.drawImage(bufferedImage, null, (lineWidth - bufferedImage.getWidth()) / 2, y);
return y + bufferedImage.getHeight() + lineHeight;
} else if (PrintAlignStyleEnum.PRINT_RIGHT.getValue().equals(align)) {
//居右
graphics2D.drawImage(bufferedImage, null, lineWidth - bufferedImage.getWidth(), y);
return y + bufferedImage.getHeight() + lineHeight;
} else {
//默认靠左
graphics2D.drawImage(bufferedImage, null, x, y);
return y + bufferedImage.getHeight() + lineHeight;
}
}
private static int drawImage(Graphics2D graphics2D, BufferedImage bufferedImage, String align, int x, int y, int lineWidth) {
//布局方式
if (PrintAlignStyleEnum.PRINT_CENTER.getValue().equals(align)) {
//居中
graphics2D.drawImage(bufferedImage, null, (lineWidth - bufferedImage.getWidth()) / 2, y);
return y + bufferedImage.getHeight() + lineHeight;
} else if (PrintAlignStyleEnum.PRINT_RIGHT.getValue().equals(align)) {
//居右
graphics2D.drawImage(bufferedImage, null, lineWidth - bufferedImage.getWidth(), y);
return y + bufferedImage.getHeight() + lineHeight;
} else {
//默认靠左
graphics2D.drawImage(bufferedImage, null, x, y);
return y + bufferedImage.getHeight() + lineHeight;
}
}
public static void main(String[] args) {
int w = 1080;
int h = 1620;
BigDecimal divide = new BigDecimal(w).divide(new BigDecimal(h), 2, BigDecimal.ROUND_CEILING);
System.out.println(divide.doubleValue());
/* int charPerLine = 10;
int lineCount = 10;
List<PrintContent> printContentList = new ArrayList<>();
PrintContent printContent = new PrintContent();
printContent.setContent("写了一个打印机遇到打印纸张输出的问题打印纸张有或者当设置纸张的时候需要横向打印");
printContentList.add(printContent);
List<PrintContent> newList = new ArrayList<>();
// 计算处理后得到信息需要打印的页数及换行
for (int j = 0; j < printContentList.size(); j++) {
PrintContent content = printContentList.get(j);
if (content.getContent().length() > charPerLine) {
//换行
String substring = content.getContent().substring(0, charPerLine);
PrintContent temp = new PrintContent();
BeanUtils.copyProperties(content, temp);
temp.setContent(substring);
newList.add(temp);
content.setContent(content.getContent().substring(charPerLine));
//裁剪后添加到过的内容到后一位
printContentList.add(j + 1, content);
//修改当前裁剪的内容
printContentList.set(j, temp);
} else {
newList.add(content);
}
}
// 计算处理后得到信息需要打印的页数
int a = newList.size();
int pageNum = a % lineCount == 0 ? (a / lineCount) : (a / lineCount) + 1;
System.out.println(JSON.toJSONString(newList));
System.out.println(pageNum);*/
}
}
package com.mortals.xhx.module.print.service.PrintComponent;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import com.mortals.xhx.common.code.PrintTypeEnum;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UrlPrintComponent extends BasePrintComponent {
public UrlPrintComponent(String type) {
super(type);
}
@Override
public void print(ComponentCons cons) {
//通过网络下载附件地址
byte[] fileBytes = HttpUtil.downloadBytes(cons.getUrl());
//获取文件后缀
String suffixName = FileUtil.getSuffix(cons.getUrl());
log.info("file lens:{}", fileBytes.length);
log.info("file suffixName:{}", suffixName);
}
@Override
public String getType() {
return PrintTypeEnum.PRINT_URL.getValue();
}
}
package com.mortals.xhx.module.print.service;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import java.util.List;
/**
* 打印业务接口
*
* @author:
* @date: 2022/12/26 13:26
*/
public interface PrintService {
Rest<Void> executePrint(PrintReq printReq);
Rest<List<Printer>> getPrintList();
Rest<List<PrinterQueue>> getPrintQueue(String printerName);
}
package com.mortals.xhx.module.print.service.impl;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.common.utils.BeanUtil;
import com.mortals.xhx.module.print.model.Printer;
import com.mortals.xhx.module.print.model.PrinterQueue;
import com.mortals.xhx.module.print.service.PrintComponent.BasePrintComponent;
import com.mortals.xhx.module.print.service.PrintComponent.ComponentCons;
import com.mortals.xhx.module.print.service.PrintService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import java.awt.print.PrinterJob;
import java.util.ArrayList;
import java.util.List;
/**
* 打印实现类
*
* @author:
* @date: 2022/12/26 14:09
*/
@Service
@Slf4j
public class PrintServiceImpl implements PrintService {
@Override
public Rest<Void> executePrint(PrintReq printReq) {
//根据打印类型
BasePrintComponent basePrintComponent = BasePrintComponent.createType(printReq.getPrintertype());
ComponentCons componentCons = new ComponentCons();
BeanUtils.copyProperties(printReq,componentCons, BeanUtil.getNullPropertyNames(printReq));
basePrintComponent.print(componentCons);
//获取打印的类型
return Rest.ok();
}
@Override
public Rest<List<Printer>> getPrintList() {
List<Printer> list = new ArrayList<>();
javax.print.PrintService[] printServices = PrinterJob.lookupPrintServices();
for (int i = 0; i < printServices.length; i++) {
log.info(printServices[i].getName());
Printer printer = new Printer();
printer.setPinter(printServices[i].getName());
list.add(printer);
}
return Rest.ok(list);
}
@Override
public Rest<List<PrinterQueue>> getPrintQueue(String printerName) {
ArrayList<PrinterQueue> printerQueues = new ArrayList<>();
javax.print.PrintService printService = null;
javax.print.PrintService[] printServices = PrinterJob.lookupPrintServices();
if (printServices == null || printServices.length == 0) {
log.info("打印失败,未找到可用打印机,请检查!");
throw new AppException("打印失败,未找到可用打印机,请检查!");
}
for (int i = 0; i < printServices.length; i++) {
log.info(printServices[i].getName());
if (printServices[i].getName().contains(printerName)) {
printService = printServices[i];
break;
}
}
//队列数量
int queue = 0;
if(printServices!=null){
AttributeSet attributes = printService.getAttributes();
for (Attribute a : attributes.toArray()) {
String name = a.getName();
String value = attributes.get(a.getClass()).toString();
log.info(name + " : " + value);
if (name.equals("queued-job-count")) {
queue = Integer.parseInt(value);
}
}
for (int i = 0; i <queue ; i++) {
PrinterQueue printerQueue = new PrinterQueue();
printerQueue.setQueueName("打印队列"+i);
printerQueues.add(printerQueue);
}
// Object[] obj = attributes.toArray();
}
return Rest.ok(printerQueues);
}
}
package com.mortals.xhx.module.sign.modle;
import lombok.Data;
/**
* 签名图片信息
* @author: zhou
* @date: 2024/7/9 9:54
*/
@Data
public class File {
/**
* 文件类型 base64
* data:image/jpg;base64,/8j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ//2Q==
*/
private String Base64String;
}
package com.mortals.xhx.module.sign.service;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.busiz.req.SignReq;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.module.sign.modle.File;
import java.util.List;
/**
* 高拍仪 业务接口
*
* @author: zxfei
* @date: 2024/1/2 9:58
*/
public interface SignService {
SignResp getSign(String sigType);
}
package com.mortals.xhx.module.sign.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.xhx.busiz.req.SignReq;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.module.sign.service.SignService;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.net.URI;
import java.net.URISyntaxException;
/**
* 签名版实现类
*
* @author: zhou
* @date: 2024/7/8 10:00
*/
@Service
@Slf4j
public class SignServiceImpl implements SignService {
@Value("${config.signUrl:ws://127.0.0.1:29999/}")
private String url;
static int runTime = 60; //60S超时返回
@Override
public SignResp getSign(String signType) {
WebSocketClient webSocketClient = null;
URI uri;
SignResp signResp = new SignResp();
if(runTime != 60){
signResp.setHWPenSign(signType);
signResp.setMsgID(-1);
signResp.setMessage("操作中,请勿重复发送指令");
return signResp;
}
//提交操作参数
SignReq signReq = new SignReq();
signReq.setHWPenSign(signType);
try {
uri = new URI(url);
} catch (Exception e) {
throw new RuntimeException(e);
}
if(webSocketClient != null && !webSocketClient.isClosed()){
String msg = JSON.toJSONString(signReq);
log.info("发送msg = " +msg);
webSocketClient.send(msg.getBytes());
}else {
webSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
String msg = JSON.toJSONString(signReq);
log.info("新连接已打开:msg =" +msg);
send(msg.getBytes());
}
@Override
public void onMessage(String message) {
log.info("接收到消息: {}",message);
if(message != null){
JSONObject jsonObject = JSON.parseObject(message);
signResp.setHWPenSign(jsonObject.getString("HWPenSign"));
signResp.setMsgID(jsonObject.getInteger("msgID"));
signResp.setMessage(jsonObject.getString("message"));
}
}
@Override
public void onClose(int code, String reason, boolean remote) {
log.info("连接已关闭,code:{} reason:{} {}",code,reason,remote);
signResp.setHWPenSign(signType);
signResp.setMsgID(-1);
signResp.setMessage("连接已关闭,code="+code+",reason="+reason);
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
log.info("链接出错了"+ex.toString());
signResp.setHWPenSign(signType);
signResp.setMsgID(-1);
signResp.setMessage(ex.toString());
}
};
webSocketClient.connect(); // 连接到WebSocket服务器
}
while (true){
try {
runTime --;
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if(signResp.getHWPenSign() != null && !signResp.getHWPenSign().equals("")){
runTime = 60;
return signResp;
}
if(runTime <= 0){
runTime = 60;
signResp.setHWPenSign(signType);
signResp.setMsgID(-1);
signResp.setMessage("链接签名板失败,操作超时");
return signResp;
}
}
}
public static void main(String[] args) {
URI uri = null;
try {
SignReq signReq = new SignReq();
signReq.setHWPenSign("HWGetDeviceStatus");
uri = new URI("ws://192.168.0.158:29999/");
WebSocketClient webSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
System.out.println("新连接已打开");
}
@Override
public void onMessage(String message) {
System.out.println("接收到消息: "+message);
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("连接已关闭,code="+code+",reason="+reason);
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
System.out.println("链接出错了"+ex.toString());
}
};
webSocketClient.connect(); // 连接到WebSocket服务器
webSocketClient.send(JSON.toJSONString(signReq));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
package com.mortals.xhx.module.social.service;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.busiz.rsp.SocialResp;
/**
* 高拍仪 业务接口
*
* @author: zxfei
* @date: 2024/1/2 9:58
*/
public interface SocialService {
SocialResp getSocial(String socialType);
}
package com.mortals.xhx.module.social.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.xhx.busiz.req.SignReq;
import com.mortals.xhx.busiz.req.SocialReq;
import com.mortals.xhx.busiz.rsp.SignResp;
import com.mortals.xhx.busiz.rsp.SocialResp;
import com.mortals.xhx.module.social.service.SocialService;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.net.URI;
import java.net.URISyntaxException;
/**
* 社保卡实现类
*
* @author: zhou
* @date: 2024/7/8 10:00
*/
@Service
@Slf4j
public class SocialServiceImpl implements SocialService {
@Value("${config.socialUrl:ws://localhost:12342/}")
private String url;
static int runTime = 60; //60S超时返回
WebSocketClient webSocketClient = null;
SocialResp socialResp = null;
@Override
public SocialResp getSocial(String socialType) {
URI uri;
socialResp = new SocialResp();
socialResp.setMessage("");
//提交操作参数
SocialReq socialReq = new SocialReq();
socialReq.setFunction(socialType);
if(socialType.equals("iReadSFZ")){ //读身份证
socialReq.setPchPhotoAddr("/tmp/head.bmp");
}
if(socialType.equals("iReadCardBas_HSM_Step1")){ //社保卡识别类型 1接触卡 2非接触卡
socialReq.setIType("2");
}
try {
uri = new URI(url);
} catch (Exception e) {
throw new RuntimeException(e);
}
if(webSocketClient != null){
String msg = JSON.toJSONString(socialReq);
log.info("发送msg = " +msg);
webSocketClient.send(msg);
}else {
webSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
String msg = JSON.toJSONString(socialReq);
log.info("新连接已打开:msg =" +msg);
send(msg);
}
@Override
public void onMessage(String message) {
log.info("接收到消息: {}",message);
if(message != null){
socialResp.setMessage(message);
}
}
@Override
public void onClose(int code, String reason, boolean remote) {
log.info("连接已关闭,code:{} reason:{} {}",code,reason,remote);
socialResp.setMessage("连接已关闭,code="+code+",reason="+reason);
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
log.info("链接出错了"+ex.toString());
socialResp.setMessage(ex.toString());
}
};
webSocketClient.connect(); // 连接到WebSocket服务器
}
while (true){
// log.info("runtime:{}",runTime);
try {
runTime --;
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if(socialResp.getMessage() != null && !socialResp.getMessage().equals("")){
runTime = 60;
break;
}
if(runTime <= 0){
runTime = 60;
socialResp.setMessage("链接社保卡失败,操作超时");
break;
}
}
return socialResp;
}
}
package com.mortals.xhx.opencv;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacv.Java2DFrameUtils;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.MatVector;
import org.bytedeco.opencv.opencv_core.Rect;
import org.opencv.imgproc.Imgproc;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.util.ArrayList;
import java.util.List;
import static org.bytedeco.opencv.global.opencv_highgui.*;//包含了所有图形接口函数
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*; //COLOR_RGB2GRAY
@Slf4j
public class Demo {
public void test(){
String filePath = "F:\\opencv-demo\\1704165443969.jpg";
Mat sourceImage = imread(filePath); // 加载图像
/* Imgproc.cvtColor(sourceImage, gray, Imgproc.COLOR_BGR2GRAY);*/
Mat gray = new Mat();
BufferedImage bufferedImage = Java2DFrameUtils.toBufferedImage(sourceImage);
Mat mat = Java2DFrameUtils.toMat(bufferedImage);
// new OpenCVFrameConverter.ToMat()
cvtColor(sourceImage, gray, COLOR_BGR2GRAY); // 转换颜色从BGR到RGB
Mat binary = new Mat();
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
Mat edges = new Mat();
Canny(binary, edges, 50, 150);
Mat hierarchy = new Mat();
MatVector matVector = new MatVector();
findContours(binary,matVector,hierarchy,RETR_TREE, CHAIN_APPROX_SIMPLE);
// 找出最大的轮廓(假设这是图片内容)
double maxArea = 0;
int maxContourIndex = 0;
for (int i = 0; i < matVector.size(); i++) {
double area = contourArea(matVector.get(i));
if (area > maxArea) {
maxArea = area;
maxContourIndex = i;
}
}
Rect rect = boundingRect(matVector.get(maxContourIndex));
Mat outImage = new Mat(sourceImage, rect);
imwrite("F:\\opencv-demo\\outimage.jpg", outImage);
// BufferedImage bufferedImage = matToBufferedImage(outImage);
// List<Pointer> contours = new ArrayList<>();
// Mat hierarchy = new Mat();
// findContours(binary, contours, hierarchy,RETR_TREE, CHAIN_APPROX_SIMPLE);
log.info("image rows:{}",sourceImage.rows());
// 转为灰度图像
/* imshow("1", image);// 原始图像
Mat gray = new Mat();
cvtColor(image, gray, COLOR_BGRA2GRAY); // 彩色图像转为灰度图像COLOR_RGB2GRAY
imshow("2", gray);// 灰度图像
Mat bin = new Mat();
threshold(gray, bin, 120, 255, THRESH_TOZERO); // 图像二值化
imshow("3", bin);// 二值图像
waitKey(0);*/
}
public static BufferedImage matToBufferedImage(Mat mat) {
byte[] data = new byte[mat.channels() * mat.cols() * mat.rows()];
//mat.get(0, 0, data); // 获取所有像素值
BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), mat.channels() == 1 ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(data, 0, targetPixels, 0, data.length);
return image;
}
public static void main(String[] args) {
new Demo().test();
}
}
package com.mortals.xhx.opencv;
import org.apache.log4j.Logger;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import java.io.File;
/**
* @author ZYW
* @date 2024-01-02 10:30
*/
public class TakePhotoProcess extends Thread{
private String imgPath;
private Mat faceMat;
private final static Scalar color = new Scalar(0, 0, 255);
public TakePhotoProcess(String imgPath, Mat faceMat) {
this.imgPath = imgPath;
this.faceMat = faceMat;
File file = new File(imgPath);
if(!file.exists()){
file.mkdir();
}
}
public void run() {
try {
long currentTime = System.currentTimeMillis();
StringBuffer samplePath = new StringBuffer();
samplePath.append(imgPath).append(currentTime).append(".jpg");
Imgcodecs.imwrite(samplePath.toString(), faceMat);
System.out.println(">>>>>>write image into->" + samplePath.toString());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
package com.mortals.xhx.opencv.UI;
import com.google.gson.Gson;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.opencv.bean.ConfigBean;
import com.mortals.xhx.opencv.bean.PhotoBean;
import com.mortals.xhx.opencv.utils.ImageUtil;
import com.mortals.xhx.opencv.utils.OpencvHelper;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;
import org.springframework.util.ObjectUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import static org.bytedeco.opencv.global.opencv_videoio.CAP_PROP_FRAME_HEIGHT;
import static org.bytedeco.opencv.global.opencv_videoio.CAP_PROP_FRAME_WIDTH;
/**
* @author ZYW
* @date 2024-01-08 13:55
*/
@Slf4j
public class CameraOprationByOpenCV {
static String configPath = "F:\\\\config.prop"; //默认测试本机路径
private static CameraOprationByOpenCV instance = null;
static JFrame frame;
static VideoCapture capture; //摄像头视频流
static Dialog setDialog; //配置框
static Dialog preDialog; //预览照片dialog
protected static VideoPanel videoCamera = new VideoPanel();
public static ArrayList<PhotoBean> photoBeanArrayList = new ArrayList<>();
static Gson gson = new Gson();
public static int cutType = 0; //0不切边 1自动切边 2 自定义切边
public static int roteAngle = 0; //旋转角度
public static int cameraIndex = 0; //选中的摄像头
public static String cameraName = ""; //选中的摄像头名称
public static int maxPhoto = 0; //照片最大拍照张数 0为不限制
public static String ratio = "640x480"; //摄像头默认分辨率
static int timer = 300; //用于两分钟无操作计时
static int preHeight = 480; //预览界面的高度
static Mat sourceMat; //原始图像
static Mat outMat; //缩放后的图像
static int count = 0;
public static void main(String[] args) {
//初始化窗口
initWindow(300,configPath);
}
private CameraOprationByOpenCV() {
}
public static CameraOprationByOpenCV getInstance() {
if (null == instance) {
synchronized (CameraOprationByOpenCV.class) {
if (null == instance) {
instance = new CameraOprationByOpenCV();
}
}
}
return instance;
}
/**
* 读取本地文件配置
*/
private static void redConfig(){
File file = new File(configPath);
try {
file.createNewFile();
} catch (IOException e) {
log.error( "创建文件失败" ); ;
}
Scanner sc = null ;
try
{
sc = new Scanner( file ) ;
String jsonString = sc.next();
ConfigBean jo = gson.fromJson(jsonString,ConfigBean.class);
if(jo != null){
cutType = jo.getCutType();
roteAngle = jo.getRoteAngle();
cameraIndex = jo.getCameraIndex();
maxPhoto = jo.getMaxPhoto();
if(jo.getRatio() != null){
ratio = jo.getRatio();
}
}else {
log.info( "配置文件为空" ); ;
}
}
catch( Exception e )
{
log.error( "读取配置文件失败"+e.toString() ); ;
}
finally
{
try
{
// log.error( "读写关闭" ) ;
sc.close();
}
catch ( Exception e )
{
}
}
}
/**
* 修改本地文件配置
*/
private static void writeConfig(){
ConfigBean cb = new ConfigBean(cutType,roteAngle,cameraIndex,maxPhoto,ratio);
File file = new File(configPath);
try {
file.createNewFile();
} catch (IOException e) {
}
FileWriter fileWriter = null ;
BufferedWriter bufferedWriter = null ; //FileWriter和BufferedWriter的初始化需要监听,此处只定义不初始化
try
{
fileWriter = new FileWriter( file ) ;
bufferedWriter = new BufferedWriter( fileWriter ) ;
bufferedWriter.write( gson.toJson(cb) ) ;
}
catch( Exception e )
{
log.error( "Error." ); ;
}
finally
{
try
{
if(bufferedWriter != null){
bufferedWriter.close(); //随手关闭文件,此处注意关闭顺序不能错误
}
if(fileWriter != null){
fileWriter.close();
}
}
catch( IOException ioe )
{
}
}
}
/**
* 初始化窗口
*/
public static Rest<ArrayList<PhotoBean>> initWindow(int runtime,String path){
configPath = path;
photoBeanArrayList.clear();
redConfig();
timer = runtime;
//AWT中接口LayoutManager有五个实现类:GridLayout(网格布局)、FlowLayout(流式布局)、CardLayout(卡片布局)、
// GridBagLayout(网格包布局)和BorderLayout(边框布局)。为了简化开发,Swing引入了一个新的布局管理器BoxLayout。
//1、创建窗口对象
frame = new JFrame("高拍仪");
Container c = frame.getContentPane();//获取窗体主容器
c.setLayout(null);
//左侧高拍仪画面区域
JPanel leftPanel = new JPanel();
leftPanel.setBorder(BorderFactory.createTitledBorder("摄像头"));
leftPanel.setBounds(10,0,660,520);
JLabel textArea = new JLabel();
Font font = new Font("Serif", Font.PLAIN, 24);
textArea.setFont(font);
textArea.setText("正在加载摄像头...");
textArea.setForeground(Color.black);
textArea.setVisible(true);
leftPanel.add(textArea);
// videoCamera.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
new CameraOprationByOpenCV().invokeCamera(videoCamera,textArea);
frame.add(videoCamera);
frame.add(leftPanel);
//右侧操作区域
JPanel rightPanel = new JPanel();
rightPanel.setBounds(680,0,300,520);
rightPanel.setBorder(BorderFactory.createTitledBorder("操作区"));
//右侧上方单选按钮区域
JPanel radioPanel1 = new JPanel(new GridLayout(1,4,10,10));
radioPanel1.setBounds(700,20,260,50);
ButtonGroup cbg = new ButtonGroup();
JRadioButton nocut = new JRadioButton("",cutType == 0?true:false);
nocut.setIcon(ImageUtil.getImage("img/cut_no.png"));
nocut.setSelectedIcon(ImageUtil.getImage("img/cut_no_check.png"));
JRadioButton autocut = new JRadioButton("",cutType == 1?true:false);
autocut.setIcon(ImageUtil.getImage("img/cut_auto.png"));
autocut.setSelectedIcon(ImageUtil.getImage("img/cut_auto_check.png"));
JRadioButton mycut = new JRadioButton("",cutType == 2?true:false);
mycut.setIcon(ImageUtil.getImage("img/cut_customize.png"));
mycut.setSelectedIcon(ImageUtil.getImage("img/cut_customize_check.png"));
//占位按钮 不然会显3列,写一个错误的图片地址
JRadioButton blank = new JRadioButton("",new ImageIcon(""),false);
nocut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "不切边");
cutType = 0;
writeConfig();
}
});
autocut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "自动切边");
cutType = 1;
writeConfig();
}
});
mycut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "自定义切边");
cutType = 2;
writeConfig();
}
});
blank.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(count == 0){
cameraList(); //读取设备摄像头数量
}
// 创建对话框
setDialog = new JDialog();
setDialog.setTitle("配置");
setDialog.setModal(true); // 设置为模式对话框
setDialog.setBounds(760,390,400, 300);
// 创建FlowLayout布局管理器并设置间距
FlowLayout layout = new FlowLayout();
layout.setHgap(10);
layout.setVgap(10);
setDialog.setLayout(layout);
//摄像头列表
JLabel cameraLabel = new JLabel("摄像头:");
JComboBox<String> cameraBox = new JComboBox<String>();//创建一个下拉列表框
cameraBox.setBounds(110,11,80,21); //设置坐标
if(count > 0){
for (int i = 0; i < count; i++) {
cameraBox.addItem("Camera "+(i+1));
}
if(cameraIndex < count){
cameraBox.setSelectedIndex(cameraIndex);
}
}
cameraBox.setEditable(true); //将下拉列表添加到容器中
cameraBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
cameraIndex = cameraBox.getSelectedIndex();
writeConfig();
setDialog.dispose();
JOptionPane.showMessageDialog(frame, "修改成功,请重启!");
}
}
});
//分辨率
JLabel whLabel = new JLabel("分辨率:");
JComboBox<String> whBox = new JComboBox<String>();//创建一个下拉列表框
whBox.setBounds(110,11,80,21); //设置坐标
// whBox.addItem("4224x3136");
// whBox.addItem("4096x3072");
// whBox.addItem("1920x1088");
// whBox.addItem("4096x3072");
// whBox.addItem("1920x1088");
whBox.addItem("1920x1080");
whBox.addItem("1280x720");
whBox.addItem("720x480");
whBox.addItem("640x480");
// whBox.addItem("352x288");
// whBox.addItem("320x240");
// whBox.addItem("176x144");
whBox.setEditable(true); //将下拉列表添加到容器中
whBox.setSelectedItem(ratio);
whBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
ratio = (String) whBox.getSelectedItem();
writeConfig();
setDialog.dispose();
JOptionPane.showMessageDialog(frame, "修改成功,请重启!");
}
}
});
//照片张数限制
JLabel maxLabel = new JLabel("最大拍照张数:");
JTextField jt = new JTextField();
if(maxPhoto == 0 ){
jt.setText("不限制");
}else {
jt.setText(maxPhoto+"");
}
jt.setColumns(14);//设置文本框长度
// jt.setFont(new Font("宋体", Font.PLAIN, 12));//设置字体
JButton jb = new JButton("保存");
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(jt.getText().equals("不限制")){
maxPhoto = 0;
writeConfig();
JOptionPane.showMessageDialog(frame, "保存成功");
}else if(isNumeric(jt.getText()) && Integer.parseInt(jt.getText()) >= 0){
maxPhoto = Integer.parseInt(jt.getText());
writeConfig();
JOptionPane.showMessageDialog(frame, "保存成功");
}else {
JOptionPane.showMessageDialog(frame, "请输入大于0的整数");
}
}
});
setDialog.add(cameraLabel);
setDialog.add(cameraBox);
setDialog.add(whLabel);
setDialog.add(whBox);
setDialog.add(maxLabel);
setDialog.add(jt);
setDialog.add(jb);
setDialog.setVisible(true);
}
});
cbg.add(nocut);
cbg.add(autocut);
cbg.add(mycut);
radioPanel1.add(nocut);
radioPanel1.add(autocut);
radioPanel1.add(mycut);
radioPanel1.add(blank);
//添加第一排单选按钮
frame.add(radioPanel1);
JPanel radioPanel2 = new JPanel(new GridLayout(1,4,10,10));
radioPanel2.setBounds(700,80,260,50);
ButtonGroup cbg1 = new ButtonGroup(); //一组Checkbox
JRadioButton norotate = new JRadioButton("",roteAngle == 0 ? true:false);
norotate.setIcon(ImageUtil.getImage("img/rotate_no.png"));
norotate.setSelectedIcon(ImageUtil.getImage("img/rotate_no_check.png"));
JRadioButton rotate90 = new JRadioButton("",roteAngle == 90 ? true:false);
rotate90.setIcon(ImageUtil.getImage("img/rotate_90.png"));
rotate90.setSelectedIcon(ImageUtil.getImage("img/rotate_90_check.png"));
JRadioButton rotate180 = new JRadioButton("",roteAngle == 180 ? true:false);
rotate180.setIcon(ImageUtil.getImage("img/rotate_180.png"));
rotate180.setSelectedIcon(ImageUtil.getImage("img/rotate_180_check.png"));
JRadioButton rotate270= new JRadioButton("",roteAngle == 270 ? true:false);
rotate270.setIcon(ImageUtil.getImage("img/rotate_270.png"));
rotate270.setSelectedIcon(ImageUtil.getImage("img/rotate_270_check.png"));
norotate.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "不旋转");
roteAngle = 0;
writeConfig();
}
});
rotate90.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转90°");
roteAngle = 90;
writeConfig();
}
});
rotate180.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转180°");
roteAngle = 180;
writeConfig();
}
});
rotate270.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转270°");
roteAngle = 270;
writeConfig();
}
});
cbg1.add(norotate);
cbg1.add(rotate90);
cbg1.add(rotate180);
cbg1.add(rotate270);
radioPanel2.add(norotate);
radioPanel2.add(rotate90);
radioPanel2.add(rotate180);
radioPanel2.add(rotate270);
//添加第二排单选按钮
frame.add(radioPanel2);
//添加拍照图片显示区域
//照片列表
ArrayList<BufferedImage> photoList = new ArrayList<>();
JPanel picPanel = new JPanel(new GridLayout(0,2,10,10));
picPanel.setSize(0,0);
//创建 JScrollPane 滚动面板,并将文本域放到滚动面板中
JScrollPane sp = new JScrollPane(picPanel);
sp.setBorder(null);
sp.setBounds(690,150,280,300);
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sp.setVisible(true);
c.add(sp);
//拍照区域按钮
JPanel subPanel = new JPanel(new GridLayout(1,2,10,10));
subPanel.setBounds(700,460,260,50);
JButton takPicBtn = new JButton();
//去除边框和背景色
takPicBtn.setBorderPainted(false);
takPicBtn.setContentAreaFilled(false);
takPicBtn.setFocusPainted(false);
takPicBtn.setOpaque(false);
takPicBtn.setIcon(ImageUtil.getImage("img/shoot.png"));
takPicBtn.setPressedIcon(ImageUtil.getImage("img/shoot_hover.png"));
takPicBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "拍照");
if(photoList.size() < maxPhoto || maxPhoto == 0){
log.info(">>>>>>take photo performed");
try {
if (!outMat.empty()) {
// Image previewImg = ImageUtils.scale2(myFace, 165, 200, true);// 等比例缩放
BufferedImage previewImg = null; //预览图
BufferedImage souceImg = null; //没缩放的大图
if (cutType == 1 || cutType == 2) {
if(videoCamera.getRect() != null){
souceImg = OpencvHelper.ImageCutByRect(outMat,videoCamera.getRect());
}
}else {
souceImg = OpencvHelper.matToBufferedImage(outMat);
}
previewImg = OpencvHelper.ImageZoom(OpencvHelper.imageToMat(souceImg),100,120);
// TakePhotoProcess takePhoto = new TakePhotoProcess(photoPath.toString(), myFhoto);
// takePhoto.start();// 照片写盘
photoList.add(previewImg);
JLabel jLabel = new MyImageLabel(new ImageIcon(previewImg));
BufferedImage finalSouceImg = souceImg;
BufferedImage finalPreviewImg = previewImg;
jLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if(e.getX() > 76 && e.getY() < 24){//删除图标的位置
photoList.remove(finalPreviewImg);
picPanel.remove(jLabel);
// 刷新JScrollPane
sp.revalidate();
sp.repaint();
JScrollBar scrollBar = sp.getVerticalScrollBar();
// 将滚动条位置设置为最大值,以滚动到最底部
scrollBar.setValue(scrollBar.getMaximum());
}else if(e.getY() < finalPreviewImg.getHeight()){ //图片位置
// 创建对话框
preDialog = new JDialog();
preDialog.setTitle("预览图");
preDialog.setModal(true); // 设置为模式对话框
// preDialog.setBounds(560,240,800, 600);
preDialog.setMinimumSize(new Dimension(800, 600));
preDialog.setSize(finalSouceImg.getWidth(), finalSouceImg.getHeight());
preDialog.setLayout(new BorderLayout());
// JLabel imgJlable = new JLabel(new ImageIcon(finalSouceImg));
ImagePanle mImgeView = new ImagePanle();
mImgeView.setPreferredSize(new Dimension(500, 500));
mImgeView.setMinimumSize(new Dimension(500, 500));
mImgeView.updateImage(finalSouceImg);
preDialog.add(mImgeView, BorderLayout.CENTER);
preDialog.setVisible(true);
}
}
});
picPanel.add(jLabel);
// 刷新JScrollPane
sp.revalidate();
sp.repaint();
JScrollBar scrollBar = sp.getVerticalScrollBar();
// 将滚动条位置设置为最大值,以滚动到最底部
scrollBar.setValue(scrollBar.getMaximum());
}else {
log.error("拍照失败->outMat : " + outMat);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(frame, "请在图像区域内画框");
log.error(">>>>>>take photo error: " + ex.getMessage());
}
}else {
JOptionPane.showMessageDialog(frame, "最大拍照张数为:"+maxPhoto);
}
}
});
subPanel.add(takPicBtn);
JButton subPicBtn = new JButton();
subPicBtn.setBorderPainted(false);
subPicBtn.setContentAreaFilled(false);
subPicBtn.setFocusPainted(false);
subPicBtn.setOpaque(false);
subPicBtn.setIcon(ImageUtil.getImage("img/upload.png"));
subPicBtn.setPressedIcon(ImageUtil.getImage("img/upload_hover.png"));
subPicBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "上传");
if(photoList.size() > 0){
photoBeanArrayList.clear();
for (int i = 0; i < photoList.size(); i++) {
photoBeanArrayList.add(new PhotoBean(System.currentTimeMillis()+".png",OpencvHelper.imageToBase64(photoList.get(i))));
}
frame.dispose();
}else {
JOptionPane.showMessageDialog(frame, "未拍摄照片");
}
}
});
subPanel.add(subPicBtn);
//添加拍照区按钮
frame.add(subPanel);
//添加右侧区域
frame.add(rightPanel);
//文字说明区
JPanel bottomPanel = new JPanel(new BorderLayout());
bottomPanel.setBorder(BorderFactory.createTitledBorder("说明"));
bottomPanel.setBounds(10,530,970,40);
JLabel textArea1 = new JLabel();
Font font1 = new Font("Serif", Font.PLAIN, 10);
textArea1.setFont(font1);
textArea1.setForeground(Color.black);
textArea1.setVisible(true);
textArea1.setText(" 软件版本 V1.0.1 摄像头:Camera "+(cameraIndex+1) +" 分辨率:"+ratio+" 最大拍照张数:"+ (maxPhoto==0?"不限制":maxPhoto));
bottomPanel.add(textArea1,BorderLayout.CENTER);
//添加文字说明区
frame.add(bottomPanel);
//合适的窗口大小
frame.pack();
//禁止改变窗口大小
frame.setResizable(false);
//设置窗口关闭退出软件 默认 JFrame.EXIT_ON_CLOSE会关闭所有窗口 DISPOSE_ON_CLOSE仅关闭当前窗口
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//设置窗口的位置和大小
frame.setBounds(460,240,1000,610);
//设置窗口对象可见
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
timer = 0; //手动关闭窗口时重置timer 停止while循环 并返回超时
//窗口关闭释放摄像头资源
if(capture != null){
capture.release();
}
if(setDialog != null && setDialog.isShowing()){
setDialog.dispose();
}
if(preDialog != null && preDialog.isShowing()){
preDialog.dispose();
}
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
while (true) {
try {
timer--;
frame.setTitle("高拍仪(操作倒计时: "+timer+" 秒)");
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if (!ObjectUtils.isEmpty(photoBeanArrayList) && photoBeanArrayList.size() > 0) {
Rest<ArrayList<PhotoBean>> rest = Rest.ok();
rest.setData(photoBeanArrayList);
return rest;
}
if(timer <= 0){
Rest<ArrayList<PhotoBean>> rest = Rest.fail();
rest.setData(null);
rest.setMsg("操作超时");
if(frame.isShowing()){
frame.dispose();
}
return rest;
}
}
}
public void invokeCamera(VideoPanel videoPanel,JLabel textArea) {
new Thread(() -> {
try {
capture = new VideoCapture(cameraIndex);
log.info("原始分辨率: " + capture.get(CAP_PROP_FRAME_WIDTH) + "x" + capture.get(CAP_PROP_FRAME_HEIGHT));
// 设置新的分辨率
String[] wh = ratio.split("x");
int newWidth = 640;
int newHeight = 480;
if(wh.length == 2){
newWidth = Integer.parseInt(wh[0]); // 新的宽度
newHeight = Integer.parseInt(wh[1]); // 新的高度
capture.set(CAP_PROP_FRAME_WIDTH, newWidth);
capture.set(CAP_PROP_FRAME_HEIGHT, newHeight);
//计算图像的宽高 按宽度等比例缩放
preHeight = 640 * newHeight / newWidth;
log.info("当前设置分辨率: " + newWidth + "x" + newHeight);
}
videoCamera.setBounds(20,20+(480 - preHeight)/2,640,preHeight); //让画面左右撑满 上下居中
log.info("视图位置:"+videoCamera.getX()+","+videoCamera.getY()+","+videoCamera.getWidth()+","+videoCamera.getHeight());
if (capture.isOpened()) {
textArea.setVisible(false);
videoPanel.setVisible(true);
sourceMat = new Mat();
outMat = new Mat();
while (true) {
capture.read(sourceMat);
outMat = OpencvHelper.ImageZoomMat(OpencvHelper.ImageRotateMat(sourceMat,roteAngle),640,preHeight);
Rectangle rectangle = null;
if(cutType == 1){ //自动切边时需要实时画框
rectangle = OpencvHelper.cutAutoGetAngele(outMat);
}
videoPanel.setImageWithMat(outMat,rectangle,cutType);
Thread.sleep(10);
}
}else {
log.error("invoke camera error : 摄像头打开失败");
textArea.setText("摄像头打开失败,请检查插线连接");
textArea.setVisible(true);
videoPanel.setVisible(false);
}
} catch (Exception e) {
log.error("invoke camera error: " + e.toString());
textArea.setText("摄像头掉线,请检查插线连接");
textArea.setVisible(true);
videoPanel.setVisible(false);
}
}).start();
}
/**
* 读取摄像头列表
*/
private static VideoCapture[] cameraList(){
// 创建VideoCapture对象列表,用于存储摄像头设备
VideoCapture[] captures = new VideoCapture[5];
// 遍历系统中的摄像头设备
for (int i = 0; i < captures.length; i++) {
try {
// 尝试打开摄像头设备
captures[i] = new VideoCapture(i);
if (captures[i].isOpened()) {
count++;
} else {
captures[i].release(); // 如果无法打开,释放资源
}
} catch (Exception e) {
e.printStackTrace();
}
}
// // 输出摄像头列表信息
log.info("找到 " + count + " 个摄像头设备:");
return captures;
}
/**
* 判断是否为数字
* @param str
* @return
*/
public static boolean isNumeric(String str) {
if (str == null || str.length() == 0) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
}
package com.mortals.xhx.opencv.UI;
import com.mortals.xhx.opencv.utils.OpencvHelper;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Rect;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Base64;
/**
* @author ZYW
* @date 2024-01-02 10:26
*/
@Slf4j
public class CapturePanel extends JPanel {
private ImageIcon imageIcon;
/**
* base64图像解码成字节流
* @param base64Image
*/
public void decodeToImage(String base64Image) throws IOException {
// 解码Base64字符串
byte[] imageBytes = Base64.getDecoder().decode(base64Image);
// 创建字节数组输入流
ByteArrayInputStream bis = new ByteArrayInputStream(imageBytes);
// 通过ImageIO读取图像
BufferedImage bufferedImage = ImageIO.read(bis);
imageIcon = new ImageIcon(bufferedImage);
// 关闭输入流
bis.close();
this.repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (imageIcon != null) {
imageIcon.paintIcon(this, g, 0, 0);
}
}
}
package com.mortals.xhx.opencv.UI;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.opencv.bean.ConfigBean;
import com.mortals.xhx.opencv.bean.PhotoBean;
import com.mortals.xhx.opencv.utils.ImageUtil;
import com.mortals.xhx.opencv.utils.OpencvHelper;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_videoio.VideoCapture;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.util.ObjectUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Scanner;
import static org.bytedeco.opencv.global.opencv_videoio.CAP_PROP_FRAME_HEIGHT;
import static org.bytedeco.opencv.global.opencv_videoio.CAP_PROP_FRAME_WIDTH;
/**
* @author ZYW
* @date 2024-01-08 13:55
*/
@Slf4j
public class CaptureUI {
static String configPath = "F:\\\\config.prop"; //默认测试本机路径
private static CaptureUI instance = null;
static JFrame frame;
static Dialog setDialog; //配置框
static Dialog preDialog; //预览照片dialog
protected static CapturePanel videoCamera = new CapturePanel();
public static ArrayList<PhotoBean> photoBeanArrayList = new ArrayList<>();
static Gson gson = new Gson();
public static int cutType = 0; //0不切边 1自动切边 2 自定义切边
public static int roteAngle = 0; //旋转角度
public static int cameraIndex = 0; //选中的摄像头
public static String cameraName = ""; //选中的摄像头名称
public static int maxPhoto = 0; //照片最大拍照张数 0为不限制
public static String ratio = "640x480"; //摄像头默认分辨率
static int timer = 300; //用于两分钟无操作计时
static Mat outMat; //缩放后的图像
static String photoPath = "/tmp/photo/"; //本地拍照图片路劲
static WebSocketClient webSocketClient = null;
public static void main(String[] args) {
//初始化窗口
initWindow(300,configPath,"ws://192.168.0.158:1818/");
}
private CaptureUI() {
}
public static CaptureUI getInstance() {
if (null == instance) {
synchronized (CaptureUI.class) {
if (null == instance) {
instance = new CaptureUI();
}
}
}
return instance;
}
/**
* 读取本地文件配置
*/
private static void redConfig(){
File file = new File(configPath);
try {
file.createNewFile();
} catch (IOException e) {
log.error( "创建文件失败" ); ;
}
Scanner sc = null ;
try
{
sc = new Scanner( file ) ;
String jsonString = sc.next();
ConfigBean jo = gson.fromJson(jsonString,ConfigBean.class);
if(jo != null){
cutType = jo.getCutType();
roteAngle = jo.getRoteAngle();
cameraIndex = jo.getCameraIndex();
maxPhoto = jo.getMaxPhoto();
if(jo.getRatio() != null){
ratio = jo.getRatio();
}
}else {
log.info( "配置文件为空" ); ;
}
}
catch( Exception e )
{
log.error( "读取配置文件失败"+e.toString() ); ;
}
finally
{
try
{
// log.error( "读写关闭" ) ;
sc.close();
}
catch ( Exception e )
{
}
}
}
/**
* 修改本地文件配置
*/
private static void writeConfig(){
ConfigBean cb = new ConfigBean(cutType,roteAngle,cameraIndex,maxPhoto,ratio);
File file = new File(configPath);
try {
file.createNewFile();
} catch (IOException e) {
}
FileWriter fileWriter = null ;
BufferedWriter bufferedWriter = null ; //FileWriter和BufferedWriter的初始化需要监听,此处只定义不初始化
try
{
fileWriter = new FileWriter( file ) ;
bufferedWriter = new BufferedWriter( fileWriter ) ;
bufferedWriter.write( gson.toJson(cb) ) ;
}
catch( Exception e )
{
log.error( "Error." ); ;
}
finally
{
try
{
if(bufferedWriter != null){
bufferedWriter.close(); //随手关闭文件,此处注意关闭顺序不能错误
}
if(fileWriter != null){
fileWriter.close();
}
}
catch( IOException ioe )
{
}
}
}
/**
* 初始化窗口
*/
public static Rest<ArrayList<PhotoBean>> initWindow(int runtime,String path,String captureUrl){
configPath = path;
photoBeanArrayList.clear();
File folder = new File(photoPath);
if(!folder.exists()){
folder.mkdir();
}else {
// 获取文件夹下所有文件
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
file.delete(); // 删除文件
} else if (file.isDirectory()) {
deleteFilesInFolder(file); // 递归删除子文件夹下的文件
}
}
}
}
redConfig();
timer = runtime;
//AWT中接口LayoutManager有五个实现类:GridLayout(网格布局)、FlowLayout(流式布局)、CardLayout(卡片布局)、
// GridBagLayout(网格包布局)和BorderLayout(边框布局)。为了简化开发,Swing引入了一个新的布局管理器BoxLayout。
//1、创建窗口对象
frame = new JFrame("高拍仪");
Container c = frame.getContentPane();//获取窗体主容器
c.setLayout(null);
//左侧高拍仪画面区域
JPanel leftPanel = new JPanel();
leftPanel.setBorder(BorderFactory.createTitledBorder("摄像头"));
leftPanel.setBounds(10,0,820,630);
JLabel textArea = new JLabel();
Font font = new Font("Serif", Font.PLAIN, 24);
textArea.setFont(font);
textArea.setText("正在加载摄像头...");
textArea.setForeground(Color.black);
textArea.setVisible(true);
leftPanel.add(textArea);
// videoCamera.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
videoCamera.setBounds(20,20,800,600); //让画面左右撑满 上下居中
initWebsocket(videoCamera,captureUrl,textArea);
frame.add(videoCamera);
frame.add(leftPanel);
//右侧操作区域
JPanel rightPanel = new JPanel();
rightPanel.setBounds(840,0,300,630);
rightPanel.setBorder(BorderFactory.createTitledBorder("操作区"));
//右侧上方单选按钮区域
JPanel radioPanel1 = new JPanel(new GridLayout(1,4,10,10));
radioPanel1.setBounds(860,20,260,50);
ButtonGroup cbg = new ButtonGroup();
JRadioButton nocut = new JRadioButton("",cutType == 0?true:false);
nocut.setIcon(ImageUtil.getImage("img/cut_no.png"));
nocut.setSelectedIcon(ImageUtil.getImage("img/cut_no_check.png"));
JRadioButton autocut = new JRadioButton("",cutType == 1?true:false);
autocut.setIcon(ImageUtil.getImage("img/cut_auto.png"));
autocut.setSelectedIcon(ImageUtil.getImage("img/cut_auto_check.png"));
JRadioButton mycut = new JRadioButton("",cutType == 2?true:false);
mycut.setIcon(ImageUtil.getImage("img/cut_sfz.png"));
mycut.setSelectedIcon(ImageUtil.getImage("img/cut_sfz_check.png"));
//占位按钮 不然会显3列,写一个错误的图片地址
JRadioButton blank = new JRadioButton("",new ImageIcon(""),false);
nocut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "不切边");
sendMess("bSetMode(0)");
cutType = 0;
writeConfig();
}
});
autocut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "自动切边");
sendMess("bSetMode(3)");
cutType = 1;
writeConfig();
}
});
mycut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "自定义切边");
sendMess("bSetMode(4)");
cutType = 2;
writeConfig();
}
});
cbg.add(nocut);
cbg.add(autocut);
cbg.add(mycut);
radioPanel1.add(nocut);
radioPanel1.add(autocut);
radioPanel1.add(mycut);
radioPanel1.add(blank);
//添加第一排单选按钮
frame.add(radioPanel1);
JPanel radioPanel2 = new JPanel(new GridLayout(1,4,10,10));
radioPanel2.setBounds(860,80,260,50);
ButtonGroup cbg1 = new ButtonGroup(); //一组Checkbox
JRadioButton norotate = new JRadioButton("",roteAngle == 0 ? true:false);
norotate.setIcon(ImageUtil.getImage("img/rotate_no.png"));
norotate.setSelectedIcon(ImageUtil.getImage("img/rotate_no_check.png"));
JRadioButton rotate90 = new JRadioButton("",roteAngle == 90 ? true:false);
rotate90.setIcon(ImageUtil.getImage("img/rotate_90.png"));
rotate90.setSelectedIcon(ImageUtil.getImage("img/rotate_90_check.png"));
JRadioButton rotate180 = new JRadioButton("",roteAngle == 180 ? true:false);
rotate180.setIcon(ImageUtil.getImage("img/rotate_180.png"));
rotate180.setSelectedIcon(ImageUtil.getImage("img/rotate_180_check.png"));
JRadioButton rotate270= new JRadioButton("",roteAngle == 270 ? true:false);
rotate270.setIcon(ImageUtil.getImage("img/rotate_270.png"));
rotate270.setSelectedIcon(ImageUtil.getImage("img/rotate_270_check.png"));
norotate.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "不旋转");
roteAngle = 0;
writeConfig();
}
});
rotate90.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转90°");
roteAngle = 90;
writeConfig();
}
});
rotate180.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转180°");
roteAngle = 180;
writeConfig();
}
});
rotate270.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "旋转270°");
roteAngle = 270;
writeConfig();
}
});
cbg1.add(norotate);
cbg1.add(rotate90);
cbg1.add(rotate180);
cbg1.add(rotate270);
radioPanel2.add(norotate);
radioPanel2.add(rotate90);
radioPanel2.add(rotate180);
radioPanel2.add(rotate270);
//添加第二排单选按钮
frame.add(radioPanel2);
//添加拍照图片显示区域
//照片列表
ArrayList<File> photoList = new ArrayList<>();
JPanel picPanel = new JPanel(new GridLayout(0,2,10,10));
picPanel.setSize(0,0);
//创建 JScrollPane 滚动面板,并将文本域放到滚动面板中
JScrollPane sp = new JScrollPane(picPanel);
sp.setBorder(null);
sp.setBounds(850,150,280,400);
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sp.setVisible(true);
c.add(sp);
//拍照区域按钮
JPanel subPanel = new JPanel(new GridLayout(1,2,10,10));
subPanel.setBounds(860,580,260,50);
JButton takPicBtn = new JButton();
//去除边框和背景色
takPicBtn.setBorderPainted(false);
takPicBtn.setContentAreaFilled(false);
takPicBtn.setFocusPainted(false);
takPicBtn.setOpaque(false);
takPicBtn.setIcon(ImageUtil.getImage("img/shoot.png"));
takPicBtn.setPressedIcon(ImageUtil.getImage("img/shoot_hover.png"));
takPicBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "拍照");
if(photoList.size() < maxPhoto || maxPhoto == 0){
long picName = System.currentTimeMillis();
sendMess("bSaveJPG("+photoPath+","+picName+")");
// try {
// Thread.sleep(1000);
// } catch (InterruptedException ex) {
// throw new RuntimeException(ex);
// }
//没缩放的大图
File souceImg = new File(photoPath+picName+".jpg");
while (!souceImg.exists()){
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
photoList.add(souceImg);
JLabel jLabel = new MyImageLabel(ImageUtil.zoomImageByFile(souceImg,100,120));
jLabel.setSize(100,120);
jLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if(e.getX() > 76 && e.getY() < 24){//删除图标的位置
photoList.remove(souceImg);
picPanel.remove(jLabel);
if(souceImg.exists()){
souceImg.delete();
}
// 刷新JScrollPane
sp.revalidate();
sp.repaint();
JScrollBar scrollBar = sp.getVerticalScrollBar();
// 将滚动条位置设置为最大值,以滚动到最底部
scrollBar.setValue(scrollBar.getMaximum());
}else if(e.getY() < 120){ //图片位置
// 创建对话框
preDialog = new JDialog();
preDialog.setTitle("预览图");
preDialog.setModal(true); // 设置为模式对话框
// preDialog.setBounds(560,240,800, 600);
preDialog.setMinimumSize(new Dimension(800, 600));
preDialog.setSize(800, 600);
preDialog.setLayout(new BorderLayout());
JLabel mImgeView = new JLabel(ImageUtil.getImageByFile(souceImg));
// ImagePanle mImgeView = new ImagePanle();
// mImgeView.setPreferredSize(new Dimension(500, 500));
// mImgeView.setMinimumSize(new Dimension(500, 500));
// mImgeView.updateImage(finalSouceImg);
preDialog.add(mImgeView, BorderLayout.CENTER);
preDialog.setVisible(true);
}
}
});
picPanel.add(jLabel);
// 刷新JScrollPane
sp.revalidate();
sp.repaint();
JScrollBar scrollBar = sp.getVerticalScrollBar();
// 将滚动条位置设置为最大值,以滚动到最底部
scrollBar.setValue(scrollBar.getMaximum());
}else {
JOptionPane.showMessageDialog(frame, "最大拍照张数为:"+maxPhoto);
}
}
});
subPanel.add(takPicBtn);
JButton subPicBtn = new JButton();
subPicBtn.setBorderPainted(false);
subPicBtn.setContentAreaFilled(false);
subPicBtn.setFocusPainted(false);
subPicBtn.setOpaque(false);
subPicBtn.setIcon(ImageUtil.getImage("img/upload.png"));
subPicBtn.setPressedIcon(ImageUtil.getImage("img/upload_hover.png"));
subPicBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// JOptionPane.showMessageDialog(frame, "上传");
if(photoList.size() > 0){
photoBeanArrayList.clear();
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".jpg")) {
photoBeanArrayList.add(new PhotoBean(file.getName(),imageToBase64(file)));
}
}
}
frame.dispose();
}else {
JOptionPane.showMessageDialog(frame, "未拍摄照片");
}
}
});
subPanel.add(subPicBtn);
//添加拍照区按钮
frame.add(subPanel);
//添加右侧区域
frame.add(rightPanel);
//合适的窗口大小
frame.pack();
//禁止改变窗口大小
frame.setResizable(false);
//设置窗口关闭退出软件 默认 JFrame.EXIT_ON_CLOSE会关闭所有窗口 DISPOSE_ON_CLOSE仅关闭当前窗口
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//设置窗口的位置和大小
frame.setBounds(380,200,1160,670);
//设置窗口对象可见
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
timer = 0; //手动关闭窗口时重置timer 停止while循环 并返回超时
if(setDialog != null && setDialog.isShowing()){
setDialog.dispose();
}
if(preDialog != null && preDialog.isShowing()){
preDialog.dispose();
}
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
while (true) {
try {
timer--;
frame.setTitle("高拍仪(操作倒计时: "+timer+" 秒)");
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if (!ObjectUtils.isEmpty(photoBeanArrayList) && photoBeanArrayList.size() > 0) {
Rest<ArrayList<PhotoBean>> rest = Rest.ok();
rest.setData(photoBeanArrayList);
destroyWebsocket();
return rest;
}
if(timer <= 0){
Rest<ArrayList<PhotoBean>> rest = Rest.fail();
rest.setData(null);
rest.setMsg("操作超时");
if(frame.isShowing()){
frame.dispose();
}
destroyWebsocket();
return rest;
}
}
}
private static void initWebsocket(CapturePanel capturePanel, String captureUrl,JLabel textArea){
URI uri;
try {
uri = new URI(captureUrl);
} catch (Exception e) {
throw new RuntimeException(e);
}
webSocketClient = new WebSocketClient(uri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
log.info("新连接已打开");
send("bStopPlay");
send("bStartPlay");
if(cutType == 2){
send("bSetMode(3)");
}else if(cutType == 3){
send("bSetMode(4)");
}else {
send("bSetMode(0)");
}
}
@Override
public void onMessage(String message) {
if(!message.startsWith("/9j/")){
log.info("接收到消息: {}",message);
}
int strBegin = message.indexOf("Begin");
if(0 == strBegin)
{
log.info("接收到消息->strBegin: {}",strBegin);
//alert(received_msg);
}
else
{
textArea.setVisible(false);
capturePanel.setVisible(true);
String img = "data:image/jpeg;base64,"+message;
// log.info("图片: {}",img);
try {
capturePanel.decodeToImage(message);
} catch (IOException e) {
textArea.setVisible(true);
capturePanel.setVisible(false);
textArea.setText("base64解码失败");
throw new RuntimeException(e);
}
}
}
@Override
public void onClose(int code, String reason, boolean remote) {
log.info("连接已关闭,code:{} reason:{} {}",code,reason,remote);
textArea.setVisible(true);
capturePanel.setVisible(false);
textArea.setText("连接已关闭,code:"+code+" reason:"+reason);
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
log.info("链接出错了"+ex.toString());
textArea.setVisible(true);
capturePanel.setVisible(false);
textArea.setText("链接出错了"+ex.getMessage());
}
};
webSocketClient.connect(); // 连接到WebSocket服务器
}
/**
* 关闭socket链接 关闭摄像头
*/
static void sendMess(String mess){
if(webSocketClient != null){
webSocketClient.send(mess);
}
}
/**
* 关闭socket链接 关闭摄像头
*/
static void destroyWebsocket(){
if(webSocketClient != null){
webSocketClient.send("bStopPlay");
}
webSocketClient.close();
}
/**
* 本地图片转BufferedImage
* @param imagePath
* @return
*/
public static BufferedImage convertToBufferedImage(String imagePath) {
try {
log.info("imagePath:{}",imagePath);
File file = new File(imagePath);
return ImageIO.read(file);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 删除文件
* @param folder
*/
private static void deleteFilesInFolder(File folder) {
File[] files = folder.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
file.delete(); // 删除文件
} else if (file.isDirectory()) {
deleteFilesInFolder(file); // 递归删除子文件夹下的文件
}
}
}
folder.delete(); // 删除空文件夹
}
/**
* 本地文件转base64
* @return
*/
public static String imageToBase64(File file) {
try {
byte[] bytesArray = new byte[(int) file.length()];
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(bytesArray);
fileInputStream.close();
return "data:image/jpeg;base64,"+Base64.getEncoder().encodeToString(bytesArray);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
package com.mortals.xhx.opencv.UI;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
/**
* @author ZYW
* @date 2024-01-09 11:21
*/
public class ImagePanle extends JPanel {
BufferedImage mSrcBuffeImg = null;
private static final long serialVersionUID = 1L;
private double mScale = 1.0;
private static final boolean B_REAL_SIZE = true;
private double mCurX = 0;
private double mCurY = 0;
private double mStartX = 0;
private double mStartY = 0;
private double mTranslateX = 0;
private double mTranslateY = 0;
// 记录最初原始坐标系,用于清除背景
AffineTransform mOriginTransform;
BufferedImage mViewBufferImg;
Graphics2D mViewG2d;
void refreshView() {
clear_buffer(mViewG2d, mOriginTransform, mViewBufferImg);
mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
repaint();
}
void clear_buffer(Graphics2D g2d, AffineTransform org, BufferedImage bufImg) {
// 将保存的测量数据,重新在经过变换后的坐标系上进行绘制
// 先恢复一下原始状态,保证清空的坐标是全部,执行清空,然后再切会来
AffineTransform temp = g2d.getTransform();
g2d.setTransform(org);
g2d.clearRect(0, 0, bufImg.getWidth(), bufImg.getHeight());
g2d.setTransform(temp);
}
public void updateImage(BufferedImage srcImage) {
mSrcBuffeImg = srcImage;
mViewBufferImg = new BufferedImage(srcImage.getWidth(), srcImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
// System.out.println("create buff image");
mViewG2d = mViewBufferImg.createGraphics();
mViewG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
mViewG2d.setBackground(new Color(128, 128, 128));
// System.out.println("crate bufg2d");
mOriginTransform = mViewG2d.getTransform();
refreshView();
}
private Point internal_getImagePoint(double mouseX, double mouseY) {
// 不管是先平移后缩放还是先缩放后平移,都以 先减 再缩放的方式可以获取正确
double rawTranslateX = mViewG2d.getTransform().getTranslateX();
double rawTranslateY = mViewG2d.getTransform().getTranslateY();
// 获取当前的 Scale Transform
double scaleX = mViewG2d.getTransform().getScaleX();
double scaleY = mViewG2d.getTransform().getScaleY();
// 不管是先平移后缩放还是先缩放后平移,都以 先减 再缩放的方式可以获取正确
int imageX = (int) ((mouseX - rawTranslateX) / scaleX);
int imageY = (int) ((mouseY - rawTranslateY) / scaleY);
return new Point(imageX, imageY);
}
public ImagePanle() {
// 启用双缓存
setDoubleBuffered(true);
this.addMouseWheelListener((MouseWheelListener) new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (mViewG2d == null) {
return;
}
mCurX = e.getX();
mCurY = e.getY();
int notches = e.getWheelRotation();
if (notches < 0) {
// 滚轮向上,放大画布
mScale = 1.1;
} else {
// 滚轮向下,缩小画布
mScale = 0.9;
}
Point imagePoint = internal_getImagePoint(e.getX(), e.getY());
int imageX = imagePoint.x;
int imageY = imagePoint.y;
// System.out.println("x:" + e.getX() + "y:" + e.getY() + ",imagex:" + imageX + "x" + imageY);
double tralateX = mScale * imageX - imageX;
double tralateY = mScale * imageY - imageY;
mViewG2d.scale(mScale, mScale);
mViewG2d.translate(-tralateX / mScale, -tralateY / mScale); // 图片方大,就需要把坐标往左移动,移动的尺度是要考虑缩放的
// 先恢复一下原始状态,保证清空的坐标是全部,执行清空,然后再切会来
AffineTransform temp = mViewG2d.getTransform();
mViewG2d.setTransform(mOriginTransform);
mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
mViewG2d.setTransform(temp);
mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
repaint(); // 重新绘制画布
}
});
this.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("mouseReleased:" + e.getX() + "x" + e.getY());
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("mousePressed----:" + e.getX() + "x" + e.getY());
mStartX = e.getX();
mStartY = e.getY();
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
// System.out.println("mouseClicked----:" + e.getX() + "x" + e.getY());
}
});
this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
if (mViewG2d == null) {
return;
}
mCurX = e.getX();
mCurY = e.getY();
// System.out.println("mouseDragged:" + e.getX() + "x" + e.getY() + "trans:" + (mCurX - mStartX) + ":"
// + (mCurY - mStartY));
// 平移坐标,也是相对于变换后的坐标系而言的,所以
double scaleX = mViewG2d.getTransform().getScaleX();
double scaleY = mViewG2d.getTransform().getScaleY();
// TODO mCurX - mStartX 太小,比如为2, 而scalX 比较大,比如为3 则移动的时候回发生 (int)2/3 ==0; 不移动。
// 解决方案,把移动 ,全部在原始坐标系上做,也就是最后绘制缓冲区的时候,drawimage(transX,transY)
mTranslateX = (mCurX - mStartX) / scaleX;
mTranslateY = (mCurY - mStartY) / scaleY;
// 自身就是累计的
mViewG2d.translate(mTranslateX, mTranslateY);
mStartX = mCurX;
mStartY = mCurY;
// System.out.println("mouseDragged: over+++");
// 先恢复一下原始状态,保证清空的坐标是全部,执行清空,然后再切会来
AffineTransform temp = mViewG2d.getTransform();
mViewG2d.setTransform(mOriginTransform);
mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
mViewG2d.setTransform(temp);
mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
repaint();
}
});
}
public void reset_scale() {
// 恢复到1.0 缩放,0,0 左上角对齐
mCurX = 0;
mCurY = 0;
mScale = 1.0;
mViewG2d.setTransform(mOriginTransform);
mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
repaint(); // 重新绘制画布
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (mViewBufferImg == null) {
return;
}
// 如果有多个“图层”要注意图层的顺序
Graphics2D g2d = ((Graphics2D) g);
g2d.drawImage(mViewBufferImg, 0, 0, null);
// System.out.println("draw-----------:" + getWidth() + "x" + getHeight());
}
}
package com.mortals.xhx.opencv.UI;
import com.mortals.xhx.opencv.utils.ImageUtil;
import com.mortals.xhx.opencv.utils.ResourcesUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
/**
* @author ZYW
* @date 2024-01-02 15:31
*/
public class MyImageLabel extends JLabel {
private ImageIcon image;
private ImageIcon delImage = ImageUtil.getImage("img/delpic.png");
public MyImageLabel(ImageIcon image) {
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 在标签上绘制图片
g2d.drawImage(image.getImage(), 0, 0, this);
// 在图片上绘制热门标签图片(假设你已经知道热门标签图片的大小和位置)
g2d.drawImage(delImage.getImage(), image.getIconWidth() - delImage.getIconWidth(), 0, this); // xPos和yPos是热门标签图片的位置坐标
}
}
package com.mortals.xhx.opencv.UI;
import cn.hutool.http.HttpUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mortals.framework.common.Rest;
import com.mortals.xhx.opencv.bean.*;
import com.mortals.xhx.opencv.utils.ImageUtil;
import com.mortals.xhx.opencv.utils.OpencvHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author ZYW
* @date 2024-01-12 9:40
*/
@Slf4j
public class SetWindow {
String filePath = "F:\\\\mid.prop";
private static SetWindow instance = null;
static JFrame frame;
static Gson gson = new Gson();
static int siteId = 0; // 目前被选中的站点id
static int windowId = 0; //被选中的窗口id
static String siteName = "";
static String windowName = "";
static String configUrl = "http://192.168.0.98:8090"; //事件服务器地址
static String siteUrl = "http://192.168.0.98:8090"; //站点列表地址
static JLabel textArea1;
static JComboBox<String> windowBox;
static JLabel windowLabel;
static ArrayList<WindowBean> windowList = new ArrayList<>();
public static void main(String[] args) {
//初始化窗口
getInstance().initWindow( getInstance().filePath, getInstance().siteUrl);
}
private SetWindow() {
}
public static SetWindow getInstance() {
if (null == instance) {
synchronized (SetWindow.class) {
if (null == instance) {
instance = new SetWindow();
}
}
}
return instance;
}
//初始化菜单
public void SystemTrayInitial() {
if (!SystemTray.isSupported()) {//判断系统是否支持托盘
log.info("系统不支持托盘");
return;
}
try {
String title = "中间件";//系统栏通知标题
String company = "";//系统通知栏内容
SystemTray systemTray = SystemTray.getSystemTray();//获取系统默认托盘
ClassPathResource classPathResource = new ClassPathResource("img/icon.png");
Image image = ImageIO.read(classPathResource.getInputStream());
// Image image = Toolkit.getDefaultToolkit().getImage("img/icon.png");
// Image image = Toolkit.getDefaultToolkit().getImage(absolutePath);//系统栏图标
TrayIcon trayIcon = new TrayIcon(image, title + "\n" + company, createMenu());//添加图标,标题,内容,菜单
trayIcon.setImageAutoSize(true);//设置图像自适应
// trayIcon.addMouseListener(new MouseAdapter() {
// @Override
// public void mouseClicked(MouseEvent e) {
// super.mouseClicked(e);
// if(e.getClickCount() == 2){ //双击操作
// }
// }
// });
systemTray.add(trayIcon);//添加托盘
trayIcon.displayMessage(title, company, TrayIcon.MessageType.INFO);//弹出一个info级别消息框
} catch (Exception e) {
log.error("系统托盘图标加载失败", e);
}
}
//托盘中的菜单
private PopupMenu createMenu() {
PopupMenu menu = new PopupMenu();//创建弹出式菜单
MenuItem exitItem = new MenuItem("exit");//创建菜单项
exitItem.addActionListener(new ActionListener() {//给菜单项添加事件监听器,单击时退出系统
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
MenuItem settingItem = new MenuItem("setting");//创建菜单项
settingItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//设置窗口对象可见
if(frame != null){
frame.setVisible(true);
}
}
});
menu.add(settingItem);
menu.add(exitItem);//添加退出系统菜单
return menu;
}
/**
* 初始化窗口
* @param path
* @param url
*/
public void initWindow(String path,String url) {
SystemTrayInitial();
filePath = path;
siteUrl = url;
// log.info(path+"==="+url);
//AWT中接口LayoutManager有五个实现类:GridLayout(网格布局)、FlowLayout(流式布局)、CardLayout(卡片布局)、
// GridBagLayout(网格包布局)和BorderLayout(边框布局)。为了简化开发,Swing引入了一个新的布局管理器BoxLayout。
//1、创建窗口对象
frame = new JFrame("配置窗口");
// 创建FlowLayout布局管理器并设置间距
FlowLayout layout = new FlowLayout();
layout.setHgap(10);
layout.setVgap(50);
frame.setLayout(layout);
textArea1 = new JLabel();
textArea1.setLocation(60,10);
textArea1.setPreferredSize(new Dimension(740,50));
textArea1.setForeground(Color.black);
textArea1.setVisible(true);
textArea1.setText("当前未配置站点");
frame.add(textArea1);
redConfig();
//好差评地址
JPanel jPanel1 = new JPanel(new FlowLayout());
JLabel maxLabel = new JLabel("事件服务器地址:");
JTextField jt = new JTextField();
jt.setText(configUrl);
jt.setColumns(18);//设置文本框长度
JButton jb = new JButton("测试");
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(!jt.getText().startsWith("http")){
JOptionPane.showMessageDialog(frame, "请输入http或https开头的地址");
}else {
try {
HttpUtil.get(jt.getText(),5000);
configUrl = jt.getText();
JOptionPane.showMessageDialog(frame, "连接成功");
}catch (Exception e1){
jt.setText(configUrl);
JOptionPane.showMessageDialog(frame, "服务器连接失败,请检查ip配置是否正确");
}
}
}
});
jPanel1.add(maxLabel);
jPanel1.add(jt);
jPanel1.add(jb);
frame.add(jPanel1);
//站点窗口列表地址
JPanel jPanel2 = new JPanel(new FlowLayout());
JLabel label2 = new JLabel("站点服务器地址:");
JTextField jt2 = new JTextField();
jt2.setText(siteUrl);
jt2.setColumns(17);//设置文本框长度
JButton jb2 = new JButton("测试");
jb2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(!jt2.getText().startsWith("http")){
JOptionPane.showMessageDialog(frame, "请输入http或https开头的地址");
}else {
try {
HttpUtil.get(jt2.getText(),5000);
siteUrl = jt2.getText();
JOptionPane.showMessageDialog(frame, "连接成功");
}catch (Exception e1){
jt2.setText(siteUrl);
JOptionPane.showMessageDialog(frame, "服务器连接失败,请检查ip配置是否正确");
}
}
}
});
jPanel2.add(label2);
jPanel2.add(jt2);
jPanel2.add(jb2);
frame.add(jPanel2);
//合适的窗口大小
frame.pack();
//禁止改变窗口大小
frame.setResizable(false);
//设置窗口关闭退出软件 默认 JFrame.EXIT_ON_CLOSE会关闭所有窗口 DISPOSE_ON_CLOSE仅关闭当前窗口
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//设置窗口的位置和大小
frame.setBounds(560,340,800,400);
//设置窗口对象可见
frame.setVisible(false);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
//窗口关闭释放摄像头资源
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
//界面重现时重新读取配置
redConfig();
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
String siteString = HttpUtil.get(siteUrl+"/inter/hcpapi/siteList",30000);
log.info(siteString);
ResultBean siteResult = gson.fromJson(siteString,ResultBean.class);
if(siteResult.getCode() == 1){
Type listType = new TypeToken<ArrayList<SiteBean>>(){}.getType();
ArrayList<SiteBean> siteList = gson.fromJson(gson.toJson(siteResult.getData()), listType);
//站点列表
JLabel siteLabel = new JLabel("站点列表:");
JComboBox<String> siteBox = new JComboBox<String>();//创建一个下拉列表框
siteBox.setPreferredSize(new Dimension(300,21)); //设置坐标
int selectedIndex = 0;
for (int i = 0; i < siteList.size(); i++) {
SiteBean siteBean = siteList.get(i);
siteBox.addItem(siteBean.getSiteName());
if(siteId == siteBean.getId()){
selectedIndex = i;
}
}
siteBox.setSelectedIndex(selectedIndex);
// siteId = siteList.get(siteBox.getSelectedIndex()).getId();
// siteName = siteList.get(siteBox.getSelectedIndex()).getSiteName();
siteBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
siteId = siteList.get(siteBox.getSelectedIndex()).getId();
siteName = siteList.get(siteBox.getSelectedIndex()).getSiteName();
log.info("选中站点为:"+siteName);
addWindowbox();
}
}
});
frame.add(siteLabel);
frame.add(siteBox);
if(siteId == 0){ //初始化查到siteid为0 则传入站点列表第一个站点id
siteId = siteList.get(siteBox.getSelectedIndex()).getId();
}
addWindowbox();
}else {
JOptionPane.showMessageDialog(frame, "站点列表接口("+siteUrl+"/inter/hcpapi/siteList"+")访问失败");
}
JButton subPicBtn = new JButton();
subPicBtn.setLocation(500,500);
subPicBtn.setBorderPainted(false);
subPicBtn.setContentAreaFilled(false);
subPicBtn.setFocusPainted(false);
subPicBtn.setOpaque(false);
subPicBtn.setIcon(ImageUtil.getImage("img/save.png"));
subPicBtn.setPressedIcon(ImageUtil.getImage("img/save_hover.png"));
subPicBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(siteId == 0){
JOptionPane.showMessageDialog(frame, "站点不能为空");
} else if (windowId == 0) {
JOptionPane.showMessageDialog(frame, "窗口不能为空");
}else {
writeConfig();
JOptionPane.showMessageDialog(frame, "保存成功");
frame.dispose();
}
}
});
frame.add(subPicBtn);
}
/**
* 添加窗口列表
*/
private void addWindowbox(){
String windowString = HttpUtil.get(siteUrl+"/inter/hcpapi/siteWindow?siteid="+siteId,30000);
log.info(windowString);
ResultBean windowResult = gson.fromJson(windowString,ResultBean.class);
if(windowResult.getCode() == 1){
Type windowType = new TypeToken<ArrayList<WindowBean>>(){}.getType();
windowList.clear();
windowList.addAll(gson.fromJson(gson.toJson(windowResult.getData()), windowType));
//站点列表
if(windowLabel == null){
windowLabel = new JLabel("窗口列表:");
frame.add(windowLabel);
}
if(windowBox == null){
windowBox = new JComboBox<String>();//创建一个下拉列表框
windowBox.setPreferredSize(new Dimension(300,21)); //设置坐标
int selectedIndex = 0;
if(windowList.size() > 0){
for (int i = 0; i < windowList.size(); i++) {
WindowBean windowBean = windowList.get(i);
windowBox.addItem(windowBean.getFromnum()+"--"+windowBean.getName());
if(windowId == windowBean.getId()){
selectedIndex = i;
}
}
log.info("selectedIndex ="+selectedIndex);
windowBox.setSelectedIndex(selectedIndex);
}
windowBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
windowId = windowList.get(windowBox.getSelectedIndex()).getId();
windowName= windowList.get(windowBox.getSelectedIndex()).getName();
log.info("选中窗口为:"+windowName);
}
}
});
frame.add(windowBox);
}else {
windowBox.removeAllItems();
int selectedIndex = 0;
if(windowList.size() > 0){
for (int i = 0; i < windowList.size(); i++) {
WindowBean windowBean = windowList.get(i);
windowBox.addItem(windowBean.getFromnum()+"--"+windowBean.getName());
if(windowId == windowBean.getId()){
selectedIndex = i;
}
}
log.info("selectedIndex ="+selectedIndex);
windowBox.setSelectedIndex(selectedIndex);
}
}
}else {
JOptionPane.showMessageDialog(frame, "窗口列表接口("+siteUrl+"/inter/hcpapi/siteWindow?siteid="+siteId+")访问失败");
}
}
/**
* 读取本地文件配置
*/
private void redConfig(){
File file = new File(filePath);
try {
file.createNewFile();
} catch (IOException e) {
log.error( "创建文件失败" ); ;
}
Scanner sc = null ;
try
{
sc = new Scanner( file ) ;
String jsonString = sc.next();
WindowConfigBean jo = gson.fromJson(jsonString,WindowConfigBean.class);
if(jo != null){
siteId = jo.getSiteId();
windowId = jo.getWindowId();
windowName = jo.getWindowName();
siteName = jo.getSiteName();
configUrl = jo.getConfigUrl();
siteUrl = jo.getSiteUrl();
if(!siteName.equals("") && siteId != 0){
textArea1.setText("当前设置站点:"+siteName+" ; 当前设置窗口:"+windowName);
}
}else {
log.info( "配置文件为空" ); ;
}
}
catch( Exception e )
{
// log.error( "读取配置文件失败" ); ;
}
finally
{
try
{
// log.error( "读写关闭" ) ;
sc.close();
}
catch ( Exception e )
{
}
}
}
/**
* 修改本地文件配置
*/
private void writeConfig(){
WindowConfigBean cb = new WindowConfigBean(siteId,windowId,siteName,windowName,configUrl,siteUrl);
File file = new File(filePath);
try {
file.createNewFile();
} catch (IOException e) {
}
FileWriter fileWriter = null ;
BufferedWriter bufferedWriter = null ; //FileWriter和BufferedWriter的初始化需要监听,此处只定义不初始化
try
{
fileWriter = new FileWriter( file ) ;
bufferedWriter = new BufferedWriter( fileWriter ) ;
bufferedWriter.write( gson.toJson(cb) ) ;
if(!siteName.equals("") && siteId != 0){
textArea1.setText("当前设置站点:"+siteName+" ; 当前设置窗口:"+windowName);
}
}
catch( Exception e )
{
log.error( "Error." ); ;
}
finally
{
try
{
bufferedWriter.close(); //随手关闭文件,此处注意关闭顺序不能错误
fileWriter.close();
}
catch( IOException ioe )
{
log.error( "写入配置文件失败->" +ioe.toString()); ;
}
}
}
}
package com.mortals.xhx.opencv.UI;
import com.mortals.xhx.opencv.utils.OpencvHelper;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Rect;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
/**
* @author ZYW
* @date 2024-01-02 10:26
*/
@Slf4j
public class VideoPanel extends JPanel {
private Image image;
private Rectangle rectangle; //返回的矩形
private Point drawStart, drawEnd; //绘制起点、终点
int cutType = 1; // 根据切边模式判断画线
public VideoPanel() {
// 初始化鼠标事件监听器
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// 鼠标按下时记录起始点
drawStart = new Point(e.getX(), e.getY());
drawEnd = drawStart;
// 触发重绘
repaint();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
// 鼠标拖动时更新终点
drawEnd = new Point(e.getX(), e.getY());
// 触发重绘
repaint();
}
});
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
// 鼠标释放时完成绘制,并设置rectangle为最终矩形
rectangle = new Rectangle(drawStart,
new Dimension(drawEnd.x - drawStart.x, drawEnd.y - drawStart.y));
// 如果需要保持矩形不变,而不是继续绘制新的矩形,则取消注释下一行
// removeMouseListener(this);
// removeMouseMotionListener(this);
// 触发重绘以显示完成的矩形(如果需要)
repaint();
}
});
}
public void setImageWithMat(Mat mat, Rectangle angle,int cutType) {
image = OpencvHelper.matToBufferedImage(mat);
if(angle != null){
this.rectangle = angle;
}
this.cutType = cutType;
this.repaint();
}
public void setImage(BufferedImage bi,Rectangle angle) {
image = bi;
if(angle != null){
this.rectangle = angle;
}
this.repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//绘制图像
if (image != null){
g.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), this);
}
Graphics2D g2d = (Graphics2D) g;
// 设置画笔的粗细为5
g2d.setStroke(new BasicStroke(2));
g2d.setColor(Color.RED);
// 如果正在绘制矩形,则使用临时的起点和终点来绘制它
if (drawStart != null && drawEnd != null && cutType == 2) {
g2d.drawRect(Math.min(drawStart.x, drawEnd.x), Math.min(drawStart.y, drawEnd.y),
Math.abs(drawEnd.x - drawStart.x), Math.abs(drawEnd.y - drawStart.y));
}
// 如果已经完成了矩形的绘制,则可以绘制一个填充的或未填充的矩形来表示它
if (rectangle != null && cutType == 1) {
g2d.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
public Rect getRect() {
Rect rect;
if(rectangle != null){
rect = new Rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}else {
rect= null;
}
return rect; // 返回最终绘制的矩形,如果还没有完成绘制则返回null
}
public static VideoPanel show(String title, int width, int height, int open) {
JFrame frame = new JFrame(title);
if (open == 0) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} else {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
frame.setSize(width, height);
frame.setBounds(0, 0, width, height);
VideoPanel videoPanel = new VideoPanel();
videoPanel.setSize(width, height);
frame.setContentPane(videoPanel);
frame.setVisible(true);
return videoPanel;
}
}
package com.mortals.xhx.opencv;
import com.github.sarxos.webcam.Webcam;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.util.List;
/**
* @author ZYW
* @date 2024-01-23 15:30
*/
public class WebCamDemo extends JFrame {
boolean isRuning = true;
public WebCamDemo(){
//通过静态方法,获取电脑上的默认摄像头
Webcam webcam=Webcam.getDefault();
System.out.println(webcam.getName());
//通过静态方法,获取电脑上所有的摄像头
List<Webcam> webcams=Webcam.getWebcams();
//遍历这个数组
for(int i=0;i<webcams.size();i++){
System.out.println(webcams.get(i).getName());
}
Webcam ComputerCam=webcams.get (0);
ComputerCam.setViewSize(new Dimension(640,480));//只有默认的几种尺寸大小,要按照规定来设置
ComputerCam.open();
//设置窗体的属性
setTitle("WebCam");
setSize(640,480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//获取摄像头的画面
Graphics g=getGraphics();
while(isRuning){
//获取一帧图像
buffimg=ComputerCam.getImage();
//调用repaint()方法,触发窗体的重绘,从而更新图像显示
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
isRuning = false;
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
}
//声明变量buffimg,用于存储从摄像头获取的图像数据
BufferedImage buffimg=null;
//重写JFrame类的paint()方法,每次在窗体重绘时被调用,用于绘制图像
@Override
public void paint(Graphics g){
if(buffimg != null){
g.drawImage(buffimg,0,0,this.getWidth(),this.getHeight(),null);
}
}
public static void main(String[] args) {
new WebCamDemo();
}
}
package com.mortals.xhx.opencv.bean;
/**
* @author ZYW
* @date 2024-01-03 15:00
*/
public class ConfigBean {
int cutType;
int roteAngle;
int cameraIndex;
int maxPhoto;
String ratio; //分辨率
public ConfigBean(int cutType, int roteAngle, int cameraIndex, int maxPhoto, String ratio) {
this.cutType = cutType;
this.roteAngle = roteAngle;
this.cameraIndex = cameraIndex;
this.maxPhoto = maxPhoto;
this.ratio = ratio;
}
public int getCutType() {
return cutType;
}
public void setCutType(int cutType) {
this.cutType = cutType;
}
public int getRoteAngle() {
return roteAngle;
}
public void setRoteAngle(int roteAngle) {
this.roteAngle = roteAngle;
}
public int getCameraIndex() {
return cameraIndex;
}
public void setCameraIndex(int cameraIndex) {
this.cameraIndex = cameraIndex;
}
public int getMaxPhoto() {
return maxPhoto;
}
public void setMaxPhoto(int maxPhoto) {
this.maxPhoto = maxPhoto;
}
public String getRatio() {
return ratio;
}
public void setRatio(String ratio) {
this.ratio = ratio;
}
}
package com.mortals.xhx.opencv.bean;
/**
* @author ZYW
* @date 2024-01-02 10:29
*/
public class FileBean {
private String fileFullPath;
private String folderName;
private String fileType;
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public String getFileFullPath() {
return fileFullPath;
}
public void setFileFullPath(String fileFullPath) {
this.fileFullPath = fileFullPath;
}
public String getFolderName() {
return folderName;
}
public void setFolderName(String folderName) {
this.folderName = folderName;
}
}
package com.mortals.xhx.opencv.bean;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author ZYW
* @date 2024-01-04 16:40
*/
public class PhotoBean {
/**
* 文件名
* 1.jpg
*/
private String filename;
/**
* 文件类型 base64
* data:image/jpg;base64,/8j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQ//2Q==
*/
@JSONField(name="Base64String")
@JsonProperty("Base64String")
private String Base64String;
public PhotoBean(String filename, String Base64String) {
this.filename = filename;
this.Base64String = Base64String;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
@JSONField(name="Base64String")
@JsonProperty("Base64String")
public String getBase64String() {
return Base64String;
}
public void setBase64String(String base64String) {
Base64String = base64String;
}
}
package com.mortals.xhx.opencv.bean;
/**
* @author ZYW
* @date 2024-01-15 9:55
*/
public class ResultBean {
int code;
String msg;
Object data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.mortals.xhx.opencv.bean;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author ZYW
* @date 2024-01-15 9:51
*/
@NoArgsConstructor
@Data
public class SiteBean {
@JsonProperty("id")
private Integer id;
@JsonProperty("createUserId")
private Integer createUserId;
@JsonProperty("createTime")
private Long createTime;
@JsonProperty("updateTime")
private Long updateTime;
@JsonProperty("siteName")
private String siteName;
@JsonProperty("siteCode")
private String siteCode;
@JsonProperty("areaID")
private String areaID;
@JsonProperty("areaCode")
private String areaCode;
@JsonProperty("areaName")
private String areaName;
@JsonProperty("proCode")
private String proCode;
@JsonProperty("cityCode")
private String cityCode;
@JsonProperty("districtCode")
private String districtCode;
@JsonProperty("siteIp")
private String siteIp;
@JsonProperty("sitePort")
private String sitePort;
@JsonProperty("longitude")
private String longitude;
@JsonProperty("latitude")
private String latitude;
@JsonProperty("siteTel")
private String siteTel;
@JsonProperty("detailAddress")
private String detailAddress;
@JsonProperty("siteRemark")
private String siteRemark;
@JsonProperty("amWorkStartTime")
private Long amWorkStartTime;
@JsonProperty("amWorkEndTime")
private Long amWorkEndTime;
@JsonProperty("pmWorkStartTime")
private Long pmWorkStartTime;
@JsonProperty("pmWorkEndTime")
private Long pmWorkEndTime;
@JsonProperty("workday1")
private Integer workday1;
@JsonProperty("workday2")
private Integer workday2;
@JsonProperty("workday3")
private Integer workday3;
@JsonProperty("workday4")
private Integer workday4;
@JsonProperty("workday5")
private Integer workday5;
@JsonProperty("workday6")
private Integer workday6;
@JsonProperty("workday7")
private Integer workday7;
@JsonProperty("onlineTake")
private Integer onlineTake;
@JsonProperty("appointment")
private Integer appointment;
@JsonProperty("gowMap")
private Integer gowMap;
@JsonProperty("level")
private Integer level;
@JsonProperty("building")
private Integer building;
@JsonProperty("logoPath")
private String logoPath;
@JsonProperty("englishName")
private String englishName;
@JsonProperty("leadingOfficial")
private String leadingOfficial;
@JsonProperty("leadingOfficialTelephone")
private String leadingOfficialTelephone;
@JsonProperty("modelIds")
private String modelIds;
}
package com.mortals.xhx.opencv.bean;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author ZYW
* @date 2024-01-15 10:28
*/
@NoArgsConstructor
@Data
public class WindowBean {
@JsonProperty("siteName")
private String siteName;
@JsonProperty("siteid")
private Integer siteid;
@JsonProperty("id")
private Integer id;
@JsonProperty("name")
private String name;
@JsonProperty("fromnum")
private String fromnum;
@JsonProperty("englishName")
private String englishName;
@JsonProperty("deptName")
private String deptName;
@JsonProperty("deptId")
private Integer deptId;
@JsonProperty("hongqi")
private Integer hongqi;
@JsonProperty("region")
private String region;
}
package com.mortals.xhx.opencv.bean;
import javax.swing.*;
/**
* @author ZYW
* @date 2024-01-15 11:27
*/
public class WindowConfigBean {
int siteId;
int windowId;
String siteName;
String windowName;
String configUrl; //事件服务器地址
String siteUrl; //站点列表访问地址
public WindowConfigBean(int siteId, int windowId, String siteName, String windowName, String configUrl, String siteUrl) {
this.siteId = siteId;
this.windowId = windowId;
this.siteName = siteName;
this.windowName = windowName;
this.configUrl = configUrl;
this.siteUrl = siteUrl;
}
public int getSiteId() {
return siteId;
}
public void setSiteId(int siteId) {
this.siteId = siteId;
}
public int getWindowId() {
return windowId;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
public String getSiteName() {
return siteName;
}
public void setSiteName(String siteName) {
this.siteName = siteName;
}
public String getWindowName() {
return windowName;
}
public void setWindowName(String windowName) {
this.windowName = windowName;
}
public String getConfigUrl() {
return configUrl;
}
public void setConfigUrl(String configUrl) {
this.configUrl = configUrl;
}
public String getSiteUrl() {
return siteUrl;
}
public void setSiteUrl(String siteUrl) {
this.siteUrl = siteUrl;
}
}
package com.mortals.xhx.opencv.utils;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Mat;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author ZYW
* @date 2024-01-08 11:14
*/
@Slf4j
public class ImageUtil {
/**
* 图片纠斜
* @param image
* @return
*/
public static BufferedImage skewCorrection(BufferedImage image) {
// Convert image to grayscale
BufferedImage grayscaleImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics g = grayscaleImage.getGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
// Apply edge detection algorithm to find lines
// ...
// Determine angle of skew
double skewAngle = 0.0;
// ...
// Rotate image to correct skew
double radians = Math.toRadians(-skewAngle);
double sin = Math.abs(Math.sin(radians));
double cos = Math.abs(Math.cos(radians));
int width = grayscaleImage.getWidth();
int height = grayscaleImage.getHeight();
int newWidth = (int) Math.floor(width * cos + height * sin);
int newHeight = (int) Math.floor(height * cos + width * sin);
BufferedImage rotatedImage = new BufferedImage(newWidth, newHeight, grayscaleImage.getType());
Graphics2D g2d = rotatedImage.createGraphics();
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, newWidth, newHeight);
int x = (newWidth - width) / 2;
int y = (newHeight - height) / 2;
g2d.translate(x, y);
g2d.rotate(radians, width / 2.0, height / 2.0);
g2d.drawRenderedImage(grayscaleImage, null);
g2d.dispose();
return rotatedImage;
}
/**
* 裁切黑边
* @param image
* @return
*/
public static BufferedImage cutAuto(BufferedImage image) {
BufferedImage originalImage = skewCorrection(image);
// 获取图片的宽度和高度
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// 创建一个新的BufferedImage,其尺寸与原始图像相同
BufferedImage imageWithBorder = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = imageWithBorder.createGraphics();
g.drawImage(originalImage, 0, 0, null);
g.dispose();
// 遍历图像,查找黑色边界并裁剪
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = imageWithBorder.getRGB(x, y);
int alpha = (pixel >> 24) & 0xff; // alpha通道
if (alpha == 0) { // 如果像素是黑色的(alpha值为0)
// 裁剪黑色边界
BufferedImage croppedImage = new BufferedImage(width - x, height - y, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = croppedImage.createGraphics();
g2d.drawImage(originalImage, 0, 0, x, y, null); // 只绘制被裁剪的部分
g2d.dispose();
imageWithBorder = croppedImage; // 将裁剪后的图像设置为当前图像
break; // 只需要找到一个黑色像素就停止遍历,因为整个图像都是黑色的了
}
}
}
return imageWithBorder;
}
/**
* 读取项目目录下的图片文件
*/
static public ImageIcon getImage(String filePath){
ImageIcon imageIcon = null;
ClassPathResource classPathResource = new ClassPathResource(filePath);
try {
imageIcon= new ImageIcon(ImageIO.read(classPathResource.getInputStream()));
} catch (IOException e) {
log.error("读取图片路径失败:"+e.toString());
throw new RuntimeException(e);
}
return imageIcon;
}
/**
* 读取本地目录下的图片文件
*/
static public ImageIcon getImageByFile(File file){
ImageIcon imageIcon = null;
try {
imageIcon= new ImageIcon(ImageIO.read(file));
} catch (IOException e) {
log.error("读取图片路径失败:"+e.toString());
throw new RuntimeException(e);
}
return imageIcon;
}
/**
* 读取本地目录下的图片文件 缩放成指定大小
*/
static public ImageIcon zoomImageByFile(File file,int width,int height){
ImageIcon imageIcon = null;
try {
// 读取图片
BufferedImage originalImage = ImageIO.read(file);
// 创建一个新的缓冲图片
BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 绘制并缩放原图到新图片
Graphics2D g2d = resizedImage.createGraphics();
g2d.drawImage(originalImage, 0, 0, width, width, null);
g2d.dispose();
imageIcon= new ImageIcon(resizedImage);
} catch (IOException e) {
log.error("读取图片路径失败:"+e.toString());
throw new RuntimeException(e);
}
return imageIcon;
}
}
package com.mortals.xhx.opencv.utils;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.Java2DFrameUtils;
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_core.Point;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import static org.bytedeco.opencv.global.opencv_core.CV_8UC3;
import static org.bytedeco.opencv.global.opencv_core.flip;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
/**
* @author ZYW
* @date 2023-12-21 10:09
*/
@Slf4j
public class OpencvHelper {
/**
* 图像缩放
* @param width 限制宽度
* @param height 限制高度
* @return 缩放后的mat
*/
public static BufferedImage ImageZoom(Mat sourceImage, int width, int height){
//创建缩放后的图像
Size newSize = new Size(width, height);
Mat outImage = new Mat();
Mat.zeros(sourceImage.size(), sourceImage.type());
//执行缩放操作
resize(sourceImage, outImage, newSize, 0, 0, INTER_LINEAR);
//保存图片
// Imgcodecs.imwrite("path/to/save/resized_image.jpg", resizedImage);
return matToBufferedImage(outImage);
}
/**
* 图像缩放
* @param width 限制宽度
* @param height 限制高度
* @return 缩放后的mat
*/
public static Mat ImageZoomMat(Mat sourceImage, int width, int height){
//创建缩放后的图像
Size newSize = new Size(width, height);
Mat outImage = new Mat();
Mat.zeros(sourceImage.size(), sourceImage.type());
//执行缩放操作
resize(sourceImage, outImage, newSize, 0, 0, INTER_LINEAR);
//保存图片
// Imgcodecs.imwrite("path/to/save/resized_image.jpg", resizedImage);
return outImage;
}
/**
* 图像旋转
* @param sourceImage 输入图片mat
* @param rote 旋转角度90、180、270
* @return 旋转后的mat
*/
public static BufferedImage ImageRotate(Mat sourceImage, int rote){
// 获取图像的尺寸
int width = sourceImage.cols();
int height = sourceImage.rows();
Mat outImage = new Mat();
// 创建一个旋转矩阵,指定旋转角度(以度为单位)
Mat rotationMatrix = getRotationMatrix2D(new Point2f(width / 2, height / 2), rote, 1);
// 使用旋转矩阵旋转图像,并将结果存储在rotatedImage中
warpAffine(sourceImage, outImage, rotationMatrix, new Size(width, height));
return matToBufferedImage(outImage);
}
/**
* 图像旋转
* @param sourceImage 输入图片mat
* @param rote 旋转角度90、180、270
* @return 旋转后的mat
*/
public static Mat ImageRotateMat(Mat sourceImage, int rote){
if(rote == 0){
return sourceImage;
}else {
// 获取图像的尺寸
int width = sourceImage.cols();
int height = sourceImage.rows();
Mat outImage = new Mat();
// 创建一个旋转矩阵,指定旋转角度(以度为单位)
Mat rotationMatrix = getRotationMatrix2D(new Point2f(width / 2, height / 2), rote, 1);
// 使用旋转矩阵旋转图像,并将结果存储在rotatedImage中
warpAffine(sourceImage, outImage, rotationMatrix, new Size(width, height));
return outImage;
}
}
/**
* 图片翻转
* @param inputPath 输入图片
* @param flip 1表示水平翻转,0表示垂直翻转,-1表示同时进行水平和垂直翻转
* @return
*/
public static BufferedImage ImageFlip(String inputPath,int flip)
{
//读取图像
Mat sourceImage = imread(inputPath);
if (sourceImage.empty()) {
System.err.println("Could not read the image");
return null;
}
Mat outImage = new Mat();
// 使用Imgproc.flip进行上下翻转,1表示水平翻转,0表示垂直翻转,-1表示同时进行水平和垂直翻转
flip(sourceImage, outImage, flip);
return matToBufferedImage(outImage);
}
/**
* 图片自动裁切
* @param sourceImage 输入图片
* @return
*/
public static BufferedImage ImageCutAuto(Mat sourceImage)
{
// // 转为灰度图像
// Mat gray = new Mat();
// cvtColor(sourceImage, gray, COLOR_BGR2GRAY);
//
// // 二值化处理
// Mat binary = new Mat();
// threshold(gray, binary, 0, 255, THRESH_BINARY |THRESH_OTSU);
//
// // 边缘检测
// Mat edges = new Mat();
// Canny(binary, edges, 50, 150);
//
// // 寻找轮廓
// MatVector matVector = new MatVector();
// Mat hierarchy = new Mat();
// findContours(binary, matVector, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
//
// // 找出最大的轮廓(假设这是图片内容)
// double maxArea = 0;
// int maxContourIndex = 0;
// for (int i = 0; i < matVector.size(); i++) {
// double area = contourArea(matVector.get(i));
// if (area > maxArea) {
// maxArea = area;
// maxContourIndex = i;
// }
// }
//
// // 根据最大轮廓裁剪图像
// Rect rect = boundingRect(matVector.get(maxContourIndex));
// Mat outImage = new Mat(sourceImage, rect);
// return matToBufferedImage(outImage);
BufferedImage bufferedImage = matToBufferedImage(sourceImage);
// 转为灰度图像
Mat gray = new Mat();
cvtColor(sourceImage, gray, COLOR_BGR2GRAY);
// 二值化处理
Mat binary = new Mat();
threshold(gray, binary, 80, 255, THRESH_BINARY |THRESH_OTSU);
//降噪 - 中值滤波
Mat blur = new Mat();
medianBlur(binary,blur,3);
//降噪 - 高斯滤波
Mat gauss = new Mat();
GaussianBlur(blur,gauss,new Size(3,3), 0);
// 膨胀和腐蚀生成轮廓
Mat element = getStructuringElement(MORPH_ELLIPSE, new Size(3, 3));
Mat dilate = new Mat();
dilate(gauss, dilate, element);//膨胀:将前景物体变大,理解成将图像断开裂缝变小
Mat erode = new Mat();
erode(dilate, erode, element);//腐蚀:将前景物体变小,理解成将图像断开裂缝变大
// 边缘检测
Mat edges = new Mat();
Canny(erode, edges, 30, 90);
// 寻找轮廓
MatVector matVector = new MatVector();
Mat hierarchy = new Mat();
findContours(edges, matVector, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
// 找出最大的轮廓(假设这是图片内容)
double maxArea = 0;
int maxContourIndex = 0;
for (int i = 0; i < matVector.size(); i++) {
double area = contourArea(matVector.get(i));
if (area > maxArea) {
maxArea = area;
maxContourIndex = i;
}
}
//计算最小外接旋转矩形
RotatedRect rectRotate = minAreaRect(matVector.get(maxContourIndex));
// 计算裁剪后的边界点
Point[] points = new Point[4];
points(rectRotate,points);
//获取中心点和大小
Point2f center = rectRotate.center();
Size2f size2f = rectRotate.size();
Size size = new Size((int)size2f.width(), (int)size2f.height());
// //计算透视变换矩阵
// Mat M = getPerspectiveTransform();
// Mat outImage = new Mat();
// warpPerspective(sourceImage, outImage, M, size);
// 根据最大轮廓裁剪图像
Rect rect = boundingRect(matVector.get(maxContourIndex));
Mat outImage = new Mat(sourceImage,rect);
return matToBufferedImage(outImage);
}
/**
* 获取矩形旋转后的坐标
* @param pt
*/
public static void points(RotatedRect rect, Point[] pt) {
double _angle = rect.angle() * Math.PI / 180.0;
double b = Math.cos(_angle) * 0.5;
double a = Math.sin(_angle) * 0.5;
pt[0] = new Point((int) (rect.center().x() - a * rect.size().height() - b * rect.size().width()), (int) (rect.center().y() + b * rect.size().height() - a * rect.size().width()));
pt[1] = new Point((int) (rect.center().x() + a * rect.size().height() - b * rect.size().width()), (int) (rect.center().y() - b * rect.size().height() - a * rect.size().width()));
pt[2] = new Point((int) (2.0 * rect.center().x() - pt[0].x()), (int) (2.0 * rect.center().y() - pt[0].y()));
pt[3] = new Point((int) (2.0 * rect.center().x() - pt[1].x()), (int) (2.0 * rect.center().y() - pt[1].y()));
}
/**
* 图片自动裁切
* @param sourceImage 输入图片
* @return
*/
public static Rectangle cutAutoGetAngele(Mat sourceImage)
{
// 转为灰度图像
Mat gray = new Mat();
cvtColor(sourceImage, gray, COLOR_BGR2GRAY);
// 二值化处理
Mat binary = new Mat();
threshold(gray, binary, 0, 255, THRESH_BINARY |THRESH_OTSU);
//降噪 - 中值滤波
Mat blur = new Mat();
medianBlur(binary,blur,3);
//降噪 - 高斯滤波
Mat gauss = new Mat();
GaussianBlur(blur,gauss,new Size(3,3), 0);
// 膨胀和腐蚀生成轮廓
Mat element = getStructuringElement(MORPH_ELLIPSE, new Size(3, 3));
Mat dilate = new Mat();
dilate(gauss, dilate, element);//膨胀:将前景物体变大,理解成将图像断开裂缝变小
Mat erode = new Mat();
erode(dilate, erode, element);//腐蚀:将前景物体变小,理解成将图像断开裂缝变大
// 边缘检测 加了边缘监测 框就会一直闪烁
Mat edges = new Mat();
Canny(erode, edges, 30, 90);
// 寻找轮廓
MatVector matVector = new MatVector();
Mat hierarchy = new Mat();
findContours(erode, matVector, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
// 找出最大的轮廓(假设这是图片内容)
double maxArea = 0;
int maxContourIndex = 0;
for (int i = 0; i < matVector.size(); i++) {
double area = contourArea(matVector.get(i));
if (area > maxArea) {
maxArea = area;
maxContourIndex = i;
}
}
//计算最小外接旋转矩形
RotatedRect rectRotate = minAreaRect(matVector.get(maxContourIndex));
// 计算裁剪后的边界点
Point[] points = new Point[4];
points(rectRotate,points);
// Scalar color = new Scalar(0, 0, 255,5);
// line(sourceImage,points[0],points[1],color);
// line(sourceImage,points[1],points[2],color);
// line(sourceImage,points[2],points[3],color);
// line(sourceImage,points[3],points[0],color);
// 根据最大轮廓裁剪图像
Rect rect = boundingRect(matVector.get(maxContourIndex));
Rectangle rectangle = new Rectangle(rect.x(),rect.y(),rect.width(),rect.height());
return rectangle;
}
/**
* 图片按照划定矩形裁切
* @param sourceImage 输入图片
* @return
*/
public static BufferedImage ImageCutByRect(Mat sourceImage,Rect rect)
{
// 根据划定轮廓裁剪图像
Mat outImage = new Mat(sourceImage, rect);
return matToBufferedImage(outImage);
}
// 将Mat转换为BufferedImage的方法
public static BufferedImage matToBufferedImage(Mat matrix) {
return Java2DFrameUtils.toBufferedImage(matrix);
}
// 将BufferedImage转换为Mat的方法
public static Mat imageToMat(BufferedImage bi) {
return Java2DFrameUtils.toMat(bi);
}
// 将BufferedImage转换为base64的方法
public static String imageToBase64(BufferedImage bufferedImage) {
// 创建ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 将BufferedImage写入到ByteArrayOutputStream中
try {
ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);
} catch (IOException e) {
return "";
}
// 将数据编码为Base64字符串
String base64String = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
return "data:image/jpg;base64,"+base64String;
}
// 根据三个点计算中间那个点的夹角 pt1 pt0 pt2
private static double getAngle(Point pt1, Point pt2, Point pt0)
{
double dx1 = pt1.x() - pt0.x();
double dy1 = pt1.y() - pt0.y();
double dx2 = pt2.x() - pt0.x();
double dy2 = pt2.y() - pt0.y();
return (dx1*dx2 + dy1*dy2)/Math.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}
// 找到最大的正方形轮廓
private static int findLargestSquare(MatVector matVector) {
double maxArea = 0;
int maxContourIndex = 0;
for (int i = 0; i < matVector.size(); i++) {
double area = contourArea(matVector.get(i));
if (area > maxArea) {
maxArea = area;
maxContourIndex = i;
}
}
return maxContourIndex;
}
// 点到点的距离
private static double getSpacePointToPoint(Point p1, Point p2) {
double a = p1.x() - p2.x();
double b = p1.y() - p2.y();
return Math.sqrt(a * a + b * b);
}
// 两直线的交点
private static Point computeIntersect(double[] a, double[] b) {
if (a.length != 4 || b.length != 4)
{throw new ClassFormatError();}
double x1 = a[0], y1 = a[1], x2 = a[2], y2 = a[3], x3 = b[0], y3 = b[1], x4 = b[2], y4 = b[3];
double d = ((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
if (d != 0) {
double x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
double y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
Point pt = new Point((int) x,(int) y);
return pt;
}
else{
return new Point(-1, -1);
}
}
// 对多个点按顺时针排序
private static void sortCorners(ArrayList<Point> corners) {
if (corners.size() == 0) return;
Point p1 = corners.get(0);
int index = 0;
for (int i = 1; i < corners.size(); i++) {
Point point = corners.get(i);
if (p1.x() > point.x()) {
p1 = point;
index = i;
}
}
corners.set(index, corners.get(0));
corners.set(0, p1);
Point lp = corners.get(0);
for (int i = 1; i < corners.size(); i++) {
for (int j = i + 1; j < corners.size(); j++) {
Point point1 = corners.get(i);
Point point2 = corners.get(j);
if ((point1.y()-lp.y()*1.0)/(point1.x()-lp.x())>(point2.y()-lp.y()*1.0)/(point2.x()-lp.x())) {
Point temp = new Point(point1.x(),point1.y());
corners.set(i, corners.get(j));
corners.set(j, temp);
}
}
}
}
}
package com.mortals.xhx.opencv.utils;
import java.io.File;
/**
* @author ZYW
* @date 2023-12-27 11:02
*/
public class ResourcesUtil {
public static final String resourcesPath = ResourcesUtil.class.getResource("/").getPath() + File.separator;
}
package com.mortals.xhx.swing;
import com.mortals.xhx.opencv.UI.SetWindow;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@Slf4j
public class MyTray {
private static MyTray instance = null;
String filePath = "/root/mid.prop";
String siteUrl = "http://192.168.0.98:8090";
public MyTray() {
}
public static MyTray getInstance() {
if (null == instance) {
synchronized (MyTray.class) {
if (null == instance) {
instance = new MyTray();
}
}
}
return instance;
}
//初始化菜单
public void SystemTrayInitial(String path,String url) {
filePath = path;
siteUrl = url;
if (!SystemTray.isSupported()) {//判断系统是否支持托盘
log.info("系统不支持托盘");
return;
}
try {
String title = "中间件";//系统栏通知标题
String company = "";//系统通知栏内容
SystemTray systemTray = SystemTray.getSystemTray();//获取系统默认托盘
ClassPathResource classPathResource = new ClassPathResource("img/icon.png");
Image image = ImageIO.read(classPathResource.getInputStream());
// Image image = Toolkit.getDefaultToolkit().getImage("img/icon.png");
// Image image = Toolkit.getDefaultToolkit().getImage(absolutePath);//系统栏图标
TrayIcon trayIcon = new TrayIcon(image, title + "\n" + company, createMenu());//添加图标,标题,内容,菜单
trayIcon.setImageAutoSize(true);//设置图像自适应
// trayIcon.addMouseListener(new MouseAdapter() {
// @Override
// public void mouseClicked(MouseEvent e) {
// super.mouseClicked(e);
// if(e.getClickCount() == 2){ //双击操作
// }
// }
// });
systemTray.add(trayIcon);//添加托盘
trayIcon.displayMessage(title, company, TrayIcon.MessageType.INFO);//弹出一个info级别消息框
} catch (Exception e) {
log.error("系统托盘图标加载失败", e);
}
}
//托盘中的菜单
private PopupMenu createMenu() {
PopupMenu menu = new PopupMenu();//创建弹出式菜单
MenuItem exitItem = new MenuItem("exit");//创建菜单项
exitItem.addActionListener(new ActionListener() {//给菜单项添加事件监听器,单击时退出系统
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
MenuItem settingItem = new MenuItem("setting");//创建菜单项
settingItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SetWindow.getInstance().initWindow(filePath,siteUrl);
}
});
menu.add(settingItem);
menu.add(exitItem);//添加退出系统菜单
return menu;
}
public static void main(String[] args) {
new MyTray().SystemTrayInitial(getInstance().filePath, getInstance().siteUrl);
}
}
\ No newline at end of file
package com.mortals.xhx.swing;
import org.springframework.util.ObjectUtils;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by Youdmeng on 2020/6/4 0004.
*/
public class SwingArea extends JPanel {
private static SwingArea instance = null;
private JProgressBar progressBar;
public String base64Text = "";
private SwingArea() {
}
public static SwingArea getInstance() {
if (null == instance) {
synchronized (SwingArea.class) {
if (null == instance) {
instance = new SwingArea();
}
}
}
return instance;
}
/* @Override
public void dispose() {
System.out.println("dispose");
//super.dispose();
}*/
public String initUI() {
// this.setTitle("测试处理程序");
// this.setResizable(false);
// this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(100, 100, 700, 540);
// this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(null);
//this.setContentPane(panel);
//文本区域
JLabel fileFild = new JLabel("无");
AtomicReference<JFileChooser> file = new AtomicReference<>(new JFileChooser());
JButton openBtn = new JButton("选择文件");
openBtn.addActionListener(e -> file.set(showFileOpenDialog(this, fileFild)));
openBtn.setBounds(160, 100, 100, 30);
//openBtn.setUI(new BEButtonUI().setNormalColor(BEButtonUI.NormalColor.green));
openBtn.setFont(new Font("宋体", Font.BOLD, 15));
openBtn.setForeground(Color.white);//字体颜色
panel.add(openBtn);
JButton action = new JButton("执行计算");
action.setBounds(370, 100, 100, 30);
action.addActionListener(e -> action(file.get()));
//action.setUI(new BEButtonUI().setNormalColor(BEButtonUI.NormalColor.green));
action.setFont(new Font("宋体", Font.BOLD, 15));
action.setForeground(Color.white);
panel.add(action);
panel.add(fileFild);
JLabel fileFildTitle = new JLabel("已选文件:");
fileFildTitle.setBounds(130, 150, 150, 30);
panel.add(fileFildTitle);
fileFild.setBounds(200, 150, 500, 30);
progressBar = new JProgressBar();
progressBar.setBounds(80, 300, 500, 30);
progressBar.setValue(0);
progressBar.setStringPainted(true);
panel.add(progressBar);
this.setVisible(true);
/* this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println(1111);
super.windowClosing(e);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println(222222);
super.windowClosed(e);
}
});*/
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if (!ObjectUtils.isEmpty(base64Text)) {
return base64Text;
}
}
}
/**
* 进度条模拟程序
*
* @param progressBar
*/
private void progressBar(JProgressBar progressBar) {
new Thread(() -> {
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.setValue(i);
if (i == 100) {
base64Text = "123456789";
}
}
}).start();
}
private void action(JFileChooser fileChooser) {
if (null == fileChooser || null == fileChooser.getSelectedFile()) {
JOptionPane.showMessageDialog(null, "请先选择要处理的文件!╮(╯▽╰)╭", "警告!", JOptionPane.WARNING_MESSAGE);
return;
}
System.out.println("执行" + fileChooser.getSelectedFile().getAbsolutePath());
progressBar(progressBar);
}
/*
* 打开文件
*/
private JFileChooser showFileOpenDialog(Component parent, JLabel textField) {
if (progressBar.getValue() != 0 && progressBar.getValue() != 100) {
JOptionPane.showMessageDialog(null, "计算过程中,不可更改文件!╮(╯▽╰)╭", "警告!", JOptionPane.WARNING_MESSAGE);
return null;
}
JFileChooser jFileChooser = new JFileChooser();
jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
jFileChooser.setMultiSelectionEnabled(false);
// 设置默认使用的文件过滤器
jFileChooser.setFileFilter(new FileNameExtensionFilter("excel(*.xlsx, *.xls)", "xls", "xlsx"));
// 打开文件选择框(线程将被阻塞, 直到选择框被关闭)
int result = jFileChooser.showOpenDialog(parent);
if (result == JFileChooser.APPROVE_OPTION) {
// 如果点击了"确定", 则获取选择的文件路径
File file = jFileChooser.getSelectedFile();
// 如果允许选择多个文件, 则通过下面方法获取选择的所有文件
// File[] files = fileChooser.getSelectedFiles();
textField.setText("");
textField.setText(file.getName() + "\n\n");
}
//进度条归零
progressBar.setValue(0);
return jFileChooser;
}
}
spring:
main:
allow-bean-definition-overriding: true
application:
log:
level: @profiles.log.level@
path: @profiles.log.path@
>>>>>>>>>>>>>>>>>>>
>> mid system<<
<<<<<<<<<<<<<<<<<<<
\ No newline at end of file
server:
port: @profiles.server.port@
servlet:
context-path: /
spring:
application:
name: mid-platform
profiles:
active: @profiles.active@
servlet:
multipart:
max-file-size: 100MB
max-request-size: 1000MB
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
serialization:
WRITE_DATES_AS_TIMESTAMPS: true
default-property-inclusion: NON_NULL
upload:
path: @profiles.filepath@
#抓取网卡评价相关参数
capture:
redirectUrl:
#打印相关参数
print:
ticket: 2 #打印小票类型,两种宽度(1.58mm,2.80mm)
#指定实现
config:
#身份证识别 新中新=xzx,
# idcard: xzx
# xzxUrl: http://localhost:8989/api/ReadMsg #新中新身份证读取地址
idcard: tmz
capture: default #高拍仪默认实现类
signUrl: ws://127.0.0.1:29999/ #签名板websocket地址
socialUrl: ws://localhost:12342/ #社保卡websocket地址
captureUrl: ws://127.0.0.1:1818/ #高拍仪websocket地址
siteconfig:
filepath: @profiles.siteconfig.filepath@
url: @profiles.siteconfig.url@
configpath: @profiles.siteconfig.configpath@
active:
active: @profiles.active@
<?xml version="1.0" encoding="UTF-8"?>
<Captures>
<Capture>
<SendServerIp>192.168.0.217</SendServerIp>
<SendServerPort>8083</SendServerPort>
<SendServerPath>/m/test/getHcpSin/form</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.217</SendServerIp>
<SendServerPort>8083</SendServerPort>
<SendServerPath>/m/test/getHcpSin/json</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.251</SendServerIp>
<SendServerPort>1023</SendServerPort>
<SendServerPath>/m/test/getHcpSin/form</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.251</SendServerIp>
<SendServerPort>1023</SendServerPort>
<SendServerPath>/m/test/getHcpSin/json</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.217</SendServerIp>
<SendServerPort>80</SendServerPort>
<SendServerPath>/m/test/getHcpSin</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.251</SendServerIp>
<SendServerPort>1023</SendServerPort>
<SendServerPath>/m/test/getHcpSin</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.10</SendServerIp>
<SendServerPort>8076</SendServerPort>
<SendServerPath>api/approval/externalsys/hcp/evaluation</SendServerPath>
</Capture>
<Capture>
<SendServerIp>192.168.0.30</SendServerIp>
<SendServerPort>17011</SendServerPort>
<SendServerPath>/m/member/test</SendServerPath>
</Capture>
<Capture>
<SendServerIp>202.61.88.86</SendServerIp>
<SendServerPort>80</SendServerPort>
<SendServerPath>/app/api/evaluate/evalExpandQueryHandler</SendServerPath>
</Capture>
</Captures>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="false" default-autowire="byType">
<!-- 事务管理对象 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 拦截模式 -->
<aop:config proxy-target-class="false">
<aop:advisor pointcut="execution(* com.mortals..*Service.*(..))" advice-ref="txAdvice" />
</aop:config>
<!-- 事务传播方式 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--tx:method name="get*" read-only="true"/ -->
<!--<tx:method name="*" read-only="false" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException,Exception" />-->
<tx:method name="remove*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="change*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="create*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="modify*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="execute*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="excute*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="start*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="increment*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="do*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="audit*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="notify*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="send*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="com.mortals.framework.exception.AppException" />
<tx:method name="doForce*" propagation="REQUIRES_NEW" rollback-for="com.mortals.framework.exception.AppException" />
<!--<tx:method name="*" read-only="true" />-->
</tx:attributes>
</tx:advice>
</beans>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-autowire="byType">
<import resource="spring-config-core.xml" />
</beans>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 定义变量后,可以使“${}”来使用变量 source来源为spring 上下文信息 -->
<springProperty scope="context" name="springApplicationName" source="spring.application.name"/>
<springProperty scope="context" name="serverPort" source="server.port"/>
<springProperty scope="context" name="logFilePath" source="application.log.path" defaultValue="/mortals/app/logs" />
<springProperty scope="context" name="logLevel" source="application.log.level" defaultValue="INFO" />
<!-- appender用来格式化日志输出节点,有俩个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略 -->
<!-- 控制台输出策略-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件输出策略-->
<appender name="fileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
<file>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 文件保存策略-->
<fileNamePattern>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-info.log.%d{yyyyMMdd}</fileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>7</MaxHistory>
</rollingPolicy>
</appender>
<!-- 异常文件输出策略-->
<appender name="fileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%X{traceId}] [%thread] [%.50c\(%L\)] - %msg%n</pattern>
</encoder>
<file>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${springApplicationName:-default}/${springApplicationName:-default}-error.log.%d{yyyyMMdd}</fileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>7</MaxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="fileInfo"/>
<appender-ref ref="fileError"/>
</root>
<!--TRACE < DEBUG < INFO < WARN < ERROR < FATAL -->
<!--用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。
<logger>仅有一个name属性,一个可选的level和一个可选的additivity属性。-->
<!-- name 用来指定受此loger约束的某一个包或者具体的某一个类-->
<!-- level 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前logger将会继承上级的级别-->
<!-- additivity 是否向上级logger传递打印信息。默认是true。false:表示只用当前logger的appender-ref。true:表示当前logger的appender-ref和rootLogger的appender-ref都有效。-->
<logger name="com.mortals.xhx.module" level="${logLevel}" additivity="false">
<appender-ref ref="console"/>
<appender-ref ref="fileInfo"/>
<appender-ref ref="fileError"/>
</logger>
</configuration>
\ No newline at end of file
源代码目录
打印机需安装
java打印问题 打印缺失 Cannot run program "/usr/bin/lpr": java.io.IOException: error=2, No such file or directory
find / -name "lpr" //查找lpr
ln -s /usr/share/bash-completion/completions/lpr /usr/bin/lpr //创建软连接
apt -y install cups-bsd //安装cups-bsd 替代lpr
\ No newline at end of file
###身份证识别
POST {{baseUrl}}/GetHardWareInfo?GetType=3&watiTime=120
Content-Type: application/x-www-form-urlencoded
{
"local": {
"baseUrl": "http://127.0.0.1:9000/"
},
"dev": {
"baseUrl": "http://192.168.0.217:18222/"
},
"test": {
"baseUrl": "http://192.168.0.43:8037/"
}
}
\ No newline at end of file
###身份证识别
POST {{baseUrl}}/GetHardWareInfo?GetType=2
Content-Type: application/x-www-form-urlencoded
,;RF;L[PLC XD9DSQ1WQE###打印
POST {{baseUrl}}/api/print/GetHardWareInfo?GetType=71
Content-Type: application/json
{
"printername": "导出为WPS PDF",
"printerip": "169.254.37.120",
"printerpapersource": "1",
"printerfile":"http://192.168.0.98:11074/file/uploadfile/1665631219662.docx"
}
###打印2
POST {{baseUrl}}/GetHardWareInfo?GetType=71
Content-Type: application/x-www-form-urlencoded
PrinterJson={"printername": "导出为WPS PDF","printertype": "url","url":"http://192.168.0.98:11074/file/uploadfile/1665631219662.docx"}
###打印3
POST {{baseUrl}}/GetHardWareInfo?GetType=73
Content-Type: application/x-www-form-urlencoded
###打印4
POST {{baseUrl}}/GetHardWareInfo?GetType=74&printerName=Microsoft Print to PDF
Content-Type: application/x-www-form-urlencoded
package httpclient.print;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.mortals.xhx.busiz.req.PrintReq;
import com.mortals.xhx.common.code.*;
import com.mortals.xhx.common.utils.Base64Util;
import com.mortals.xhx.module.print.model.PrintContent;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@Slf4j
@RunWith(JUnit4.class)
public class PrintTest {
private String domain;
private String baseStr="abcdefghijklmnopqrstuvwxyz123456789现实中我们经常遇到这样的需求寻找某个字是否存在于通规这字中换句话说即判断某字是否属于当今中国大陆的规范汉字文件找起字来费时费力网络上似也没有类似的检索工具且二三级字表中存在较多生僻的扩展区汉字目前不少网页仍无法完整显示这";
@Before
public void init(){
//domain="http://127.0.0.1:8037";
domain="http://192.168.0.43:8037";
}
@Test
public void testPrintTicket() {
//测试打印小票
PrintReq printReq = new PrintReq();
printReq.setPapertype(PaperTypeEnum.PAPER_TICKET.getValue());
printReq.setPrintertype(PrintTypeEnum.PRINT_NORMAL.getValue());
// printReq.setPrintername("lp1");
printReq.setPrinterpaperwidth("240");
List<PrintContent> contents = new ArrayList<>();
PrintContent printContent = new PrintContent();
printContent.initAttrValue();
//printContent.setAlign(PrintAlignStyleEnum.PRINT_CENTER.getValue());
contents.add(printContent);
for (int i = 0; i < 50; i++) {
printContent = new PrintContent();
printContent.initAttrValue();
//printContent.setAlign(PrintAlignStyleEnum.PRINT_CENTER.getValue());
//printContent.setContent(RandomUtil.randomString(30));
printContent.setContent(RandomUtil.randomString(baseStr,20));
// RandomUtil.randomStringWithoutStr(RandomUtil.randomString(30));
contents.add(printContent);
}
printContent = new PrintContent();
printContent.initAttrValue();
//printContent.setAlign(PrintAlignStyleEnum.PRINT_CENTER.getValue());
printContent.setContent("adfasdfafdasdfasfddddddaaaaddadddsd");
contents.add(printContent);
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setPrinttype(PrintContentTypeEnum.PRINT_SEPARATE.getValue());
printContent.setContent("#");
contents.add(printContent);
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setFontsize("16");
printContent.setFontstyle(PrintFontStyleEnum.PRINT_BOLD.getValue());
printContent.setAlign(PrintAlignStyleEnum.PRINT_CENTER.getValue());
printContent.setContent("人民银行");
contents.add(printContent);
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setPrinttype(PrintContentTypeEnum.PRINT_SEPARATE.getValue());
printContent.setContent("=");
contents.add(printContent);
/* //添加条形码
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setPrinttype(PrintContentTypeEnum.PRINT_BARCODE.getValue());
printContent.setAlign(PrintAlignStyleEnum.PRINT_RIGHT.getValue());
printContent.setContent("12455454554424");
contents.add(printContent);
//添加二维码
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setPrinttype(PrintContentTypeEnum.PRINT_QRCODE.getValue());
printContent.setAlign(PrintAlignStyleEnum.PRINT_CENTER.getValue());
printContent.setContent("http://www.baidu.com");
printContent.setImgwidth("100");
contents.add(printContent);
//添加图片
printContent = new PrintContent();
printContent.initAttrValue();
printContent.setPrinttype(PrintContentTypeEnum.PRINT_IMG.getValue());
printContent.setContent("https://pic1.zhimg.com/v2-a661800d008ddef5569085ee779826f9_r.jpg");
printContent.setImgwidth("100");
contents.add(printContent);*/
//JSON.toJSONString(printReq)
printReq.setContents(contents);
String url = domain+"/GetHardWareInfo";
HashMap<String, Object> params = new HashMap<>();
params.put("GetType", "71");
params.put("PrinterJson", JSON.toJSONString(printReq));
String rest = HttpUtil.post(url, params);
log.info("打印响应结果:" + rest);
}
@Test
public void testPrintBase64() {
File file = new File("F:\\test.txt");
String prefix = "txt";
// base64文件内容
String base64String = Base64Util.encodeBase64File(prefix, file);
PrintReq printReq = new PrintReq();
printReq.setPapertype(PaperTypeEnum.PAPER_A4.getValue());
printReq.setPrintertype(PrintTypeEnum.PRINT_BASE64.getValue());
printReq.setBase64(base64String);
//printReq.setPrinterpaperwidth("140");
String url = domain+"/GetHardWareInfo";
HashMap<String, Object> params = new HashMap<>();
params.put("GetType", "71");
params.put("PrinterJson", JSON.toJSONString(printReq));
String rest = HttpUtil.post(url, params);
log.info("打印响应结果:" + rest);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment