Commit 7e3e0b8e authored by sunsongtao's avatar sunsongtao

注释

parents
Pipeline #51 failed with stages

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
.log
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 打包Web工程,生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Auth工程。
echo.
cd %~dp0
cd ../xiaoniu-auth/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-auth.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Gateway工程。
echo.
cd %~dp0
cd ../xiaoniu-gateway/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-gateway.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-File工程。
echo.
cd %~dp0
cd ../xiaoniu-modules/xiaoniu-file/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-file.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-Gen工程。
echo.
cd %~dp0
cd ../xiaoniu-modules/xiaoniu-gen/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-gen.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-Job工程。
echo.
cd %~dp0
cd ../xiaoniu-modules/xiaoniu-job/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-modules-job.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-museum工程。
echo.
cd %~dp0
cd ../xiaoniu-modules/xiaoniu-museum/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-modules-museum.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Modules-System工程。
echo.
cd %~dp0
cd ../xiaoniu-modules/xiaoniu-system/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-system.jar
cd bin
pause
\ No newline at end of file
@echo off
echo.
echo [信息] 使用Jar命令运行Monitor工程。
echo.
cd %~dp0
cd ../xiaoniu-visual/xiaoniu-monitor/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xiaoniu-visual-monitor.jar
cd bin
pause
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu</artifactId>
<version>1.5.0</version>
<name>xiaoniu-cloud</name>
<description>小牛微服务管理系统</description>
<properties>
<xiaoniu.version>1.5.0</xiaoniu.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>17</java.version>
<spring-boot.version>3.2.3</spring-boot.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.0.0-RC1</spring-cloud-alibaba.version>
<spring-framework.version>6.1.5</spring-framework.version>
<spring-boot-admin.version>3.2.3</spring-boot-admin.version>
<swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.6.2</swagger.core.version>
<tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>5.2.0</pagehelper.boot.version>
<druid.version>1.2.18</druid.version>
<dynamic-ds.version>4.2.0</dynamic-ds.version>
<commons.io.version>2.13.0</commons.io.version>
<minio.version>8.2.2</minio.version>
<qiniu.version>[7.13.0, 7.13.99]</qiniu.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<fastjson.version>2.0.43</fastjson.version>
<jjwt.version>0.9.1</jjwt.version>
<transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
<lombok.version>1.18.24</lombok.version>
<mybatis-spring-boot-starter.version>3.5.3.1</mybatis-spring-boot-starter.version>
<hutool-all.version>5.7.14</hutool-all.version>
<p6spy.version>3.9.1</p6spy.version>
<javax.servlet.version>4.0.1</javax.servlet.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- FastDFS 分布式文件系统 -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${tobato.version}</version>
</dependency>
<!-- Swagger 依赖配置 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>${swagger.core.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.core.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- 代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- sql性能分析插件 -->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>${p6spy.version}</version>
</dependency>
<!-- JSON 解析器和生成器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- 线程传递值 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>${transmittable-thread-local.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- 系统接口 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-api-system</artifactId>
<version>${xiaoniu.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool-all.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>${hutool-all.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>xiaoniu-api</module>
<module>xiaoniu-auth</module>
<module>xiaoniu-common</module>
<module>xiaoniu-gateway</module>
<module>xiaoniu-modules</module>
<module>xiaoniu-visual</module>
</modules>
<packaging>pom</packaging>
<dependencies>
<!-- bootstrap 启动器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu</artifactId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>xiaoniu-api-system</module>
<module>xiaoniu-subsystem-api</module>
</modules>
<artifactId>xiaoniu-api</artifactId>
<packaging>pom</packaging>
<description>
xiaoniu-api系统接口
</description>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-api</artifactId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xiaoniu-api-system</artifactId>
<description>
xiaoniu-api-system系统接口模块
</description>
<dependencies>
<!-- xiaoniu Common Core-->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
package com.xiaoniu.system.api;
import com.xiaoniu.common.core.constant.ServiceNameConstants;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.domain.SysFile;
import com.xiaoniu.system.api.factory.RemoteFileFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件服务
*
* @author xiaoniu
*/
@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);
}
package com.xiaoniu.system.api;
import com.xiaoniu.common.core.constant.SecurityConstants;
import com.xiaoniu.common.core.constant.ServiceNameConstants;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.domain.SysLogininfor;
import com.xiaoniu.system.api.domain.SysOperLog;
import com.xiaoniu.system.api.factory.RemoteLogFallbackFactory;
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;
/**
* 日志服务
*
* @author xiaoniu
*/
@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) throws Exception;
/**
* 保存访问记录
*
* @param sysLogininfor 访问实体
* @param source 请求来源
* @return 结果
*/
@PostMapping("/logininfor")
public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
package com.xiaoniu.system.api;
import com.xiaoniu.common.core.constant.SecurityConstants;
import com.xiaoniu.common.core.constant.ServiceNameConstants;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.domain.SysUser;
import com.xiaoniu.system.api.factory.RemoteUserFallbackFactory;
import com.xiaoniu.system.api.model.LoginUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* 用户服务
*
* @author xiaoniu
*/
@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);
}
package com.xiaoniu.system.api.domain;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.ArrayList;
import java.util.List;
/**
* 部门表 sys_dept
*
* @author xiaoniu
*/
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;
/** 子部门 */
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;
}
@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();
}
}
package com.xiaoniu.system.api.domain;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.constant.UserConstants;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 字典数据表 sys_dict_data
*
* @author xiaoniu
*/
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();
}
}
package com.xiaoniu.system.api.domain;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 字典类型表 sys_dict_type
*
* @author xiaoniu
*/
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();
}
}
package com.xiaoniu.system.api.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* 文件信息
*
* @author xiaoniu
*/
public class SysFile
{
/**
* 文件名称
*/
private String name;
/**
* 文件地址
*/
private String url;
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;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.append("url", getUrl())
.toString();
}
}
package com.xiaoniu.system.api.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import java.util.Date;
/**
* 系统访问记录表 sys_logininfor
*
* @author xiaoniu
*/
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;
}
}
\ No newline at end of file
package com.xiaoniu.system.api.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import lombok.Data;
import java.util.Date;
/**
* 操作日志记录表 oper_log
*
* @author xiaoniu
*/
@Data
@TableName("tb_sys_oper_log")
public class SysOperLog {
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;
/**
* 请求方法
*/
@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;
}
package com.xiaoniu.system.api.domain;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Set;
/**
* 角色表 sys_role
*
* @author xiaoniu
*/
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();
}
}
package com.xiaoniu.system.api.domain;
import com.xiaoniu.common.core.annotation.Excel;
import com.xiaoniu.common.core.annotation.Excel.ColumnType;
import com.xiaoniu.common.core.annotation.Excel.Type;
import com.xiaoniu.common.core.annotation.Excels;
import com.xiaoniu.common.core.web.domain.BaseEntity;
import com.xiaoniu.common.core.xss.Xss;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.util.Date;
import java.util.List;
/**
* 用户对象 sys_user
*
* @author xiaoniu
*/
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 = "手机号码", cellType = ColumnType.TEXT)
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;
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;
}
@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();
}
}
package com.xiaoniu.system.api.factory;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.RemoteFileService;
import com.xiaoniu.system.api.domain.SysFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
/**
* 文件服务降级处理
*
* @author xiaoniu
*/
@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());
}
};
}
}
package com.xiaoniu.system.api.factory;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.RemoteLogService;
import com.xiaoniu.system.api.domain.SysLogininfor;
import com.xiaoniu.system.api.domain.SysOperLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 日志服务降级处理
*
* @author xiaoniu
*/
@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 R.fail("保存操作日志失败:" + throwable.getMessage());
}
@Override
public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
{
return R.fail("保存登录日志失败:" + throwable.getMessage());
}
};
}
}
package com.xiaoniu.system.api.factory;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.system.api.RemoteUserService;
import com.xiaoniu.system.api.domain.SysUser;
import com.xiaoniu.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 用户服务降级处理
*
* @author xiaoniu
*/
@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());
}
};
}
}
package com.xiaoniu.system.api.model;
import com.xiaoniu.system.api.domain.SysUser;
import lombok.Data;
import java.io.Serializable;
import java.util.Set;
/**
* 用户信息
*
* @author xiaoniu
*/
@Data
public class LoginUser implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* 用户唯一标识
*/
private String token;
/**
* 用户名id
*/
private Long userid;
/**
* 单位id
*/
private Long unitId;
/**
* 用户名
*/
private String username;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 角色列表
*/
private Set<String> roles;
/**
* 用户信息
*/
private SysUser sysUser;
}
com.xiaoniu.system.api.factory.RemoteUserFallbackFactory
com.xiaoniu.system.api.factory.RemoteLogFallbackFactory
com.xiaoniu.system.api.factory.RemoteFileFallbackFactory
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-api</artifactId>
<version>1.5.0</version>
</parent>
<artifactId>xiaoniu-subsystem-api</artifactId>
<packaging>pom</packaging>
<modules>
<module>system-api</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- xiaoniu Common Core-->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-subsystem-api</artifactId>
<version>1.5.0</version>
</parent>
<artifactId>system-api</artifactId>
</project>
\ No newline at end of file
package com.xiaoniu.api.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* @Author haoxuyang
* @Date 2024/11/29 10:29
*/
@Data
public class ApiLogininforDTO {
/**
* ID
*/
private Long infoId;
/**
* 用户账号
*/
private String userName;
/**
* 状态 0成功 1失败
*/
private String status;
/**
* 地址
*/
private String ipaddr;
/**
* 描述
*/
private String msg;
/**
* 访问时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date accessTime;
}
package com.xiaoniu.api.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xiaoniu.common.core.annotation.Excel;
import lombok.Data;
import java.util.Date;
/**
* @Author haoxuyang
* @Date 2024/11/29 11:18
*/
@Data
public class ApiOperLogDTO {
/**
* 操作模块
*/
@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;
}
package com.xiaoniu.api.feign;
import com.xiaoniu.api.dto.ApiLogininforDTO;
import com.xiaoniu.api.dto.ApiOperLogDTO;
import com.xiaoniu.api.vo.ApiLoginUserVO;
import com.xiaoniu.common.core.constant.ServiceNameConstants;
import com.xiaoniu.common.core.constant.providerConstant.SubSystemProviderConstant;
import com.xiaoniu.common.core.domain.R;
import io.swagger.v3.oas.annotations.Hidden;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @Author haoxuyang
* @Date 2024/11/29 9:11
*/
@Hidden
@FeignClient(name = ServiceNameConstants.SUB_SYSTEM_SERVICE)
public interface IUserProvider {
/**
* 通过用户名查询用户信息
*
* @param username 用户名
* @return 结果
*/
@GetMapping(SubSystemProviderConstant.PROVIDER_XIAONIU_SUBSYSTEM_SYSUSER_GETUSERBYUSERNAME)
R<ApiLoginUserVO> getUserInfo(@RequestParam String username);
/**
* 添加登陆记录
*
* @param dto dto
* @return 结果
*/
@PostMapping(SubSystemProviderConstant.PROVIDER_XIAONIU_SUBSYSTEM_LOGININFOR_SAVELOGININFOR)
R<Boolean> saveLogininfor(@RequestBody ApiLogininforDTO dto);
/**
* 添加操作日志记录
*
* @param dto dto
* @return 结果
*/
@PostMapping(SubSystemProviderConstant.PROVIDER_XIAONIU_SUBSYSTEM_LOGININFOR_SAVEOPERLOG)
R<Boolean> saveOperLog(@RequestBody ApiOperLogDTO dto);
}
package com.xiaoniu.api.vo;
import lombok.Data;
import java.util.Set;
/**
* @Author haoxuyang
* @Date 2024/11/29 9:15
*/
@Data
public class ApiLoginUserVO {
/**
* 用户名id
*/
private Long userId;
/**
* 单位id
*/
private Long unitId;
/**
* 用户名
*/
private String userName;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 密码
*/
private String passWord;
/**
* 删除标志(0代表存在 2代表删除)
*/
private String delFlag;
/**
* 帐号状态(0正常 1停用)
*/
private String status;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 角色列表
*/
private Set<String> roles;
}
FROM openjdk:17
#FROM sopjava:11
MAINTAINER haoxuyang
# 定义环境变量,会被后续的RUN命令使用,并且在容器运行期间保持
# java启动参数,默认为空
# 配置文件参数,默认为test环境
ENV PROFILES="test"
#ENV PARAMS="-server -Dlog4j2.formatMsgNoLookups=true"
ENV PARAMS="-server -Xmx512m -Xms256m -Xmn256m -Xss256k -XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=0 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -Ddruid.mysql.usePingMethod=false -Dlog4j2.formatMsgNoLookups=true"
ENV TimeZone=Asia/Shanghai
# 设置容器的默认字符集为 UTF-8
ENV LANG=C.UTF-8
COPY /target/xiaoniu-auth.jar /usr/xiaoniu-auth.jar
WORKDIR /usr
RUN ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
ENTRYPOINT ["sh","-c","java $PARAMS -jar xiaoniu-auth.jar --spring.profiles.active=$PROFILES"]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu</artifactId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xiaoniu-auth</artifactId>
<description>
xiaoniu-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>
<!-- xiaoniu Common Security-->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-security</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>system-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-swagger</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<finalName>genxiu-auth</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.xiaoniu.auth;
import com.xiaoniu.common.security.annotation.EnableRyFeignClients;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
* 认证授权中心
*
* @author xiaoniu
*/
@EnableRyFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class XiaoNiuAuthApplication
{
public static void main(String[] args)
{
SpringApplication.run(XiaoNiuAuthApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 认证授权中心启动成功 ლ(´ڡ`ლ)゙ ");
}
}
package com.xiaoniu.auth.controller;
import com.xiaoniu.auth.form.LoginBody;
import com.xiaoniu.auth.form.RegisterBody;
import com.xiaoniu.auth.service.SysLoginService;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.common.core.utils.JwtUtils;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.security.auth.AuthUtil;
import com.xiaoniu.common.security.service.TokenService;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.system.api.model.LoginUser;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* token 控制
*
* @author xiaoniu
*/
@RestController
@AllArgsConstructor
@RequestMapping
@Tag(name = "用户登录管理", description = "用户登录管理接口")
public class TokenController {
private final TokenService tokenService;
private final SysLoginService sysLoginService;
@PostMapping("/login")
public R<?> login(@RequestBody LoginBody form) {
// 用户登录
LoginUser 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();
}
}
package com.xiaoniu.auth.form;
/**
* 用户登录对象
*
* @author xiaoniu
*/
public class LoginBody
{
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
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;
}
}
package com.xiaoniu.auth.form;
/**
* 用户注册对象
*
* @author xiaoniu
*/
public class RegisterBody extends LoginBody
{
}
package com.xiaoniu.auth.service;
import com.xiaoniu.api.feign.IUserProvider;
import com.xiaoniu.api.vo.ApiLoginUserVO;
import com.xiaoniu.common.core.constant.CacheConstants;
import com.xiaoniu.common.core.constant.Constants;
import com.xiaoniu.common.core.constant.SecurityConstants;
import com.xiaoniu.common.core.constant.UserConstants;
import com.xiaoniu.common.core.domain.R;
import com.xiaoniu.common.core.enums.UserStatus;
import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.common.core.text.Convert;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.utils.ip.IpUtils;
import com.xiaoniu.common.redis.service.RedisService;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.system.api.RemoteUserService;
import com.xiaoniu.system.api.domain.SysUser;
import com.xiaoniu.system.api.model.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 登录校验方法
*
* @author xiaoniu
*/
@Component
public class SysLoginService {
@Autowired
private RemoteUserService remoteUserService;
@Autowired
private SysPasswordService passwordService;
@Autowired
private SysRecordLogService recordLogService;
@Autowired
private RedisService redisService;
@Autowired
private IUserProvider userProvider;
/**
* 登录
*/
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.USERNAME_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);
R<ApiLoginUserVO> userResult = userProvider.getUserInfo(username);
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();
ApiLoginUserVO userInfo = userResult.getData();
// SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(userInfo.getDelFlag())) {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(userInfo.getStatus())) {
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
SysUser user = new SysUser();
BeanUtils.copyProperties(userInfo, user);
user.setPassword(userInfo.getPassWord());
passwordService.validate(user, password);
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
LoginUser loginUser = new LoginUser();
loginUser.setUserid(user.getUserId());
loginUser.setUsername(user.getUserName());
loginUser.setLoginTime(userInfo.getLoginTime());
loginUser.setExpireTime(userInfo.getExpireTime());
loginUser.setIpaddr(userInfo.getIpaddr());
loginUser.setPermissions(userInfo.getPermissions());
loginUser.setRoles(userInfo.getRoles());
loginUser.setUnitId(userInfo.getUnitId());
return loginUser;
}
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, "注册成功");
}
}
package com.xiaoniu.auth.service;
import com.xiaoniu.common.core.constant.CacheConstants;
import com.xiaoniu.common.core.exception.ServiceException;
import com.xiaoniu.common.redis.service.RedisService;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.system.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 登录密码方法
*
* @author xiaoniu
*/
@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));
}
}
}
package com.xiaoniu.auth.service;
import com.xiaoniu.api.dto.ApiLogininforDTO;
import com.xiaoniu.api.feign.IUserProvider;
import com.xiaoniu.common.core.constant.Constants;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.utils.ip.IpUtils;
import com.xiaoniu.system.api.RemoteLogService;
import com.xiaoniu.system.api.domain.SysLogininfor;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 记录日志方法
*
* @author xiaoniu
*/
@Component
public class SysRecordLogService {
@Autowired
private RemoteLogService remoteLogService;
@Resource
private IUserProvider userProvider;
/**
* 记录登录信息
*
* @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);
logininfor.setAccessTime(new Date());
// 日志状态
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);
}
ApiLogininforDTO aPiLogininforDTO = new ApiLogininforDTO();
BeanUtils.copyProperties(logininfor, aPiLogininforDTO);
userProvider.saveLogininfor(aPiLogininforDTO);
// remoteLogService.saveLogininfor(logininfor, SecurityConstants.INNER);
}
}
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
( ) ___ ___ __ ( ) ___ __ ___ / __
\\ / / / / // ) ) // ) ) // ) ) / / // / / ____ // ) ) // / / / / // ) )
\/ / / / // / / // / / // / / / / // / / // / / // / / / / // / /
/ /\ / / ((___( ( ((___/ / // / / / / ((___( ( ((___( ( ((___( ( / / // / /
# Tomcat
server:
port: 9204
# Spring
spring:
application:
# 应用名称
name: genxiu-auth
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: localhost:8848
# server-addr: 81.70.250.68:8848
# 注册组
group: DEFAULT_GROUP
namespace: ${spring.profiles.active}
config:
# 配置中心地址
server-addr: localhost:8848
# server-addr: 81.70.250.68:8848
# 注册组
group: DEFAULT_GROUP
namespace: ${spring.profiles.active}
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application.${spring.cloud.nacos.config.file-extension}
username: nacos
password: nacos
# username: museum-nacos
# password: uE$2Xmm@P6DOC&uwi7&AYkBOWd5XQ9o1
config:
import:
- optional:nacos:genxiu-common.${spring.cloud.nacos.config.file-extension}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="C:/genxiu/jar/logs/genxiu-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.xiaoniu" 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>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu</artifactId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>xiaoniu-common-core</module>
<module>xiaoniu-common-datascope</module>
<module>xiaoniu-common-datasource</module>
<module>xiaoniu-common-log</module>
<module>xiaoniu-common-redis</module>
<module>xiaoniu-common-seata</module>
<module>xiaoniu-common-security</module>
<module>xiaoniu-common-sensitive</module>
<module>xiaoniu-common-swagger</module>
<module>xiaoniu-common-mybatis</module>
</modules>
<properties>
<baomidou.version>3.5.5</baomidou.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<mysql-connector-java.version>8.0.23</mysql-connector-java.version>
</properties>
<artifactId>xiaoniu-common</artifactId>
<packaging>pom</packaging>
<description>
xiaoniu-common通用模块
</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<!-- 核心模块 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-core</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 接口模块 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-swagger</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 安全模块 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-security</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 数据脱敏 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-sensitive</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 权限范围 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-datascope</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-datasource</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-seata</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 日志记录 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-log</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 缓存服务 -->
<dependency>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common-redis</artifactId>
<version>${project.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.xiaoniu</groupId>-->
<!-- <artifactId>xiaoniu-common-lkl-sdk</artifactId>-->
<!-- <version>${project.version}</version>-->
<!-- </dependency>-->
</dependencies>
</dependencyManagement>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.xiaoniu</groupId>
<artifactId>xiaoniu-common</artifactId>
<version>1.5.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xiaoniu-common-core</artifactId>
<description>
xiaoniu-common-core核心模块
</description>
<dependencies>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<!-- 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>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</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>
<version>2.3.1</version>
</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>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
<!-- Swagger -->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
</project>
package com.xiaoniu.common.core.annotation;
import com.xiaoniu.common.core.utils.poi.ExcelHandlerAdapter;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
/**
* 自定义导出Excel数据注解
*
* @author xiaoniu
*/
@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 "";
/**
* 分隔符,读取字符串组内容
*/
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), TEXT(3);
private final int value;
ColumnType(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
}
\ No newline at end of file
package com.xiaoniu.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 xiaoniu
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
Excel[] value();
}
\ No newline at end of file
package com.xiaoniu.common.core.annotation;
import java.lang.annotation.*;
/**
* 自定义注解防止表单重复提交
*
* @author xiaoniu
*
*/
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit
{
/**
* 间隔时间(ms),小于此时间视为重复提交
*/
public long interval() default 1000;
/**
* 提示消息
*/
public String message() default "不允许重复提交,请稍候再试";
}
package com.xiaoniu.common.core.config;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.xiaoniu.common.core.jackson.BigNumberSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* jackson 配置
*
* @author Lion Li
*/
@Slf4j
@AutoConfiguration(before = JacksonAutoConfiguration.class)
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
// 全局配置序列化返回 JSON 处理
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
builder.modules(javaTimeModule);
builder.timeZone(TimeZone.getDefault());
log.info("初始化 jackson 配置");
};
}
}
package com.xiaoniu.common.core.constant;
/**
* 缓存常量信息
*
* @author xiaoniu
*/
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:";
/**
* 支付回调 redis key
*/
public static final String PAY_NOTICE = "pay_notice:";
/**
* 分账订单缓存 redis key
*/
public static final String SEPARATE_ORDER_KEY = "separate_order:";
/**
* 洗车完成响应参数 redis key
*/
public static final String CAR_WASH_COMPLETE_KEY = "car_wash_complete:";
/**
* 客户端登陆存放信息token redis key
*/
public static final String API_CLIENT_TOKEN_KEY = "api_client_tokens:";
/**
* 搜索历史记录 redis key
*/
public static final String STORE_SEARCHES_HIS_KEY = "store_searches_his:";
/**
* 验证码 redis key
*/
public static final String STORE_SMS_CODE_KEY = "store_sms_code_key:";
/**
* 找回密码验证码 redis key
*/
public static final String RET_STORE_SMS_CODE_KEY = "ret_store_sms_code_key:";
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* 购物车缓存管理 cache key
*/
public static final String SHOP_CAR_ORDER_KEY = "shop_car_order:";
/**
* 基本订单创建缓存管理 cache key
*/
public static final String CREAT_ORDER_KEY = "creat_order:";
/**
* 字典管理 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";
/**
* 防重提交 redis key
*/
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
/**
* 小程序令牌 redis key
*/
public static final String XCX_MEMBER_ACCESS_TOKEN_KEY = "xcx_member_access_token:";
/**
* 小程序登录用户 redis key
*/
public static final String MEMBER_LOGIN_TOKEN_KEY = "member_login_token:";
/**
* 客户端登录用户 redis key
*/
public static final String CLIENT_LOGIN_TOKEN_KEY = "client_login_token:";
/**
* 门店登录用户 redis key
*/
public static final String STORE_LOGIN_TOKEN_KEY = "store_login_token:";
/**
* 信息设置 redis key
*/
public static final String INFORMATION_SETTING_KEY = "information_setting:";
/**
* loginid构造拼接字符串
*/
public static final String LOGINID_JOIN_CODE = ":";
/**
* 优惠券库存 redis key
*/
public static final String COUPON_INVENTORY_KEY = "coupon_inventory:";
}
package com.xiaoniu.common.core.constant;
/**
* 通用常量信息
*
* @author xiaoniu
*/
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:";
/**
* 业务异常消息
*/
public static final String EXCEPTION_MSG = "fail";
/**
* 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 Integer ZERO = 0;
public static final Integer ONE = 1;
public static final Integer TWO = 2;
public static final Integer THREE = 3;
public static final Integer FOUR = 4;
public static final Integer FIVE = 5;
public static final Integer SIX = 6;
public static final Integer SEVEN = 7;
public static final Integer EIGHT = 8;
public static final Integer NINE = 9;
public static final Integer TEN = 10;
public static final Integer TWELVE = 12;
public static final Integer SIXTY = 60;
/**
* 门店端请求前缀
*/
public static final String API_STORE = "/api/store";
/**
* 客户端请求前缀
*/
public static final String API_CLIENT = "/api/client";
/**
* 超管的userId 用于判断是不是超管
*/
public static final int ADMIN_USERID = -127001;
/**
* 超管的角色ID 用于判断是不是超管
*/
public static final int ADMIN_ROLEID = -127001;
/**
* 登录成功状态
*/
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";
/**
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
*/
public static final String[] JSON_WHITELIST_STR = {"org.springframework", "com.xiaoniu"};
/**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/
public static final String[] JOB_WHITELIST_STR = {"com.xiaoniu.job.task"};
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = {"java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.xiaoniu.common.core.utils.file"};
/**
* 请求方式
*/
public static final String GET = "get";
public static final String POST = "post";
public static final String BODY = "body";
}
package com.xiaoniu.common.core.constant;
/**
* 代码生成通用常量
*
* @author xiaoniu
*/
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",
"bit", "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";
}
package com.xiaoniu.common.core.constant;
/**
* 返回状态码
*
* @author xiaoniu
*/
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;
}
package com.xiaoniu.common.core.constant;
/**
* 任务调度通用常量
*
* @author xiaoniu
*/
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;
}
}
}
package com.xiaoniu.common.core.constant;
/**
* 权限相关通用常量
*
* @author xiaoniu
*/
public class SecurityConstants
{
/**
* 用户ID字段
*/
public static final String DETAILS_USER_ID = "user_id";
/**
* 用户名字段
*/
public static final String DETAILS_USERNAME = "username";
/**
* 单位ID字段
*/
public static final String DETAILS_UNIT_ID = "unit_id";
/**
* 授权信息字段
*/
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";
}
package com.xiaoniu.common.core.constant;
/**
* 服务名称
*
* @author xiaoniu
*/
public class ServiceNameConstants
{
/**
* 认证服务的serviceid
*/
public static final String AUTH_SERVICE = "genxiu-auth";
/**
* app博物馆的serviceid
*/
public static final String APP_SERVICE = "genxiu-app";
/**
* 系统模块的serviceid
*/
public static final String SYSTEM_SERVICE = "genxiu-system";
/**
* 机关系统模块的serviceid
*/
public static final String SUB_SYSTEM_SERVICE = "genxiu-subsystem";
/**
* 文件服务的serviceid
*/
public static final String FILE_SERVICE = "genxiu-file";
}
package com.xiaoniu.common.core.constant;
/**
* Token的Key常量
*
* @author xiaoniu
*/
public class TokenConstants
{
/**
* 令牌自定义标识
*/
public static final String AUTHENTICATION = "Authorization";
/**
* 令牌前缀
*/
public static final String PREFIX = "Bearer ";
/**
* 令牌秘钥
*/
public final static String SECRET = "Pn^1&%u8&xCa2hTTkFbz4f2JJ0WyWKEr";
}
package com.xiaoniu.common.core.constant;
/**
* 用户常量信息
*
* @author xiaoniu
*/
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;
/**
* 管理员ID
*/
public static final Long ADMIN_ID = -1270012023L;
}
package com.xiaoniu.common.core.constant.providerConstant;
/**
* @Author haoxuyang
* @Description //TODO
* @Date 2023/9/11 14:01
**/
public interface SubSystemProviderConstant {
/**
* 远程调用公共前缀
*/
String PROVIDER = "/provider";
String XIAONIU_SUBSYSTEM = "/xiaoniu_subsystem";
/**
* 远程调用用戶信息
*/
String SYSUSER = "/sysuser";
String LOGININFOR = "/logininfor";
/**
* 根据用户名获取用户信息
*/
String PROVIDER_XIAONIU_SUBSYSTEM_SYSUSER_GETUSERBYUSERNAME = SYSUSER + "/getUserByUserName";
/**
* 保存登陆日志
*/
String PROVIDER_XIAONIU_SUBSYSTEM_LOGININFOR_SAVELOGININFOR = LOGININFOR + "/saveLogininfor";
/**
* 保存操作日志
*/
String PROVIDER_XIAONIU_SUBSYSTEM_LOGININFOR_SAVEOPERLOG = LOGININFOR + "/saveOperLog";
}
package com.xiaoniu.common.core.context;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.xiaoniu.common.core.constant.SecurityConstants;
import com.xiaoniu.common.core.text.Convert;
import com.xiaoniu.common.core.utils.StringUtils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 获取当前线程变量中的 用户id、用户名称、Token等信息
* 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取
*
* @author xiaoniu
*/
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 Long getUnitId()
{
return Convert.toLong(get(SecurityConstants.DETAILS_UNIT_ID),0L);
}
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();
}
}
package com.xiaoniu.common.core.enums;
import java.math.BigDecimal;
/**
* @Author haoxuyang
* @Date 2024/10/26 11:15
*/
public enum CarWashPriceEnum {
FIVE_MINUTES("5分钟", BigDecimal.TEN),
TEN_MINUTES("10分钟", new BigDecimal(20)),
FIFTEEN_MINUTES("15分钟", new BigDecimal(30)),
;
/**
* 类型名称
*/
private String type;
/**
* 价格
*/
private BigDecimal price;
CarWashPriceEnum(String type, BigDecimal price) {
this.type = type;
this.price = price;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public static BigDecimal getValueByType(String type) {
CarWashPriceEnum[] carWashPriceEnums = values();
for (CarWashPriceEnum carWashPriceEnum : carWashPriceEnums) {
if (carWashPriceEnum.getType().equals(type)) {
return carWashPriceEnum.getPrice();
}
}
return null;
}
}
package com.xiaoniu.common.core.exception;
/**
* 验证码错误异常类
*
* @author xiaoniu
*/
public class CaptchaException extends RuntimeException
{
private static final long serialVersionUID = 1L;
public CaptchaException(String msg)
{
super(msg);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment