first commit

This commit is contained in:
zc
2026-02-06 11:10:26 +08:00
commit e2bc4b3f80
898 changed files with 135230 additions and 0 deletions

46
.gitignore vendored Normal file
View File

@@ -0,0 +1,46 @@
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml

97
LICENSE Normal file
View File

@@ -0,0 +1,97 @@
<<<<<<< HEAD
MIT License
Copyright (c) 2020 若依
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=======
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
>>>>>>> e064a512bd1c86778726333606699cbb4eb2fa0a

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# fk-master
访客后台

12
bin/clean.bat Normal file
View File

@@ -0,0 +1,12 @@
@echo off
echo.
echo [<5B><>Ϣ] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>target<65><74><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

12
bin/package.bat Normal file
View File

@@ -0,0 +1,12 @@
@echo off
echo.
echo [<5B><>Ϣ] <20><><EFBFBD><EFBFBD>Web<65><62><EFBFBD>̣<EFBFBD><CCA3><EFBFBD><EFBFBD><EFBFBD>war/jar<61><72><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

14
bin/run-auth.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Auth<74><68><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-auth/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-auth.jar
cd bin
pause

14
bin/run-gateway.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Gateway<61><79><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-gateway/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-gateway.jar
cd bin
pause

14
bin/run-modules-file.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Modules-File<6C><65><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-file/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-file.jar
cd bin
pause

14
bin/run-modules-gen.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Modules-Gen<65><6E><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-gen/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-gen.jar
cd bin
pause

14
bin/run-modules-job.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Modules-Job<6F><62><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-job/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-job.jar
cd bin
pause

View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Modules-System<65><6D><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-modules/ruoyi-system/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-modules-system.jar
cd bin
pause

14
bin/run-monitor.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9>Jar<61><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Monitor<6F><72><EFBFBD>̡<EFBFBD>
echo.
cd %~dp0
cd ../ruoyi-visual/ruoyi-monitor/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar ruoyi-visual-monitor.jar
cd bin
pause

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft-api</artifactId>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dcsoft-api-system</artifactId>
<description>
dcsoft-api-system系统接口模块
</description>
<dependencies>
<!-- RuoYi Common Core-->
<dependency>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft-common-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,31 @@
package com.dcsoft.system.api;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.constant.ServiceNameConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.domain.SysAuth;
import com.dcsoft.system.api.domain.SysLogininfor;
import com.dcsoft.system.api.domain.SysOperLog;
import com.dcsoft.system.api.factory.RemoteLogFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* 日志服务
*
* @author dcsoft
*/
@FeignClient(contextId = "remoteAuthService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class)
public interface RemoteAuthService
{
/**
* 保存系统日志
*
* @param id appkey
* @param source 请求来源
* @return 结果
*/
@GetMapping("/auth/{id}")
public R<SysAuth> getAuth(@PathVariable("id") String id, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@@ -0,0 +1,63 @@
package com.dcsoft.system.api;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import com.dcsoft.common.core.constant.ServiceNameConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.domain.SysFile;
import com.dcsoft.system.api.factory.RemoteFileFallbackFactory;
/**
* 文件服务
*
* @author dcsoft
*/
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class)
public interface RemoteFileService
{
/**
* 上传文件
*
* @param file 文件信息
* @return 结果
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
/**
* 上传文件
*
* @param file 文件信息
* @return 结果
*/
@PostMapping(value = "/uploadMinio", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> uploadMinio(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName);
/**
* 上传文件
*
* @param file 文件信息
* @return 结果
*/
@PostMapping(value = "/uploadMinio1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> uploadMinio1(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName);
/**
* 上传文件
*
* @param file 文件信息
* @return 结果
*/
@PostMapping(value = "/uploadMinios", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> uploadMinios(@RequestPart(value = "file") MultipartFile file,@RequestPart(value = "fileName") String fileName);
@PostMapping(value = "/uploadMinioCar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> uploadMinioCar(@RequestPart(value = "file") MultipartFile file);
}

View File

@@ -0,0 +1,41 @@
package com.dcsoft.system.api;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.constant.ServiceNameConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.domain.SysLogininfor;
import com.dcsoft.system.api.domain.SysOperLog;
import com.dcsoft.system.api.factory.RemoteLogFallbackFactory;
/**
* 日志服务
*
* @author dcsoft
*/
@FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class)
public interface RemoteLogService
{
/**
* 保存系统日志
*
* @param sysOperLog 日志实体
* @param source 请求来源
* @return 结果
*/
@PostMapping("/operlog")
public R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 保存访问记录
*
* @param sysLogininfor 访问实体
* @param source 请求来源
* @return 结果
*/
@PostMapping("/logininfor")
public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@@ -0,0 +1,95 @@
package com.dcsoft.system.api;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.constant.ServiceNameConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.web.domain.AjaxResult;
import com.dcsoft.common.core.web.page.TableDatasInfo;
import com.dcsoft.system.api.domain.FaceStudentBody;
import com.dcsoft.system.api.domain.SysFile;
import com.dcsoft.system.api.factory.RemoteLogFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* 日志服务
*
* @author dcsoft
*/
@FeignClient(contextId = "remoteStudentService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class)
public interface RemoteStudentService
{
/**
* 保存系统日志
*
* @param source 请求来源
* @return 结果
*/
@PostMapping(value = "/student/studentList")
public TableDatasInfo studentList(@RequestBody FaceStudentBody faceStudent, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/student/gatherMonth")
public void gatherMonth(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/config/backSql")
public void backUp(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/student/gather")
public void gather(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/peopleLeave/peopleLeave")
public void peopleLeave(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 新增请假人员信息
* @param source
*/
@PostMapping(value = "/gather/saveAskForLeave")
void saveAskForLeave(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 新增补卡信息
* @param inner
*/
@PostMapping(value = "/gather/saveCardReplacement")
void saveCardReplacement(String inner);
/**
* 定时批量下发
*/
@PostMapping(value = "/sysPeople/batchDistribute")
void batchDistribute(String inner);
@PostMapping(value = "/sysBranch/saveBranchTree")
void saveBranchTree(String inner);
@PostMapping(value = "/sysPeople/saveUserInfo")
void saveUserInfo(String inner);
@PostMapping(value = "/sysBranch/saveStation")
void saveStation(String inner);
@PostMapping(value = "/sysPeople/batchDown")
void batchDown(String inner);
@PostMapping(value = "/consumeRecord/amendConsume")
void amendConsume(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/subsidyRecord/createJob")
public AjaxResult createConsumeSubsidy(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/consumeRecord/syncConsume")
void syncConsume(String inner);
@PostMapping(value = "/consumeGroup/createConsumeGroup")
void createConsumeGroup(String inner);
@PostMapping(value = "/consumePeopleDay/syncHkRecord")
public AjaxResult syncHkRecord(@RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/visitor/personHkDelete")
public AjaxResult personHkDelete(@RequestPart(value = "guid") String guid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
@PostMapping(value = "/visitor/carHkDelete")
public AjaxResult carHkDelete(@RequestPart(value = "carNo") String carNo, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@@ -0,0 +1,62 @@
package com.dcsoft.system.api;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.constant.ServiceNameConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.domain.SysUser;
import com.dcsoft.system.api.factory.RemoteUserFallbackFactory;
import com.dcsoft.system.api.model.LoginUser;
/**
* 用户服务
*
* @author dcsoft
*/
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService
{
/**
* 通过用户名查询用户信息
*
* @param username 用户名
* @param source 请求来源
* @return 结果
*/
@GetMapping("/user/info/{username}")
public R<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 注册用户信息
*
* @param sysUser 用户信息
* @param source 请求来源
* @return 结果
*/
@PostMapping("/user/register")
public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 通过用户名查询用户信息
*
* @param openid 绑定的openid
* @param source 请求来源
* @return 结果
*/
@GetMapping("/user/wxinfo/{openid}")
public R<LoginUser> getWxUserInfo(@PathVariable("openid") String openid, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
/**
* 更新openid
*
* @param sysUser 用户信息
* @return 结果
*/
@PostMapping("/user/updateOpenId")
public R<Boolean> updateOpenId(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}

View File

@@ -0,0 +1,180 @@
package com.dcsoft.system.api.domain;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.web.domain.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.File;
import java.util.Date;
/**
* 学生信息对象 face_student
*
* @author nichun
* @date 2023-03-30
*/
public class FaceStudentBody extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 学生Id */
private Long id;
/** 学工号 */
@Excel(name = "学工号")
private String stuId;
/** 姓名 */
@Excel(name = "姓名")
private String name;
/** 手机号 */
@Excel(name = "手机号")
private String phone;
/** 证件号 */
@Excel(name = "证件号")
private String idCard;
/** 图片 */
@Excel(name = "图片")
private String imgs;
private File file;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
private String pageNum;
private String pageSize;
private String label;
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getPageNum() {
return pageNum;
}
public void setPageNum(String pageNum) {
this.pageNum = pageNum;
}
public String getPageSize() {
return pageSize;
}
public void setPageSize(String pageSize) {
this.pageSize = pageSize;
}
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setStuId(String stuId)
{
this.stuId = stuId;
}
public String getStuId()
{
return stuId;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setPhone(String phone)
{
this.phone = phone;
}
public String getPhone()
{
return phone;
}
public void setIdCard(String idCard)
{
this.idCard = idCard;
}
public String getIdCard()
{
return idCard;
}
public void setImgs(String imgs)
{
this.imgs = imgs;
}
public String getImgs()
{
return imgs;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("stuId", getStuId())
.append("name", getName())
.append("phone", getPhone())
.append("idCard", getIdCard())
.append("imgs", getImgs())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@@ -0,0 +1,70 @@
package com.dcsoft.system.api.domain;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.web.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 认证数据对象 sys_auth
*
* @author nichun
* @date 2023-03-29
*/
public class SysAuth extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 访客Id */
private Long id;
/** appKey */
@Excel(name = "appKey")
private String appKey;
/** appSecret */
@Excel(name = "appSecret")
private String appSecret;
public void setId(Long id)
{
this.id = id;
}
public Long getId()
{
return id;
}
public void setAppKey(String appKey)
{
this.appKey = appKey;
}
public String getAppKey()
{
return appKey;
}
public void setAppSecret(String appSecret)
{
this.appSecret = appSecret;
}
public String getAppSecret()
{
return appSecret;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("appKey", getAppKey())
.append("appSecret", getAppSecret())
.append("remark", getRemark())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@@ -0,0 +1,215 @@
package com.dcsoft.system.api.domain;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 部门表 sys_dept
*
* @author dcsoft
*/
public class SysDept extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 部门ID */
private Long deptId;
/** 父部门ID */
private Long parentId;
/** 祖级列表 */
private String ancestors;
/** 部门名称 */
private String deptName;
/** 显示顺序 */
private Integer orderNum;
/** 负责人 */
private String leader;
/** 联系电话 */
private String phone;
/** 邮箱 */
private String email;
/** 部门状态:0正常,1停用 */
private String status;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
/** 父部门名称 */
private String parentName;
/** 同步IDaas externalId */
private String externalId;
/** 子部门 */
private List<SysDept> children = new ArrayList<SysDept>();
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
public Long getParentId()
{
return parentId;
}
public void setParentId(Long parentId)
{
this.parentId = parentId;
}
public String getAncestors()
{
return ancestors;
}
public void setAncestors(String ancestors)
{
this.ancestors = ancestors;
}
@NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
@NotNull(message = "显示顺序不能为空")
public Integer getOrderNum()
{
return orderNum;
}
public void setOrderNum(Integer orderNum)
{
this.orderNum = orderNum;
}
public String getLeader()
{
return leader;
}
public void setLeader(String leader)
{
this.leader = leader;
}
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
public String getPhone()
{
return phone;
}
public void setPhone(String phone)
{
this.phone = phone;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getParentName()
{
return parentName;
}
public void setParentName(String parentName)
{
this.parentName = parentName;
}
public List<SysDept> getChildren()
{
return children;
}
public void setChildren(List<SysDept> children)
{
this.children = children;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("deptId", getDeptId())
.append("parentId", getParentId())
.append("ancestors", getAncestors())
.append("deptName", getDeptName())
.append("orderNum", getOrderNum())
.append("leader", getLeader())
.append("phone", getPhone())
.append("email", getEmail())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.toString();
}
}

View File

@@ -0,0 +1,176 @@
package com.dcsoft.system.api.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.constant.UserConstants;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 字典数据表 sys_dict_data
*
* @author dcsoft
*/
public class SysDictData extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典编码 */
@Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
private Long dictCode;
/** 字典排序 */
@Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
private Long dictSort;
/** 字典标签 */
@Excel(name = "字典标签")
private String dictLabel;
/** 字典键值 */
@Excel(name = "字典键值")
private String dictValue;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 样式属性(其他样式扩展) */
private String cssClass;
/** 表格字典样式 */
private String listClass;
/** 是否默认Y是 N否 */
@Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
private String isDefault;
/** 状态0正常 1停用 */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictCode()
{
return dictCode;
}
public void setDictCode(Long dictCode)
{
this.dictCode = dictCode;
}
public Long getDictSort()
{
return dictSort;
}
public void setDictSort(Long dictSort)
{
this.dictSort = dictSort;
}
@NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel()
{
return dictLabel;
}
public void setDictLabel(String dictLabel)
{
this.dictLabel = dictLabel;
}
@NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue()
{
return dictValue;
}
public void setDictValue(String dictValue)
{
this.dictValue = dictValue;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass()
{
return cssClass;
}
public void setCssClass(String cssClass)
{
this.cssClass = cssClass;
}
public String getListClass()
{
return listClass;
}
public void setListClass(String listClass)
{
this.listClass = listClass;
}
public boolean getDefault()
{
return UserConstants.YES.equals(this.isDefault);
}
public String getIsDefault()
{
return isDefault;
}
public void setIsDefault(String isDefault)
{
this.isDefault = isDefault;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode())
.append("dictSort", getDictSort())
.append("dictLabel", getDictLabel())
.append("dictValue", getDictValue())
.append("dictType", getDictType())
.append("cssClass", getCssClass())
.append("listClass", getListClass())
.append("isDefault", getIsDefault())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -0,0 +1,96 @@
package com.dcsoft.system.api.domain;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 字典类型表 sys_dict_type
*
* @author dcsoft
*/
public class SysDictType extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 字典主键 */
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
private Long dictId;
/** 字典名称 */
@Excel(name = "字典名称")
private String dictName;
/** 字典类型 */
@Excel(name = "字典类型")
private String dictType;
/** 状态0正常 1停用 */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
public Long getDictId()
{
return dictId;
}
public void setDictId(Long dictId)
{
this.dictId = dictId;
}
@NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName()
{
return dictName;
}
public void setDictName(String dictName)
{
this.dictName = dictName;
}
@NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType()
{
return dictType;
}
public void setDictType(String dictType)
{
this.dictType = dictType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId())
.append("dictName", getDictName())
.append("dictType", getDictType())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -0,0 +1,64 @@
package com.dcsoft.system.api.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 文件信息
*
* @author dcsoft
*/
public class SysFile
{
/**
* 文件名称
*/
private String name;
/**
* 文件地址
*/
private String url;
/**
* 文件特征值
*/
private String feature;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getUrl()
{
return url;
}
public void setUrl(String url)
{
this.url = url;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.append("url", getUrl())
.toString();
}
}

View File

@@ -0,0 +1,102 @@
package com.dcsoft.system.api.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 系统访问记录表 sys_logininfor
*
* @author dcsoft
*/
public class SysLogininfor extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** ID */
@Excel(name = "序号", cellType = ColumnType.NUMERIC)
private Long infoId;
/** 用户账号 */
@Excel(name = "用户账号")
private String userName;
/** 状态 0成功 1失败 */
@Excel(name = "状态", readConverterExp = "0=成功,1=失败")
private String status;
/** 地址 */
@Excel(name = "地址")
private String ipaddr;
/** 描述 */
@Excel(name = "描述")
private String msg;
/** 访问时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date accessTime;
public Long getInfoId()
{
return infoId;
}
public void setInfoId(Long infoId)
{
this.infoId = infoId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getIpaddr()
{
return ipaddr;
}
public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
public Date getAccessTime()
{
return accessTime;
}
public void setAccessTime(Date accessTime)
{
this.accessTime = accessTime;
}
}

View File

@@ -0,0 +1,255 @@
package com.dcsoft.system.api.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 操作日志记录表 oper_log
*
* @author dcsoft
*/
public class SysOperLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 日志主键 */
@Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
private Long operId;
/** 操作模块 */
@Excel(name = "操作模块")
private String title;
/** 业务类型0其它 1新增 2修改 3删除 */
@Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
private Integer businessType;
/** 业务类型数组 */
private Integer[] businessTypes;
/** 请求方法 */
@Excel(name = "请求方法")
private String method;
/** 请求方式 */
@Excel(name = "请求方式")
private String requestMethod;
/** 操作类别0其它 1后台用户 2手机端用户 */
@Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
private Integer operatorType;
/** 操作人员 */
@Excel(name = "操作人员")
private String operName;
/** 部门名称 */
@Excel(name = "部门名称")
private String deptName;
/** 请求url */
@Excel(name = "请求地址")
private String operUrl;
/** 操作地址 */
@Excel(name = "操作地址")
private String operIp;
/** 请求参数 */
@Excel(name = "请求参数")
private String operParam;
/** 返回参数 */
@Excel(name = "返回参数")
private String jsonResult;
/** 操作状态0正常 1异常 */
@Excel(name = "状态", readConverterExp = "0=正常,1=异常")
private Integer status;
/** 错误消息 */
@Excel(name = "错误消息")
private String errorMsg;
/** 操作时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date operTime;
/** 消耗时间 */
@Excel(name = "消耗时间", suffix = "毫秒")
private Long costTime;
public Long getOperId()
{
return operId;
}
public void setOperId(Long operId)
{
this.operId = operId;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public Integer getBusinessType()
{
return businessType;
}
public void setBusinessType(Integer businessType)
{
this.businessType = businessType;
}
public Integer[] getBusinessTypes()
{
return businessTypes;
}
public void setBusinessTypes(Integer[] businessTypes)
{
this.businessTypes = businessTypes;
}
public String getMethod()
{
return method;
}
public void setMethod(String method)
{
this.method = method;
}
public String getRequestMethod()
{
return requestMethod;
}
public void setRequestMethod(String requestMethod)
{
this.requestMethod = requestMethod;
}
public Integer getOperatorType()
{
return operatorType;
}
public void setOperatorType(Integer operatorType)
{
this.operatorType = operatorType;
}
public String getOperName()
{
return operName;
}
public void setOperName(String operName)
{
this.operName = operName;
}
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public String getOperUrl()
{
return operUrl;
}
public void setOperUrl(String operUrl)
{
this.operUrl = operUrl;
}
public String getOperIp()
{
return operIp;
}
public void setOperIp(String operIp)
{
this.operIp = operIp;
}
public String getOperParam()
{
return operParam;
}
public void setOperParam(String operParam)
{
this.operParam = operParam;
}
public String getJsonResult()
{
return jsonResult;
}
public void setJsonResult(String jsonResult)
{
this.jsonResult = jsonResult;
}
public Integer getStatus()
{
return status;
}
public void setStatus(Integer status)
{
this.status = status;
}
public String getErrorMsg()
{
return errorMsg;
}
public void setErrorMsg(String errorMsg)
{
this.errorMsg = errorMsg;
}
public Date getOperTime()
{
return operTime;
}
public void setOperTime(Date operTime)
{
this.operTime = operTime;
}
public Long getCostTime()
{
return costTime;
}
public void setCostTime(Long costTime)
{
this.costTime = costTime;
}
}

View File

@@ -0,0 +1,241 @@
package com.dcsoft.system.api.domain;
import java.util.Set;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.web.domain.BaseEntity;
/**
* 角色表 sys_role
*
* @author dcsoft
*/
public class SysRole extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 角色ID */
@Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
private Long roleId;
/** 角色名称 */
@Excel(name = "角色名称")
private String roleName;
/** 角色权限 */
@Excel(name = "角色权限")
private String roleKey;
/** 角色排序 */
@Excel(name = "角色排序")
private Integer roleSort;
/** 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope;
/** 菜单树选择项是否关联显示( 0父子不互相关联显示 1父子互相关联显示 */
private boolean menuCheckStrictly;
/** 部门树选择项是否关联显示0父子不互相关联显示 1父子互相关联显示 */
private boolean deptCheckStrictly;
/** 角色状态0正常 1停用 */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
/** 用户是否存在此角色标识 默认不存在 */
private boolean flag = false;
/** 菜单组 */
private Long[] menuIds;
/** 部门组(数据权限) */
private Long[] deptIds;
/** 角色菜单权限 */
private Set<String> permissions;
public SysRole()
{
}
public SysRole(Long roleId)
{
this.roleId = roleId;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public boolean isAdmin()
{
return isAdmin(this.roleId);
}
public static boolean isAdmin(Long roleId)
{
return roleId != null && 1L == roleId;
}
@NotBlank(message = "角色名称不能为空")
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
public String getRoleName()
{
return roleName;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
@NotBlank(message = "权限字符不能为空")
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
public String getRoleKey()
{
return roleKey;
}
public void setRoleKey(String roleKey)
{
this.roleKey = roleKey;
}
@NotNull(message = "显示顺序不能为空")
public Integer getRoleSort()
{
return roleSort;
}
public void setRoleSort(Integer roleSort)
{
this.roleSort = roleSort;
}
public String getDataScope()
{
return dataScope;
}
public void setDataScope(String dataScope)
{
this.dataScope = dataScope;
}
public boolean isMenuCheckStrictly()
{
return menuCheckStrictly;
}
public void setMenuCheckStrictly(boolean menuCheckStrictly)
{
this.menuCheckStrictly = menuCheckStrictly;
}
public boolean isDeptCheckStrictly()
{
return deptCheckStrictly;
}
public void setDeptCheckStrictly(boolean deptCheckStrictly)
{
this.deptCheckStrictly = deptCheckStrictly;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public boolean isFlag()
{
return flag;
}
public void setFlag(boolean flag)
{
this.flag = flag;
}
public Long[] getMenuIds()
{
return menuIds;
}
public void setMenuIds(Long[] menuIds)
{
this.menuIds = menuIds;
}
public Long[] getDeptIds()
{
return deptIds;
}
public void setDeptIds(Long[] deptIds)
{
this.deptIds = deptIds;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId())
.append("roleName", getRoleName())
.append("roleKey", getRoleKey())
.append("roleSort", getRoleSort())
.append("dataScope", getDataScope())
.append("menuCheckStrictly", isMenuCheckStrictly())
.append("deptCheckStrictly", isDeptCheckStrictly())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -0,0 +1,355 @@
package com.dcsoft.system.api.domain;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.dcsoft.common.core.annotation.Excel;
import com.dcsoft.common.core.annotation.Excel.ColumnType;
import com.dcsoft.common.core.annotation.Excel.Type;
import com.dcsoft.common.core.annotation.Excels;
import com.dcsoft.common.core.web.domain.BaseEntity;
import com.dcsoft.common.core.xss.Xss;
/**
* 用户对象 sys_user
*
* @author dcsoft
*/
public class SysUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 用户ID */
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/** 部门ID */
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
/** 用户账号 */
@Excel(name = "登录名称")
private String userName;
/** 用户昵称 */
@Excel(name = "用户名称")
private String nickName;
/** 用户邮箱 */
@Excel(name = "用户邮箱")
private String email;
/** 手机号码 */
@Excel(name = "手机号码")
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/** 用户头像 */
private String avatar;
/** 密码 */
private String password;
/** 帐号状态0正常 1停用 */
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志0代表存在 2代表删除 */
private String delFlag;
/** 最后登录IP */
@Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp;
/** 最后登录时间 */
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date loginDate;
/** 部门对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
/** 角色对象 */
private List<SysRole> roles;
/** 角色组 */
private Long[] roleIds;
/** 岗位组 */
private Long[] postIds;
/** 角色ID */
private Long roleId;
private String openid;
/** 同步IDaas externalId */
private String externalId;
private Long equipmentId;
public SysUser()
{
}
public SysUser(Long userId)
{
this.userId = userId;
}
public Long getUserId()
{
return userId;
}
public void setUserId(Long userId)
{
this.userId = userId;
}
public boolean isAdmin()
{
return isAdmin(this.userId);
}
public static boolean isAdmin(Long userId)
{
return userId != null && 1L == userId;
}
public Long getDeptId()
{
return deptId;
}
public void setDeptId(Long deptId)
{
this.deptId = deptId;
}
@Xss(message = "用户昵称不能包含脚本字符")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName()
{
return nickName;
}
public void setNickName(String nickName)
{
this.nickName = nickName;
}
@Xss(message = "用户账号不能包含脚本字符")
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
@Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getAvatar()
{
return avatar;
}
public void setAvatar(String avatar)
{
this.avatar = avatar;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
public String getLoginIp()
{
return loginIp;
}
public void setLoginIp(String loginIp)
{
this.loginIp = loginIp;
}
public Date getLoginDate()
{
return loginDate;
}
public void setLoginDate(Date loginDate)
{
this.loginDate = loginDate;
}
public SysDept getDept()
{
return dept;
}
public void setDept(SysDept dept)
{
this.dept = dept;
}
public List<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> roles)
{
this.roles = roles;
}
public Long[] getRoleIds()
{
return roleIds;
}
public void setRoleIds(Long[] roleIds)
{
this.roleIds = roleIds;
}
public Long[] getPostIds()
{
return postIds;
}
public void setPostIds(Long[] postIds)
{
this.postIds = postIds;
}
public Long getRoleId()
{
return roleId;
}
public void setRoleId(Long roleId)
{
this.roleId = roleId;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public Long getEquipmentId() {
return equipmentId;
}
public void setEquipmentId(Long equipmentId) {
this.equipmentId = equipmentId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userId", getUserId())
.append("deptId", getDeptId())
.append("userName", getUserName())
.append("nickName", getNickName())
.append("email", getEmail())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("avatar", getAvatar())
.append("password", getPassword())
.append("status", getStatus())
.append("delFlag", getDelFlag())
.append("loginIp", getLoginIp())
.append("loginDate", getLoginDate())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("dept", getDept())
.toString();
}
}

View File

@@ -0,0 +1,37 @@
package com.dcsoft.system.api.factory;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.RemoteAuthService;
import com.dcsoft.system.api.domain.SysAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 日志服务降级处理
*
* @author dcsoft
*/
@Component
public class RemoteAuthFallbackFactory implements FallbackFactory<RemoteAuthService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteAuthFallbackFactory.class);
@Override
public RemoteAuthService create(Throwable throwable)
{
log.error("认证服务调用失败:{}", throwable.getMessage());
return new RemoteAuthService()
{
@Override
public R<SysAuth> getAuth(String id, String source)
{
return null;
}
};
}
}

View File

@@ -0,0 +1,59 @@
package com.dcsoft.system.api.factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.RemoteFileService;
import com.dcsoft.system.api.domain.SysFile;
/**
* 文件服务降级处理
*
* @author dcsoft
*/
@Component
public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class);
@Override
public RemoteFileService create(Throwable throwable)
{
log.error("文件服务调用失败:{}", throwable.getMessage());
return new RemoteFileService()
{
@Override
public R<SysFile> upload(MultipartFile file)
{
return R.fail("上传文件失败:" + throwable.getMessage());
}
@Override
public R<SysFile> uploadMinio(MultipartFile file,String fileName)
{
return R.fail("上传文件失败:" + throwable.getMessage());
}
@Override
public R<SysFile> uploadMinio1(MultipartFile file, String fileName) {
return null;
}
@Override
public R<SysFile> uploadMinios(MultipartFile file,String fileName)
{
return R.fail("上传文件失败:" + throwable.getMessage());
}
@Override
public R<SysFile> uploadMinioCar(MultipartFile file) {
return R.fail("上传文件失败:" + throwable.getMessage());
}
};
}
}

View File

@@ -0,0 +1,42 @@
package com.dcsoft.system.api.factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.RemoteLogService;
import com.dcsoft.system.api.domain.SysLogininfor;
import com.dcsoft.system.api.domain.SysOperLog;
/**
* 日志服务降级处理
*
* @author dcsoft
*/
@Component
public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteLogFallbackFactory.class);
@Override
public RemoteLogService create(Throwable throwable)
{
log.error("日志服务调用失败:{}", throwable.getMessage());
return new RemoteLogService()
{
@Override
public R<Boolean> saveLog(SysOperLog sysOperLog, String source)
{
return null;
}
@Override
public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
{
return null;
}
};
}
}

View File

@@ -0,0 +1,130 @@
package com.dcsoft.system.api.factory;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.web.domain.AjaxResult;
import com.dcsoft.common.core.web.page.TableDatasInfo;
import com.dcsoft.system.api.RemoteStudentService;
import com.dcsoft.system.api.domain.FaceStudentBody;
import com.dcsoft.system.api.domain.SysFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 日志服务降级处理
*
* @author dcsoft
*/
@Component
public class RemoteStudentFallbackFactory implements FallbackFactory<RemoteStudentService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteStudentFallbackFactory.class);
@Override
public RemoteStudentService create(Throwable throwable)
{
log.error("学生信息调用失败:{}", throwable.getMessage());
return new RemoteStudentService()
{
@Override
public TableDatasInfo studentList(FaceStudentBody faceStudent, String source)
{
return null;
}
@Override
public void gatherMonth(String source)
{
return ;
}
@Override
public void backUp(String source)
{
return ;
}
@Override
public void gather(String source)
{
return ;
}
@Override
public void peopleLeave(String source) {
return ;
}
@Override
public void saveAskForLeave(String source) {
}
@Override
public void saveCardReplacement(String inner) {
}
@Override
public void batchDistribute(String inner) {
}
@Override
public void saveBranchTree(String inner) {
}
@Override
public void saveUserInfo(String inner) {
}
@Override
public void saveStation(String inner) {
}
@Override
public void batchDown(String inner) {
}
@Override
public void amendConsume(String source) {
}
@Override
public AjaxResult createConsumeSubsidy(String source) {
return null;
}
@Override
public void syncConsume(String inner) {
}
@Override
public void createConsumeGroup(String inner) {
}
@Override
public AjaxResult syncHkRecord(String source) {
return null;
}
@Override
public AjaxResult personHkDelete(String guid, String source) {
return null;
}
@Override
public AjaxResult carHkDelete(String carNo, String source) {
return null;
}
};
}
}

View File

@@ -0,0 +1,53 @@
package com.dcsoft.system.api.factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.system.api.RemoteUserService;
import com.dcsoft.system.api.domain.SysUser;
import com.dcsoft.system.api.model.LoginUser;
/**
* 用户服务降级处理
*
* @author dcsoft
*/
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
@Override
public RemoteUserService create(Throwable throwable)
{
log.error("用户服务调用失败:{}", throwable.getMessage());
return new RemoteUserService()
{
@Override
public R<LoginUser> getUserInfo(String username, String source)
{
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> registerUserInfo(SysUser sysUser, String source)
{
return R.fail("注册用户失败:" + throwable.getMessage());
}
@Override
public R<LoginUser> getWxUserInfo(String openid, String source)
{
return R.fail("获取用户失败:" + throwable.getMessage());
}
@Override
public R<Boolean> updateOpenId(SysUser sysUser, String source)
{
return R.fail("绑定用户openid失败:" + throwable.getMessage());
}
};
}
}

View File

@@ -0,0 +1,150 @@
package com.dcsoft.system.api.model;
import java.io.Serializable;
import java.util.Set;
import com.dcsoft.system.api.domain.SysUser;
/**
* 用户信息
*
* @author dcsoft
*/
public class LoginUser implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* 用户唯一标识
*/
private String token;
/**
* 用户名id
*/
private Long userid;
/**
* 用户名
*/
private String username;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 角色列表
*/
private Set<String> roles;
/**
* 用户信息
*/
private SysUser sysUser;
public String getToken()
{
return token;
}
public void setToken(String token)
{
this.token = token;
}
public Long getUserid()
{
return userid;
}
public void setUserid(Long userid)
{
this.userid = userid;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public Long getLoginTime()
{
return loginTime;
}
public void setLoginTime(Long loginTime)
{
this.loginTime = loginTime;
}
public Long getExpireTime()
{
return expireTime;
}
public void setExpireTime(Long expireTime)
{
this.expireTime = expireTime;
}
public String getIpaddr()
{
return ipaddr;
}
public void setIpaddr(String ipaddr)
{
this.ipaddr = ipaddr;
}
public Set<String> getPermissions()
{
return permissions;
}
public void setPermissions(Set<String> permissions)
{
this.permissions = permissions;
}
public Set<String> getRoles()
{
return roles;
}
public void setRoles(Set<String> roles)
{
this.roles = roles;
}
public SysUser getSysUser()
{
return sysUser;
}
public void setSysUser(SysUser sysUser)
{
this.sysUser = sysUser;
}
}

View File

@@ -0,0 +1,3 @@
com.dcsoft.system.api.factory.RemoteUserFallbackFactory
com.dcsoft.system.api.factory.RemoteLogFallbackFactory
com.dcsoft.system.api.factory.RemoteFileFallbackFactory

22
dcsoft-api/pom.xml Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft</artifactId>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>dcsoft-api-system</module>
</modules>
<artifactId>dcsoft-api</artifactId>
<packaging>pom</packaging>
<description>
dcsoft-api系统接口
</description>
</project>

100
dcsoft-auth/pom.xml Normal file
View File

@@ -0,0 +1,100 @@
<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">
<parent>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft</artifactId>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dcsoft-auth</artifactId>
<description>
dcsoft-auth认证授权中心
</description>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- RuoYi Common Security-->
<dependency>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.idsmanager.dingdang</groupId>
<artifactId>jwt-sdk</artifactId>
<version>1.1.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/JWT-SDK-1.1.1_1.8.jar</systemPath>
</dependency>
<dependency>
<groupId>rg.jose4j.jwt</groupId>
<artifactId>jose4j-sdk</artifactId>
<version>0.4.3</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/jose4j-0.4.3.jar</systemPath>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,26 @@
package com.dcsoft.auth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import com.dcsoft.common.security.annotation.EnableRyFeignClients;
/**
* 认证授权中心
*
* @author dcsoft
*/
@EnableRyFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class DCSAuthApplication
{
public static void main(String[] args)
{
SpringApplication.run(com.dcsoft.auth.DCSAuthApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ \n" +
" ___ ___ ___ \n" +
" | \\ / __| / __| \n" +
" | |) | | (__ \\__ \\ \n" +
" |___/ \\___| |___/ ");
}
}

View File

@@ -0,0 +1,27 @@
package com.dcsoft.auth.bean;
import lombok.Builder;
import lombok.Data;
/**
* @author penghao
* @createDate 2022/05/10
* @createTime 10:05
*/
@Data
@Builder
public class CheckParams {
private long lastValidateTime;
private String macAddress;
private String cpuSerial;
private Long generatedTime;
private Long expiredTime;
private String version;
}

View File

@@ -0,0 +1,22 @@
package com.dcsoft.auth.bean;
import lombok.Getter;
@Getter
public enum ValidateCodeEnum {
SUCCESS(200, "验证通过"),
EXPIRED(1101, "授权已过期"),
ILLEGAL(1102, "授权码不正确"),
EXCEPTION(1103, "解析签名异常"),
FILE_NOT_EXIST(1104, "license文件不存在"),
UNAUTHORIZED(1105, "产品未授权");
private Integer code;
private String message;
ValidateCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}

View File

@@ -0,0 +1,38 @@
package com.dcsoft.auth.bean;
import lombok.Data;
@Data
public class ValidateResult {
/**
* 是否验证通过
*/
private Boolean isValidate;
/**
* 验证结果状态码
*/
private Integer code;
/**
* 验证结果信息
*/
private String message;
public static ValidateResult ok() {
ValidateResult result = new ValidateResult();
result.setIsValidate(true);
result.setCode(ValidateCodeEnum.SUCCESS.getCode());
result.setMessage(ValidateCodeEnum.SUCCESS.getMessage());
return result;
}
public static ValidateResult error(ValidateCodeEnum codeEnum) {
ValidateResult result = new ValidateResult();
result.setIsValidate(false);
result.setCode(codeEnum.getCode());
result.setMessage(codeEnum.getMessage());
return result;
}
}

View File

@@ -0,0 +1,184 @@
package com.dcsoft.auth.controller;
import com.dcsoft.auth.service.SysAuthService;
import com.dcsoft.common.core.constant.CacheConstants;
import com.dcsoft.common.core.utils.JwtUtils;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.core.web.domain.AjaxResult;
import com.dcsoft.common.core.web.page.TableDatasInfo;
import com.dcsoft.common.redis.service.RedisService;
import com.dcsoft.system.api.domain.FaceStudentBody;
import com.dcsoft.system.api.domain.SysAuth;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* token 控制
*
* @author dcsoft
*/
@RestController
@RequestMapping("/face-api")
public class ApiController
{
@Autowired
private RedisService redisService;
@Autowired
private SysAuthService sysAuthService;
/**
* 鉴权接口
*/
@GetMapping("/auth")
public AjaxResult auth(HttpServletRequest request)
{
String timestamp=request.getHeader("timestamp");
String appKey=request.getHeader("appKey");
String sign=request.getHeader("sign");
if(StringUtils.isEmpty(timestamp)){
return AjaxResult.error("timestamp is empty");
}
Long timeLong=new Date().getTime()/1000-Long.parseLong(timestamp);
if(timeLong>5*60){
return AjaxResult.error("timestamp is timeOut");
}
if(StringUtils.isEmpty(appKey)){
return AjaxResult.error("appKey is empty");
}
if(StringUtils.isEmpty(sign)){
return AjaxResult.error("sign is empty");
}
//appSecret通过后台获取
SysAuth auth=sysAuthService.getAuth(appKey);
String appSecret=auth.getAppSecret();
String sign1= EncodeByMD5(appKey+timestamp+appSecret).toLowerCase();
//比较两次秘钥的sign的值是否一致
if(sign.equals(sign1)){
//根据appKey生成token
// Jwt存储信息
Map<String, Object> claimsMap = new HashMap<String, Object>();
String verifyKey = CacheConstants.AUTH_KEY + appKey;
claimsMap.put(CacheConstants.AUTH_KEY, appKey);
String token =JwtUtils.createToken(claimsMap);
redisService.setCacheObject(verifyKey,token);
redisService.expire(verifyKey,24*60*60);
return AjaxResult.success("token get success",token);
}else{
return AjaxResult.error("sign create error");
}
}
/**
* 人脸信息接口
*/
@PostMapping("/faceInfo")
public TableDatasInfo faceInfo(HttpServletRequest request)
{
TableDatasInfo msg=new TableDatasInfo();
String token=request.getHeader("token");
Boolean flag=validate(token);
if(flag){
String phone=request.getParameter("phone");
String idCard=request.getParameter("id_card");
String label=request.getParameter("label");
String pageNum=request.getParameter("pageNum");
String pageSize=request.getParameter("pageSize");
if(StringUtils.isEmpty(pageNum)){
pageNum="1";
}
if(StringUtils.isEmpty(pageSize)){
pageSize="10";
}
String endTime=request.getParameter("endTime");
String startTime=request.getParameter("startTime");
FaceStudentBody faceStudent=new FaceStudentBody();
faceStudent.setPhone(phone);
faceStudent.setIdCard(idCard);
faceStudent.setPageNum(pageNum);
faceStudent.setPageSize(pageSize);
faceStudent.setLabel(label);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-HH-mm");
try {
if(StringUtils.isNotEmpty(startTime)){
faceStudent.setStartTime(sdf.parse(startTime));
}
if(StringUtils.isNotEmpty(endTime)){
faceStudent.setEndTime(sdf.parse(endTime));
}
} catch (ParseException e) {
throw new RuntimeException(e);
}
msg=sysAuthService.studentList(faceStudent);
}else{
msg.setCode(500);
msg.setMsg("token is timeOut or is error");
}
return msg;
}
public Boolean validate(String token){
if (StringUtils.isEmpty(token)){
return false;
}
Claims claims = JwtUtils.parseToken(token);
if (claims == null)
{
return false;
}
String appKey=JwtUtils.getValue(claims,CacheConstants.AUTH_KEY);
//所有请求 token 及其他参数都写在 header 中
String verifyKey = CacheConstants.AUTH_KEY + appKey;
String tokens = redisService.getCacheObject(verifyKey);
if(StringUtils.isEmpty(tokens)) {//重新获取token
return false;
}
if(token.equals(tokens)){
return true;
}else{
return false;
}
}
/**
* 对字符串进行32位MD5加密
* @param str
* @return
*/
public static String EncodeByMD5(String str) {
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes("UTF-8"));
// digest()最后确定返回md5 hash值返回值为8为字符串。因为md5 hash值是16位的hex值实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值用字符串来表示得到字符串形式的hash值
String md5=new BigInteger(1, md.digest()).toString(16);
//BigInteger会把0省略掉需补全至32位
return fillMD5(md5);
} catch (Exception e) {
throw new RuntimeException("MD5加密错误:"+e.getMessage(),e);
}
}
private static String fillMD5(String md5) {
//如果不够32位则回调自身补零最后返回32位长度的签名
return md5.length() == 32 ? md5 : fillMD5("0" + md5);
}
}

View File

@@ -0,0 +1,206 @@
package com.dcsoft.auth.controller;
import javax.servlet.http.HttpServletRequest;
import com.dcsoft.auth.bean.ValidateResult;
import com.dcsoft.auth.form.IDaasBody;
import com.dcsoft.auth.utils.LicenseManager;
import com.dcsoft.auth.utils.LicenseThread;
import com.idsmanager.dingdang.jwt.DingdangUserRetriever;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import com.dcsoft.auth.form.LoginBody;
import com.dcsoft.auth.form.RegisterBody;
import com.dcsoft.auth.service.SysLoginService;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.utils.JwtUtils;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.security.auth.AuthUtil;
import com.dcsoft.common.security.service.TokenService;
import com.dcsoft.common.security.utils.SecurityUtils;
import com.dcsoft.system.api.model.LoginUser;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
/**
* token 控制
*
* @author dcsoft
*/
@RestController
public class TokenController
{
@Autowired
private TokenService tokenService;
@Autowired
private SysLoginService sysLoginService;
@Value("${license.enabled}")
private Boolean enabled;
@PostMapping("login")
public R<?> login(@RequestBody LoginBody form)
{
/* if(enabled){
ValidateResult validateResult = LicenseThread.validateResult.get("Authorize");
if (!validateResult.getIsValidate()){
return R.fail(validateResult.getMessage());
}
}*/
LoginUser userInfo=new LoginUser();
// 用户登录
if("weixin".equals(form.getFlag())){
R<LoginUser> userInfos=sysLoginService.getWxUserInfo(form);
//userInfo=sysLoginService.login(form.getUsername());
userInfo = userInfos.getData();
if(userInfo==null){
R.fail();
}
}else if("app".equals(form.getFlag())){
userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
//保存用户openid
if(StringUtils.isNotEmpty(form.getOpenid())){
sysLoginService.updateOpenId(userInfo,form);
}
}else{
userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
}
// 获取登录token
return R.ok(tokenService.createToken(userInfo));
}
@PostMapping("app")
public R<?> app(@RequestBody LoginBody form)
{
/* if(enabled){
ValidateResult validateResult = LicenseThread.validateResult.get("Authorize");
if (!validateResult.getIsValidate()){
return R.fail(validateResult.getMessage());
}
}*/
LoginUser userInfo=new LoginUser();
// 用户登录
if("weixin".equals(form.getFlag())){
R<LoginUser> userInfos=sysLoginService.getWxUserInfo(form);
userInfo = userInfos.getData();
if(userInfo==null){
R.fail();
}
}else if("app".equals(form.getFlag())){
userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
//保存用户openid
if(!"".equals(form.getOpenid())){
sysLoginService.updateOpenId(userInfo,form);
}
}else{
userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
}
// 获取登录token
return R.ok(tokenService.createToken(userInfo));
}
@DeleteMapping("logout")
public R<?> logout(HttpServletRequest request)
{
String token = SecurityUtils.getToken(request);
if (StringUtils.isNotEmpty(token))
{
String username = JwtUtils.getUserName(token);
// 删除用户缓存记录
AuthUtil.logoutByToken(token);
// 记录用户退出日志
sysLoginService.logout(username);
}
return R.ok();
}
@PostMapping("refresh")
public R<?> refresh(HttpServletRequest request)
{
LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser))
{
// 刷新令牌有效期
tokenService.refreshToken(loginUser);
return R.ok();
}
return R.ok();
}
@PostMapping("register")
public R<?> register(@RequestBody RegisterBody registerBody)
{
// 用户注册
sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
return R.ok();
}
/* @PostMapping("validate")
public R<?> validate(@RequestBody IDaasBody iDaasBody)
{
String name= null;
try {
name = checkUsername(iDaasBody.getIdToken());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
LoginUser userInfo=new LoginUser();
// 用户登录
userInfo = sysLoginService.login(name);
// 获取登录token
return R.ok(tokenService.createToken(userInfo));
}*/
/* private String checkUsername(String id_token) throws
UnsupportedEncodingException {
//1.使⽤公钥解析id_token使⽤publicKey解密上⼀步获取的id_token令牌
DingdangUserRetriever retriever = new DingdangUserRetriever(id_token,publickey);
DingdangUserRetriever.User user = null;
try {
//2.获取⽤户信息
user = retriever.retrieve();
} catch (Exception e) {
return "error";
}
//3.如果publicKey不正确或者id_token过期获取到的⽤户信息可能为null
if (null == user) {
return "error";
}
//4.获取到⽤户信息检测⽤户名是否存在⾃⼰的业务系统中isExistedUsername⽅法为示例实现
if (StringUtils.isNotEmpty(user.getUsername())) {
return user.getUsername();
} else {
//8.如果不存在,返回登录失败⻚⾯,提示⽤户不存在
return "error";
}
}*/
//获取服务器标识接口
@GetMapping("/getServerID")
public Map<String,Object> getServerID(){
Map<String,Object> retMap=new HashMap<>(2);
retMap.put("code","200");
retMap.put("serverID", LicenseManager.getSystemSign());
return retMap;
}
//授权码更新接口
@PostMapping("/updateSign")
public Map<String,Object> updateSign(String sign){
Map<String,Object> retMap=new HashMap<>(2);
LicenseManager.updateSign(sign);
LicenseThread.validateAfterUpdateSign();
retMap.put("code","200");
retMap.put("msg","激活成功!");
return retMap;
}
}

View File

@@ -0,0 +1,35 @@
package com.dcsoft.auth.form;
/**
* 用户登录对象
*
* @author dcsoft
*/
public class AuthBody
{
/**
* appKey
*/
private String appKey;
/**
* appSecret
*/
private String appSecret;
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
}

View File

@@ -0,0 +1,35 @@
package com.dcsoft.auth.form;
/**
* 用户登录对象
*
* @author dcsoft
*/
public class IDaasBody
{
/**
* idToken
*/
private String idToken;
/**
* targetUrl
*/
private String targetUrl;
public String getIdToken() {
return idToken;
}
public void setIdToken(String idToken) {
this.idToken = idToken;
}
public String getTargetUrl() {
return targetUrl;
}
public void setTargetUrl(String targetUrl) {
this.targetUrl = targetUrl;
}
}

View File

@@ -0,0 +1,74 @@
package com.dcsoft.auth.form;
/**
* 用户登录对象
*
* @author dcsoft
*/
public class LoginBody
{
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 登录方式
* **/
private String flag;
/**
* 微信openid
* **/
private String openid;
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
@Override
public String toString() {
return "LoginBody{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", flag='" + flag + '\'' +
", openid='" + openid + '\'' +
'}';
}
}

View File

@@ -0,0 +1,11 @@
package com.dcsoft.auth.form;
/**
* 用户注册对象
*
* @author dcsoft
*/
public class RegisterBody extends LoginBody
{
}

View File

@@ -0,0 +1,45 @@
package com.dcsoft.auth.service;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.web.page.TableDatasInfo;
import com.dcsoft.system.api.RemoteAuthService;
import com.dcsoft.system.api.RemoteStudentService;
import com.dcsoft.system.api.domain.FaceStudentBody;
import com.dcsoft.system.api.domain.SysAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 登录校验方法
*
* @author dcsoft
*/
@Component
public class SysAuthService
{
@Autowired
private RemoteAuthService remoteAuthService;
@Autowired
private RemoteStudentService remoteStudentService;
public SysAuth getAuth(String appKey)
{
// 查询用户信息
R<SysAuth> userResult = remoteAuthService.getAuth(appKey, SecurityConstants.INNER);
return userResult.getData();
}
public TableDatasInfo studentList(FaceStudentBody faceStudent)
{
// 查询用户信息
TableDatasInfo userResult = remoteStudentService.studentList(faceStudent, SecurityConstants.INNER);
return userResult;
}
}

View File

@@ -0,0 +1,212 @@
package com.dcsoft.auth.service;
import com.dcsoft.auth.form.LoginBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.dcsoft.common.core.constant.CacheConstants;
import com.dcsoft.common.core.constant.Constants;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.constant.UserConstants;
import com.dcsoft.common.core.domain.R;
import com.dcsoft.common.core.enums.UserStatus;
import com.dcsoft.common.core.exception.ServiceException;
import com.dcsoft.common.core.text.Convert;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.core.utils.ip.IpUtils;
import com.dcsoft.common.redis.service.RedisService;
import com.dcsoft.common.security.utils.SecurityUtils;
import com.dcsoft.system.api.RemoteUserService;
import com.dcsoft.system.api.domain.SysUser;
import com.dcsoft.system.api.model.LoginUser;
/**
* 登录校验方法
*
* @author dcsoft
*/
@Component
public class SysLoginService
{
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private SysPasswordService passwordService;
@Autowired
private SysRecordLogService recordLogService;
@Autowired
private RedisService redisService;
/**
* 登录
*/
public LoginUser login(String username, String password)
{
// 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
throw new ServiceException("用户/密码必须填写");
}
// 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
throw new ServiceException("用户密码不在指定范围");
}
// 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
throw new ServiceException("用户名不在指定范围");
}
// IP黑名单校验
String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾访问IP已被列入系统黑名单");
throw new ServiceException("很遗憾访问IP已被列入系统黑名单");
}
// 查询用户信息
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
passwordService.validate(user, password);
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
return userInfo;
}
public void logout(String loginName)
{
recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功");
}
/**
* 注册
*/
public void register(String username, String password)
{
// 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password))
{
throw new ServiceException("用户/密码必须填写");
}
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
throw new ServiceException("账户长度必须在2到20个字符之间");
}
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
throw new ServiceException("密码长度必须在5到20个字符之间");
}
// 注册用户信息
SysUser sysUser = new SysUser();
sysUser.setUserName(username);
sysUser.setNickName(username);
sysUser.setPassword(SecurityUtils.encryptPassword(password));
R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
if (R.FAIL == registerResult.getCode())
{
throw new ServiceException(registerResult.getMsg());
}
recordLogService.recordLogininfor(username, Constants.REGISTER, "注册成功");
}
/**
* 登录
*/
public LoginUser login(String username)
{
// 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
throw new ServiceException("用户名不在指定范围");
}
// IP黑名单校验
String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾访问IP已被列入系统黑名单");
throw new ServiceException("很遗憾访问IP已被列入系统黑名单");
}
// 查询用户信息
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
return userInfo;
}
public void updateOpenId(LoginUser userInfo, LoginBody form) {
// 注册用户信息
SysUser sysUser = new SysUser();
sysUser=userInfo.getSysUser();
sysUser.setUserName(form.getUsername());
sysUser.setOpenid(form.getOpenid());
R<?> registerResult = remoteUserService.updateOpenId(sysUser, SecurityConstants.INNER);
if (R.FAIL == registerResult.getCode())
{
throw new ServiceException(registerResult.getMsg());
}
}
public R<LoginUser> getWxUserInfo(LoginBody form) {
R<LoginUser> registerResult = remoteUserService.getWxUserInfo(form.getOpenid(), SecurityConstants.INNER);
return registerResult;
}
}

View File

@@ -0,0 +1,85 @@
package com.dcsoft.auth.service;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.dcsoft.common.core.constant.CacheConstants;
import com.dcsoft.common.core.constant.Constants;
import com.dcsoft.common.core.exception.ServiceException;
import com.dcsoft.common.redis.service.RedisService;
import com.dcsoft.common.security.utils.SecurityUtils;
import com.dcsoft.system.api.domain.SysUser;
/**
* 登录密码方法
*
* @author dcsoft
*/
@Component
public class SysPasswordService
{
@Autowired
private RedisService redisService;
private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;
private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;
@Autowired
private SysRecordLogService recordLogService;
/**
* 登录账户密码错误次数缓存键名
*
* @param username 用户名
* @return 缓存键key
*/
private String getCacheKey(String username)
{
return CacheConstants.PWD_ERR_CNT_KEY + username;
}
public void validate(SysUser user, String password)
{
String username = user.getUserName();
Integer retryCount = redisService.getCacheObject(getCacheKey(username));
if (retryCount == null)
{
retryCount = 0;
}
if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{
String errMsg = String.format("密码输入错误%s次帐户锁定%s分钟", maxRetryCount, lockTime);
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL,errMsg);
throw new ServiceException(errMsg);
}
if (!matches(user, password))
{
retryCount = retryCount + 1;
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
redisService.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new ServiceException("用户不存在/密码错误");
}
else
{
clearLoginRecordCache(username);
}
}
public boolean matches(SysUser user, String rawPassword)
{
return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
}
public void clearLoginRecordCache(String loginName)
{
if (redisService.hasKey(getCacheKey(loginName)))
{
redisService.deleteObject(getCacheKey(loginName));
}
}
}

View File

@@ -0,0 +1,48 @@
package com.dcsoft.auth.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.dcsoft.common.core.constant.Constants;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.utils.StringUtils;
import com.dcsoft.common.core.utils.ip.IpUtils;
import com.dcsoft.system.api.RemoteLogService;
import com.dcsoft.system.api.domain.SysLogininfor;
/**
* 记录日志方法
*
* @author dcsoft
*/
@Component
public class SysRecordLogService
{
@Autowired
private RemoteLogService remoteLogService;
/**
* 记录登录信息
*
* @param username 用户名
* @param status 状态
* @param message 消息内容
* @return
*/
public void recordLogininfor(String username, String status, String message)
{
SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(username);
logininfor.setIpaddr(IpUtils.getIpAddr());
logininfor.setMsg(message);
// 日志状态
if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
{
logininfor.setStatus(Constants.LOGIN_SUCCESS_STATUS);
}
else if (Constants.LOGIN_FAIL.equals(status))
{
logininfor.setStatus(Constants.LOGIN_FAIL_STATUS);
}
remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
}
}

View File

@@ -0,0 +1,108 @@
package com.dcsoft.auth.test;
import com.dcsoft.auth.utils.AESUtils;
import com.dcsoft.auth.utils.DateUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;
/**
* @author penghao
* @Description 生成签名
* @createDate 2022/05/05
* @createTime 17:41
*/
public class CreateSign {
public static void main(String[] args) {
//系统标识---由mac地址+cpu序列号 使用AES加密而来
// String systemSign = "1jfNqzhz66e8egvhsONUXJMDNalNPTLWDO1lLBetwck=";
//生效起始时间
// String generatedTimeStr = "2022-05-09 00:00:00";
//生效截止时间
// String expiredTimeStr = "2022-05-11 00:00:00";
//上一次校验时间(初始值)
// String lastValidateTimeStr = "2022-05-09 00:00:01";
//项目部署序列号(版本标识)
// String version = "dmoiji3xkoa4p33";
//license生成路径
// String path = "C:\\Users\\Administrator\\Desktop\\license.xml";
System.out.println(" mac地址+cpu序列号");
Scanner sc1 = new Scanner(System.in);
String signBuilder = sc1.nextLine();
String sign = AESUtils.encrypt(signBuilder);
System.out.println("mac地址+cpu序列号 AES加密生成签名"+sign);
Scanner sc = new Scanner(System.in);
System.out.println("请输入系统标识串(部署的服务获取):");
String systemSign = sc.nextLine();
System.out.println("请输入生效起始时间格式如2022-05-05 00:00:00");
String generatedTimeStr = sc.nextLine();
System.out.println("请输入生效截止时间格式如2022-05-05 00:00:00");
String expiredTimeStr = sc.nextLine();
System.out.println("请输入上一次校验时间初始值格式如2022-05-05 00:00:00");
String lastValidateTimeStr = sc.nextLine();
System.out.println("请输入项目部署唯一版本号(不能带“-”):");
String version = sc.nextLine();
System.out.println("请输入license文件生成路径");
String path = sc.nextLine();
createLicense(systemSign, generatedTimeStr, expiredTimeStr, lastValidateTimeStr, version, path);
System.out.println("license文件生成成功文件路径" + path);
}
private static void createLicense(String systemSign, String generatedTimeStr, String expiredTimeStr, String lastValidateTimeStr, String version, String path) {
try {
//解密系统标识得到mac地址+cpu序列号
String macAndCpu = AESUtils.decrypt(systemSign);
System.out.println("客户服务器mac地址和cpu序列号" + macAndCpu);
//MAC复制-CPU序列号-生效起始时间-生效结束结束时间-软件产品序列号(项目版本唯一标识)
// String content = "A8:A1:59:41:89:36-BFEBFBFF000906EA-20220506-20220507-dmoiji3xkoa4p33";
StringBuilder signBuilder = new StringBuilder(macAndCpu);
//生效起始时间
long generatedTime = DateUtils.getTimeInMillis(generatedTimeStr);
//生效截止时间
long expiredTime = DateUtils.getTimeInMillis(expiredTimeStr);
//项目唯一标识
signBuilder.append("-").append(generatedTime).append("-").append(expiredTime).append("-").append(version);
String sign = AESUtils.encrypt(signBuilder.toString());
System.out.println("AES加密生成签名");
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.println(sign);
System.out.println("-----------------------------------------------------------------------------------------------");
//生成licence文件
Document document = DocumentHelper.createDocument();
//根节点
Element rootEle = document.addElement("license");
//功能数据节点,扩展参数时可在此节点下扩展
Element dataEle = rootEle.addElement("features");
Element featureEle = dataEle.addElement("feature");
featureEle.addAttribute("name", "lastValidateTi");
featureEle.addAttribute("ti", AESUtils.encrypt(String.valueOf(DateUtils.getTimeInMillis(lastValidateTimeStr))));
//签名节点
Element signEle = rootEle.addElement("signature");
signEle.setText(sign);
System.out.println(document.asXML());
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置编码格式
format.setEncoding("UTF-8");
FileWriter fileWriter = new FileWriter(new File(path));
XMLWriter xmlWriter = new XMLWriter(fileWriter, format);
// 设置是否转义,默认使用转义字符
xmlWriter.setEscapeText(false);
xmlWriter.write(document);
xmlWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,97 @@
package com.dcsoft.auth.utils;
import org.springframework.util.Base64Utils;
import javax.crypto.KeyGenerator;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
/**
* @version V1.0
* @desc AES 加密工具类
*/
public class AESUtils {
/**
* RSA加密后的AES秘钥
*/
private static String aesEncyptPwd="ZIkun+KvXFWLZLYUwXqFWazQeRe119AkcGcl+p8Erzi4EEaHBFYcQuGuKthIE+1IWSQxoUpUJkT0T1+xtoRi3txDnBikdrFhccGZdRpqwRv58q5nqxJX4wVrq0Ms02KBKgQRTqqlzfYLzQcYPyhv8KPE8JDVkttic+W+j5pFles=";
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* AES 加密操作
*
* @param content 待加密内容
* @return 返回Base64转码后的加密数据
*/
public static String encrypt(String content) {
try {
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
byte[] byteContent = content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(RSAUtils.decrypt(aesEncyptPwd)));
byte[] result = cipher.doFinal(byteContent);
return Base64Utils.encodeToString(result);
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("AES加密失败");
}
return null;
}
/**
* AES 解密操作
*
* @param content 已加密内容
* @return
*/
public static String decrypt(String content) {
try {
//实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(RSAUtils.decrypt(aesEncyptPwd)));
//执行操作
byte[] result = cipher.doFinal(Base64Utils.decodeFromString(content));
return new String(result, "utf-8");
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("AES解密失败");
}
return null;
}
/**
* 生成加密秘钥
*
* @return
*/
private static SecretKeySpec getSecretKey(String aesKey) {
//返回生成指定算法密钥生成器的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
//AES 要求密钥长度为 128
SecureRandom random=SecureRandom.getInstance("SHA1PRNG","SUN");
random.setSeed(aesKey.getBytes());
kg.init(128, random);
//生成一个密钥
SecretKey secretKey = kg.generateKey();
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
System.out.println("生成加密秘钥失败");
} catch (NoSuchProviderException e) {
e.printStackTrace();
System.out.println("生成加密秘钥失败");
}
return null;
}
}

View File

@@ -0,0 +1,28 @@
package com.dcsoft.auth.utils;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @author penghao
* @Description TODO
* @createDate 2022/05/09
* @createTime 13:27
*/
public class DateUtils {
public static Long getTimeInMillis(String formatTime){
try {
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=format.parse(formatTime);
Calendar calendar=Calendar.getInstance();
calendar.setTime(date);
return calendar.getTimeInMillis();
}catch (Exception e){
e.printStackTrace();
System.out.println("日期转换失败");
}
return 0L;
}
}

View File

@@ -0,0 +1,54 @@
package com.dcsoft.auth.utils;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
/**
* @Description 生成公钥私钥对
* @createDate 2022/05/05
* @createTime 14:25
*/
public class KeyGenerator {
/**
* 私钥
*/
private static byte[] privateKey;
/**
* 公钥
*/
private static byte[] publicKey;
/**
* 加密算法
*/
private static final String KEY_ALGORITHM = "RSA";
public void generater() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.genKeyPair();
RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();
privateKey = Base64.getEncoder().encode(priKey.getEncoded());
publicKey = Base64.getEncoder().encode(pubKey.getEncoded());
System.out.println("公钥:" + new String(publicKey));
System.out.println("私钥:" + new String(privateKey));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.out.println("生成密钥对失败!");
}
}
public static void main(String[] args) {
KeyGenerator keyGenerator = new KeyGenerator();
keyGenerator.generater();
}
}

View File

@@ -0,0 +1,167 @@
package com.dcsoft.auth.utils;
import com.dcsoft.auth.bean.CheckParams;
import com.dcsoft.auth.bean.ValidateCodeEnum;
import com.dcsoft.auth.bean.ValidateResult;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author PH
*/
@Slf4j
@Component
public class LicenseManager {
public static Map<String, ValidateResult> validate() {
Map<String, ValidateResult> result = new HashMap<>();
CheckParams checkParams = null;
try {
checkParams = getCheckParams(result);
if (checkParams == null) {
return result;
}
} catch (Exception e) {
e.printStackTrace();
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.EXCEPTION));
return result;
}
//校验mac地址
if (!checkParams.getMacAddress().equals(Systemutils.getMacAddress())) {
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.UNAUTHORIZED));
return result;
}
//校验cpu序列号
if (!checkParams.getCpuSerial().equals(Systemutils.getCpuNum())) {
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.UNAUTHORIZED));
return result;
}
long currentTi = System.currentTimeMillis();
//校验时间
if (notAfterLastValidateTime(checkParams.getLastValidateTime(), currentTi) || notAfter(checkParams.getGeneratedTime(), currentTi)
|| notBefore(checkParams.getExpiredTime(), currentTi)) {
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.EXPIRED));
return result;
}
result.put("Authorize", ValidateResult.ok());
return result;
}
public static String getSystemSign() {
String MacAddress = Systemutils.getMacAddress();
String cpuNum = Systemutils.getCpuNum();
return AESUtils.encrypt(MacAddress + "-" + cpuNum);
}
public static void updateSign(String sign) {
try {
Document document = readLicense();
Element rootElement = document.getRootElement();
Element signatureEle = rootElement.element("signature");
signatureEle.setText(sign);
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置编码格式
format.setEncoding("UTF-8");
String path = System.getProperty("user.dir");
FileWriter fileWriter = new FileWriter(new File(path + File.separator + "license.xml"));
XMLWriter xmlWriter = new XMLWriter(fileWriter, format);
// 设置是否转义,默认使用转义字符
xmlWriter.setEscapeText(false);
xmlWriter.write(document);
xmlWriter.close();
log.info("更新授权码成功");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("更新授权码失败!");
}
}
private static boolean notAfterLastValidateTime(long lastValidateTime, long currentTi) {
return lastValidateTime >= currentTi;
}
private static boolean notBefore(Long expiredTime, long currentTi) {
return expiredTime <= currentTi;
}
private static boolean notAfter(long generatedTime, long currentTi) {
return generatedTime >= currentTi;
}
private static CheckParams getCheckParams(Map<String, ValidateResult> result) {
//读取license文件
Document document = readLicense();
if (document == null) {
log.error("license 读取失败!");
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.FILE_NOT_EXIST));
return null;
}
Element rootElement = document.getRootElement();
Element dataEle = rootElement.element("features");
List<Element> featuresEles = dataEle.elements();
Element lastValidateTimeEle = featuresEles.get(0);
//提取上一次验证时间
String lastValidateTimeStr = lastValidateTimeEle.attributeValue("ti");
long lastValidateTime = Long.parseLong(AESUtils.decrypt(lastValidateTimeStr));
log.debug("上一次校验时间:{}", lastValidateTime);
//提取签名内容
Element signEle = rootElement.element("signature");
String signStr = signEle.getText();
String sign = AESUtils.decrypt(signStr);
if (sign == null) {
log.error("授权码不正确");
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.ILLEGAL));
return null;
}
log.debug("签名内容:{}", sign);
String[] signArr = sign.split("-");
if (signArr.length != 5) {
log.error("授权码不正确");
result.put("Authorize", ValidateResult.error(ValidateCodeEnum.ILLEGAL));
return null;
}
CheckParams params = CheckParams.builder().lastValidateTime(lastValidateTime).macAddress(signArr[0])
.cpuSerial(signArr[1]).generatedTime(Long.parseLong(signArr[2])).expiredTime(Long.parseLong(signArr[3]))
.version(signArr[4]).build();
return params;
}
private static Document readLicense() {
Document document = null;
try {
SAXReader saxReader = new SAXReader();
String path = System.getProperty("user.dir");
document = saxReader.read(new File(path + File.separator + "license.xml"));
return document;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
// String sign = AESUtils.decrypt("VorZodH/B6eeNLPA09TNJ8fpjlvrsckBk3VW3Pvr2qzhQVdeL38xS8unNFFxzQrjZ70f4wIoi1Tg1wlZq9DFKuVyp2zD20A//lDswyaD8NsmwMR72R2Ua+Gb0dp+PpM3b9gx2iIFIAtKOyaJlMMV8H4az/EKc/d733lyHfY3wbhsmo4vUvsqPYiriaj+psPu7DgO0DsQqw0xjAblpcrfL1xc42E3STEi9NTNbbBTsLU=");
String s="PXVnqRD54Gd4f0cEECwqpL0KYlN40lDtUTQRhpSURSqYg+QzDF4/9mYLcu0JNMxsy1O5ZrsAhSLjNzf0TGO05w==";
System.out.println(AESUtils.decrypt(s));
}
}

