Commit cb33404f authored by 郭晓俊's avatar 郭晓俊

Merge branch 'GJYZJ_V1.0' of

http://gitlab.archser.com/common/aserver.git into GJYZJ_V1.0 Conflicts: src/main/resources/DBUpdate/DM_UpdateSQL.xml
parents 216d4228 3d672676
<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>
<groupId>com.archser</groupId>
<artifactId>aserver</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>aserver</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<jdk.version>1.8</jdk.version>
<junit.version>3.8.1</junit.version>
<jfinal.version>4.2</jfinal.version>
<cos.version>2017.5</cos.version>
<apachelog4j.version>2.11.1</apachelog4j.version>
<log4j.version>1.2.17</log4j.version>
<jfinalundertow.version>1.6</jfinalundertow.version>
<druid.version>1.0.29</druid.version>
<fastjson.version>1.2.55</fastjson.version>
<oracle.version>11.2.0.3</oracle.version>
<jjwt.version>0.10.6</jjwt.version>
<dubbo.version>2.7.2</dubbo.version>
<resteasy.version>4.1.1.Final</resteasy.version>
</properties>
<!-- 使用阿里 maven 库 -->
<repositories>
<repository>
<id>nexus</id>
<url>http://nexus.archser.com:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>${cos.version}</version>
</dependency>
<!-- <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId>
<version>${apachelog4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <version>${apachelog4j.version}</version>
</dependency> -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- undertow -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal-undertow</artifactId>
<version>${jfinalundertow.version}</version>
</dependency>
<!-- WebSocket 支持 -->
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>2.0.16.Final</version>
</dependency>
<!-- 避免控制台输出如下提示信息: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
项目中实际上用不到这个 jar 包 注意:eclipse 下可以将 scope 设置为 provided -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
<!-- 打包前改成 provided,此处使用 compile 仅为支持 IDEA -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- webSocket 开始-->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- webSocket 结束-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 国密加密需要的依赖 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- 对接单点登录调用的依赖 -->
<dependency>
<groupId>com.spbportal.sso</groupId>
<artifactId>spbportal-ssoClient-test</artifactId>
<version>1.0</version>
</dependency>
<!--自选库 -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>${jfinal.version}</version>
</dependency>
<dependency>
<groupId>dm.jdbc</groupId>
<artifactId>DmJdbcDriver17</artifactId>
<version>8.1.1.30</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<finalName>aserver</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<!-- java8 保留参数名编译参数 -->
<compilerArgument>-parameters</compilerArgument>
<compilerArguments>
<verbose />
</compilerArguments>
</configuration>
</plugin>
<!-- jar 包中的配置文件优先级高于 config 目录下的 "同名文件" 因此,打包时需要排除掉 jar 包中来自 src/main/resources
目录的 配置文件,否则部署时 config 目录中的同名配置文件不会生效 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<excludes>
<exclude>*.txt</exclude>
<exclude>*.xml</exclude>
<exclude>*.properties</exclude>
</excludes>
</configuration>
</plugin>
<!-- 使用 mvn clean package 打包 更多配置可参考官司方文档:http://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!-- 打包生成的文件名 -->
<finalName>${project.artifactId}</finalName>
<!-- jar 等压缩文件在被打包进入 zip、tar.gz 时是否压缩,设置为 false 可加快打包速度 -->
<recompressZippedFiles>false</recompressZippedFiles>
<!-- 打包生成的文件是否要追加 release.xml 中定义的 id 值 -->
<appendAssemblyId>true</appendAssemblyId>
<!-- 指向打包描述文件 package.xml -->
<descriptors>
<descriptor>package.xml</descriptor>
</descriptors>
<!-- 打包结果输出的基础目录 -->
<outputDirectory>${project.build.directory}/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<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>
<groupId>com.archser</groupId>
<artifactId>aserver</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>aserver</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<jdk.version>1.8</jdk.version>
<junit.version>3.8.1</junit.version>
<jfinal.version>4.2</jfinal.version>
<cos.version>2017.5</cos.version>
<apachelog4j.version>2.11.1</apachelog4j.version>
<log4j.version>1.2.17</log4j.version>
<jfinalundertow.version>1.6</jfinalundertow.version>
<druid.version>1.0.29</druid.version>
<fastjson.version>1.2.55</fastjson.version>
<oracle.version>11.2.0.3</oracle.version>
<jjwt.version>0.10.6</jjwt.version>
<dubbo.version>2.7.2</dubbo.version>
<resteasy.version>4.1.1.Final</resteasy.version>
</properties>
<!-- 使用阿里 maven 库 -->
<repositories>
<repository>
<id>nexus</id>
<url>http://nexus.archser.com:8081/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>cos</artifactId>
<version>${cos.version}</version>
</dependency>
<!-- <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId>
<version>${apachelog4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <version>${apachelog4j.version}</version>
</dependency> -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- undertow -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal-undertow</artifactId>
<version>${jfinalundertow.version}</version>
</dependency>
<!-- WebSocket 支持 -->
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>2.0.16.Final</version>
</dependency>
<!-- 避免控制台输出如下提示信息: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
项目中实际上用不到这个 jar 包 注意:eclipse 下可以将 scope 设置为 provided -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
<!-- 打包前改成 provided,此处使用 compile 仅为支持 IDEA -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>2.50</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- webSocket 开始 -->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- webSocket 结束 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 国密加密需要的依赖 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- 对接单点登录调用的依赖 -->
<dependency>
<groupId>com.spbportal.sso</groupId>
<artifactId>spbportal-ssoClient-test</artifactId>
<version>1.0</version>
</dependency>
<!--自选库 -->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>jfinal</artifactId>
<version>${jfinal.version}</version>
</dependency>
<dependency>
<groupId>dm.jdbc</groupId>
<artifactId>DmJdbcDriver17</artifactId>
<version>8.1.1.30</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<finalName>aserver</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<!-- java8 保留参数名编译参数 -->
<compilerArgument>-parameters</compilerArgument>
<compilerArguments>
<verbose />
</compilerArguments>
</configuration>
</plugin>
<!-- jar 包中的配置文件优先级高于 config 目录下的 "同名文件" 因此,打包时需要排除掉 jar 包中来自 src/main/resources
目录的 配置文件,否则部署时 config 目录中的同名配置文件不会生效 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<excludes>
<exclude>*.txt</exclude>
<exclude>*.xml</exclude>
<exclude>*.properties</exclude>
</excludes>
</configuration>
</plugin>
<!-- 使用 mvn clean package 打包 更多配置可参考官司方文档:http://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!-- 打包生成的文件名 -->
<finalName>${project.artifactId}</finalName>
<!-- jar 等压缩文件在被打包进入 zip、tar.gz 时是否压缩,设置为 false 可加快打包速度 -->
<recompressZippedFiles>false</recompressZippedFiles>
<!-- 打包生成的文件是否要追加 release.xml 中定义的 id 值 -->
<appendAssemblyId>true</appendAssemblyId>
<!-- 指向打包描述文件 package.xml -->
<descriptors>
<descriptor>package.xml</descriptor>
</descriptors>
<!-- 打包结果输出的基础目录 -->
<outputDirectory>${project.build.directory}/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.archser.aserver.common.config;
import com.alibaba.druid.filter.stat.StatFilter;
import com.archser.aserver.controller.BugController;
import com.archser.aserver.controller.IndexController;
import com.archser.aserver.controller.KeyController;
import com.archser.aserver.controller.MediumController;
import com.archser.aserver.controller.MenuController;
import com.archser.aserver.controller.MessageController;
import com.archser.aserver.controller.SettingController;
import com.archser.aserver.controller.SystemController;
import com.archser.aserver.controller.UserController;
import com.archser.aserver.interceptor.JwtInterceptor;
import com.archser.aserver.model._MappingKit;
import com.archser.aserver.service.DBService;
import com.archser.aserver.websocket.MessageWebSocket;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.handler.UrlSkipHandler;
import com.jfinal.json.MixedJsonFactory;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.render.ViewType;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.server.undertow.WebBuilder;
import com.jfinal.template.Engine;
public class MainConfig extends JFinalConfig {
/**
* 将全局配置提出来 方便其他地方重用
*/
private static Prop p;
/**
* 配置JFinal常量
*/
@Override
public void configConstant(Constants me) {
// 读取数据库配置文件
loadConfig();
// 设置当前是否为开发模式
me.setDevMode(p.getBoolean("devMode"));
// 设置默认上传文件保存路径 getFile等使用
me.setBaseUploadPath("upload/temp/");
// 设置上传最大限制尺寸
// me.setMaxPostSize(1024*1024*10);
// 设置默认下载文件路径 renderFile使用
me.setBaseDownloadPath("download");
// 设置默认视图类型
me.setViewType(ViewType.JFINAL_TEMPLATE);
// 设置404渲染视图
// me.setError404View("404.html");
// 设置json工厂
me.setJsonFactory(MixedJsonFactory.me());
// 设置启用依赖注入
me.setInjectDependency(true);
}
/**
* 配置项目路由 路由拆分到 FrontRutes 与 AdminRoutes 之中配置的好处: 1:可分别配置不同的 baseViewPath 与 Interceptor
* 2:避免多人协同开发时,频繁修改此文件带来的版本冲突 3:避免本文件中内容过多,拆分后可读性增强 4:便于分模块管理路由
*/
@Override
public void configRoute(Routes me) {
// 推荐拆分方式 如果需要就解开注释 创建对应的 Routes
// me.add(new WechatRoutes());//配置微信端访问路由
// 普通不拆分的方式配置 如下
// 设置默认访问首页路由 可使用http://localhost:port 直接访问 如果80端口 port可以省略
me.add("/", IndexController.class);
me.add("/setting", SettingController.class);
me.add("/user", UserController.class);
me.add("/message", MessageController.class);
me.add("/menu", MenuController.class);
me.add("/key", KeyController.class);
me.add("/system", SystemController.class);
me.add("/bug", BugController.class);
me.add("/medium",MediumController.class);
}
// 先加载开发环境配置,再追加生产环境的少量配置覆盖掉开发环境配置
static void loadConfig() {
if (p == null) {
p = PropKit.use("config.properties").appendIfExists("config-pro.properties");
}
}
/**
* 获取数据库插件 抽取成独立的方法,便于重用该方法,减少代码冗余
*/
public static DruidPlugin getDruidPlugin() {
loadConfig();
return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"), p.get("jdbc.driver"));
}
/**
* 配置JFinal插件 数据库连接池 ActiveRecordPlugin 缓存 定时任务 自定义插件
*/
@Override
public void configPlugin(Plugins me) {
loadConfig();
// 配置数据库连接池插件
DruidPlugin dbPlugin = getDruidPlugin();
dbPlugin.addFilter(new StatFilter()); // 添加 StatFilter 才会有统计数据
// 数据映射 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(dbPlugin);
arp.setShowSql(p.getBoolean("devMode"));
arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
arp.setDialect(new OracleDialect());
arp.addSqlTemplate("oracle.sql");
/******** 在此添加数据库 表-Model 映射 *********/
// 如果使用了JFinal Model 生成器 生成了BaseModel 把下面注释解开即可
_MappingKit.mapping(arp);
// 添加到插件列表中
me.add(dbPlugin);
me.add(arp);
}
/**
* 配置全局拦截器
*/
@Override
public void configInterceptor(Interceptors me) {
me.add(new JwtInterceptor());
//统一拦截错误
// me.add(new UnifiedErrorInterceptor());
//错误不会返回页面
// RenderManager.me().setRenderFactory(new ErrorRender());
}
/**
* 配置全局处理器
*/
@Override
public void configHandler(Handlers me) {
// 说明:druid的统计页面涉及安全性 需要自行处理根据登录权限判断是否能访问统计页面
// me.add(DruidKit.getDruidStatViewHandler()); // druid 统计页面功能
me.add(new UrlSkipHandler("^/services/.+", false));
me.add(new UrlSkipHandler("/*\\.ws/", false));
}
/**
* 项目启动后调用
*/
@Override
public void onStart() {
String dbType=p.get("dbType");
if(dbType==null || "".equals(dbType.trim())) {
System.out.println("数据库配置文件中dbType不能为空值");
return;
}
dbType=dbType.trim();
dbType=dbType.toUpperCase();
String configPath=PathKit.getRootClassPath()+"/DBUpdate/";
DBService dbService= new DBService();
dbService.upgrade(configPath, dbType);
}
/**
* 配置模板引擎
*/
@Override
public void configEngine(Engine me) {
// 配置模板支持热加载
me.setDevMode(p.getBoolean("engineDevMode", false));
// 这里只有选择JFinal TPL的时候才用
// 配置共享函数模板
// me.addSharedFunction("/view/common/layout.html")
}
public static void main(String[] args) {
UndertowServer.create(MainConfig.class, "undertow.properties").configWeb(builder -> {
addWebSocket(builder);
}) .start();
}
/**
* 添加websocket
* @param builder
*/
public static void addWebSocket(WebBuilder builder) {
loadConfig();
if(p.getBoolean("openMessageWebSocket") != null && p.getBoolean("openMessageWebSocket") ) {
addMessageWebSocket(builder);
}
}
/**
* 添加消息中心的websocket
* @param builder
*/
public static void addMessageWebSocket(WebBuilder builder) {
builder.addWebSocketEndpoint(MessageWebSocket.class);
}
}
package com.archser.aserver.common.config;
import com.alibaba.druid.filter.stat.StatFilter;
import com.archser.aserver.controller.BugController;
import com.archser.aserver.controller.IndexController;
import com.archser.aserver.controller.KeyController;
import com.archser.aserver.controller.MediumController;
import com.archser.aserver.controller.MenuController;
import com.archser.aserver.controller.MessageController;
import com.archser.aserver.controller.SettingController;
import com.archser.aserver.controller.SystemController;
import com.archser.aserver.controller.UserController;
import com.archser.aserver.interceptor.JwtInterceptor;
import com.archser.aserver.model._MappingKit;
import com.archser.aserver.service.DBService;
import com.archser.aserver.websocket.MessageWebSocket;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.handler.UrlSkipHandler;
import com.jfinal.json.MixedJsonFactory;
import com.jfinal.kit.PathKit;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.render.ViewType;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.server.undertow.WebBuilder;
import com.jfinal.template.Engine;
public class MainConfig extends JFinalConfig {
/**
* 将全局配置提出来 方便其他地方重用
*/
private static Prop p;
/**
* 配置JFinal常量
*/
@Override
public void configConstant(Constants me) {
// 读取数据库配置文件
loadConfig();
// 设置当前是否为开发模式
me.setDevMode(p.getBoolean("devMode"));
// 设置默认上传文件保存路径 getFile等使用
me.setBaseUploadPath("upload/temp/");
// 设置上传最大限制尺寸
// me.setMaxPostSize(1024*1024*10);
// 设置默认下载文件路径 renderFile使用
me.setBaseDownloadPath("download");
// 设置默认视图类型
me.setViewType(ViewType.JFINAL_TEMPLATE);
// 设置404渲染视图
// me.setError404View("404.html");
// 设置json工厂
me.setJsonFactory(MixedJsonFactory.me());
// 设置启用依赖注入
me.setInjectDependency(true);
}
/**
* 配置项目路由 路由拆分到 FrontRutes 与 AdminRoutes 之中配置的好处: 1:可分别配置不同的 baseViewPath 与 Interceptor
* 2:避免多人协同开发时,频繁修改此文件带来的版本冲突 3:避免本文件中内容过多,拆分后可读性增强 4:便于分模块管理路由
*/
@Override
public void configRoute(Routes me) {
// 推荐拆分方式 如果需要就解开注释 创建对应的 Routes
// me.add(new WechatRoutes());//配置微信端访问路由
// 普通不拆分的方式配置 如下
// 设置默认访问首页路由 可使用http://localhost:port 直接访问 如果80端口 port可以省略
me.add("/", IndexController.class);
me.add("/setting", SettingController.class);
me.add("/user", UserController.class);
me.add("/message", MessageController.class);
me.add("/menu", MenuController.class);
me.add("/key", KeyController.class);
me.add("/system", SystemController.class);
me.add("/bug", BugController.class);
me.add("/medium",MediumController.class);
}
// 先加载开发环境配置,再追加生产环境的少量配置覆盖掉开发环境配置
static void loadConfig() {
if (p == null) {
p = PropKit.use("config.properties").appendIfExists("config-pro.properties");
}
}
/**
* 获取数据库插件 抽取成独立的方法,便于重用该方法,减少代码冗余
*/
public static DruidPlugin getDruidPlugin() {
loadConfig();
return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"), p.get("jdbc.driver"));
}
/**
* 配置JFinal插件 数据库连接池 ActiveRecordPlugin 缓存 定时任务 自定义插件
*/
@Override
public void configPlugin(Plugins me) {
loadConfig();
// 配置数据库连接池插件
DruidPlugin dbPlugin = getDruidPlugin();
dbPlugin.addFilter(new StatFilter()); // 添加 StatFilter 才会有统计数据
// 数据映射 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(dbPlugin);
arp.setShowSql(p.getBoolean("devMode"));
arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
arp.setDialect(new OracleDialect());
arp.addSqlTemplate("oracle.sql");
/******** 在此添加数据库 表-Model 映射 *********/
// 如果使用了JFinal Model 生成器 生成了BaseModel 把下面注释解开即可
_MappingKit.mapping(arp);
// 添加到插件列表中
me.add(dbPlugin);
me.add(arp);
// 添加Redis 配置
RedisPlugin redis = new RedisPlugin("redis", PropKit.get("redis.url"), PropKit.get("redis.password"));
me.add(redis);
}
/**
* 配置全局拦截器
*/
@Override
public void configInterceptor(Interceptors me) {
me.add(new JwtInterceptor());
//统一拦截错误
// me.add(new UnifiedErrorInterceptor());
//错误不会返回页面
// RenderManager.me().setRenderFactory(new ErrorRender());
}
/**
* 配置全局处理器
*/
@Override
public void configHandler(Handlers me) {
// 说明:druid的统计页面涉及安全性 需要自行处理根据登录权限判断是否能访问统计页面
// me.add(DruidKit.getDruidStatViewHandler()); // druid 统计页面功能
me.add(new UrlSkipHandler("^/services/.+", false));
me.add(new UrlSkipHandler("/*\\.ws/", false));
}
/**
* 项目启动后调用
*/
@Override
public void onStart() {
String dbType=p.get("dbType");
if(dbType==null || "".equals(dbType.trim())) {
System.out.println("数据库配置文件中dbType不能为空值");
return;
}
dbType=dbType.trim();
dbType=dbType.toUpperCase();
String configPath=PathKit.getRootClassPath()+"/DBUpdate/";
DBService dbService= new DBService();
dbService.upgrade(configPath, dbType);
}
/**
* 配置模板引擎
*/
@Override
public void configEngine(Engine me) {
// 配置模板支持热加载
me.setDevMode(p.getBoolean("engineDevMode", false));
// 这里只有选择JFinal TPL的时候才用
// 配置共享函数模板
// me.addSharedFunction("/view/common/layout.html")
}
public static void main(String[] args) {
UndertowServer.create(MainConfig.class, "undertow.properties").configWeb(builder -> {
addWebSocket(builder);
}) .start();
}
/**
* 添加websocket
* @param builder
*/
public static void addWebSocket(WebBuilder builder) {
loadConfig();
if(p.getBoolean("openMessageWebSocket") != null && p.getBoolean("openMessageWebSocket") ) {
addMessageWebSocket(builder);
}
}
/**
* 添加消息中心的websocket
* @param builder
*/
public static void addMessageWebSocket(WebBuilder builder) {
builder.addWebSocketEndpoint(MessageWebSocket.class);
}
}
package com.archser.aserver.controller;
import java.math.BigInteger;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import com.alibaba.fastjson.JSON;
import com.archser.aserver.interceptor.JwtInterceptor;
import com.archser.aserver.model.System;
import com.archser.aserver.model.User;
import com.archser.aserver.service.LogService;
import com.archser.aserver.service.UserService;
import com.archser.aserver.util.CollectionUtil;
import com.archser.aserver.util.HttpRequestUtil;
import com.archser.aserver.util.KeysUtil;
import com.archser.aserver.util.gm.BCECUtil;
import com.archser.aserver.util.gm.SM2Util;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.spbportal.sso.SsoToken;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* IndexController 指向系统访问首页
*
* @author jbolt.cn
* @email 909854136@qq.com
* @date 2018年11月4日 下午9:02:52
*/
public class IndexController extends Controller {
/**
* 登陆用户名,密码解密
*/
public static final String PRIVATE_KEY_D = "38627fffe8003e6d2faa76d4eae2f74fd9cd7be257ab36c356c4f01bbc17e41d";
public static final ECPrivateKeyParameters USER_PRIVATE_KEY = BCECUtil.createECPrivateKeyParameters(
new BigInteger(ByteUtils.fromHexString(PRIVATE_KEY_D)), SM2Util.DOMAIN_PARAMS);
private static Log log = Log.getLog(IndexController.class);
/**
* 超期时间:24小时,即:24 * 60 * 60 * 1000
*/
private static int EXPIRATION = 24 * 60 * 60 * 1000;
private static int permitLoginTimes = 5;// 允许登陆次数
private static int hour = 2; // 两小时内不可登录
@Inject
private LogService logService;
@Inject
private UserService userService;
/**
* 首页Action
*/
public void index() {
render("index.html");
}
/**
* 修改密码
*/
public void updatePassword() {
String username = this.getPara("username");
String password = this.getPara("newPwd");
password = HashKit.sha256(password);
int a = userService.updatePwd(password, username);
if (a == 0) {
this.renderJson(Ret.fail("msg", "修改失败"));
logService.saveAsLog("operate", username, JwtInterceptor.getIpAddr(getRequest()),
username + "修改密码操作:修改密码失败", "aserver");
return;
}
this.renderJson(Ret.ok("msg", "修改成功"));
logService.saveAsLog("operate", username, JwtInterceptor.getIpAddr(getRequest()), username + "修改密码操作:修改密码成功",
"aserver");
}
private String decrypt(String sm2Cipher) throws InvalidCipherTextException {
return new String(SM2Util.decrypt(USER_PRIVATE_KEY, ByteUtils.fromHexString("04" + sm2Cipher)));
}
/**
* 登录验证
*/
@Clear(JwtInterceptor.class)
// @Before(LoginValidator.class)
public void login() {
String app = this.getPara("app");
String username = this.getPara("username");
String password = this.getPara("password");
String callback = this.getPara("callback");
// 解密用户名和密码
try {
username = decrypt(username);
password = decrypt(password);
} catch (Exception e1) {
e1.printStackTrace();
username = this.getPara("username");
password = this.getPara("password");
}
password = HashKit.sha256(password);
java.lang.System.out.println("Login: " + username);
User user = User.dao.template("getUser", username).findFirst();
if (user == null) {
this.renderJson(Ret.fail("msg", "用户名或密码不存在: " + username));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "该用户非本系统用户正在非法登录", app);
return;
}
// 一旦开启三员 admin用户不能使用
if ("admin".equals(user.getUsername())) {
Integer userCount = Db.queryInt(Db.getSql("hasThreeMemberUsersCount"));
boolean isExistThreeMemberUsers = userCount == null ? false : (userCount.intValue() > 0 ? true : false);
if (isExistThreeMemberUsers) {
this.renderJson(Ret.fail("msg", "已开启三员管理,admin失效了。"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:已开启三员管理", app);
return;
}
}
if (Integer.valueOf(user.getLocked()) == 1) {
this.renderJson(Ret.fail("msg", "当前账户已被锁定"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:该用户已被锁定", app);
return;
}
if (!password.equals(user.getPassword())) {
if (this.checkErrorCount(user)) {
this.renderJson(Ret.fail("msg", "您的错误次数已达5次以上,请稍后再试!"));
return;
} else {
int errorCount = permitLoginTimes - (user.getErrorcount() == null ? 0 : user.getErrorcount()) - 1;
if (user.getErrorcount() == 4) {
this.renderJson(Ret.fail("msg", "用户名或密码验证失败,您的账户于两小时后才可登录!"));
return;
} else {
this.renderJson(Ret.fail("msg", "用户名或密码验证失败,您还有" + errorCount + "次机会!"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:密码验证错误",
app);
return;
}
}
}
Integer errorcount = user.getErrorcount();
if (errorcount != null && errorcount != 0) {
if (!this.checkWhenPwdOk(user)) {
Date date = new Date();
long hour1 = 2 * 60 * 60;
long begin = date.getTime();
long end = user.getLastLoginTime().getTime();
long between = (begin - end) / 1000;
long hour2 = (hour1 - between) % (24 * 3600) / 3600;
long minute = (hour1 - between) % 3600 / 60;
long second = (hour1 - between) % 60;
if (between < hour1) {
this.renderJson(Ret.fail("msg", "您的账户还剩" + hour2 + "小时" + minute + "分" + second + "秒才可登录!"));
return;
}
}
}
if (!"admin".equals(user.getUsername())) {
Integer noLockedRolesCount = Db.queryInt(Db.getSql("hasNoLockedRolesCount"), user.getUsername());
boolean noLockedRolesFlag = noLockedRolesCount == null ? false
: (noLockedRolesCount.intValue() > 0 ? true : false);
if (!noLockedRolesFlag) {
this.renderJson(Ret.fail("msg", "拥有的角色全部被锁定,不能登录系统了。"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:该用户拥有的角色全部被锁定",
app);
return;
}
}
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if (system == null) {
this.renderJson(Ret.fail("msg", "没有找到应用:" + app));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:没有找到应用" + app,
app);
return;
}
if (StrKit.isBlank(system.getPrivatekey()) || StrKit.isBlank(system.getKeyid())) {
this.renderJson(Ret.fail("msg", "没有找到应用的密钥:" + app));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:没有找到应用的密钥" + app,
app);
return;
}
//查询用户是否有该系统的权限
// boolean homeAuth = userService.checkUserSystemPermission(user.getId(), app);
// if (!homeAuth) {
// this.renderJson(Ret.fail("msg", "您没有权限登录" + system.getTitle() + "系统"));
// logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:您没有权限登录此系统" + app,
// app);
// return;
// }
List<System> systemList = userService.findSystemWithUserPermission(user.getId());
/** 修改如果登陆用户为admin用户则直接登陆 huwenbin 2020/5/20 start*/
if (!"admin".equals(user.getUsername())) {
if ((systemList == null || systemList.isEmpty())) {
this.renderJson(Ret.fail("msg", "您没有权限登录" + system.getTitle() + "系统"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:您没有权限登录此系统" + app,
app);
return;
}
Optional<System> systemOptional = userService.getSystemByName(app, systemList);
if (!systemOptional.isPresent()) {// 没有当前系统的权限
system = systemList.get(0);
app = system.getName();
callback = system.getUrl();
}
}
/** 修改如果登陆用户为admin用户则直接登陆 huwenbin 2020/5/20 end */
try {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", username).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
if (errorcount != null && errorcount != 0) {
this.setErrZero(user);
}
this.renderJson(Ret.ok("token", jws).set("callback", callback));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()),
username + "登录" + app + "成功", app);
} catch (Exception e) {
log.error("生成登录票据失败", e);
this.renderJson(Ret.fail("msg", "生成登录票据失败"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "生成登录票据失败", app);
}
}
// 密码正确时错误次数清零
private void setErrZero(User user) {
Db.update(Db.getSqlPara("updateForOk", Kv.by("id", user.getId())));
}
//密码错误时判断错误次数是否为5次
private boolean checkErrorCount(User user) {
Kv cond= Kv.by("id", user.getId()).set("hour",hour).set("permitLoginTimes",permitLoginTimes);
List<Record> currentList =Db.find(Db.getSqlPara("getErrorCount",cond));
int currentNum = 0;
for (Record record : currentList) {
currentNum = Integer.parseInt(record.get("flag").toString());
}
if (currentNum >= permitLoginTimes) {
return true;
}else {
//执行+1或=1的操作
Db.update(Db.getSqlPara("updateForErr",cond));
return false;
}
}
//密码正确时判断次数和锁定时间是否在指定范围内
private boolean checkWhenPwdOk(User user) {
List<Record> currentList =Db.find(Db.getSqlPara("checkWhenPwdOk", Kv.by("id", user.getId()).set("hour",hour).set("permitLoginTimes",permitLoginTimes)));
int currentNum = 0;
if (currentList == null || currentList.size() == 0) {
return true;
}
for (Record record : currentList) {
currentNum = Integer.parseInt(record.get("flag").toString());
}
if(currentNum >= permitLoginTimes) {
return false;
}else {
return true;
}
}
/**
* 通过门户系统单点登录
*
* @author Guo XJ
* @date 2019-12-13 15:08:00
*/
public void ssoByPortalSystem() {
try {
//获取app
String app = getPara("app",null);
if(app == null) {
renderJson(Ret.fail("msg","获取服务信息失败"));
return ;
}
//获取到门户系统的Token
String ssotoken = getPara("ssotoken");
//获取到personCode(用户唯一标识)
SsoToken st = new SsoToken();
st.initialise(ssotoken);
String personCode = st.getTokenId();
//获取用户
Record user = userService.getUserInfoByPersonCode(personCode);
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if(system == null) {
renderJson(Ret.fail("msg","获取服务信息失败"));
return ;
}
//判断用户是否存在
if(user != null && user.getStr("username") != null) {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", user.getStr("username")).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
this.renderJson(Ret.ok("token", jws));
return;
}else {
this.renderJson(Ret.fail("msg","没有找到当前用户"));
return;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
this.renderJson(Ret.fail("msg","登录出错!"));
}
}
/**
* 根据邮政门户传回的code 获取用户信息
*
* @Title: getUserInfoForH5
* @author LDC
* @date 2019-11-19 03:22:34
*/
@Clear
public void getUserInfoForH5() {
String code = getPara("code", null);
if (code == null) {
renderJson(Ret.fail("msg", "获取用户信息失败"));
return;
}
String app = getPara("app", null);
if (app == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
Map<String, String> paramMap = new LinkedHashMap<String, String>();
paramMap.put("client_id", "MmEepJkH7Hiz7EtS");
paramMap.put("code", code);
paramMap.put("state", "1");
paramMap.put("grant_type", "authorization_code");
paramMap.put("scope", "scope");
paramMap.put("redirect_uri", PropKit.get("redirect_uri"));
Iterator<Entry<String, String>> entrySet = paramMap.entrySet().iterator();
StringBuilder builder = new StringBuilder();
while (entrySet.hasNext()) {
Entry<String, String> next = entrySet.next();
builder.append(next.getKey()).append("=").append(next.getValue()).append("&");
}
String param = builder.deleteCharAt(builder.length() - 1).toString();
String result = HttpRequestUtil.sendPost(PropKit.get("authUrl"), param);
Kv parseObject = JSON.parseObject(result, Kv.class);
Object access_token = parseObject.get("access_token");
if (access_token == null) {
renderJson(Ret.fail("msg", "获取授权失败,请重新登录"));
return;
}
String sendPost = HttpRequestUtil.sendPost(PropKit.get("userInfoUrl"),
"access_token=" + access_token.toString());
Kv userObj = JSON.parseObject(sendPost, Kv.class);
Object uuid = userObj.get("uuid");
if (uuid == null) {
renderJson(Ret.fail("msg", "获取用户信息失败"));
return;
}
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if (system == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
Record userInfo = Db.findById("AS_USER", "UUID", uuid.toString());
if (userInfo == null) {
renderJson(Ret.fail("msg", "没有找到当前用户"));
return;
}
String userName = userInfo.getStr("USERNAME");
if (userName == null) {
renderJson(Ret.fail("msg", "获取用户名失败"));
return;
}
try {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", userName).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
this.renderJson(Ret.ok("token", jws));
logService.saveAsLog("login", userName, JwtInterceptor.getIpAddr(getRequest()),
userName + "登录" + app + "成功", app);
} catch (Exception e) {
log.error("生成登录票据失败", e);
this.renderJson(Ret.fail("msg", "生成登录票据失败"));
logService.saveAsLog("login", userName, JwtInterceptor.getIpAddr(getRequest()), "生成登录票据失败", app);
}
}
}
package com.archser.aserver.controller;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import com.alibaba.fastjson.JSON;
import com.archser.aserver.interceptor.JwtInterceptor;
import com.archser.aserver.model.System;
import com.archser.aserver.model.User;
import com.archser.aserver.service.LogService;
import com.archser.aserver.service.UserService;
import com.archser.aserver.util.HttpRequestUtil;
import com.archser.aserver.util.KeysUtil;
import com.archser.aserver.util.gm.BCECUtil;
import com.archser.aserver.util.gm.SM2Util;
import com.jfinal.aop.Clear;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Redis;
import com.spbportal.sso.SsoToken;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
* IndexController 指向系统访问首页
*
* @author jbolt.cn
* @email 909854136@qq.com
* @date 2018年11月4日 下午9:02:52
*/
public class IndexController extends Controller {
/**
* 登陆用户名,密码解密
*/
public static final String PRIVATE_KEY_D = "38627fffe8003e6d2faa76d4eae2f74fd9cd7be257ab36c356c4f01bbc17e41d";
public static final ECPrivateKeyParameters USER_PRIVATE_KEY = BCECUtil.createECPrivateKeyParameters(
new BigInteger(ByteUtils.fromHexString(PRIVATE_KEY_D)), SM2Util.DOMAIN_PARAMS);
private static Log log = Log.getLog(IndexController.class);
/**
* 超期时间:24小时,即:24 * 60 * 60 * 1000
*/
private static int EXPIRATION = 24 * 60 * 60 * 1000;
private static int permitLoginTimes = 5;// 允许登陆次数
private static int hour = 2; // 两小时内不可登录
@Inject
private LogService logService;
@Inject
private UserService userService;
/**
* 首页Action
*/
public void index() {
render("index.html");
}
/**
* 修改密码
*/
public void updatePassword() {
String username = this.getPara("username");
String password = this.getPara("newPwd");
password = HashKit.sha256(password);
int a = userService.updatePwd(password, username);
if (a == 0) {
this.renderJson(Ret.fail("msg", "修改失败"));
logService.saveAsLog("operate", username, JwtInterceptor.getIpAddr(getRequest()),
username + "修改密码操作:修改密码失败", "aserver");
return;
}
this.renderJson(Ret.ok("msg", "修改成功"));
logService.saveAsLog("operate", username, JwtInterceptor.getIpAddr(getRequest()), username + "修改密码操作:修改密码成功",
"aserver");
}
private String decrypt(String sm2Cipher) throws InvalidCipherTextException {
return new String(SM2Util.decrypt(USER_PRIVATE_KEY, ByteUtils.fromHexString("04" + sm2Cipher)));
}
/**
* 登录验证
*/
@Clear(JwtInterceptor.class)
// @Before(LoginValidator.class)
public void login() {
String app = this.getPara("app");
String username = this.getPara("username");
String password = this.getPara("password");
String callback = this.getPara("callback");
// 解密用户名和密码
try {
username = decrypt(username);
password = decrypt(password);
} catch (Exception e1) {
e1.printStackTrace();
username = this.getPara("username");
password = this.getPara("password");
}
password = HashKit.sha256(password);
User user = User.dao.template("getUser", username).findFirst();
if (user == null) {
this.renderJson(Ret.fail("msg", "用户名或密码不存在: " + username));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "该用户非本系统用户正在非法登录", app);
return;
}
// 一旦开启三员 admin用户不能使用
if ("admin".equals(user.getUsername())) {
Integer userCount = Db.queryInt(Db.getSql("hasThreeMemberUsersCount"));
boolean isExistThreeMemberUsers = userCount == null ? false : (userCount.intValue() > 0 ? true : false);
if (isExistThreeMemberUsers) {
this.renderJson(Ret.fail("msg", "已开启三员管理,admin失效了。"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:已开启三员管理", app);
return;
}
}
if (Integer.valueOf(user.getLocked()) == 1) {
this.renderJson(Ret.fail("msg", "当前账户已被锁定"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:该用户已被锁定", app);
return;
}
if (!password.equals(user.getPassword())) {
if (this.checkErrorCount(user)) {
this.renderJson(Ret.fail("msg", "您的错误次数已达5次以上,请稍后再试!"));
return;
} else {
int errorCount = permitLoginTimes - (user.getErrorcount() == null ? 0 : user.getErrorcount()) - 1;
if (user.getErrorcount() == 4) {
this.renderJson(Ret.fail("msg", "用户名或密码验证失败,您的账户于两小时后才可登录!"));
return;
} else {
this.renderJson(Ret.fail("msg", "用户名或密码验证失败,您还有" + errorCount + "次机会!"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:密码验证错误",
app);
return;
}
}
}
Integer errorcount = user.getErrorcount();
if (errorcount != null && errorcount != 0) {
if (!this.checkWhenPwdOk(user)) {
Date date = new Date();
long hour1 = 2 * 60 * 60;
long begin = date.getTime();
long end = user.getLastLoginTime().getTime();
long between = (begin - end) / 1000;
long hour2 = (hour1 - between) % (24 * 3600) / 3600;
long minute = (hour1 - between) % 3600 / 60;
long second = (hour1 - between) % 60;
if (between < hour1) {
this.renderJson(Ret.fail("msg", "您的账户还剩" + hour2 + "小时" + minute + "分" + second + "秒才可登录!"));
return;
}
}
}
if (!"admin".equals(user.getUsername())) {
Integer noLockedRolesCount = Db.queryInt(Db.getSql("hasNoLockedRolesCount"), user.getUsername());
boolean noLockedRolesFlag = noLockedRolesCount == null ? false
: (noLockedRolesCount.intValue() > 0 ? true : false);
if (!noLockedRolesFlag) {
this.renderJson(Ret.fail("msg", "拥有的角色全部被锁定,不能登录系统了。"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:该用户拥有的角色全部被锁定",
app);
return;
}
}
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if (system == null) {
this.renderJson(Ret.fail("msg", "没有找到应用:" + app));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:没有找到应用" + app,
app);
return;
}
if (StrKit.isBlank(system.getPrivatekey()) || StrKit.isBlank(system.getKeyid())) {
this.renderJson(Ret.fail("msg", "没有找到应用的密钥:" + app));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:没有找到应用的密钥" + app,
app);
return;
}
//查询用户是否有该系统的权限
// boolean homeAuth = userService.checkUserSystemPermission(user.getId(), app);
// if (!homeAuth) {
// this.renderJson(Ret.fail("msg", "您没有权限登录" + system.getTitle() + "系统"));
// logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "登录失败,原因:您没有权限登录此系统" + app,
// app);
// return;
// }
List<System> systemList = userService.findSystemWithUserPermission(user.getId());
/** 修改如果登陆用户为admin用户则直接登陆 huwenbin 2020/5/20 start */
if (!"admin".equals(user.getUsername())) {
if ((systemList == null || systemList.isEmpty())) {
this.renderJson(Ret.fail("msg", "您没有权限登录" + system.getTitle() + "系统"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()),
"登录失败,原因:您没有权限登录此系统" + app, app);
return;
}
Optional<System> systemOptional = userService.getSystemByName(app, systemList);
if (!systemOptional.isPresent()) {// 没有当前系统的权限
system = systemList.get(0);
app = system.getName();
callback = system.getUrl();
}
}
/** 修改如果登陆用户为admin用户则直接登陆 huwenbin 2020/5/20 end */
try {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", username).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
if (errorcount != null && errorcount != 0) {
this.setErrZero(user);
}
/**
* 20200706 lidecai 将用户信息保存到Redis start
*/
Map<Object, Object> userInfo = new HashMap<>();
Iterator<Entry<String, Object>> userIterator = user._getAttrsEntrySet().iterator();
Entry<String, Object> nextAttr = null;
while(userIterator.hasNext()) {
nextAttr = userIterator.next();
userInfo.put(nextAttr.getKey().trim().toLowerCase(), nextAttr.getValue());
}
try {
Redis.use().hmset(username + "_INFO", userInfo);
// 设置过期时间
Redis.use().expire(username, 60 * 60 * 24);
}catch (Exception e) {
e.printStackTrace();
}
this.renderJson(Ret.ok("token", jws).set("callback", callback));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), username + "登录" + app + "成功", app);
/**
* 20200706 lidecai 将用户信息保存到Redis end
*/
} catch (Exception e) {
log.error("生成登录票据失败", e);
this.renderJson(Ret.fail("msg", "生成登录票据失败"));
logService.saveAsLog("login", username, JwtInterceptor.getIpAddr(getRequest()), "生成登录票据失败", app);
}
}
// 密码正确时错误次数清零
private void setErrZero(User user) {
Db.update(Db.getSqlPara("updateForOk", Kv.by("id", user.getId())));
}
//密码错误时判断错误次数是否为5次
private boolean checkErrorCount(User user) {
Kv cond = Kv.by("id", user.getId()).set("hour", hour).set("permitLoginTimes", permitLoginTimes);
List<Record> currentList = Db.find(Db.getSqlPara("getErrorCount", cond));
int currentNum = 0;
for (Record record : currentList) {
currentNum = Integer.parseInt(record.get("flag").toString());
}
if (currentNum >= permitLoginTimes) {
return true;
} else {
//执行+1或=1的操作
Db.update(Db.getSqlPara("updateForErr", cond));
return false;
}
}
//密码正确时判断次数和锁定时间是否在指定范围内
private boolean checkWhenPwdOk(User user) {
List<Record> currentList = Db.find(Db.getSqlPara("checkWhenPwdOk",
Kv.by("id", user.getId()).set("hour", hour).set("permitLoginTimes", permitLoginTimes)));
int currentNum = 0;
if (currentList == null || currentList.size() == 0) {
return true;
}
for (Record record : currentList) {
currentNum = Integer.parseInt(record.get("flag").toString());
}
if (currentNum >= permitLoginTimes) {
return false;
} else {
return true;
}
}
/**
* 通过门户系统单点登录
*
* @author Guo XJ
* @date 2019-12-13 15:08:00
*/
public void ssoByPortalSystem() {
try {
//获取app
String app = getPara("app", null);
if (app == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
//获取到门户系统的Token
String ssotoken = getPara("ssotoken");
//获取到personCode(用户唯一标识)
SsoToken st = new SsoToken();
st.initialise(ssotoken);
String personCode = st.getTokenId();
//获取用户
Record user = userService.getUserInfoByPersonCode(personCode);
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if (system == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
//判断用户是否存在
if (user != null && user.getStr("username") != null) {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", user.getStr("username")).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
this.renderJson(Ret.ok("token", jws));
return;
} else {
this.renderJson(Ret.fail("msg", "没有找到当前用户"));
return;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
this.renderJson(Ret.fail("msg", "登录出错!"));
}
}
/**
* 根据邮政门户传回的code 获取用户信息
*
* @Title: getUserInfoForH5
* @author LDC
* @date 2019-11-19 03:22:34
*/
@Clear
public void getUserInfoForH5() {
String code = getPara("code", null);
if (code == null) {
renderJson(Ret.fail("msg", "获取用户信息失败"));
return;
}
String app = getPara("app", null);
if (app == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
Map<String, String> paramMap = new LinkedHashMap<String, String>();
paramMap.put("client_id", "MmEepJkH7Hiz7EtS");
paramMap.put("code", code);
paramMap.put("state", "1");
paramMap.put("grant_type", "authorization_code");
paramMap.put("scope", "scope");
paramMap.put("redirect_uri", PropKit.get("redirect_uri"));
Iterator<Entry<String, String>> entrySet = paramMap.entrySet().iterator();
StringBuilder builder = new StringBuilder();
while (entrySet.hasNext()) {
Entry<String, String> next = entrySet.next();
builder.append(next.getKey()).append("=").append(next.getValue()).append("&");
}
String param = builder.deleteCharAt(builder.length() - 1).toString();
String result = HttpRequestUtil.sendPost(PropKit.get("authUrl"), param);
Kv parseObject = JSON.parseObject(result, Kv.class);
Object access_token = parseObject.get("access_token");
if (access_token == null) {
renderJson(Ret.fail("msg", "获取授权失败,请重新登录"));
return;
}
String sendPost = HttpRequestUtil.sendPost(PropKit.get("userInfoUrl"),
"access_token=" + access_token.toString());
Kv userObj = JSON.parseObject(sendPost, Kv.class);
Object uuid = userObj.get("uuid");
if (uuid == null) {
renderJson(Ret.fail("msg", "获取用户信息失败"));
return;
}
System system = System.dao.template("getSystemPrivatekey", app).findFirst();
if (system == null) {
renderJson(Ret.fail("msg", "获取服务信息失败"));
return;
}
Record userInfo = Db.findById("AS_USER", "UUID", uuid.toString());
if (userInfo == null) {
renderJson(Ret.fail("msg", "没有找到当前用户"));
return;
}
String userName = userInfo.getStr("USERNAME");
if (userName == null) {
renderJson(Ret.fail("msg", "获取用户名失败"));
return;
}
try {
String jws = Jwts.builder()
// 设置密匙ID
.setHeaderParam(JwsHeader.KEY_ID, system.getKeyid())
// 赋予应用
.setSubject(app)
// 签发时间
.setIssuedAt(new Date())
// 超期时间
.setExpiration(new Date(java.lang.System.currentTimeMillis() + EXPIRATION))
// 用户名
.claim("name", userName).claim("ip", JwtInterceptor.getIpAddr(getRequest()))
// 签名
.signWith(KeysUtil.privatekey(system.getPrivatekey()), SignatureAlgorithm.RS256).compact();
this.renderJson(Ret.ok("token", jws));
logService.saveAsLog("login", userName, JwtInterceptor.getIpAddr(getRequest()),
userName + "登录" + app + "成功", app);
} catch (Exception e) {
log.error("生成登录票据失败", e);
this.renderJson(Ret.fail("msg", "生成登录票据失败"));
logService.saveAsLog("login", userName, JwtInterceptor.getIpAddr(getRequest()), "生成登录票据失败", app);
}
}
/**
* 退出系统,清空Redis 中的用户信息
* @Time:2020年7月6日 - 下午5:19:58
* @author:李德才
* @param:
* @return: void
* @throws
*/
public void loginOut() {
String userName = getAttrForStr("username");
Redis.use().del(userName + "_INFO");
renderJson(Ret.ok());
}
}
......@@ -6,7 +6,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
import com.archser.aserver.interceptor.JwtInterceptor;
import com.archser.aserver.model.Config;
import com.archser.aserver.service.LogService;
import com.archser.aserver.service.SystemService;
import com.archser.aserver.validator.SettingValidator;
import com.jfinal.aop.Before;
......@@ -28,176 +30,212 @@ import sun.misc.BASE64Encoder;
@SuppressWarnings("restriction")
public class SettingController extends Controller {
/**
* 通用的获取配置方法
*
* @param name
*/
@Before(SettingValidator.class)
public void index(String name) {
String val = null;
try {
val = this.getConfig(name);
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok(name, val));
}
/**
* 获取所有配置
*/
public void all() {
this.renderJson(Ret.ok("configs", Config.dao.findAll()));
}
@Inject
private SystemService systemService;
/**
*
*/
public void findConfigList() {
String searchText = this.getPara("searchText");
List<Config> configs = systemService.findConfigList(searchText);
this.renderJson(Ret.ok("configs", configs));
}
/**
* 获取单点登录地址<br>
* 常用配置项
*/
@Clear
// @Before(UnifiedErrorInterceptor.class)
public void sso() {
String val = null;
try {
val = this.getConfig("sso");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("sso", val));
}
/**
* 获取设置信息<br>
* 常用配置项
*/
public void search() {
String val = null;
try {
val = this.getConfig("search");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("search", val));
}
/**
* 获取设置信息<br>
* 常用配置项
*/
public void logoUrl() {
String filePath = PathKit.getWebRootPath() + File.separator + "logo" + File.separator + "logo.png";
this.renderJson(Ret.ok("logoUrl", ImageToBase64(filePath)));
}
private static String ImageToBase64(String imgPath) {
byte[] data = null;
// 读取图片字节数组
try {
InputStream in = new FileInputStream(imgPath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
// 返回Base64编码过的字节数组字符串
return encoder.encode(Objects.requireNonNull(data));
// System.out.println("本地图片转换Base64:" + encoder.encode(Objects.requireNonNull(data)));
}
// public void logoUrl() {
// String val = null;
// try {
// val = this.getConfig("logoUrl");
// } catch (Exception e) {
// this.renderJson(Ret.fail("msg", e.getMessage()));
// }
// this.renderJson(Ret.ok("logoUrl", val));
// }
public void getServerName() {
String val = null;
try {
val = this.getConfig("serverName");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("serverName", val));
}
/**
* 获取配置项目
*
* @param name
* @return
* @throws Exception
*/
private String getConfig(String name) throws Exception {
String val = Db.queryStr(Db.getSql("getConfigByName"), name);
if (val == null) {
throw new Exception("配置项不存在(name='" + name + "')");
}
return val;
}
/**
* @used 添加修改配置
*/
@Before(Tx.class)
public void add() {
Config config = getModel(Config.class, "", true);
if (config == null) {
renderJson(Ret.fail("msg", "请填写完整数据"));
} else if (config.getId() == null || config.getId() == 0) {
config.set("ID", Config.SEQ_NEXTVAL);
config.save();
renderJson(Ret.ok("ok", "添加成功"));
} else if (config.getId() != 0) {
config.update();
renderJson(Ret.ok("ok", "修改成功"));
}
}
/**
* @used 删除配置
*/
@Before(Tx.class)
public void dele() {
String ids = this.getPara("ids");
String[] idsArray = ids.split(",");
if (ids == null || idsArray.length == 0) {
renderJson(Ret.fail("msg", "请选择数据"));
}
Boolean success = false;
for (String id : idsArray) {
Config config = new Config();
config.setId(Integer.valueOf(id));
success = config.delete();
}
if (success) {
renderJson(Ret.ok());
} else {
renderJson(Ret.fail("msg", "删除数据出错"));
}
}
@Inject
private LogService logService;
/**
* 通用的获取配置方法
*
* @param name
*/
@Before(SettingValidator.class)
public void index(String name) {
String val = null;
try {
val = this.getConfig(name);
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok(name, val));
}
/**
* 获取所有配置
*/
public void all() {
this.renderJson(Ret.ok("configs", Config.dao.findAll()));
}
@Inject
private SystemService systemService;
/**
*
*/
public void findConfigList() {
String searchText = this.getPara("searchText");
List<Config> configs = systemService.findConfigList(searchText);
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 start */
if (configs != null && configs.size() != 0) {
this.renderJson(Ret.ok("configs", configs));
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-查询数据包含:" + searchText + "的数据", "aserver");
} else {
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-查询数据失败", "aserver");
}
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 end */
}
/**
* 获取单点登录地址<br>
* 常用配置项
*/
@Clear
// @Before(UnifiedErrorInterceptor.class)
public void sso() {
String val = null;
try {
val = this.getConfig("sso");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("sso", val));
}
/**
* 获取设置信息<br>
* 常用配置项
*/
public void search() {
String val = null;
try {
val = this.getConfig("search");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("search", val));
}
/**
* 获取设置信息<br>
* 常用配置项
*/
public void logoUrl() {
String filePath =
PathKit.getWebRootPath() + File.separator + "logo" + File.separator + "logo.png";
this.renderJson(Ret.ok("logoUrl", ImageToBase64(filePath)));
}
private static String ImageToBase64(String imgPath) {
byte[] data = null;
// 读取图片字节数组
try {
InputStream in = new FileInputStream(imgPath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
// 返回Base64编码过的字节数组字符串
return encoder.encode(Objects.requireNonNull(data));
// System.out.println("本地图片转换Base64:" + encoder.encode(Objects.requireNonNull(data)));
}
// public void logoUrl() {
// String val = null;
// try {
// val = this.getConfig("logoUrl");
// } catch (Exception e) {
// this.renderJson(Ret.fail("msg", e.getMessage()));
// }
// this.renderJson(Ret.ok("logoUrl", val));
// }
public void getServerName() {
String val = null;
try {
val = this.getConfig("serverName");
} catch (Exception e) {
this.renderJson(Ret.fail("msg", e.getMessage()));
}
this.renderJson(Ret.ok("serverName", val));
}
/**
* 获取配置项目
*
* @param name
* @return
* @throws Exception
*/
private String getConfig(String name) throws Exception {
String val = Db.queryStr(Db.getSql("getConfigByName"), name);
if (val == null) {
throw new Exception("配置项不存在(name='" + name + "')");
}
return val;
}
/**
* @used 添加修改配置
*/
@Before(Tx.class)
public void add() {
Config config = getModel(Config.class, "", true);
Boolean success = false;
if (config == null) {
renderJson(Ret.fail("msg", "请填写完整数据"));
} else if (config.getId() == null || config.getId() == 0) {
config.set("ID", Config.SEQ_NEXTVAL);
success = config.save();
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 start */
if (success) {
renderJson(Ret.ok("ok", "添加成功"));
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-添加配置-配置名称为-" + config.getName() + "-添加成功", "aserver");
} else {
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-添加配置-配置名称为-" + config.getName() + "-添加失败", "aserver");
}
} else if (config.getId() != 0) {
success = config.update();
if (success) {
renderJson(Ret.ok("ok", "修改成功"));
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-编辑配置-配置名称为-" + config.getName() + "-修改成功", "aserver");
} else {
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-编辑配置-配置名称为-" + config.getName() + "-修改失败", "aserver");
}
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 end */
}
}
/**
* @used 删除配置
*/
@Before(Tx.class)
public void dele() {
String ids = this.getPara("ids");
String[] idsArray = ids.split(",");
if (ids == null || idsArray.length == 0) {
renderJson(Ret.fail("msg", "请选择数据"));
}
Boolean success = false;
StringBuilder sb = new StringBuilder();
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 start */
for (String id : idsArray) {
sb.append(Config.dao.findById(Integer.valueOf(id)).getName() + ",");
success = Config.dao.deleteById(Integer.valueOf(id));
}
if (success) {
renderJson(Ret.ok());
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-删除配置-配置名称为-" + sb.substring(0, sb.lastIndexOf(",")) + "-删除成功", "aserver");
} else {
renderJson(Ret.fail("msg", "删除数据出错"));
logService.saveAsLog("operate", getAttr("username"), JwtInterceptor.getIpAddr(getRequest()),
"应用管理-配置-删除配置-配置名称为-" + sb.substring(0, sb.lastIndexOf(",")) + "-删除失败", "aserver");
}
/** xiaoying 20200715 YZJ-4212 功能操作中没有应用管理的日志 end */
}
}
package com.archser.aserver.controller;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import com.archser.aserver.model.User;
import com.archser.aserver.service.UserService;
import com.jfinal.core.Controller;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
/**
* 用户相关操作
*
* @author dgq
*
*/
public class UserController extends Controller {
@Inject
UserService userService;
/**
* 获取用户信息
*/
public void info() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
user.remove("password");
this.renderJson(Ret.ok("userInfo", user));
}
/**
* 修改用户密码
*/
@SuppressWarnings("unused")
public void updatePwd() {
String username = this.getAttr("username");
String password = this.getPara("newPwd");
password = HashKit.sha256(password);
int flag = Db.update(Db.getSql("updatePassword"), password, username);
if (flag == 0) {
this.renderJson(Ret.fail("msg","修改失败"));
}
this.renderJson(Ret.ok("msg","修改成功"));
}
/**
* 修改用户
*/
public void updateUser() {
User user = this.getModel(User.class, "user", true);
if (user == null) {
renderJson("msg", "数据参数错误,请重新修改");
return;
}
boolean flag = user.update();
if (flag) {
renderJson(Ret.ok("msg", "数据修改成功!"));
return;
} else {
renderJson(Ret.fail("msg", "Error ! 请联系管理员解决。"));
}
}
/**
* 查询角色
*/
@SuppressWarnings("unused")
public void getRoleData() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
int userId = user.getId();
List<Record> records = Db.find(Db.getSql("getRolesByUserId"), userId);
List<Integer> ids = new ArrayList<Integer>();
for (Record record : records) {
ids.add(record.getInt("ROLE_ID"));
}
List<Record> dataList = Db.find(Db.getSqlPara("getRole",Kv.by("ids", ids)));
if (dataList != null) {
this.renderJson(Ret.ok("list", dataList));
} else {
this.renderJson(Ret.fail("msg", "未找到数据"));
}
}
/**
* 验证原密码输入的是否正确
*/
public void validateOldPassword() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
String oldPwd = getPara("oldPwd");
String encryptionString = HashKit.sha256(oldPwd);
if (encryptionString.equals(user.getPassword())) {
renderJson(Ret.ok());
} else {
renderJson(Ret.fail());
}
}
}
package com.archser.aserver.controller;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Inject;
import com.archser.aserver.model.User;
import com.archser.aserver.service.UserService;
import com.jfinal.core.Controller;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Redis;
/**
* 用户相关操作
*
* @author dgq
*
*/
public class UserController extends Controller {
@Inject
UserService userService;
private static final String _INFO = "_INFO";
/**
* 获取用户信息
*/
public void info() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
user.remove("password");
this.renderJson(Ret.ok("userInfo", user));
}
/**
* 修改用户密码
* @throws SQLException
*/
public void updatePwd() {
String username = this.getAttr("username");
String password = this.getPara("newPwd");
password = HashKit.sha256(password);
int flag = Db.update(Db.getSql("updatePassword"), password, username);
if (flag == 0) {
this.renderJson(Ret.fail("msg","修改失败"));
return ;
}
try {
Redis.use().hset(username+ _INFO, "password", password);
}catch (Exception e) {
e.printStackTrace();
}
this.renderJson(Ret.ok("msg","修改成功"));
}
/**
* 修改用户
*/
public void updateUser() {
User user = this.getModel(User.class, "user", true);
if (user == null) {
renderJson("msg", "数据参数错误,请重新修改");
return;
}
boolean flag = user.update();
if (flag) {
updateUserForRedis(user);
renderJson(Ret.ok("msg", "数据修改成功!"));
return;
} else {
renderJson(Ret.fail("msg", "Error ! 请联系管理员解决。"));
}
}
/**
* 修改Redis中的用户信息
*@Time:2020年7月10日 - 上午8:48:48
* @author:李德才
* @param: @param user
* @return: void
* @throws
*/
public void updateUserForRedis(User user) {
try {
Iterator<Entry<String, Object>> userIterator = user._getAttrsEntrySet().iterator();
Map<Object, Object> userMap = new HashMap<>();
Entry<String, Object> userAttr = null;
while (userIterator.hasNext()) {
userAttr = userIterator.next();
userMap.put(userAttr.getKey().toString().trim().toLowerCase(), userAttr.getValue());
}
Redis.use().hmset(user.getUsername() + _INFO, userMap);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查询角色
*/
public void getRoleData() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
int userId = user.getId();
List<Record> records = Db.find(Db.getSql("getRolesByUserId"), userId);
List<Integer> ids = new ArrayList<Integer>();
for (Record record : records) {
ids.add(record.getInt("ROLE_ID"));
}
List<Record> dataList = Db.find(Db.getSqlPara("getRole",Kv.by("ids", ids)));
if (dataList != null) {
this.renderJson(Ret.ok("list", dataList));
} else {
this.renderJson(Ret.fail("msg", "未找到数据"));
}
}
/**
* 验证原密码输入的是否正确
*/
public void validateOldPassword() {
String username = this.getAttr("username");
User user = User.dao.template("getUser", username).findFirst();
String oldPwd = getPara("oldPwd");
String encryptionString = HashKit.sha256(oldPwd);
if (encryptionString.equals(user.getPassword())) {
renderJson(Ret.ok());
} else {
renderJson(Ret.fail());
}
}
}
......@@ -764,6 +764,7 @@
alter table AS_CHECK_RECORD_RESULT add(DATASIGN1 VARCHAR2(200));
</sql>
</version>
<version edition="43" description="档案分类排序">
<sql creator="xiaoying" createDate="20200703" note="档案分类排序">
alter table AS_TREECLASSFIC add(SERIALINDEX VARCHAR2(500));
......@@ -918,7 +919,6 @@
</sql>
</version>
<version edition="45" description="ES搜索模板升级">
<sql creator="zhanglongfa" createDate="20200708" note="盘点记录详细表添加字段">
alter table AS_CHECK_RECORD_RESULT add(STATE VARCHAR2(50));
......@@ -926,11 +926,378 @@
alter table AS_CHECK_RECORD_RESULT add(LEVEL VARCHAR2(200));
alter table AS_CHECK_RECORD_RESULT add(DATASIGN VARCHAR2(200));
</sql>
</version>
<version edition="46" description="序列">
<sql creator="yangrifei" createDate="20200715" note="序列">
CREATE SEQUENCE "SEQ_AS_VIDEO_TRANSITION" INCREMENT BY 1 START WITH 1 MAXVALUE 9223372036854775807 MINVALUE 1;
</sql>
</version>
<version edition="47" description="添加全宗信息表">
<sql creator="yangchengwu" createDate="20200715" note="全宗信息表">
CREATE TABLE "AS_FOND"
(
"ID" NUMBER NOT NULL,
"FOND_ID" VARCHAR2(40),
"NAME" VARCHAR2(40),
"DESCRIPTION" VARCHAR2(255),
"ORGAN_ID" VARCHAR2(40),
"CREATE_TIME" TIMESTAMP(6),
"REMARK" VARCHAR2(255),
"IDSEQ" VARCHAR2(500),
CONSTRAINT "SYS_C0090555" NOT CLUSTER PRIMARY KEY("ID")) STORAGE(ON "MAIN", CLUSTERBTR) ;
COMMENT ON COLUMN "AS_FOND"."CREATE_TIME" IS '创建时间';
COMMENT ON COLUMN "AS_FOND"."DESCRIPTION" IS '全宗描述';
COMMENT ON COLUMN "AS_FOND"."FOND_ID" IS '全宗id';
COMMENT ON COLUMN "AS_FOND"."NAME" IS '全宗名称';
COMMENT ON COLUMN "AS_FOND"."ORGAN_ID" IS '关联机构';
COMMENT ON COLUMN "AS_FOND"."REMARK" IS '备注';
</sql>
</version>
<version edition="48" description="修改AS_VIDEO_TRANSITION表字段长度">
<sql creator="yangrifei" createDate="20200716" note="修改AS_VIDEO_TRANSITION表字段长度">
alter table AS_VIDEO_TRANSITION modify(VIDEO_KEY VARCHAR(255));
alter table AS_VIDEO_TRANSITION modify(VIDEO_VALUE VARCHAR(255));
</sql>
</version>
<version edition="49" description="编研管理专题表添加主键">
<sql creator="zhanglongfa" createDate="20200716" note="编研管理专题表添加主键">
alter table as_compilation_topic add primary key(id);
alter table as_compilation_plan add primary key(id);
</sql>
</version>
<version edition="50" description="更新统一检索高级检索搜索模板">
<sql creator="zhanglongfa" createDate="20200717" note="添加上级可查询下级全总">
delete from AS_SEARCH_TEMPLATE where key
in('advance_search_and',
'advance_search_and_original',
'advance_search_and_original_noSearchData',
'advance_search_or',
'advance_search_or_original');
insert into "AS_SEARCH_TEMPLATE" ("ID","KEY","TEMPLATE","DESCRIPTION","PARAS","INDICES") values (181, 'advance_search_and_original', '{
"_source" : {
"excludes" : ["files.*"]
},
"query" : {
"bool" : {
"must" :{
"bool": {
"must": [
{
"bool": {
"must": {
"match_phrase": {
"idseq": {
"query": "{{idseq}}"
}
}
}
}
},
{{#toJson}}searchData{{/toJson}},
{
"nested": {
"path": "files",
"query": {
"multi_match": {
"query": "{{original}}",
"type": "best_fields"
}
}
}
}
]
}
},
"filter": [
{"term" : {"business_id": "{{businessId}}"}},
{"term" : {"lib_id": "{{libId}}"}}
]
}
},
"from" : "{{from}}",
"size" : "{{size}}",
"highlight" : {
"fields" : {
"*" : {}
}
}
}', '搜索指定档案分类,类型,以及搜索项', '{
"idseq": "109.",
"libId": "881",
"original": "测试",
"size": "10",
"businessId": "2",
"from": "0",
"searchData": [
{
"match": {
"题名": "测试归档"
}
}
]
}', 'archser');
insert into "AS_SEARCH_TEMPLATE" ("ID","KEY","TEMPLATE","DESCRIPTION","PARAS","INDICES") values (44, 'advance_search_or', '{
"_source" : {
"excludes" : ["files.*"]
},
"query" : {
"bool" : {
"must" : {
"bool":{
"must" : [
{
"bool": {
"should": {{#toJson}}searchData{{/toJson}}
}
}
]
}
},
"filter": [
{
"bool": {
"should": [
{
"prefix": {
"idseq": "109."
}
},
{
"term": {
"idseq.keyword": "109."
}
}
]
}
},
{"term" : {"business_id": "{{businessId}}"}},
{"term" : {"lib_id": "{{libId}}"}}
]
}
},
"from" : "{{from}}",
"size" : "{{size}}",
"highlight" : {
"fields" : {
"*" : {}
}
}
}
', '搜索指定档案分类,类型,以及搜索项', '{
"idseq": "109.",
"businessId": "2",
"libId": "1",
"from":"0",
"size":"100",
"searchData":[{
"match": {"保管期限": "永久"}
},{
"terms": {"年度":[2017,2018,2019]}
}]
}', 'archser');
insert into "AS_SEARCH_TEMPLATE" ("ID","KEY","TEMPLATE","DESCRIPTION","PARAS","INDICES") values (45, 'advance_search_and', '{
"_source" : {
"excludes" : ["files.*"]
},
"query" : {
"bool" : {
"must" : [
{
"bool": {
"must":{{#toJson}}searchData{{/toJson}}
}
}
],
"filter": [
{
"bool": {
"should": [
{
"prefix": {
"idseq": "109."
}
},
{
"term": {
"idseq.keyword": "109."
}
}
]
}
},
{"term" : {"business_id": "{{businessId}}"}},
{"term" : {"lib_id": "{{libId}}"}}
]
}
},
"from" : "{{from}}",
"size" : "{{size}}",
"highlight" : {
"fields" : {
"*" : {}
}
}
}', '搜索指定档案分类,类型,以及搜索项', '{
"idseq": "109.",
"businessId": "1",
"libId": "1",
"from":"0",
"size":"10",
"searchData":[{
"match":{
"保管期限":"永久"
}
},{
"terms":{
"年度": [2017,2018,2019]
}
}]
}', 'archser');
insert into "AS_SEARCH_TEMPLATE" ("ID","KEY","TEMPLATE","DESCRIPTION","PARAS","INDICES") values (368, 'advance_search_or_original', '{
"_source" : {
"excludes" : ["files.*"]
},
"query" : {
"bool" : {
"must" :{
"bool": {
"must" : [
{
"bool": {
"should": [
{{#toJson}}searchData{{/toJson}},
{
"nested": {
"path": "files",
"query": {
"multi_match": {
"query": "{{original}}",
"type": "best_fields"
}
}
}
}
]
}
}
]
}
},
"filter": [
{
"bool": {
"should": [
{
"prefix": {
"idseq": "109."
}
},
{
"term": {
"idseq.keyword": "109."
}
}
]
}
},
{"term" : {"business_id": "{{businessId}}"}},
{"term" : {"lib_id": "{{libId}}"}}
]
}
},
"from" : "{{from}}",
"size" : "{{size}}",
"highlight" : {
"fields" : {
"*" : {}
}
}
}', '搜索指定档案分类,类型,以及搜索项', '{
"idseq": "109.",
"libId": "881",
"original": "测试",
"size": "10",
"businessId": "2",
"from": "0",
"searchData": [
{
"match": {
"题名": "测试归档"
}
}
]
}', 'archser');
insert into "AS_SEARCH_TEMPLATE" ("ID","KEY","TEMPLATE","DESCRIPTION","PARAS","INDICES") values (371, 'advance_search_and_original_noSearchData', '{
"_source" : {
"excludes" : ["files.*"]
},
"query" : {
"bool" : {
"must" :{
"bool": {
"must": [
{
"nested": {
"path": "files",
"query": {
"multi_match": {
"query": "{{original}}",
"type": "best_fields"
}
}
}
}
]
}
},
"filter": [
{
"bool": {
"should": [
{
"prefix": {
"idseq": "109."
}
},
{
"term": {
"idseq.keyword": "109."
}
}
]
}
},
{"term" : {"business_id": "{{businessId}}"}},
{"term" : {"lib_id": "{{libId}}"}}
]
}
},
"from" : "{{from}}",
"size" : "{{size}}",
"highlight" : {
"fields" : {
"*" : {}
}
}
}', '搜索指定档案分类,类型,以及搜索项', '{
"idseq": "109.",
"libId": "881",
"original": "测试",
"size": "10",
"businessId": "2",
"from": "0"
}', 'archser');
</sql>
</version>
<version edition="46" description="档案分类ID">
<version edition="51" description="档案分类ID">
<sql creator="guoxiaojun" createDate="20200717" note="档案分类ID">
alter table AS_IDENTIFY_TASK add CLASSIFY_ID NUMBER(9,0);
</sql>
</version>
</version>
</update>
\ No newline at end of file
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