update:格式化代码

This commit is contained in:
hrz
2025-03-29 18:00:06 +08:00
parent 630cb13066
commit 25b7e76407
101 changed files with 644 additions and 508 deletions
@@ -1,6 +1,10 @@
package xiaozhi.common.annotation; package xiaozhi.common.annotation;
import java.lang.annotation.*; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* 数据过滤注解 * 数据过滤注解
@@ -1,6 +1,10 @@
package xiaozhi.common.annotation; package xiaozhi.common.annotation;
import java.lang.annotation.*; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/** /**
* 操作日志注解 * 操作日志注解
@@ -1,14 +1,15 @@
package xiaozhi.common.aspect; package xiaozhi.common.aspect;
import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException;
/** /**
* Redis切面处理类 * Redis切面处理类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -19,7 +20,7 @@ import org.springframework.stereotype.Component;
@Component @Component
public class RedisAspect { public class RedisAspect {
/** /**
* 是否开启redis缓存 true开启 false关闭 * 是否开启redis缓存 true开启 false关闭
*/ */
@Value("${renren.redis.open}") @Value("${renren.redis.open}")
private boolean open; private boolean open;
@@ -1,12 +1,14 @@
package xiaozhi.common.config; package xiaozhi.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import xiaozhi.common.interceptor.DataFilterInterceptor; import xiaozhi.common.interceptor.DataFilterInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/** /**
* mybatis-plus配置 * mybatis-plus配置
@@ -1,11 +1,12 @@
package xiaozhi.common.config; package xiaozhi.common.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi; import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
/** /**
* Swagger配置 * Swagger配置
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -16,7 +17,7 @@ public class SwaggerConfig {
@Bean @Bean
public GroupedOpenApi userApi() { public GroupedOpenApi userApi() {
String[] paths = {"/**"}; String[] paths = { "/**" };
return GroupedOpenApi.builder().group("xiaozhi") return GroupedOpenApi.builder().group("xiaozhi")
.pathsToMatch(paths).build(); .pathsToMatch(paths).build();
} }
@@ -1,12 +1,13 @@
package xiaozhi.common.entity; package xiaozhi.common.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable; import lombok.Data;
import java.util.Date;
/** /**
* 基础实体类,所有实体都需要继承 * 基础实体类,所有实体都需要继承
@@ -1,6 +1,5 @@
package xiaozhi.common.exception; package xiaozhi.common.exception;
import xiaozhi.common.utils.MessageUtils; import xiaozhi.common.utils.MessageUtils;
/** /**
@@ -10,7 +9,6 @@ import xiaozhi.common.utils.MessageUtils;
*/ */
public class RenException extends RuntimeException { public class RenException extends RuntimeException {
private int code; private int code;
private String msg; private String msg;
@@ -1,11 +1,11 @@
package xiaozhi.common.page; package xiaozhi.common.page;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/** /**
* 分页工具类 * 分页工具类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,10 +1,10 @@
package xiaozhi.common.page; package xiaozhi.common.page;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 令牌信息 * 令牌信息
* *
@@ -14,7 +14,6 @@ import java.io.Serializable;
@Schema(description = "令牌信息") @Schema(description = "令牌信息")
public class TokenDTO implements Serializable { public class TokenDTO implements Serializable {
@Schema(description = "密码") @Schema(description = "密码")
private String token; private String token;
@@ -1,6 +1,5 @@
package xiaozhi.common.redis; package xiaozhi.common.redis;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
@@ -8,6 +7,8 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import jakarta.annotation.Resource;
/** /**
* Redis配置 * Redis配置
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,14 +1,15 @@
package xiaozhi.common.redis; package xiaozhi.common.redis;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
/** /**
* Redis工具类 * Redis工具类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,10 +1,10 @@
package xiaozhi.common.service; package xiaozhi.common.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection; import java.util.Collection;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
/** /**
* 基础服务接口,所有Service接口都要继承 * 基础服务接口,所有Service接口都要继承
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -56,7 +56,8 @@ public interface BaseService<T> {
* </p> * </p>
* *
* @param entity 实体对象 * @param entity 实体对象
* @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper} * @param updateWrapper 实体对象封装操作类
* {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
*/ */
boolean update(T entity, Wrapper<T> updateWrapper); boolean update(T entity, Wrapper<T> updateWrapper);
@@ -1,11 +1,11 @@
package xiaozhi.common.service; package xiaozhi.common.service;
import xiaozhi.common.page.PageData;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import xiaozhi.common.page.PageData;
/** /**
* CRUD基础服务接口 * CRUD基础服务接口
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,9 +1,9 @@
package xiaozhi.common.user; package xiaozhi.common.user;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import lombok.Data;
/** /**
* 登录用户信息 * 登录用户信息
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,20 +1,21 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import jakarta.servlet.http.HttpServletRequest; import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/** /**
* Http * Http
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -70,15 +71,15 @@ public class HttpContextUtils {
} }
public static String getLanguage() { public static String getLanguage() {
//默认语言 // 默认语言
String defaultLanguage = "zh-CN"; String defaultLanguage = "zh-CN";
//request // request
HttpServletRequest request = getHttpServletRequest(); HttpServletRequest request = getHttpServletRequest();
if (request == null) { if (request == null) {
return defaultLanguage; return defaultLanguage;
} }
//请求语言 // 请求语言
defaultLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE); defaultLanguage = request.getHeader(HttpHeaders.ACCEPT_LANGUAGE);
return defaultLanguage; return defaultLanguage;
@@ -1,8 +1,9 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import org.apache.commons.lang3.StringUtils;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/** /**
* IP地址 * IP地址
@@ -1,13 +1,14 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
/** /**
* JSON 工具类 * JSON 工具类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -59,7 +60,8 @@ public class JsonUtils {
return new ArrayList<>(); return new ArrayList<>();
} }
try { try {
return objectMapper.readValue(text, objectMapper.getTypeFactory().constructCollectionType(List.class, clazz)); return objectMapper.readValue(text,
objectMapper.getTypeFactory().constructCollectionType(List.class, clazz));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -1,11 +1,11 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import java.io.Serializable;
/** /**
* 响应数据 * 响应数据
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -36,7 +36,6 @@ public class Result<T> implements Serializable {
return this; return this;
} }
public Result<T> error() { public Result<T> error() {
this.code = ErrorCode.INTERNAL_SERVER_ERROR; this.code = ErrorCode.INTERNAL_SERVER_ERROR;
this.msg = MessageUtils.getMessage(this.code); this.msg = MessageUtils.getMessage(this.code);
@@ -1,11 +1,11 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.Data;
/** /**
* 树节点,所有需要实现树节点的,都需要继承该类 * 树节点,所有需要实现树节点的,都需要继承该类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,16 +1,17 @@
package xiaozhi.common.validator; package xiaozhi.common.validator;
import xiaozhi.common.exception.RenException; import java.util.Locale;
import jakarta.validation.ConstraintViolation; import java.util.Set;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator; import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator; import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator;
import java.util.Locale; import jakarta.validation.ConstraintViolation;
import java.util.Set; import jakarta.validation.Validation;
import jakarta.validation.Validator;
import xiaozhi.common.exception.RenException;
/** /**
* hibernate-validator校验工具类 * hibernate-validator校验工具类
@@ -35,7 +36,7 @@ public class ValidatorUtils {
throws RenException { throws RenException {
Locale.setDefault(LocaleContextHolder.getLocale()); Locale.setDefault(LocaleContextHolder.getLocale());
Validator validator = Validation.byDefaultProvider().configure().messageInterpolator( Validator validator = Validation.byDefaultProvider().configure().messageInterpolator(
new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(getMessageSource()))) new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(getMessageSource())))
.buildValidatorFactory().getValidator(); .buildValidatorFactory().getValidator();
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups); Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
@@ -1,8 +1,9 @@
package xiaozhi.common.xss; package xiaozhi.common.xss;
import org.apache.commons.lang3.StringUtils;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import org.apache.commons.lang3.StringUtils;
/** /**
* SQL过滤 * SQL过滤
@@ -20,19 +21,20 @@ public class SqlFilter {
if (StringUtils.isBlank(str)) { if (StringUtils.isBlank(str)) {
return null; return null;
} }
//去掉'|"|;|\字符 // 去掉'|"|;|\字符
str = StringUtils.replace(str, "'", ""); str = StringUtils.replace(str, "'", "");
str = StringUtils.replace(str, "\"", ""); str = StringUtils.replace(str, "\"", "");
str = StringUtils.replace(str, ";", ""); str = StringUtils.replace(str, ";", "");
str = StringUtils.replace(str, "\\", ""); str = StringUtils.replace(str, "\\", "");
//转换成小写 // 转换成小写
str = str.toLowerCase(); str = str.toLowerCase();
//非法字符 // 非法字符
String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"}; String[] keywords = { "master", "truncate", "insert", "select", "delete", "update", "declare", "alter",
"drop" };
//判断是否包含非法字符 // 判断是否包含非法字符
for (String keyword : keywords) { for (String keyword : keywords) {
if (str.contains(keyword)) { if (str.contains(keyword)) {
throw new RenException(ErrorCode.INVALID_SYMBOL); throw new RenException(ErrorCode.INVALID_SYMBOL);
@@ -1,6 +1,5 @@
package xiaozhi.common.xss; package xiaozhi.common.xss;
import jakarta.servlet.DispatcherType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
@@ -8,6 +7,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.PathMatcher; import org.springframework.util.PathMatcher;
import jakarta.servlet.DispatcherType;
/** /**
* XSS 配置文件 * XSS 配置文件
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,11 +1,17 @@
package xiaozhi.common.xss; package xiaozhi.common.xss;
import jakarta.servlet.*; import java.io.IOException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.util.PathMatcher; import org.springframework.util.PathMatcher;
import java.io.IOException; import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
/** /**
* XSS过滤 * XSS过滤
@@ -38,7 +44,8 @@ public class XssFilter implements Filter {
private boolean shouldNotFilter(HttpServletRequest request) { private boolean shouldNotFilter(HttpServletRequest request) {
// 放行不过滤的URL // 放行不过滤的URL
return properties.getExcludeUrls().stream().anyMatch(excludeUrl -> pathMatcher.match(excludeUrl, request.getServletPath())); return properties.getExcludeUrls().stream()
.anyMatch(excludeUrl -> pathMatcher.match(excludeUrl, request.getServletPath()));
} }
@Override @Override
@@ -1,20 +1,20 @@
package xiaozhi.common.xss; package xiaozhi.common.xss;
import cn.hutool.core.io.IoUtil;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import cn.hutool.core.io.IoUtil;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
/** /**
* XSS过滤处理 * XSS过滤处理
@@ -29,18 +29,18 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
@Override @Override
public ServletInputStream getInputStream() throws IOException { public ServletInputStream getInputStream() throws IOException {
//非json类型,直接返回 // 非json类型,直接返回
if (!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))) { if (!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))) {
return super.getInputStream(); return super.getInputStream();
} }
//为空,直接返回 // 为空,直接返回
String json = IoUtil.readUtf8(super.getInputStream()); String json = IoUtil.readUtf8(super.getInputStream());
if (StringUtils.isBlank(json)) { if (StringUtils.isBlank(json)) {
return super.getInputStream(); return super.getInputStream();
} }
//xss过滤 // xss过滤
json = xssEncode(json); json = xssEncode(json);
final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
return new ServletInputStream() { return new ServletInputStream() {
@@ -1,11 +1,12 @@
package xiaozhi.common.xss; package xiaozhi.common.xss;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
/** /**
* XSS 配置项 * XSS 配置项
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -22,13 +22,15 @@ public class XssUtils extends Safelist {
*/ */
private static Safelist xssWhitelist() { private static Safelist xssWhitelist() {
return new Safelist() return new Safelist()
//支持的标签 // 支持的标签
.addTags("a", "b", "blockquote", "br", "caption", "cite", "code", "col", "colgroup", "dd", "div", "dl", .addTags("a", "b", "blockquote", "br", "caption", "cite", "code", "col", "colgroup", "dd", "div", "dl",
"dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol", "p", "pre", "q", "small", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol", "p", "pre", "q",
"strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "u", "ul", "small",
"strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "u",
"ul",
"embed", "object", "param", "span") "embed", "object", "param", "span")
//支持的标签属性 // 支持的标签属性
.addAttributes("a", "href", "class", "style", "target", "rel", "nofollow") .addAttributes("a", "href", "class", "style", "target", "rel", "nofollow")
.addAttributes("blockquote", "cite") .addAttributes("blockquote", "cite")
.addAttributes("code", "class", "style") .addAttributes("code", "class", "style")
@@ -44,13 +46,16 @@ public class XssUtils extends Safelist {
.addAttributes("ul", "type", "style") .addAttributes("ul", "type", "style")
.addAttributes("pre", "class", "style") .addAttributes("pre", "class", "style")
.addAttributes("div", "class", "id", "style") .addAttributes("div", "class", "id", "style")
.addAttributes("embed", "src", "wmode", "flashvars", "pluginspage", "allowFullScreen", "allowfullscreen", .addAttributes("embed", "src", "wmode", "flashvars", "pluginspage", "allowFullScreen",
"quality", "width", "height", "align", "allowScriptAccess", "allowscriptaccess", "allownetworking", "type") "allowfullscreen",
.addAttributes("object", "type", "id", "name", "data", "width", "height", "style", "classid", "codebase") "quality", "width", "height", "align", "allowScriptAccess", "allowscriptaccess",
"allownetworking", "type")
.addAttributes("object", "type", "id", "name", "data", "width", "height", "style", "classid",
"codebase")
.addAttributes("param", "name", "value") .addAttributes("param", "name", "value")
.addAttributes("span", "class", "style") .addAttributes("span", "class", "style")
//标签属性对应的协议 // 标签属性对应的协议
.addProtocols("a", "href", "ftp", "http", "https", "mailto") .addProtocols("a", "href", "ftp", "http", "https", "mailto")
.addProtocols("img", "src", "http", "https") .addProtocols("img", "src", "http", "https")
.addProtocols("blockquote", "cite", "http", "https") .addProtocols("blockquote", "cite", "http", "https")
@@ -1,6 +1,7 @@
package xiaozhi.modules.agent.dao; package xiaozhi.modules.agent.dao;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.agent.entity.AgentEntity; import xiaozhi.modules.agent.entity.AgentEntity;
@@ -1,20 +1,17 @@
package xiaozhi.modules.agent.dao; package xiaozhi.modules.agent.dao;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xiaozhi.modules.agent.entity.AgentTemplateEntity; import xiaozhi.modules.agent.entity.AgentTemplateEntity;
/** /**
* @author chenerlei * @author chenerlei
* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Mapper * @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Mapper
* @createDate 2025-03-22 11:48:18 * @createDate 2025-03-22 11:48:18
*/ */
@Mapper @Mapper
public interface AgentTemplateDao extends BaseMapper<AgentTemplateEntity> { public interface AgentTemplateDao extends BaseMapper<AgentTemplateEntity> {
} }
@@ -1,11 +1,11 @@
package xiaozhi.modules.agent.dto; package xiaozhi.modules.agent.dto;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 智能体创建DTO * 智能体创建DTO
* 专用于新增智能体,不包含id、agentCode和sort字段,这些字段由系统自动生成/设置默认值 * 专用于新增智能体,不包含id、agentCode和sort字段,这些字段由系统自动生成/设置默认值
@@ -1,11 +1,11 @@
package xiaozhi.modules.agent.dto; package xiaozhi.modules.agent.dto;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 智能体更新DTO * 智能体更新DTO
* 专用于更新智能体,id字段是必需的,用于标识要更新的智能体 * 专用于更新智能体,id字段是必需的,用于标识要更新的智能体
@@ -1,11 +1,12 @@
package xiaozhi.modules.agent.entity; package xiaozhi.modules.agent.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.util.Date;
@Data @Data
@TableName("ai_agent") @TableName("ai_agent")
@Schema(description = "智能体信息") @Schema(description = "智能体信息")
@@ -1,17 +1,20 @@
package xiaozhi.modules.agent.entity; package xiaozhi.modules.agent.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data; import lombok.Data;
/** /**
* 智能体配置模板表 * 智能体配置模板表
*
* @TableName ai_agent_template * @TableName ai_agent_template
*/ */
@TableName(value ="ai_agent_template") @TableName(value = "ai_agent_template")
@Data @Data
public class AgentTemplateEntity implements Serializable { public class AgentTemplateEntity implements Serializable {
/** /**
@@ -1,12 +1,12 @@
package xiaozhi.modules.agent.service; package xiaozhi.modules.agent.service;
import java.util.List;
import java.util.Map;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.agent.entity.AgentEntity; import xiaozhi.modules.agent.entity.AgentEntity;
import java.util.List;
import java.util.Map;
public interface AgentService extends BaseService<AgentEntity> { public interface AgentService extends BaseService<AgentEntity> {
/** /**
* 根据用户ID获取智能体列表 * 根据用户ID获取智能体列表
@@ -1,9 +1,9 @@
package xiaozhi.modules.agent.service; package xiaozhi.modules.agent.service;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
/** /**
* @author chenerlei * @author chenerlei
* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service * @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service
@@ -15,6 +15,6 @@ import xiaozhi.modules.agent.service.AgentTemplateService;
*/ */
@Service @Service
public class AgentTemplateServiceImpl extends ServiceImpl<AgentTemplateDao, AgentTemplateEntity> public class AgentTemplateServiceImpl extends ServiceImpl<AgentTemplateDao, AgentTemplateEntity>
implements AgentTemplateService { implements AgentTemplateService {
} }
@@ -1,31 +1,38 @@
package xiaozhi.modules.device.controller; package xiaozhi.modules.device.controller;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
import xiaozhi.modules.device.dto.DeviceReportReqDTO; import xiaozhi.modules.device.dto.DeviceReportReqDTO;
import xiaozhi.modules.device.dto.DeviceReportRespDTO; import xiaozhi.modules.device.dto.DeviceReportRespDTO;
import xiaozhi.modules.device.service.DeviceService; import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.modules.device.utils.NetworkUtil; import xiaozhi.modules.device.utils.NetworkUtil;
import java.nio.charset.StandardCharsets;
@Tag(name = "设备管理", description = "OTA 相关接口") @Tag(name = "设备管理", description = "OTA 相关接口")
@RestController @RestController
@RequiredArgsConstructor @RequiredArgsConstructor
@RequestMapping("/ota") @RequestMapping("/ota")
public class OTAController public class OTAController {
{
private final DeviceService deviceService; private final DeviceService deviceService;
@Operation(summary = "检查 OTA 版本和设备激活状态") @Operation(summary = "检查 OTA 版本和设备激活状态")
@@ -33,14 +40,9 @@ public class OTAController
public ResponseEntity<String> checkOTAVersion( public ResponseEntity<String> checkOTAVersion(
@RequestBody DeviceReportReqDTO deviceReportReqDTO, @RequestBody DeviceReportReqDTO deviceReportReqDTO,
@Parameter(name = "Device-Id", description = "设备唯一标识", required = true, in = ParameterIn.HEADER) @Parameter(name = "Device-Id", description = "设备唯一标识", required = true, in = ParameterIn.HEADER) @RequestHeader("Device-Id") String deviceId,
@RequestHeader("Device-Id")
String deviceId,
@Parameter(name = "Client-Id", description = "客户端标识", required = true, in = ParameterIn.HEADER) @Parameter(name = "Client-Id", description = "客户端标识", required = true, in = ParameterIn.HEADER) @RequestHeader("Client-Id") String clientId) {
@RequestHeader("Client-Id")
String clientId
) {
if (StringUtils.isAnyBlank(deviceId, clientId)) { if (StringUtils.isAnyBlank(deviceId, clientId)) {
return createResponse(DeviceReportRespDTO.createError("Device ID is required")); return createResponse(DeviceReportRespDTO.createError("Device ID is required"));
} }
@@ -1,7 +1,9 @@
package xiaozhi.modules.device.dao; package xiaozhi.modules.device.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xiaozhi.modules.device.entity.DeviceEntity; import xiaozhi.modules.device.entity.DeviceEntity;
@Mapper @Mapper
@@ -8,7 +8,6 @@ import lombok.Setter;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
@Setter @Setter
@Getter @Getter
@Schema(description = "设备固件信息上报求请求体") @Schema(description = "设备固件信息上报求请求体")
@@ -7,8 +7,7 @@ import lombok.Setter;
@Data @Data
@Schema(description = "设备OTA检测版本返回体,包含激活码要求") @Schema(description = "设备OTA检测版本返回体,包含激活码要求")
public class DeviceReportRespDTO public class DeviceReportRespDTO {
{
@Schema(description = "服务器时间") @Schema(description = "服务器时间")
private ServerTime serverTime; private ServerTime serverTime;
@@ -38,8 +37,7 @@ public class DeviceReportRespDTO
@Setter @Setter
@Getter @Getter
public static class Activation public static class Activation {
{
@Schema(description = "激活码") @Schema(description = "激活码")
private String code; private String code;
@@ -50,8 +48,7 @@ public class DeviceReportRespDTO
@Getter @Getter
@Setter @Setter
public static class ServerTime public static class ServerTime {
{
@Schema(description = "时间戳") @Schema(description = "时间戳")
private Long timestamp; private Long timestamp;
@@ -1,10 +1,11 @@
package xiaozhi.modules.device.dto; package xiaozhi.modules.device.dto;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 设备解绑表单 * 设备解绑表单
*/ */
@@ -1,11 +1,12 @@
package xiaozhi.modules.device.entity; package xiaozhi.modules.device.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.util.Date;
@Data @Data
@TableName("ai_device") @TableName("ai_device")
@Schema(description = "设备信息") @Schema(description = "设备信息")
@@ -1,13 +1,23 @@
package xiaozhi.modules.device.service.impl; package xiaozhi.modules.device.service.impl;
import cn.hutool.core.util.RandomUtil; import java.time.Instant;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import java.util.Date;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.HashMap;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hutool.core.util.RandomUtil;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
@@ -20,10 +30,6 @@ import xiaozhi.modules.device.entity.DeviceEntity;
import xiaozhi.modules.device.service.DeviceService; import xiaozhi.modules.device.service.DeviceService;
import xiaozhi.modules.security.user.SecurityUser; import xiaozhi.modules.security.user.SecurityUser;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Service @Service
public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity> implements DeviceService { public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity> implements DeviceService {
@@ -35,8 +41,8 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
// 添加构造函数来初始化 deviceMapper // 添加构造函数来初始化 deviceMapper
public DeviceServiceImpl(DeviceDao deviceDao, public DeviceServiceImpl(DeviceDao deviceDao,
@Value("${app.fronted-url:http://localhost:8001}") String frontedUrl, @Value("${app.fronted-url:http://localhost:8001}") String frontedUrl,
RedisTemplate<String, Object> redisTemplate) { RedisTemplate<String, Object> redisTemplate) {
this.deviceDao = deviceDao; this.deviceDao = deviceDao;
this.frontedUrl = frontedUrl; this.frontedUrl = frontedUrl;
this.redisTemplate = redisTemplate; this.redisTemplate = redisTemplate;
@@ -104,22 +110,23 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
} }
@Override @Override
public DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId, DeviceReportReqDTO deviceReport) { public DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId,
DeviceReportReqDTO deviceReport) {
DeviceReportRespDTO response = new DeviceReportRespDTO(); DeviceReportRespDTO response = new DeviceReportRespDTO();
response.setServerTime(buildServerTime()); response.setServerTime(buildServerTime());
// todo: 此处是固件信息,目前是针对固件上传上来的版本号再返回回去 // todo: 此处是固件信息,目前是针对固件上传上来的版本号再返回回去
// 在未来开发了固件更新功能,需要更换此处代码, // 在未来开发了固件更新功能,需要更换此处代码,
// 或写定时任务定期请求虾哥的OTA,获取最新的版本讯息保存到服务内 // 或写定时任务定期请求虾哥的OTA,获取最新的版本讯息保存到服务内
DeviceReportRespDTO.Firmware firmware = new DeviceReportRespDTO.Firmware(); DeviceReportRespDTO.Firmware firmware = new DeviceReportRespDTO.Firmware();
firmware.setVersion(deviceReport.getApplication().getVersion()); firmware.setVersion(deviceReport.getApplication().getVersion());
firmware.setUrl("http://localhost:8002/xiaozhi-esp32-api/api/v1/ota/download"); firmware.setUrl("http://localhost:8002/xiaozhi-esp32-api/api/v1/ota/download");
response.setFirmware(firmware); response.setFirmware(firmware);
DeviceEntity deviceById = getDeviceById(deviceId); DeviceEntity deviceById = getDeviceById(deviceId);
if (deviceById != null) { // 如果设备存在,则更新上次连接时间 if (deviceById != null) { // 如果设备存在,则更新上次连接时间
deviceById.setLastConnectedAt(new Date()); deviceById.setLastConnectedAt(new Date());
deviceDao.updateById(deviceById); deviceDao.updateById(deviceById);
} else { // 如果设备不存在,则生成激活码 } else { // 如果设备不存在,则生成激活码
String safeDeviceId = deviceId.replace(":", "_").toLowerCase(); String safeDeviceId = deviceId.replace(":", "_").toLowerCase();
String dataKey = String.format("ota:activation:data:%s", safeDeviceId); String dataKey = String.format("ota:activation:data:%s", safeDeviceId);
@@ -161,8 +168,6 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
return response; return response;
} }
@Override @Override
public DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader) { public DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader) {
DeviceEntity device = new DeviceEntity(); DeviceEntity device = new DeviceEntity();
@@ -189,13 +194,11 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
public PageData<DeviceEntity> adminDeviceList(Map<String, Object> params) { public PageData<DeviceEntity> adminDeviceList(Map<String, Object> params) {
IPage<DeviceEntity> page = deviceDao.selectPage( IPage<DeviceEntity> page = deviceDao.selectPage(
getPage(params, "sort", true), getPage(params, "sort", true),
new QueryWrapper<>() new QueryWrapper<>());
);
return new PageData<>(page.getRecords(), page.getTotal()); return new PageData<>(page.getRecords(), page.getTotal());
} }
private DeviceReportRespDTO.ServerTime buildServerTime() private DeviceReportRespDTO.ServerTime buildServerTime() {
{
DeviceReportRespDTO.ServerTime serverTime = new DeviceReportRespDTO.ServerTime(); DeviceReportRespDTO.ServerTime serverTime = new DeviceReportRespDTO.ServerTime();
TimeZone tz = TimeZone.getDefault(); TimeZone tz = TimeZone.getDefault();
serverTime.setTimestamp(Instant.now().toEpochMilli()); serverTime.setTimestamp(Instant.now().toEpochMilli());
@@ -1,22 +1,21 @@
package xiaozhi.modules.device.utils; package xiaozhi.modules.device.utils;
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
/** /**
* 网络工具类 * 网络工具类
*/ */
public class NetworkUtil public class NetworkUtil {
{
/** /**
* MAC地址正则表达式 * MAC地址正则表达式
*/ */
private static final Pattern macPattern = Pattern.compile("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"); private static final Pattern macPattern = Pattern.compile("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$");
/** /**
* 判断MAC地址是否合法 * 判断MAC地址是否合法
*/ */
public static boolean isMacAddressValid(String mac) { public static boolean isMacAddressValid(String mac) {
if (StringUtils.isBlank(mac)) { if (StringUtils.isBlank(mac)) {
return false; return false;
@@ -17,6 +17,7 @@ public class DeviceOtaVO {
public Activation() { public Activation() {
} }
public Activation(String code, String message) { public Activation(String code, String message) {
this.code = code; this.code = code;
this.message = message; this.message = message;
@@ -35,6 +36,7 @@ public class DeviceOtaVO {
public ServerTime() { public ServerTime() {
} }
public ServerTime(Long timestamp, Integer timezone_offset) { public ServerTime(Long timestamp, Integer timezone_offset) {
this.timestamp = timestamp; this.timestamp = timestamp;
this.timezone_offset = timezone_offset; this.timezone_offset = timezone_offset;
@@ -45,8 +47,10 @@ public class DeviceOtaVO {
public static class Firmware { public static class Firmware {
private String version; private String version;
private String url; private String url;
public Firmware() { public Firmware() {
} }
public Firmware(String version, String url) { public Firmware(String version, String url) {
this.version = version; this.version = version;
this.url = url; this.url = url;
@@ -1,10 +1,21 @@
package xiaozhi.modules.model.controller; package xiaozhi.modules.model.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
import xiaozhi.modules.model.dto.ModelConfigBodyDTO; import xiaozhi.modules.model.dto.ModelConfigBodyDTO;
@@ -13,8 +24,6 @@ import xiaozhi.modules.model.dto.ModelProviderDTO;
import xiaozhi.modules.model.service.ModelConfigService; import xiaozhi.modules.model.service.ModelConfigService;
import xiaozhi.modules.model.service.ModelProviderService; import xiaozhi.modules.model.service.ModelProviderService;
import java.util.List;
@AllArgsConstructor @AllArgsConstructor
@RestController @RestController
@RequestMapping("/models") @RequestMapping("/models")
@@ -29,7 +38,7 @@ public class ModelController {
@Operation(summary = "获取所有模型名称") @Operation(summary = "获取所有模型名称")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<List<String>> getModelNames(@RequestParam String modelType, public Result<List<String>> getModelNames(@RequestParam String modelType,
@RequestParam(required = false) String modelName) { @RequestParam(required = false) String modelName) {
List<String> modelNameList = modelConfigService.getModelCodeList(modelType, modelName); List<String> modelNameList = modelConfigService.getModelCodeList(modelType, modelName);
return new Result<List<String>>().ok(modelNameList); return new Result<List<String>>().ok(modelNameList);
} }
@@ -45,51 +54,49 @@ public class ModelController {
@GetMapping("/{modelType}/{provideCode}/fields") @GetMapping("/{modelType}/{provideCode}/fields")
@Operation(summary = "获取模型供应器字段") @Operation(summary = "获取模型供应器字段")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<List<String>> getModelProviderFields(@PathVariable String modelType, @PathVariable String provideCode) { public Result<List<String>> getModelProviderFields(@PathVariable String modelType,
@PathVariable String provideCode) {
List<String> fieldList = modelProviderService.getFieldList(modelType, provideCode); List<String> fieldList = modelProviderService.getFieldList(modelType, provideCode);
return new Result<List<String>>().ok(fieldList); return new Result<List<String>>().ok(fieldList);
} }
@GetMapping("/models/list") @GetMapping("/models/list")
@Operation(summary = "获取模型配置列表") @Operation(summary = "获取模型配置列表")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<PageData<ModelConfigDTO>> getModelConfigList(@RequestParam String modelType, public Result<PageData<ModelConfigDTO>> getModelConfigList(@RequestParam String modelType,
@RequestParam(required = false) String modelName, @RequestParam(required = false) String modelName,
@RequestParam(required = false, defaultValue = "0") Integer page, @RequestParam(required = false, defaultValue = "0") Integer page,
@RequestParam(required = false,defaultValue = "10") Integer limit) { @RequestParam(required = false, defaultValue = "10") Integer limit) {
PageData<ModelConfigDTO> pageList = modelConfigService.getPageList(modelType, modelName, page, limit); PageData<ModelConfigDTO> pageList = modelConfigService.getPageList(modelType, modelName, page, limit);
return new Result<PageData<ModelConfigDTO>>().ok(pageList); return new Result<PageData<ModelConfigDTO>>().ok(pageList);
} }
@PostMapping("/models/{modelType}/{provideCode}") @PostMapping("/models/{modelType}/{provideCode}")
@Operation(summary = "新增模型配置") @Operation(summary = "新增模型配置")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<ModelConfigDTO> addModelConfig(@PathVariable String modelType, public Result<ModelConfigDTO> addModelConfig(@PathVariable String modelType,
@PathVariable String provideCode, @PathVariable String provideCode,
@RequestBody ModelConfigBodyDTO modelConfigBodyDTO) { @RequestBody ModelConfigBodyDTO modelConfigBodyDTO) {
ModelConfigDTO modelConfigDTO = modelConfigService.add(modelType, provideCode, modelConfigBodyDTO); ModelConfigDTO modelConfigDTO = modelConfigService.add(modelType, provideCode, modelConfigBodyDTO);
return new Result<ModelConfigDTO>().ok(modelConfigDTO); return new Result<ModelConfigDTO>().ok(modelConfigDTO);
} }
@PutMapping("/models/{modelType}/{provideCode}/{id}") @PutMapping("/models/{modelType}/{provideCode}/{id}")
@Operation(summary = "编辑模型配置") @Operation(summary = "编辑模型配置")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<ModelConfigDTO> editModelConfig(@PathVariable String modelType, public Result<ModelConfigDTO> editModelConfig(@PathVariable String modelType,
@PathVariable String provideCode, @PathVariable String provideCode,
@PathVariable String id, @PathVariable String id,
@RequestBody ModelConfigBodyDTO modelConfigBodyDTO) { @RequestBody ModelConfigBodyDTO modelConfigBodyDTO) {
ModelConfigDTO modelConfigDTO = modelConfigService.edit(modelType, provideCode, id, modelConfigBodyDTO); ModelConfigDTO modelConfigDTO = modelConfigService.edit(modelType, provideCode, id, modelConfigBodyDTO);
return new Result<ModelConfigDTO>().ok(modelConfigDTO); return new Result<ModelConfigDTO>().ok(modelConfigDTO);
} }
@DeleteMapping("/models/{modelType}/{provideCode}/{id}") @DeleteMapping("/models/{modelType}/{provideCode}/{id}")
@Operation(summary = "删除模型配置") @Operation(summary = "删除模型配置")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<Void> deleteModelConfig(@PathVariable String modelType, @PathVariable String provideCode, @PathVariable String id) { public Result<Void> deleteModelConfig(@PathVariable String modelType, @PathVariable String provideCode,
@PathVariable String id) {
modelConfigService.delete(modelType, provideCode, id); modelConfigService.delete(modelType, provideCode, id);
return new Result<>(); return new Result<>();
} }
@@ -98,7 +105,7 @@ public class ModelController {
@Operation(summary = "获取模型音色") @Operation(summary = "获取模型音色")
@RequiresPermissions("sys:role:normal") @RequiresPermissions("sys:role:normal")
public Result<List<String>> getVoiceList(@PathVariable String modelName, public Result<List<String>> getVoiceList(@PathVariable String modelName,
@RequestParam(required = false) String voiceName) { @RequestParam(required = false) String voiceName) {
List<String> voiceList = modelConfigService.getVoiceList(modelName, voiceName); List<String> voiceList = modelConfigService.getVoiceList(modelName, voiceName);
return new Result<List<String>>().ok(voiceList); return new Result<List<String>>().ok(voiceList);
@@ -1,12 +1,13 @@
package xiaozhi.modules.model.dao; package xiaozhi.modules.model.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.model.entity.ModelConfigEntity; import xiaozhi.modules.model.entity.ModelConfigEntity;
import java.util.List;
@Mapper @Mapper
public interface ModelConfigDao extends BaseDao<ModelConfigEntity> { public interface ModelConfigDao extends BaseDao<ModelConfigEntity> {
@@ -1,12 +1,13 @@
package xiaozhi.modules.model.dao; package xiaozhi.modules.model.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.model.entity.ModelProviderEntity; import xiaozhi.modules.model.entity.ModelProviderEntity;
import java.util.List;
@Mapper @Mapper
public interface ModelProviderDao extends BaseDao<ModelProviderEntity> { public interface ModelProviderDao extends BaseDao<ModelProviderEntity> {
@@ -1,10 +1,10 @@
package xiaozhi.modules.model.dto; package xiaozhi.modules.model.dto;
import java.io.Serial;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serial;
@Data @Data
@Schema(description = "模型供应器/商") @Schema(description = "模型供应器/商")
public class ModelConfigBodyDTO { public class ModelConfigBodyDTO {
@@ -12,9 +12,9 @@ public class ModelConfigBodyDTO {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") // @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)")
// private String modelType; // private String modelType;
// //
@Schema(description = "模型编码(如AliLLM、DoubaoTTS)") @Schema(description = "模型编码(如AliLLM、DoubaoTTS)")
private String modelCode; private String modelCode;
@@ -1,11 +1,11 @@
package xiaozhi.modules.model.dto; package xiaozhi.modules.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data @Data
@Schema(description = "模型供应器/商") @Schema(description = "模型供应器/商")
public class ModelConfigDTO implements Serializable { public class ModelConfigDTO implements Serializable {
@@ -1,19 +1,20 @@
package xiaozhi.modules.model.dto; package xiaozhi.modules.model.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data @Data
@Schema(description = "模型供应器/商") @Schema(description = "模型供应器/商")
public class ModelProviderDTO implements Serializable { public class ModelProviderDTO implements Serializable {
// //
// @Schema(description = "主键") // @Schema(description = "主键")
// private Long id; // private Long id;
@Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)")
private String modelType; private String modelType;
@@ -1,16 +1,16 @@
package xiaozhi.modules.model.entity; package xiaozhi.modules.model.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.util.Date;
@Data @Data
@TableName("ai_model_config") @TableName("ai_model_config")
@Schema(description = "模型配置表") @Schema(description = "模型配置表")
@@ -1,15 +1,16 @@
package xiaozhi.modules.model.entity; package xiaozhi.modules.model.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.util.Date;
@Data @Data
@TableName("ai_model_provider") @TableName("ai_model_provider")
@Schema(description = "模型供应器表") @Schema(description = "模型供应器表")
@@ -1,11 +1,11 @@
package xiaozhi.modules.model.service; package xiaozhi.modules.model.service;
import java.util.List;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.modules.model.dto.ModelConfigBodyDTO; import xiaozhi.modules.model.dto.ModelConfigBodyDTO;
import xiaozhi.modules.model.dto.ModelConfigDTO; import xiaozhi.modules.model.dto.ModelConfigDTO;
import java.util.List;
public interface ModelConfigService { public interface ModelConfigService {
List<String> getModelCodeList(String modelType, String modelName); List<String> getModelCodeList(String modelType, String modelName);
@@ -1,13 +1,13 @@
package xiaozhi.modules.model.service; package xiaozhi.modules.model.service;
import java.util.List;
import xiaozhi.modules.model.dto.ModelProviderDTO; import xiaozhi.modules.model.dto.ModelProviderDTO;
import xiaozhi.modules.model.entity.ModelProviderEntity; import xiaozhi.modules.model.entity.ModelProviderEntity;
import java.util.List;
public interface ModelProviderService { public interface ModelProviderService {
// List<String> getModelNames(String modelType, String modelName); // List<String> getModelNames(String modelType, String modelName);
List<ModelProviderDTO> getListByModelType(String modelType); List<ModelProviderDTO> getListByModelType(String modelType);
@@ -1,13 +1,19 @@
package xiaozhi.modules.model.service.impl; package xiaozhi.modules.model.service.impl;
import cn.hutool.core.collection.CollectionUtil; import java.util.HashMap;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.Map;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
@@ -22,13 +28,10 @@ import xiaozhi.modules.model.service.ModelConfigService;
import xiaozhi.modules.model.service.ModelProviderService; import xiaozhi.modules.model.service.ModelProviderService;
import xiaozhi.modules.timbre.service.TimbreService; import xiaozhi.modules.timbre.service.TimbreService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, ModelConfigEntity> implements ModelConfigService { public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, ModelConfigEntity>
implements ModelConfigService {
private final ModelConfigDao modelConfigDao; private final ModelConfigDao modelConfigDao;
private final ModelProviderService modelProviderService; private final ModelProviderService modelProviderService;
@@ -50,8 +53,7 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
getPage(params, "sort", true), getPage(params, "sort", true),
new QueryWrapper<ModelConfigEntity>() new QueryWrapper<ModelConfigEntity>()
.eq("model_type", modelType) .eq("model_type", modelType)
.like(StringUtils.isNotBlank(modelName), "model_name", modelName) .like(StringUtils.isNotBlank(modelName), "model_name", modelName));
);
return getPageData(modelConfigEntityIPage, ModelConfigDTO.class); return getPageData(modelConfigEntityIPage, ModelConfigDTO.class);
} }
@@ -119,6 +121,6 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
ModelConfigEntity modelConfigEntity = modelConfigEntities.get(0); ModelConfigEntity modelConfigEntity = modelConfigEntities.get(0);
String id = modelConfigEntity.getId(); String id = modelConfigEntity.getId();
return timbreService.getVoiceNames(id, voiceName); return timbreService.getVoiceNames(id, voiceName);
} }
} }
@@ -1,9 +1,13 @@
package xiaozhi.modules.model.service.impl; package xiaozhi.modules.model.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.List;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.modules.model.dao.ModelProviderDao; import xiaozhi.modules.model.dao.ModelProviderDao;
@@ -11,11 +15,10 @@ import xiaozhi.modules.model.dto.ModelProviderDTO;
import xiaozhi.modules.model.entity.ModelProviderEntity; import xiaozhi.modules.model.entity.ModelProviderEntity;
import xiaozhi.modules.model.service.ModelProviderService; import xiaozhi.modules.model.service.ModelProviderService;
import java.util.List;
@Service @Service
@AllArgsConstructor @AllArgsConstructor
public class ModelProviderServiceImpl extends BaseServiceImpl<ModelProviderDao, ModelProviderEntity> implements ModelProviderService { public class ModelProviderServiceImpl extends BaseServiceImpl<ModelProviderDao, ModelProviderEntity>
implements ModelProviderService {
private final ModelProviderDao modelProviderDao; private final ModelProviderDao modelProviderDao;
@@ -5,7 +5,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.filter.DelegatingFilterProxy;
/** /**
* Filter配置 * Filter配置
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -18,7 +17,7 @@ public class FilterConfig {
public FilterRegistrationBean<DelegatingFilterProxy> shiroFilterRegistration() { public FilterRegistrationBean<DelegatingFilterProxy> shiroFilterRegistration() {
FilterRegistrationBean<DelegatingFilterProxy> registration = new FilterRegistrationBean<>(); FilterRegistrationBean<DelegatingFilterProxy> registration = new FilterRegistrationBean<>();
registration.setFilter(new DelegatingFilterProxy("shiroFilter")); registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
//该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 // 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理
registration.addInitParameter("targetFilterLifecycle", "true"); registration.addInitParameter("targetFilterLifecycle", "true");
registration.setEnabled(true); registration.setEnabled(true);
registration.setOrder(Integer.MAX_VALUE - 1); registration.setOrder(Integer.MAX_VALUE - 1);
@@ -1,9 +1,8 @@
package xiaozhi.modules.security.config; package xiaozhi.modules.security.config;
import com.fasterxml.jackson.databind.DeserializationFeature; import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.TimeZone;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.ByteArrayHttpMessageConverter;
@@ -15,8 +14,10 @@ import org.springframework.http.converter.support.AllEncompassingFormHttpMessage
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List; import com.fasterxml.jackson.databind.DeserializationFeature;
import java.util.TimeZone; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@Configuration @Configuration
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {
@@ -45,14 +46,14 @@ public class WebMvcConfig implements WebMvcConfigurer {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
//忽略未知属性 // 忽略未知属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//日期格式转换 // 日期格式转换
//mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN)); // mapper.setDateFormat(new SimpleDateFormat(DateUtils.DATE_TIME_PATTERN));
mapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); mapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//Long类型转String类型 // Long类型转String类型
SimpleModule simpleModule = new SimpleModule(); SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance); simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
@@ -1,12 +1,13 @@
package xiaozhi.modules.security.dao; package xiaozhi.modules.security.dao;
import java.util.Date;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.security.entity.SysUserTokenEntity; import xiaozhi.modules.security.entity.SysUserTokenEntity;
import java.util.Date;
/** /**
* 系统用户Token * 系统用户Token
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,11 +1,11 @@
package xiaozhi.modules.security.dto; package xiaozhi.modules.security.dto;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 登录表单 * 登录表单
*/ */
@@ -1,13 +1,14 @@
package xiaozhi.modules.security.entity; package xiaozhi.modules.security.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable; import lombok.Data;
import java.util.Date;
/** /**
* 系统用户Token * 系统用户Token
@@ -1,7 +1,15 @@
package xiaozhi.modules.security.oauth2; package xiaozhi.modules.security.oauth2;
import jakarta.annotation.Resource; import java.util.HashSet;
import org.apache.shiro.authc.*; import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.realm.AuthorizingRealm;
@@ -10,6 +18,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import jakarta.annotation.Resource;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.user.UserDetail; import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
@@ -19,9 +29,6 @@ import xiaozhi.modules.security.service.ShiroService;
import xiaozhi.modules.sys.entity.SysUserEntity; import xiaozhi.modules.sys.entity.SysUserEntity;
import xiaozhi.modules.sys.enums.SuperAdminEnum; import xiaozhi.modules.sys.enums.SuperAdminEnum;
import java.util.HashSet;
import java.util.Set;
/** /**
* 认证 * 认证
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -47,7 +54,7 @@ public class Oauth2Realm extends AuthorizingRealm {
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
UserDetail user = (UserDetail) principals.getPrimaryPrincipal(); UserDetail user = (UserDetail) principals.getPrimaryPrincipal();
//用户权限列表 // 用户权限列表
Set<String> permsSet = new HashSet<>(); Set<String> permsSet = new HashSet<>();
if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) { if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
@@ -69,22 +76,22 @@ public class Oauth2Realm extends AuthorizingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String accessToken = (String) token.getPrincipal(); String accessToken = (String) token.getPrincipal();
//根据accessToken,查询用户信息 // 根据accessToken,查询用户信息
SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken); SysUserTokenEntity tokenEntity = shiroService.getByToken(accessToken);
//token失效 // token失效
if (tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) { if (tokenEntity == null || tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID)); throw new IncorrectCredentialsException(MessageUtils.getMessage(ErrorCode.TOKEN_INVALID));
} }
//查询用户信息 // 查询用户信息
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId()); SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
//转换成UserDetail对象 // 转换成UserDetail对象
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class); UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
userDetail.setToken(accessToken); userDetail.setToken(accessToken);
//账号锁定 // 账号锁定
if (userDetail.getStatus() == null) { if (userDetail.getStatus() == null) {
logger.error("账号状态异常,status 不能为空"); logger.error("账号状态异常,status 不能为空");
throw new DisabledAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_DISABLE)); throw new DisabledAccountException(MessageUtils.getMessage(ErrorCode.ACCOUNT_DISABLE));
@@ -1,10 +1,10 @@
package xiaozhi.modules.security.oauth2; package xiaozhi.modules.security.oauth2;
import xiaozhi.common.exception.RenException;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.UUID; import java.util.UUID;
import xiaozhi.common.exception.RenException;
/** /**
* 生成token * 生成token
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -5,22 +5,28 @@ import java.io.UnsupportedEncodingException;
import java.security.SecureRandom; import java.security.SecureRandom;
/** /**
* BCrypt implements OpenBSD-style Blowfish password hashing using the scheme described in * BCrypt implements OpenBSD-style Blowfish password hashing using the scheme
* described in
* "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres. * "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres.
* <p> * <p>
* This password hashing system tries to thwart off-line password cracking using a * This password hashing system tries to thwart off-line password cracking using
* computationally-intensive hashing algorithm, based on Bruce Schneier's Blowfish cipher. * a
* The work factor of the algorithm is parameterised, so it can be increased as computers * computationally-intensive hashing algorithm, based on Bruce Schneier's
* Blowfish cipher.
* The work factor of the algorithm is parameterised, so it can be increased as
* computers
* get faster. * get faster.
* <p> * <p>
* Usage is really simple. To hash a password for the first time, call the hashpw method * Usage is really simple. To hash a password for the first time, call the
* hashpw method
* with a random salt, like this: * with a random salt, like this:
* <p> * <p>
* <code> * <code>
* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br> * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br>
* </code> * </code>
* <p> * <p>
* To check whether a plaintext password matches one that has been hashed previously, use * To check whether a plaintext password matches one that has been hashed
* previously, use
* the checkpw method: * the checkpw method:
* <p> * <p>
* <code> * <code>
@@ -30,7 +36,8 @@ import java.security.SecureRandom;
* &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It does not match");<br> * &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It does not match");<br>
* </code> * </code>
* <p> * <p>
* The gensalt() method takes an optional parameter (log_rounds) that determines the * The gensalt() method takes an optional parameter (log_rounds) that determines
* the
* computational complexity of the hashing: * computational complexity of the hashing:
* <p> * <p>
* <code> * <code>
@@ -38,7 +45,8 @@ import java.security.SecureRandom;
* String stronger_salt = BCrypt.gensalt(12)<br> * String stronger_salt = BCrypt.gensalt(12)<br>
* </code> * </code>
* <p> * <p>
* The amount of work increases exponentially (2**log_rounds), so each increment is twice * The amount of work increases exponentially (2**log_rounds), so each increment
* is twice
* as much work. The default log_rounds is 10, and the valid range is 4 to 31. * as much work. The default log_rounds is 10, and the valid range is 4 to 31.
* *
* @author Damien Miller * @author Damien Miller
@@ -51,11 +59,11 @@ public class BCrypt {
// Blowfish parameters // Blowfish parameters
private static final int BLOWFISH_NUM_ROUNDS = 16; private static final int BLOWFISH_NUM_ROUNDS = 16;
// Initial contents of key schedule // Initial contents of key schedule
private static final int P_orig[] = {0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, private static final int P_orig[] = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377,
0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b}; 0x9216d5d9, 0x8979fb1b };
private static final int S_orig[] = {0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, private static final int S_orig[] = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7,
0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5,
@@ -225,24 +233,24 @@ public class BCrypt {
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76,
0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0,
0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}; 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 };
// bcrypt IV: "OrpheanBeholderScryDoubt" // bcrypt IV: "OrpheanBeholderScryDoubt"
static private final int bf_crypt_ciphertext[] = {0x4f727068, 0x65616e42, static private final int bf_crypt_ciphertext[] = { 0x4f727068, 0x65616e42,
0x65686f6c, 0x64657253, 0x63727944, 0x6f756274}; 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 };
// Table for Base64 encoding // Table for Base64 encoding
static private final char base64_code[] = {'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', static private final char base64_code[] = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
// Table for Base64 decoding // Table for Base64 decoding
static private final byte index_64[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, static private final byte index_64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1}; 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1 };
static final int MIN_LOG_ROUNDS = 4; static final int MIN_LOG_ROUNDS = 4;
static final int MAX_LOG_ROUNDS = 31; static final int MAX_LOG_ROUNDS = 31;
// Expanded Blowfish key // Expanded Blowfish key
@@ -250,7 +258,8 @@ public class BCrypt {
private int S[]; private int S[];
/** /**
* Encode a byte array using bcrypt's slightly-modified base64 encoding scheme. Note * Encode a byte array using bcrypt's slightly-modified base64 encoding scheme.
* Note
* that this is <strong>not</strong> compatible with the standard MIME-base64 * that this is <strong>not</strong> compatible with the standard MIME-base64
* encoding. * encoding.
* *
@@ -306,7 +315,8 @@ public class BCrypt {
} }
/** /**
* Decode a string encoded using bcrypt's base64 scheme to a byte array. Note that * Decode a string encoded using bcrypt's base64 scheme to a byte array. Note
* that
* this is *not* compatible with the standard MIME-base64 encoding. * this is *not* compatible with the standard MIME-base64 encoding.
* *
* @param s the string to decode * @param s the string to decode
@@ -365,7 +375,7 @@ public class BCrypt {
int i, n, l = lr[off], r = lr[off + 1]; int i, n, l = lr[off], r = lr[off + 1];
l ^= P[0]; l ^= P[0];
for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2; ) { for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
// Feistel substitution on left word // Feistel substitution on left word
n = S[(l >> 24) & 0xff]; n = S[(l >> 24) & 0xff];
n += S[0x100 | ((l >> 16) & 0xff)]; n += S[0x100 | ((l >> 16) & 0xff)];
@@ -388,7 +398,8 @@ public class BCrypt {
* Cycically extract a word of key material * Cycically extract a word of key material
* *
* @param data the string to extract the data from * @param data the string to extract the data from
* @param offp a "pointer" (as a one-entry array) to the current offset into data * @param offp a "pointer" (as a one-entry array) to the current offset into
* data
* @return the next word of material from data * @return the next word of material from data
*/ */
private static int streamtoword(byte data[], int offp[]) { private static int streamtoword(byte data[], int offp[]) {
@@ -420,8 +431,8 @@ public class BCrypt {
*/ */
private void key(byte key[]) { private void key(byte key[]) {
int i; int i;
int koffp[] = {0}; int koffp[] = { 0 };
int lr[] = {0, 0}; int lr[] = { 0, 0 };
int plen = P.length, slen = S.length; int plen = P.length, slen = S.length;
for (i = 0; i < plen; i++) { for (i = 0; i < plen; i++) {
@@ -443,15 +454,16 @@ public class BCrypt {
/** /**
* Perform the "enhanced key schedule" step described by Provos and Mazieres in * Perform the "enhanced key schedule" step described by Provos and Mazieres in
* "A Future-Adaptable Password Scheme" http://www.openbsd.org/papers/bcrypt-paper.ps * "A Future-Adaptable Password Scheme"
* http://www.openbsd.org/papers/bcrypt-paper.ps
* *
* @param data salt information * @param data salt information
* @param key password information * @param key password information
*/ */
private void ekskey(byte data[], byte key[]) { private void ekskey(byte data[], byte key[]) {
int i; int i;
int koffp[] = {0}, doffp[] = {0}; int koffp[] = { 0 }, doffp[] = { 0 };
int lr[] = {0, 0}; int lr[] = { 0, 0 };
int plen = P.length, slen = S.length; int plen = P.length, slen = S.length;
for (i = 0; i < plen; i++) { for (i = 0; i < plen; i++) {
@@ -487,7 +499,8 @@ public class BCrypt {
* *
* @param password the password to hash * @param password the password to hash
* @param salt the binary salt to hash with the password * @param salt the binary salt to hash with the password
* @param log_rounds the binary logarithm of the number of rounds of hashing to apply * @param log_rounds the binary logarithm of the number of rounds of hashing to
* apply
* @return an array containing the binary hashed password * @return an array containing the binary hashed password
*/ */
private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
@@ -524,7 +537,8 @@ public class BCrypt {
* Hash a password using the OpenBSD bcrypt scheme * Hash a password using the OpenBSD bcrypt scheme
* *
* @param password the password to hash * @param password the password to hash
* @param salt the salt to hash with (perhaps generated using BCrypt.gensalt) * @param salt the salt to hash with (perhaps generated using
* BCrypt.gensalt)
* @return the hashed password * @return the hashed password
* @throws IllegalArgumentException if invalid salt is passed * @throws IllegalArgumentException if invalid salt is passed
*/ */
@@ -599,8 +613,10 @@ public class BCrypt {
/** /**
* Generate a salt for use with the BCrypt.hashpw() method * Generate a salt for use with the BCrypt.hashpw() method
* *
* @param log_rounds the log2 of the number of rounds of hashing to apply - the work * @param log_rounds the log2 of the number of rounds of hashing to apply - the
* factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. * work
* factor therefore increases as 2**log_rounds. Minimum 4,
* maximum 31.
* @param random an instance of SecureRandom to use * @param random an instance of SecureRandom to use
* @return an encoded salt value * @return an encoded salt value
*/ */
@@ -626,8 +642,10 @@ public class BCrypt {
/** /**
* Generate a salt for use with the BCrypt.hashpw() method * Generate a salt for use with the BCrypt.hashpw() method
* *
* @param log_rounds the log2 of the number of rounds of hashing to apply - the work * @param log_rounds the log2 of the number of rounds of hashing to apply - the
* factor therefore increases as 2**log_rounds. Minimum 4, maximum 31. * work
* factor therefore increases as 2**log_rounds. Minimum 4,
* maximum 31.
* @return an encoded salt value * @return an encoded salt value
*/ */
public static String gensalt(int log_rounds) { public static String gensalt(int log_rounds) {
@@ -635,7 +653,8 @@ public class BCrypt {
} }
/** /**
* Generate a salt for use with the BCrypt.hashpw() method, selecting a reasonable * Generate a salt for use with the BCrypt.hashpw() method, selecting a
* reasonable
* default for the number of hashing rounds to apply * default for the number of hashing rounds to apply
* *
* @return an encoded salt value * @return an encoded salt value
@@ -1,15 +1,18 @@
package xiaozhi.modules.security.password; package xiaozhi.modules.security.password;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** /**
* Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients * Implementation of PasswordEncoder that uses the BCrypt strong hashing
* can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom * function. Clients
* instance. The larger the strength parameter the more work will have to be done * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a
* SecureRandom
* instance. The larger the strength parameter the more work will have to be
* done
* (exponentially) to hash the passwords. The default value is 10. * (exponentially) to hash the passwords. The default value is 10.
* *
* @author Dave Syer * @author Dave Syer
@@ -10,20 +10,23 @@ package xiaozhi.modules.security.password;
public interface PasswordEncoder { public interface PasswordEncoder {
/** /**
* Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1
* or
* greater hash combined with an 8-byte or greater randomly generated salt. * greater hash combined with an 8-byte or greater randomly generated salt.
*/ */
String encode(CharSequence rawPassword); String encode(CharSequence rawPassword);
/** /**
* Verify the encoded password obtained from storage matches the submitted raw * Verify the encoded password obtained from storage matches the submitted raw
* password after it too is encoded. Returns true if the passwords match, false if * password after it too is encoded. Returns true if the passwords match, false
* if
* they do not. The stored password itself is never decoded. * they do not. The stored password itself is never decoded.
* *
* @param rawPassword the raw password to encode and match * @param rawPassword the raw password to encode and match
* @param encodedPassword the encoded password from storage to compare with * @param encodedPassword the encoded password from storage to compare with
* @return true if the raw password, after encoding, matches the encoded password from * @return true if the raw password, after encoding, matches the encoded
* storage * password from
* storage
*/ */
boolean matches(CharSequence rawPassword, String encodedPassword); boolean matches(CharSequence rawPassword, String encodedPassword);
@@ -18,19 +18,17 @@ public class PasswordUtils {
return passwordEncoder.encode(str); return passwordEncoder.encode(str);
} }
/** /**
* 比较密码是否相等 * 比较密码是否相等
* *
* @param str 明文密码 * @param str 明文密码
* @param password 加密后密码 * @param password 加密后密码
* @return true:成功 false:失败 * @return true:成功 false:失败
*/ */
public static boolean matches(String str, String password) { public static boolean matches(String str, String password) {
return passwordEncoder.matches(str, password); return passwordEncoder.matches(str, password);
} }
public static void main(String[] args) { public static void main(String[] args) {
String str = "admin"; String str = "admin";
String password = encode(str); String password = encode(str);
@@ -1,9 +1,9 @@
package xiaozhi.modules.security.service; package xiaozhi.modules.security.service;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import jakarta.servlet.http.HttpServletResponse;
/** /**
* 验证码 * 验证码
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -21,7 +21,7 @@ public interface CaptchaService {
* *
* @param uuid uuid * @param uuid uuid
* @param code 验证码 * @param code 验证码
* @return true:成功 false:失败 * @return true:成功 false:失败
*/ */
boolean validate(String uuid, String code); boolean validate(String uuid, String code);
} }
@@ -1,9 +1,10 @@
package xiaozhi.modules.security.user; package xiaozhi.modules.security.user;
import xiaozhi.common.user.UserDetail;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject;
import xiaozhi.common.user.UserDetail;
/** /**
* Shiro工具类 * Shiro工具类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -1,9 +1,10 @@
package xiaozhi.modules.sys.controller; package xiaozhi.modules.sys.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** /**
* 用户管理 * 用户管理
@@ -1,12 +1,13 @@
package xiaozhi.modules.sys.dao; package xiaozhi.modules.sys.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.dto.SysDictDataDTO; import xiaozhi.modules.sys.dto.SysDictDataDTO;
import xiaozhi.modules.sys.entity.DictData; import xiaozhi.modules.sys.entity.DictData;
import xiaozhi.modules.sys.entity.SysDictDataEntity; import xiaozhi.modules.sys.entity.SysDictDataEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* 字典数据 * 字典数据
@@ -1,11 +1,12 @@
package xiaozhi.modules.sys.dao; package xiaozhi.modules.sys.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.entity.DictType; import xiaozhi.modules.sys.entity.DictType;
import xiaozhi.modules.sys.entity.SysDictTypeEntity; import xiaozhi.modules.sys.entity.SysDictTypeEntity;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* 字典类型 * 字典类型
@@ -1,11 +1,12 @@
package xiaozhi.modules.sys.dao; package xiaozhi.modules.sys.dao;
import xiaozhi.common.dao.BaseDao; import java.util.List;
import xiaozhi.modules.sys.entity.SysParamsEntity;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.entity.SysParamsEntity;
/** /**
* 参数管理 * 参数管理
@@ -1,6 +1,7 @@
package xiaozhi.modules.sys.dao; package xiaozhi.modules.sys.dao;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.entity.SysUserEntity; import xiaozhi.modules.sys.entity.SysUserEntity;
@@ -1,11 +1,11 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* 修改密码 * 修改密码
*/ */
@@ -1,20 +1,21 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.validator.group.AddGroup;
import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null; import jakarta.validation.constraints.Null;
import lombok.Data; import lombok.Data;
import xiaozhi.common.utils.DateUtils;
import java.io.Serializable; import xiaozhi.common.validator.group.AddGroup;
import java.util.Date; import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
/** /**
* 字典数据 * 字典数据
@@ -23,7 +24,6 @@ import java.util.Date;
@Schema(description = "字典数据") @Schema(description = "字典数据")
public class SysDictDataDTO implements Serializable { public class SysDictDataDTO implements Serializable {
@Schema(description = "id") @Schema(description = "id")
@Null(message = "{id.null}", groups = AddGroup.class) @Null(message = "{id.null}", groups = AddGroup.class)
@NotNull(message = "{id.require}", groups = UpdateGroup.class) @NotNull(message = "{id.require}", groups = UpdateGroup.class)
@@ -1,20 +1,21 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.validator.group.AddGroup;
import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null; import jakarta.validation.constraints.Null;
import lombok.Data; import lombok.Data;
import xiaozhi.common.utils.DateUtils;
import java.io.Serializable; import xiaozhi.common.validator.group.AddGroup;
import java.util.Date; import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
/** /**
* 字典类型 * 字典类型
@@ -23,7 +24,6 @@ import java.util.Date;
@Schema(description = "字典类型") @Schema(description = "字典类型")
public class SysDictTypeDTO implements Serializable { public class SysDictTypeDTO implements Serializable {
@Schema(description = "id") @Schema(description = "id")
@Null(message = "{id.null}", groups = AddGroup.class) @Null(message = "{id.null}", groups = AddGroup.class)
@NotNull(message = "{id.require}", groups = UpdateGroup.class) @NotNull(message = "{id.require}", groups = UpdateGroup.class)
@@ -1,19 +1,20 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.validator.group.AddGroup;
import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null; import jakarta.validation.constraints.Null;
import lombok.Data; import lombok.Data;
import xiaozhi.common.utils.DateUtils;
import java.io.Serializable; import xiaozhi.common.validator.group.AddGroup;
import java.util.Date; import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
/** /**
* 参数管理 * 参数管理
@@ -22,7 +23,6 @@ import java.util.Date;
@Schema(description = "参数管理") @Schema(description = "参数管理")
public class SysParamsDTO implements Serializable { public class SysParamsDTO implements Serializable {
@Schema(description = "id") @Schema(description = "id")
@Null(message = "{id.null}", groups = AddGroup.class) @Null(message = "{id.null}", groups = AddGroup.class)
@NotNull(message = "{id.require}", groups = UpdateGroup.class) @NotNull(message = "{id.require}", groups = UpdateGroup.class)
@@ -1,22 +1,24 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import org.hibernate.validator.constraints.Range;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.validator.group.AddGroup;
import xiaozhi.common.validator.group.DefaultGroup;
import xiaozhi.common.validator.group.UpdateGroup;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Null; import jakarta.validation.constraints.Null;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Range; import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.validator.group.AddGroup;
import java.io.Serializable; import xiaozhi.common.validator.group.DefaultGroup;
import java.util.Date; import xiaozhi.common.validator.group.UpdateGroup;
import java.util.List;
/** /**
* 用户管理 * 用户管理
@@ -1,6 +1,7 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
/** /**
@@ -1,11 +1,12 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
/** /**
* 字典类型 * 字典类型
*/ */
@@ -1,13 +1,14 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import xiaozhi.common.entity.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import xiaozhi.common.entity.BaseEntity;
import java.util.Date;
/** /**
* 数据字典 * 数据字典
@@ -1,13 +1,14 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import xiaozhi.common.entity.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import xiaozhi.common.entity.BaseEntity;
import java.util.Date;
/** /**
* 字典类型 * 字典类型
@@ -1,13 +1,14 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import xiaozhi.common.entity.BaseEntity;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import xiaozhi.common.entity.BaseEntity;
import java.util.Date;
/** /**
* 参数管理 * 参数管理
@@ -25,7 +26,7 @@ public class SysParamsEntity extends BaseEntity {
*/ */
private String paramValue; private String paramValue;
/** /**
* 类型 0:系统参数 1:非系统参数 * 类型 0:系统参数 1:非系统参数
*/ */
private Integer paramType; private Integer paramType;
/** /**
@@ -1,14 +1,15 @@
package xiaozhi.modules.sys.entity; package xiaozhi.modules.sys.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import xiaozhi.common.entity.BaseEntity; import xiaozhi.common.entity.BaseEntity;
import java.util.Date;
/** /**
* 系统用户 * 系统用户
*/ */
@@ -25,11 +26,11 @@ public class SysUserEntity extends BaseEntity {
*/ */
private String password; private String password;
/** /**
* 超级管理员 0:否 1:是 * 超级管理员 0:否 1:是
*/ */
private Integer superAdmin; private Integer superAdmin;
/** /**
* 状态 0:停用 1:正常 * 状态 0:停用 1:正常
*/ */
private Integer status; private Integer status;
/** /**
@@ -1,9 +1,10 @@
package xiaozhi.modules.sys.redis; package xiaozhi.modules.sys.redis;
import org.springframework.stereotype.Component;
import lombok.AllArgsConstructor;
import xiaozhi.common.redis.RedisKeys; import xiaozhi.common.redis.RedisKeys;
import xiaozhi.common.redis.RedisUtils; import xiaozhi.common.redis.RedisUtils;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
/** /**
* 参数管理 * 参数管理
@@ -1,12 +1,12 @@
package xiaozhi.modules.sys.service; package xiaozhi.modules.sys.service;
import java.util.Map;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.sys.dto.SysDictDataDTO; import xiaozhi.modules.sys.dto.SysDictDataDTO;
import xiaozhi.modules.sys.entity.SysDictDataEntity; import xiaozhi.modules.sys.entity.SysDictDataEntity;
import java.util.Map;
/** /**
* 数据字典 * 数据字典
*/ */
@@ -1,14 +1,14 @@
package xiaozhi.modules.sys.service; package xiaozhi.modules.sys.service;
import java.util.List;
import java.util.Map;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.sys.dto.SysDictTypeDTO; import xiaozhi.modules.sys.dto.SysDictTypeDTO;
import xiaozhi.modules.sys.entity.DictType; import xiaozhi.modules.sys.entity.DictType;
import xiaozhi.modules.sys.entity.SysDictTypeEntity; import xiaozhi.modules.sys.entity.SysDictTypeEntity;
import java.util.List;
import java.util.Map;
/** /**
* 数据字典 * 数据字典
*/ */
@@ -1,14 +1,13 @@
package xiaozhi.modules.sys.service; package xiaozhi.modules.sys.service;
import java.util.List;
import java.util.Map;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.sys.dto.SysParamsDTO; import xiaozhi.modules.sys.dto.SysParamsDTO;
import xiaozhi.modules.sys.entity.SysParamsEntity; import xiaozhi.modules.sys.entity.SysParamsEntity;
import java.util.List;
import java.util.Map;
/** /**
* 参数管理 * 参数管理
*/ */
@@ -8,7 +8,6 @@ import xiaozhi.modules.sys.dto.SysUserDTO;
import xiaozhi.modules.sys.entity.SysUserEntity; import xiaozhi.modules.sys.entity.SysUserEntity;
import xiaozhi.modules.sys.vo.AdminPageUserVO; import xiaozhi.modules.sys.vo.AdminPageUserVO;
/** /**
* 系统用户 * 系统用户
*/ */
@@ -24,26 +23,31 @@ public interface SysUserService extends BaseService<SysUserEntity> {
/** /**
* 验证是否允许修改密码更改 * 验证是否允许修改密码更改
* @param userId 用户id *
* @param userId 用户id
* @param passwordDTO 验证密码的参数 * @param passwordDTO 验证密码的参数
*/ */
void changePassword(Long userId, PasswordDTO passwordDTO); void changePassword(Long userId, PasswordDTO passwordDTO);
/** /**
* 直接修改密码,不需要验证 * 直接修改密码,不需要验证
* @param userId 用户id *
* @param userId 用户id
* @param password 密码 * @param password 密码
*/ */
void changePasswordDirectly(Long userId, String password); void changePasswordDirectly(Long userId, String password);
/** /**
* 重置密码 * 重置密码
*
* @param userId 用户id * @param userId 用户id
* @return 随机生成符合规范的密码 * @return 随机生成符合规范的密码
*/ */
String resetPassword(Long userId); String resetPassword(Long userId);
/** /**
* 管理员分页用户信息 * 管理员分页用户信息
*
* @param dto 分页查找参数 * @param dto 分页查找参数
* @return 用户列表分页数据 * @return 用户列表分页数据
*/ */
@@ -1,10 +1,15 @@
package xiaozhi.modules.sys.service.impl; package xiaozhi.modules.sys.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.Arrays;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
@@ -13,21 +18,18 @@ import xiaozhi.modules.sys.dto.SysDictDataDTO;
import xiaozhi.modules.sys.entity.SysDictDataEntity; import xiaozhi.modules.sys.entity.SysDictDataEntity;
import xiaozhi.modules.sys.service.SysDictDataService; import xiaozhi.modules.sys.service.SysDictDataService;
import java.util.Arrays;
import java.util.Map;
/** /**
* 字典类型 * 字典类型
*/ */
@Service @Service
public class SysDictDataServiceImpl extends BaseServiceImpl<SysDictDataDao, SysDictDataEntity> implements SysDictDataService { public class SysDictDataServiceImpl extends BaseServiceImpl<SysDictDataDao, SysDictDataEntity>
implements SysDictDataService {
@Override @Override
public PageData<SysDictDataDTO> page(Map<String, Object> params) { public PageData<SysDictDataDTO> page(Map<String, Object> params) {
IPage<SysDictDataEntity> page = baseDao.selectPage( IPage<SysDictDataEntity> page = baseDao.selectPage(
getPage(params, "sort", true), getPage(params, "sort", true),
getWrapper(params) getWrapper(params));
);
return getPageData(page, SysDictDataDTO.class); return getPageData(page, SysDictDataDTO.class);
} }
@@ -71,7 +73,7 @@ public class SysDictDataServiceImpl extends BaseServiceImpl<SysDictDataDao, SysD
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long[] ids) { public void delete(Long[] ids) {
//删除 // 删除
deleteBatchIds(Arrays.asList(ids)); deleteBatchIds(Arrays.asList(ids));
} }
} }
@@ -1,11 +1,17 @@
package xiaozhi.modules.sys.service.impl; package xiaozhi.modules.sys.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.Arrays;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.List;
import lombok.AllArgsConstructor; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
@@ -17,24 +23,20 @@ import xiaozhi.modules.sys.entity.DictType;
import xiaozhi.modules.sys.entity.SysDictTypeEntity; import xiaozhi.modules.sys.entity.SysDictTypeEntity;
import xiaozhi.modules.sys.service.SysDictTypeService; import xiaozhi.modules.sys.service.SysDictTypeService;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/** /**
* 字典类型 * 字典类型
*/ */
@AllArgsConstructor @AllArgsConstructor
@Service @Service
public class SysDictTypeServiceImpl extends BaseServiceImpl<SysDictTypeDao, SysDictTypeEntity> implements SysDictTypeService { public class SysDictTypeServiceImpl extends BaseServiceImpl<SysDictTypeDao, SysDictTypeEntity>
implements SysDictTypeService {
private final SysDictDataDao sysDictDataDao; private final SysDictDataDao sysDictDataDao;
@Override @Override
public PageData<SysDictTypeDTO> page(Map<String, Object> params) { public PageData<SysDictTypeDTO> page(Map<String, Object> params) {
IPage<SysDictTypeEntity> page = baseDao.selectPage( IPage<SysDictTypeEntity> page = baseDao.selectPage(
getPage(params, "sort", true), getPage(params, "sort", true),
getWrapper(params) getWrapper(params));
);
return getPageData(page, SysDictTypeDTO.class); return getPageData(page, SysDictTypeDTO.class);
} }
@@ -76,7 +78,7 @@ public class SysDictTypeServiceImpl extends BaseServiceImpl<SysDictTypeDao, SysD
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long[] ids) { public void delete(Long[] ids) {
//删除 // 删除
deleteBatchIds(Arrays.asList(ids)); deleteBatchIds(Arrays.asList(ids));
} }
@@ -6,6 +6,7 @@ import lombok.Data;
/** /**
* 管理员分页展示用户的VO * 管理员分页展示用户的VO
* @ zjy * @ zjy
*
* @since 2025-3-25 * @since 2025-3-25
*/ */
@Data @Data
@@ -1,12 +1,23 @@
package xiaozhi.modules.timbre.controller; package xiaozhi.modules.timbre.controller;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
@@ -16,8 +27,6 @@ import xiaozhi.modules.timbre.dto.TimbrePageDTO;
import xiaozhi.modules.timbre.service.TimbreService; import xiaozhi.modules.timbre.service.TimbreService;
import xiaozhi.modules.timbre.vo.TimbreDetailsVO; import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
import java.util.Map;
/** /**
* 音色控制层 * 音色控制层
* *
@@ -77,9 +86,8 @@ public class TimbreController {
@Operation(summary = "音色删除") @Operation(summary = "音色删除")
@RequiresPermissions("sys:role:superAdmin") @RequiresPermissions("sys:role:superAdmin")
public Result<Void> delete(@PathVariable Long id) { public Result<Void> delete(@PathVariable Long id) {
timbreService.delete(new Long[]{id}); timbreService.delete(new Long[] { id });
return new Result<>(); return new Result<>();
} }
} }
@@ -1,11 +1,14 @@
package xiaozhi.modules.timbre.dao; package xiaozhi.modules.timbre.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xiaozhi.modules.timbre.entity.TimbreEntity; import xiaozhi.modules.timbre.entity.TimbreEntity;
/** /**
* 音色持久层定义 * 音色持久层定义
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
@@ -5,9 +5,9 @@ import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
/** /**
* 音色表数据DTO * 音色表数据DTO
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
@@ -6,6 +6,7 @@ import lombok.Data;
/** /**
* 音色分页参数DTO * 音色分页参数DTO
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
@@ -1,15 +1,17 @@
package xiaozhi.modules.timbre.entity; package xiaozhi.modules.timbre.entity;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import xiaozhi.common.entity.BaseEntity; import xiaozhi.common.entity.BaseEntity;
import java.util.Date;
/** /**
* 音色表实体类 * 音色表实体类
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
@@ -1,5 +1,7 @@
package xiaozhi.modules.timbre.service; package xiaozhi.modules.timbre.service;
import java.util.List;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.modules.timbre.dto.TimbreDataDTO; import xiaozhi.modules.timbre.dto.TimbreDataDTO;
@@ -7,17 +9,16 @@ import xiaozhi.modules.timbre.dto.TimbrePageDTO;
import xiaozhi.modules.timbre.entity.TimbreEntity; import xiaozhi.modules.timbre.entity.TimbreEntity;
import xiaozhi.modules.timbre.vo.TimbreDetailsVO; import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
import java.util.List;
/** /**
* 音色的业务层的定义 * 音色的业务层的定义
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
public interface TimbreService extends BaseService<TimbreEntity> { public interface TimbreService extends BaseService<TimbreEntity> {
/** /**
* 分页获取音色指定tts的下的音色 * 分页获取音色指定tts的下的音色
*
* @param dto 分页查找参数 * @param dto 分页查找参数
* @return 音色列表分页数据 * @return 音色列表分页数据
*/ */
@@ -25,6 +26,7 @@ public interface TimbreService extends BaseService<TimbreEntity> {
/** /**
* 获取音色指定id的详情信息 * 获取音色指定id的详情信息
*
* @param timbreId 音色表id * @param timbreId 音色表id
* @return 音色信息 * @return 音色信息
*/ */
@@ -32,19 +34,22 @@ public interface TimbreService extends BaseService<TimbreEntity> {
/** /**
* 保存音色信息 * 保存音色信息
*
* @param dto 需要保存数据 * @param dto 需要保存数据
*/ */
void save(TimbreDataDTO dto); void save(TimbreDataDTO dto);
/** /**
* 保存音色信息 * 保存音色信息
*
* @param timbreId 需要修改的id * @param timbreId 需要修改的id
* @param dto 需要修改的数据 * @param dto 需要修改的数据
*/ */
void update(Long timbreId,TimbreDataDTO dto); void update(Long timbreId, TimbreDataDTO dto);
/** /**
* 批量删除音色 * 批量删除音色
*
* @param ids 需要被删除的音色id列表 * @param ids 需要被删除的音色id列表
*/ */
void delete(Long[] ids); void delete(Long[] ids);
@@ -1,12 +1,19 @@
package xiaozhi.modules.timbre.service.impl; package xiaozhi.modules.timbre.service.impl;
import cn.hutool.core.collection.CollectionUtil; import java.util.Arrays;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import java.util.HashMap;
import com.baomidou.mybatisplus.core.metadata.IPage; import java.util.List;
import lombok.AllArgsConstructor; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
@@ -18,13 +25,9 @@ import xiaozhi.modules.timbre.entity.TimbreEntity;
import xiaozhi.modules.timbre.service.TimbreService; import xiaozhi.modules.timbre.service.TimbreService;
import xiaozhi.modules.timbre.vo.TimbreDetailsVO; import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* 音色的业务层的实现 * 音色的业务层的实现
*
* @author zjy * @author zjy
* @since 2025-3-21 * @since 2025-3-21
*/ */
@@ -38,16 +41,15 @@ public class TimbreServiceImpl extends BaseServiceImpl<TimbreDao, TimbreEntity>
public PageData<TimbreDetailsVO> page(TimbrePageDTO dto) { public PageData<TimbreDetailsVO> page(TimbrePageDTO dto) {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<String, Object>();
params.put(Constant.PAGE, dto.getPage()); params.put(Constant.PAGE, dto.getPage());
params.put(Constant.LIMIT,dto.getLimit()); params.put(Constant.LIMIT, dto.getLimit());
IPage<TimbreEntity> page = baseDao.selectPage( IPage<TimbreEntity> page = baseDao.selectPage(
getPage(params, "sort", true), getPage(params, "sort", true),
//定义查询条件 // 定义查询条件
new QueryWrapper<TimbreEntity>() new QueryWrapper<TimbreEntity>()
//必须按照ttsID查找 // 必须按照ttsID查找
.eq("tts_model_id",dto.getTtsModelId()) .eq("tts_model_id", dto.getTtsModelId())
//如果有音色名字,按照音色名模糊查找 // 如果有音色名字,按照音色名模糊查找
.like(StringUtils.isNotBlank(dto.getName()),"name",dto.getName()) .like(StringUtils.isNotBlank(dto.getName()), "name", dto.getName()));
);
return getPageData(page, TimbreDetailsVO.class); return getPageData(page, TimbreDetailsVO.class);
} }
@@ -99,7 +101,7 @@ public class TimbreServiceImpl extends BaseServiceImpl<TimbreDao, TimbreEntity>
/** /**
* 处理是不是tts模型的id * 处理是不是tts模型的id
*/ */
private void isTtsModelId(String ttsModelId){ private void isTtsModelId(String ttsModelId) {
//等模型配置那边写好调用方法判断 // 等模型配置那边写好调用方法判断
} }
} }

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