View File

@@ -0,0 +1,59 @@
package com.dcsoft.auth.utils;
import com.dcsoft.auth.bean.ValidateResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author penghao
* @createDate 2022/05/11
* @createTime 16:42
*/
@Component
@Slf4j
public class LicenseThread implements Runnable {
public static Map<String, ValidateResult> validateResult = null;
@Value("${license.checkTime}")
private Long checkTime;
@Bean
public void startThread() {
Thread thread = new Thread(this);
thread.setDaemon(true);
thread.start();
log.debug("license校验结果");
}
@Override
public void run() {
while (true) {
validateResult = LicenseManager.validate();
if (validateResult != null) {
ValidateResult result = validateResult.get("Authorize");
log.debug("license校验结果" + result.getMessage());
}
try {
//正式改为12个小时校验一次保持与登录同步即可
// TimeUnit.HOURS.sleep(12);
//测试1分钟校验一次
TimeUnit.SECONDS.sleep(checkTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static boolean validateAfterUpdateSign() {
validateResult = LicenseManager.validate();
ValidateResult result = validateResult.get("Authorize");
return result != null && result.getIsValidate();
}
}

View File

@@ -0,0 +1,67 @@
package com.dcsoft.auth.utils;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* @Description 对AES密码加密
* @createDate 2022/05/05
* @createTime 14:28
*/
public class RSAUtils {
/**
* 公钥base64
*/
private static String puk = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdfujgTmG4aOa4oK2VysmKvAI+hurN/wuKQjzgJTo3ct6TH5NHFHncb9KXijC1xk2Po+pJ8UjU4XGjU4gq5yhTdeSYPYR6hj5jqLy8fkWpFzeC6RvM4bLDe1lDNKphpcUoo5ZO7T77w9fX2lgJSyy/8LxdBThc4Megga3KW1/W4wIDAQAB";
/**
* 加密
*
* @return
* @throws Exception
*/
protected static String encrypt(String content) throws Exception {
byte[] publicKeyBytes = puk.getBytes();
X509EncodedKeySpec x = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBytes));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(x);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] result = cipher.doFinal(content.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(result);
}
/**
* 私钥base64
*/
private static String prk = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJ1+6OBOYbho5rigrZXKyYq8Aj6G6s3/C4pCPOAlOjdy3pMfk0cUedxv0peKMLXGTY+j6knxSNThcaNTiCrnKFN15Jg9hHqGPmOovLx+RakXN4LpG8zhssN7WUM0qmGlxSijlk7tPvvD19faWAlLLL/wvF0FOFzgx6CBrcpbX9bjAgMBAAECgYA8uRWohg//PdLXFHxY6JrUNrDW0sXtLoyQfgFimnfbsRpHt0DdgvOJHkQf0VP+gbqdyyEl6TWfflyGEErL39wX1rrosy+LpiN0HeISERJuwJtuiGeR+0qw+Xz2M7VE+e5oD94dRtlzERft2mcDbQAQYUCFNgUBtd1dCJgMJPZJYQJBANHxKKHqMbsH91JsGP8eCu+yeMah0X8cT79nwD71SJRc03W5P1MPKhRyGWJj0M+Wax32pAPCMTfbj19scLplJpUCQQDADD5OuSLYRVqx68/CYbFVK3ye/YD4Cgc+0kT9SoI9bLB10JumHT0seDGeXQqwUPAF3bBZGI8pW2bdtzDj8YGXAkABQXgEv+ncPIf2Lj9YB035cQ/X4E/oerrfYjd8KOtuN7/sDFecn5KY3LXaKM6u7y9k1nzUqOyycNXCtFtYQhKhAkBvgyxyvaFz/uFoyko6zksP705Pa1eFrx0B50pT4P26+O+FmXmnfPbWaXw2PkREmNqmLVGGinImS4JxXzuuP79FAkAFQejjE+5Twi8oSCcNwse7FFP86U6jgcc+S+XCUUkLXQ5SPlkyb037hwoV1lEEJpcyI2tSFRxBKT89KZN0Nfat";
protected static String decrypt(String signEncrypt) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
byte[] privateKeyBytes = prk.getBytes();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBytes));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] result = cipher.doFinal(Base64.getDecoder().decode(signEncrypt));
return new String(result);
}
public static void main(String[] args) throws Exception {
String password = "123456";
String a = encrypt(password);
System.out.println("AES加密秘钥" + a);
}
}

View File

@@ -0,0 +1,102 @@
package com.dcsoft.auth.utils;
import lombok.extern.slf4j.Slf4j;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
/**
* @author penghao
*/
@Slf4j
public class Systemutils {
protected static String getMacAddress() {
try {
java.util.Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
StringBuilder sb = new StringBuilder();
while (en.hasMoreElements()) {
NetworkInterface iface = en.nextElement();
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
for (InterfaceAddress addr : addrs) {
InetAddress ip = addr.getAddress();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
continue;
}
if (network.getName().toLowerCase().startsWith("ens")) {
byte[] mac = network.getHardwareAddress();
if (mac == null) {
continue;
}
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
String xxy = sb.toString().replaceAll("-", "").toUpperCase();
log.info("xxy地址{}", xxy);
return xxy;
}
}
}
} catch (Exception e) {
e.printStackTrace();
log.error("读取本机系统信息失败!");
}
return null;
}
protected static String getCpuNum() {
BufferedReader reader = null;
InputStreamReader ir = null;
try {
String[] linux = {"/bin/bash", "-c", "dmidecode -t processor | grep 'ID' | awk -F ':' '{print $2}' | head -n 1"};
String[] windows = {"wmic", "cpu", "get", "ProcessorId"};
// 获取系统信息
String property = System.getProperty("os.name");
Process process = Runtime.getRuntime().exec(property.contains("Window") ? windows : linux);
process.getOutputStream().close();
ir = new InputStreamReader(process.getInputStream());
reader = new BufferedReader(ir);
String xxw = reader.readLine();
if (xxw != null) {
xxw = xxw.replaceAll(" ", "");
}
log.info("xxw识别码:{}", xxw);
return xxw;
} catch (Exception e) {
e.printStackTrace();
log.error("获取系统信息失败!");
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ir != null) {
try {
ir.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
public static void main(String[] args) throws Exception {
// List<String> macs = getMacAddress();
// System.out.println("本机的mac网卡的地址列表" + macs);
System.out.println(getCpuNum());
}
}

View File

@@ -0,0 +1,7 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
___ ___ ___ ___ _ _ _____ _ _
| \ / __| / __| ___ / \ | | | | |_ _| | || |
| |) | | (__ \__ \ |___| | - | | |_| | | | | __ |
|___/ \___| |___/ _____ |_|_| \___/ _|_|_ |_||_|

View File

@@ -0,0 +1,25 @@
# Tomcat
server:
port: 9200
# Spring
spring:
application:
# 应用名称
name: dcsoft-auth
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

Binary file not shown.

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/dcsoft-auth" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.dcsoft" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.dcsoft</groupId>
<artifactId>dcsoft-common</artifactId>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dcsoft-common-core</artifactId>
<description>
dcsoft-common-core核心模块
</description>
<dependencies>
<!-- SpringCloud Openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- SpringCloud Loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Spring Context Support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<!-- Transmittable ThreadLocal -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
</dependency>
<!-- Pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!-- Hibernate Validator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Alibaba Fastjson -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!-- Jwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<!-- Jaxb -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<!-- Apache Lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Commons Io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- Java Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- huTool 工具类库 核心包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,187 @@
package com.dcsoft.common.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import com.dcsoft.common.core.utils.poi.ExcelHandlerAdapter;
/**
* 自定义导出Excel数据注解
*
* @author dcsoft
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel
{
/**
* 导出时在excel中排序
*/
public int sort() default Integer.MAX_VALUE;
/**
* 导出到Excel中的名字.
*/
public String name() default "";
/**
* 日期格式, 如: yyyy-MM-dd
*/
public String dateFormat() default "";
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
public String readConverterExp() default "";
/**
* 如果是字典类型请设置字典的type值 (如: sys_user_sex)
*/
public String dictType() default "";
/**
* 分隔符,读取字符串组内容
*/
public String separator() default ",";
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
public int scale() default -1;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 导出时在excel中每个列的高度 单位为字符
*/
public double height() default 14;
/**
* 导出时在excel中每个列的宽 单位为字符
*/
public double width() default 16;
/**
* 文字后缀,如% 90 变成90%
*/
public String suffix() default "";
/**
* 当值为空时,字段的默认值
*/
public String defaultValue() default "";
/**
* 提示信息
*/
public String prompt() default "";
/**
* 设置只能选择不能输入的列内容.
*/
public String[] combo() default {};
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/
public boolean needMerge() default false;
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public boolean isExport() default true;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 导出类型0数字 1字符串
*/
public ColumnType cellType() default ColumnType.STRING;
/**
* 导出列头背景色
*/
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
* 导出列头字体颜色
*/
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景色
*/
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色
*/
public IndexedColors color() default IndexedColors.BLACK;
/**
* 导出字段对齐方式
*/
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/**
* 自定义数据处理器
*/
public Class<?> handler() default ExcelHandlerAdapter.class;
/**
* 自定义数据处理器参数
*/
public String[] args() default {};
/**
* 字段类型0导出导入1仅导出2仅导入
*/
Type type() default Type.ALL;
public enum Type
{
ALL(0), EXPORT(1), IMPORT(2);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
public enum ColumnType
{
NUMERIC(0), STRING(1), IMAGE(2);
private final int value;
ColumnType(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
}

View File

@@ -0,0 +1,18 @@
package com.dcsoft.common.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel注解集
*
* @author dcsoft
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
Excel[] value();
}

View File

@@ -0,0 +1,73 @@
package com.dcsoft.common.core.constant;
/**
* 缓存常量信息
*
* @author dcsoft
*/
public class CacheConstants
{
/**
* 缓存有效期默认720分钟
*/
public final static long EXPIRATION = 720;
/**
* 缓存刷新时间默认120分钟
*/
public final static long REFRESH_TIME = 120;
/**
* 密码最大错误次数
*/
public final static int PASSWORD_MAX_RETRY_COUNT = 5;
/**
* 密码锁定时间默认10分钟
*/
public final static long PASSWORD_LOCK_TIME = 10;
/**
* 权限缓存前缀
*/
public final static String LOGIN_TOKEN_KEY = "login_tokens:";
/**
* 验证码 redis key
*/
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* 字典管理 cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/**
* 登录账户密码错误次数 redis key
*/
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
/**
* 登录IP黑名单 cache key
*/
public static final String SYS_LOGIN_BLACKIPLIST = SYS_CONFIG_KEY + "sys.login.blackIPList";
/** UNIUNBI redis key */
public static final String AUTH_KEY = "auth_codes:";
/** 微信 redis key */
public static final String WX_KEY = "weixin_code:";
public static final String LOGIN_TOKEN = "redis_login_token:";
public static final String WEIXIN_TOKEN = "weixin_token:";
public static final String QYWEIXIN_TOKEN = "qyweixin_token:";
public static final String QY_LOGIN_TOKEN = "qy_login_token:";
}

View File

@@ -0,0 +1,220 @@
package com.dcsoft.common.core.constant;
/**
* 通用常量信息
*
* @author dcsoft
*/
public class Constants
{
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* www主域
*/
public static final String WWW = "www.";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 成功标记
*/
public static final Integer SUCCESS = 200;
/**
* 失败标记
*/
public static final Integer FAIL = 500;
/**
* 登录成功状态
*/
public static final String LOGIN_SUCCESS_STATUS = "0";
/**
* 登录失败状态
*/
public static final String LOGIN_FAIL_STATUS = "1";
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
/**
* 当前记录起始索引
*/
public static final String PAGE_NUM = "pageNum";
/**
* 每页显示记录数
*/
public static final String PAGE_SIZE = "pageSize";
/**
* 排序列
*/
public static final String ORDER_BY_COLUMN = "orderByColumn";
/**
* 排序的方向 "desc" 或者 "asc".
*/
public static final String IS_ASC = "isAsc";
/**
* 验证码有效期(分钟)
*/
public static final long CAPTCHA_EXPIRATION = 2;
/**
* 资源映射路径 前缀
*/
public static final String RESOURCE_PREFIX = "/profile";
/**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/
public static final String[] JOB_WHITELIST_STR = { "com.dcsoft" };
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.dcsoft.common.core.utils.file" };
/**
* 0
*/
public static final String ZERO = "0";
/**
* 1
*/
public static final String ONE = "1";
/**
* 2
*/
public static final String TWO = "2";
/**
* 5
*/
public static final String FIVE = "5";
/**
* 200
*/
public static final String CODE = "200";
/**
* OK
*/
public static final String OK = "ok";
/**
* 宇泛门禁设备开关门状态1开门
*/
public static final Integer ACCESS_CONTROL_ONE = 1;
/**
* 宇泛门禁设备开关门状态2关门
*/
public static final Integer ACCESS_CONTROL_TWO = 2;
/**
*
*/
public static final String TTS_MOD_CONTENT = "未授权,请联系管理员";
/**
*
*/
public static final String DISPLAY_MOD_CONTENT = "未授权,请联系管理员";
/**
* 梯控结束时间
*/
public static final String END_TIME = "2099-12-31 23:59:59";
/**
* 梯控起始可用时间
*/
public static final String START_DAY_TIME = "00:00:00";
/**
* 梯控结束可用时间
*/
public static final String END_DAY_TIME = "23:59:59";
/**
* 梯控星期
*/
public static final String WEEK = "1 1 1 1 1 1 1";
public static final String CONTENT = "{\n" +
" \"touser\": \"%\", \n" +
" \"template_id\": \"wODO_BDj8n1grelUSGTNvpZbSnFdhzC3odWHek0brSM\",\n" +
" \"url\": \"#\",\n" +
" \"data\": {\n" +
" \"first\": {\n" +
" \"value\": \"广州腾讯科技有限公司\"\n" +
" },\n" +
" \"keyword1\": {\n" +
" \"value\": \"广州腾讯科技有限公司\"\n" +
" },\n" +
" \"keyword2\": {\n" +
" \"value\": \"2019年8月8日\"\n" +
" }\n" +
" }\n" +
"}";
}

View File

@@ -0,0 +1,117 @@
package com.dcsoft.common.core.constant;
/**
* 代码生成通用常量
*
* @author dcsoft
*/
public class GenConstants
{
/** 单表(增删改查) */
public static final String TPL_CRUD = "crud";
/** 树表(增删改查) */
public static final String TPL_TREE = "tree";
/** 主子表(增删改查) */
public static final String TPL_SUB = "sub";
/** 树编码字段 */
public static final String TREE_CODE = "treeCode";
/** 树父编码字段 */
public static final String TREE_PARENT_CODE = "treeParentCode";
/** 树名称字段 */
public static final String TREE_NAME = "treeName";
/** 上级菜单ID字段 */
public static final String PARENT_MENU_ID = "parentMenuId";
/** 上级菜单名称字段 */
public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
/** 数据库文本类型 */
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
/** 数据库时间类型 */
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
/** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bigint", "float", "double", "decimal" };
/** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
/** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time" };
/** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time", "remark" };
/** Entity基类字段 */
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
/** Tree基类字段 */
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors" };
/** 文本框 */
public static final String HTML_INPUT = "input";
/** 文本域 */
public static final String HTML_TEXTAREA = "textarea";
/** 下拉框 */
public static final String HTML_SELECT = "select";
/** 单选框 */
public static final String HTML_RADIO = "radio";
/** 复选框 */
public static final String HTML_CHECKBOX = "checkbox";
/** 日期控件 */
public static final String HTML_DATETIME = "datetime";
/** 图片上传控件 */
public static final String HTML_IMAGE_UPLOAD = "imageUpload";
/** 文件上传控件 */
public static final String HTML_FILE_UPLOAD = "fileUpload";
/** 富文本控件 */
public static final String HTML_EDITOR = "editor";
/** 字符串类型 */
public static final String TYPE_STRING = "String";
/** 整型 */
public static final String TYPE_INTEGER = "Integer";
/** 长整型 */
public static final String TYPE_LONG = "Long";
/** 浮点型 */
public static final String TYPE_DOUBLE = "Double";
/** 高精度计算类型 */
public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 时间类型 */
public static final String TYPE_DATE = "Date";
/** 模糊查询 */
public static final String QUERY_LIKE = "LIKE";
/** 相等查询 */
public static final String QUERY_EQ = "EQ";
/** 需要 */
public static final String REQUIRE = "1";
}

View File

@@ -0,0 +1,94 @@
package com.dcsoft.common.core.constant;
/**
* 返回状态码
*
* @author dcsoft
*/
public class HttpStatus
{
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功,但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限,授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源,服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突,或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据,媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
/**
* 系统警告消息
*/
public static final int WARN = 601;
}

View File

@@ -0,0 +1,50 @@
package com.dcsoft.common.core.constant;
/**
* 任务调度通用常量
*
* @author dcsoft
*/
public class ScheduleConstants
{
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
/** 执行目标key */
public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
/** 默认 */
public static final String MISFIRE_DEFAULT = "0";
/** 立即触发执行 */
public static final String MISFIRE_IGNORE_MISFIRES = "1";
/** 触发一次执行 */
public static final String MISFIRE_FIRE_AND_PROCEED = "2";
/** 不触发立即执行 */
public static final String MISFIRE_DO_NOTHING = "3";
public enum Status
{
/**
* 正常
*/
NORMAL("0"),
/**
* 暂停
*/
PAUSE("1");
private String value;
private Status(String value)
{
this.value = value;
}
public String getValue()
{
return value;
}
}
}

View File

@@ -0,0 +1,49 @@
package com.dcsoft.common.core.constant;
/**
* 权限相关通用常量
*
* @author dcsoft
*/
public class SecurityConstants
{
/**
* 用户ID字段
*/
public static final String DETAILS_USER_ID = "user_id";
/**
* 用户名字段
*/
public static final String DETAILS_USERNAME = "username";
/**
* 授权信息字段
*/
public static final String AUTHORIZATION_HEADER = "authorization";
/**
* 请求来源
*/
public static final String FROM_SOURCE = "from-source";
/**
* 内部请求
*/
public static final String INNER = "inner";
/**
* 用户标识
*/
public static final String USER_KEY = "user_key";
/**
* 登录用户
*/
public static final String LOGIN_USER = "login_user";
/**
* 角色权限
*/
public static final String ROLE_PERMISSION = "role_permission";
}

View File

@@ -0,0 +1,24 @@
package com.dcsoft.common.core.constant;
/**
* 服务名称
*
* @author dcsoft
*/
public class ServiceNameConstants
{
/**
* 认证服务的serviceid
*/
public static final String AUTH_SERVICE = "dcsoft-auth";
/**
* 系统模块的serviceid
*/
public static final String SYSTEM_SERVICE = "dcsoft-system";
/**
* 文件服务的serviceid
*/
public static final String FILE_SERVICE = "dcsoft-file";
}

View File

@@ -0,0 +1,25 @@
package com.dcsoft.common.core.constant;
/**
* Token的Key常量
*
* @author dcsoft
*/
public class TokenConstants
{
/**
* 令牌自定义标识
*/
public static final String AUTHENTICATION = "Authorization";
/**
* 令牌前缀
*/
public static final String PREFIX = "Bearer ";
/**
* 令牌秘钥
*/
public final static String SECRET = "abcdefghijklmnopqrstuvwxyz";
}

View File

@@ -0,0 +1,80 @@
package com.dcsoft.common.core.constant;
/**
* 用户常量信息
*
* @author dcsoft
*/
public class UserConstants
{
/**
* 平台内系统用户的唯一标志
*/
public static final String SYS_USER = "SYS_USER";
/** 正常状态 */
public static final String NORMAL = "0";
/** 异常状态 */
public static final String EXCEPTION = "1";
/** 用户封禁状态 */
public static final String USER_DISABLE = "1";
/** 角色封禁状态 */
public static final String ROLE_DISABLE = "1";
/** 部门正常状态 */
public static final String DEPT_NORMAL = "0";
/** 部门停用状态 */
public static final String DEPT_DISABLE = "1";
/** 字典正常状态 */
public static final String DICT_NORMAL = "0";
/** 是否为系统默认(是) */
public static final String YES = "Y";
/** 是否菜单外链(是) */
public static final String YES_FRAME = "0";
/** 是否菜单外链(否) */
public static final String NO_FRAME = "1";
/** 菜单类型(目录) */
public static final String TYPE_DIR = "M";
/** 菜单类型(菜单) */
public static final String TYPE_MENU = "C";
/** 菜单类型(按钮) */
public static final String TYPE_BUTTON = "F";
/** Layout组件标识 */
public final static String LAYOUT = "Layout";
/** ParentView组件标识 */
public final static String PARENT_VIEW = "ParentView";
/** InnerLink组件标识 */
public final static String INNER_LINK = "InnerLink";
/** 校验是否唯一的返回标识 */
public final static boolean UNIQUE = true;
public final static boolean NOT_UNIQUE = false;
/**
* 用户名长度限制
*/
public static final int USERNAME_MIN_LENGTH = 2;
public static final int USERNAME_MAX_LENGTH = 20;
/**
* 密码长度限制
*/
public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20;
}

View File

@@ -0,0 +1,98 @@
package com.dcsoft.common.core.context;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.dcsoft.common.core.constant.SecurityConstants;
import com.dcsoft.common.core.text.Convert;
import com.dcsoft.common.core.utils.StringUtils;
/**
* 获取当前线程变量中的 用户id、用户名称、Token等信息
* 注意: 必须在网关通过请求头的方法传入同时在HeaderInterceptor拦截器设置值。 否则这里无法获取
*
* @author dcsoft
*/
public class SecurityContextHolder
{
private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
public static void set(String key, Object value)
{
Map<String, Object> map = getLocalMap();
map.put(key, value == null ? StringUtils.EMPTY : value);
}
public static String get(String key)
{
Map<String, Object> map = getLocalMap();
return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
}
public static <T> T get(String key, Class<T> clazz)
{
Map<String, Object> map = getLocalMap();
return StringUtils.cast(map.getOrDefault(key, null));
}
public static Map<String, Object> getLocalMap()
{
Map<String, Object> map = THREAD_LOCAL.get();
if (map == null)
{
map = new ConcurrentHashMap<String, Object>();
THREAD_LOCAL.set(map);
}
return map;
}
public static void setLocalMap(Map<String, Object> threadLocalMap)
{
THREAD_LOCAL.set(threadLocalMap);
}
public static Long getUserId()
{
return Convert.toLong(get(SecurityConstants.DETAILS_USER_ID), 0L);
}
public static void setUserId(String account)
{
set(SecurityConstants.DETAILS_USER_ID, account);
}
public static String getUserName()
{
return get(SecurityConstants.DETAILS_USERNAME);
}
public static void setUserName(String username)
{
set(SecurityConstants.DETAILS_USERNAME, username);
}
public static String getUserKey()
{
return get(SecurityConstants.USER_KEY);
}
public static void setUserKey(String userKey)
{
set(SecurityConstants.USER_KEY, userKey);
}
public static String getPermission()
{
return get(SecurityConstants.ROLE_PERMISSION);
}
public static void setPermission(String permissions)
{
set(SecurityConstants.ROLE_PERMISSION, permissions);
}
public static void remove()
{
THREAD_LOCAL.remove();
}
}

View File

@@ -0,0 +1,115 @@
package com.dcsoft.common.core.domain;
import java.io.Serializable;
import com.dcsoft.common.core.constant.Constants;
/**
* 响应信息主体
*
* @author dcsoft
*/
public class R<T> implements Serializable
{
private static final long serialVersionUID = 1L;
/** 成功 */
public static final int SUCCESS = Constants.SUCCESS;
/** 失败 */
public static final int FAIL = Constants.FAIL;
private int code;
private String msg;
private T data;
public static <T> R<T> ok()
{
return restResult(null, SUCCESS, null);
}
public static <T> R<T> ok(T data)
{
return restResult(data, SUCCESS, null);
}
public static <T> R<T> ok(T data, String msg)
{
return restResult(data, SUCCESS, msg);
}
public static <T> R<T> fail()
{
return restResult(null, FAIL, null);
}
public static <T> R<T> fail(String msg)
{
return restResult(null, FAIL, msg);
}
public static <T> R<T> fail(T data)
{
return restResult(data, FAIL, null);
}
public static <T> R<T> fail(T data, String msg)
{
return restResult(data, FAIL, msg);
}
public static <T> R<T> fail(int code, String msg)
{
return restResult(null, code, msg);
}
private static <T> R<T> restResult(T data, int code, String msg)
{
R<T> apiResult = new R<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
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 T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
public static <T> Boolean isError(R<T> ret)
{
return !isSuccess(ret);
}
public static <T> Boolean isSuccess(R<T> ret)
{
return R.SUCCESS == ret.getCode();
}
}

View File

@@ -0,0 +1,28 @@
package com.dcsoft.common.core.enums;
/**
* 园区/公司类型
*
* @author dcsoft
*/
public enum CompanyType {
HEADQUARTERS("1", "总部"),
TD_PARK("2", "田东园区")
;
CompanyType(String code, String name) {
this.code = code;
this.name = name;
}
private String code;
private String name;
public String getCode() {
return code;
}
public String getValue() {
return name;
}
}

View File

@@ -0,0 +1,30 @@
package com.dcsoft.common.core.enums;
/**
* 用户状态
*
* @author dcsoft
*/
public enum UserStatus
{
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
private final String code;
private final String info;
UserStatus(String code, String info)
{
this.code = code;
this.info = info;
}
public String getCode()
{
return code;
}
public String getInfo()
{
return info;
}
}

View File

@@ -0,0 +1,27 @@
package com.dcsoft.common.core.enums.exception;
public enum CommonExceptionEnum {
RULE_ERROR(1000, "您所所在得部门所属规则未绑定设备"),
REQUEST_ERROR(1001, "请求异常"),
PEOPLE_ERROR(1002, "您的信息未录入"),
QR_CODE_ERROR(1003, "二维码过期"),
DEVICE_INITIALIZE_ERROR(1004, "设备序列号不能为空"),
;
private Integer errCode;
private String errMsg;
CommonExceptionEnum(Integer errCode, String errMsg) {
this.errCode = errCode;
this.errMsg = errMsg;
}
public Integer getCode() {
return errCode;
}
public String getMessage() {
return errMsg;
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception;
/**
* 验证码错误异常类
*
* @author dcsoft
*/
public class CaptchaException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public CaptchaException(String msg)
{
super(msg);
}
}

View File

@@ -0,0 +1,31 @@
package com.dcsoft.common.core.exception;
/**
* 检查异常
*
* @author dcsoft
*/
public class CheckedException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public CheckedException(String message)
{
super(message);
}
public CheckedException(Throwable cause)
{
super(cause);
}
public CheckedException(String message, Throwable cause)
{
super(message, cause);
}
public CheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
{
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,15 @@
package com.dcsoft.common.core.exception;
/**
* 演示模式异常
*
* @author dcsoft
*/
public class DemoModeException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public DemoModeException()
{
}
}

View File

@@ -0,0 +1,58 @@
package com.dcsoft.common.core.exception;
/**
* 全局异常
*
* @author dcsoft
*/
public class GlobalException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public GlobalException()
{
}
public GlobalException(String message)
{
this.message = message;
}
public String getDetailMessage()
{
return detailMessage;
}
public GlobalException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
@Override
public String getMessage()
{
return message;
}
public GlobalException setMessage(String message)
{
this.message = message;
return this;
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception;
/**
* 内部认证异常
*
* @author dcsoft
*/
public class InnerAuthException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public InnerAuthException(String message)
{
super(message);
}
}

View File

@@ -0,0 +1,15 @@
package com.dcsoft.common.core.exception;
/**
* 权限异常
*
* @author dcsoft
*/
public class PreAuthorizeException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public PreAuthorizeException()
{
}
}

View File

@@ -0,0 +1,74 @@
package com.dcsoft.common.core.exception;
/**
* 业务异常
*
* @author dcsoft
*/
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
private Integer code;
/**
* 错误提示
*/
private String message;
/**
* 错误明细,内部调试错误
*
* 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/
private String detailMessage;
/**
* 空构造方法,避免反序列化问题
*/
public ServiceException()
{
}
public ServiceException(String message)
{
this.message = message;
}
public ServiceException(Integer code, String message)
{
this.message = message;
this.code = code;
}
public String getDetailMessage()
{
return detailMessage;
}
@Override
public String getMessage()
{
return message;
}
public Integer getCode()
{
return code;
}
public ServiceException setMessage(String message)
{
this.message = message;
return this;
}
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
}

View File

@@ -0,0 +1,26 @@
package com.dcsoft.common.core.exception;
/**
* 工具类异常
*
* @author dcsoft
*/
public class UtilException extends RuntimeException
{
private static final long serialVersionUID = 8247610319171014183L;
public UtilException(Throwable e)
{
super(e.getMessage(), e);
}
public UtilException(String message)
{
super(message);
}
public UtilException(String message, Throwable throwable)
{
super(message, throwable);
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception.auth;
/**
* 未能通过的登录认证异常
*
* @author dcsoft
*/
public class NotLoginException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public NotLoginException(String message)
{
super(message);
}
}

View File

@@ -0,0 +1,23 @@
package com.dcsoft.common.core.exception.auth;
import org.apache.commons.lang3.StringUtils;
/**
* 未能通过的权限认证异常
*
* @author dcsoft
*/
public class NotPermissionException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public NotPermissionException(String permission)
{
super(permission);
}
public NotPermissionException(String[] permissions)
{
super(StringUtils.join(permissions, ","));
}
}

View File

@@ -0,0 +1,23 @@
package com.dcsoft.common.core.exception.auth;
import org.apache.commons.lang3.StringUtils;
/**
* 未能通过的角色认证异常
*
* @author dcsoft
*/
public class NotRoleException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public NotRoleException(String role)
{
super(role);
}
public NotRoleException(String[] roles)
{
super(StringUtils.join(roles, ","));
}
}

View File

@@ -0,0 +1,79 @@
package com.dcsoft.common.core.exception.base;
/**
* 基础异常
*
* @author dcsoft
*/
public class BaseException extends RuntimeException
{
private static final long serialVersionUID = 1L;
/**
* 所属模块
*/
private String module;
/**
* 错误码
*/
private String code;
/**
* 错误码对应的参数
*/
private Object[] args;
/**
* 错误消息
*/
private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage)
{
this.module = module;
this.code = code;
this.args = args;
this.defaultMessage = defaultMessage;
}
public BaseException(String module, String code, Object[] args)
{
this(module, code, args, null);
}
public BaseException(String module, String defaultMessage)
{
this(module, null, null, defaultMessage);
}
public BaseException(String code, Object[] args)
{
this(null, code, args, null);
}
public BaseException(String defaultMessage)
{
this(null, null, null, defaultMessage);
}
public String getModule()
{
return module;
}
public String getCode()
{
return code;
}
public Object[] getArgs()
{
return args;
}
public String getDefaultMessage()
{
return defaultMessage;
}
}

View File

@@ -0,0 +1,19 @@
package com.dcsoft.common.core.exception.file;
import com.dcsoft.common.core.exception.base.BaseException;
/**
* 文件信息异常类
*
* @author dcsoft
*/
public class FileException extends BaseException
{
private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args)
{
super("file", code, args, null);
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception.file;
/**
* 文件名称超长限制异常类
*
* @author dcsoft
*/
public class FileNameLengthLimitExceededException extends FileException
{
private static final long serialVersionUID = 1L;
public FileNameLengthLimitExceededException(int defaultFileNameLength)
{
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception.file;
/**
* 文件名大小限制异常类
*
* @author dcsoft
*/
public class FileSizeLimitExceededException extends FileException
{
private static final long serialVersionUID = 1L;
public FileSizeLimitExceededException(long defaultMaxSize)
{
super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
}
}

View File

@@ -0,0 +1,61 @@
package com.dcsoft.common.core.exception.file;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
* 文件上传异常类
*
* @author dcsoft
*/
public class FileUploadException extends Exception
{
private static final long serialVersionUID = 1L;
private final Throwable cause;
public FileUploadException()
{
this(null, null);
}
public FileUploadException(final String msg)
{
this(msg, null);
}
public FileUploadException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
@Override
public void printStackTrace(PrintStream stream)
{
super.printStackTrace(stream);
if (cause != null)
{
stream.println("Caused by:");
cause.printStackTrace(stream);
}
}
@Override
public void printStackTrace(PrintWriter writer)
{
super.printStackTrace(writer);
if (cause != null)
{
writer.println("Caused by:");
cause.printStackTrace(writer);
}
}
@Override
public Throwable getCause()
{
return cause;
}
}

View File

@@ -0,0 +1,80 @@
package com.dcsoft.common.core.exception.file;
import java.util.Arrays;
/**
* 文件上传 误异常类
*
* @author dcsoft
*/
public class InvalidExtensionException extends FileUploadException
{
private static final long serialVersionUID = 1L;
private String[] allowedExtension;
private String extension;
private String filename;
public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
{
super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
this.allowedExtension = allowedExtension;
this.extension = extension;
this.filename = filename;
}
public String[] getAllowedExtension()
{
return allowedExtension;
}
public String getExtension()
{
return extension;
}
public String getFilename()
{
return filename;
}
public static class InvalidImageExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidFlashExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidMediaExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
public static class InvalidVideoExtensionException extends InvalidExtensionException
{
private static final long serialVersionUID = 1L;
public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
{
super(allowedExtension, extension, filename);
}
}
}

View File

@@ -0,0 +1,34 @@
package com.dcsoft.common.core.exception.job;
/**
* 计划策略异常
*
* @author dcsoft
*/
public class TaskException extends Exception
{
private static final long serialVersionUID = 1L;
private Code code;
public TaskException(String msg, Code code)
{
this(msg, code, null);
}
public TaskException(String msg, Code code, Exception nestedEx)
{
super(msg, nestedEx);
this.code = code;
}
public Code getCode()
{
return code;
}
public enum Code
{
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
}
}

View File

@@ -0,0 +1,16 @@
package com.dcsoft.common.core.exception.user;
/**
* 验证码失效异常类
*
* @author dcsoft
*/
public class CaptchaExpireException extends UserException
{
private static final long serialVersionUID = 1L;
public CaptchaExpireException()
{
super("user.jcaptcha.expire", null);
}
}

Some files were not shown because too many files have changed in this diff Show More