mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 07:03:53 +08:00
update:优化泛型代码
This commit is contained in:
@@ -167,12 +167,6 @@
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- SLF4J + Log4j2 实现(可选) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- 阿里云maven仓库 -->
|
||||
|
||||
@@ -6,11 +6,11 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 日期转换
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package xiaozhi.common.exception;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import xiaozhi.common.utils.Result;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import xiaozhi.common.utils.Result;
|
||||
|
||||
/**
|
||||
* 异常处理器
|
||||
@@ -23,35 +23,34 @@ public class RenExceptionHandler {
|
||||
* 处理自定义异常
|
||||
*/
|
||||
@ExceptionHandler(RenException.class)
|
||||
public Result handleRenException(RenException ex) {
|
||||
Result result = new Result();
|
||||
public Result<Void> handleRenException(RenException ex) {
|
||||
Result<Void> result = new Result<>();
|
||||
result.error(ex.getCode(), ex.getMsg());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public Result handleDuplicateKeyException(DuplicateKeyException ex) {
|
||||
Result result = new Result();
|
||||
public Result<Void> handleDuplicateKeyException(DuplicateKeyException ex) {
|
||||
Result<Void> result = new Result<>();
|
||||
result.error(ErrorCode.DB_RECORD_EXISTS);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ExceptionHandler(UnauthorizedException.class)
|
||||
public Result handleUnauthorizedException(UnauthorizedException ex) {
|
||||
Result result = new Result();
|
||||
public Result<Void> handleUnauthorizedException(UnauthorizedException ex) {
|
||||
Result<Void> result = new Result<>();
|
||||
result.error(ErrorCode.FORBIDDEN);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result handleException(Exception ex) {
|
||||
public Result<Void> handleException(Exception ex) {
|
||||
log.error(ex.getMessage(), ex);
|
||||
|
||||
return new Result().error();
|
||||
return new Result<Void>().error();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
package xiaozhi.common.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.user.UserDetail;
|
||||
import xiaozhi.modules.security.user.SecurityUser;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.user.UserDetail;
|
||||
import xiaozhi.modules.security.user.SecurityUser;
|
||||
|
||||
/**
|
||||
* 公共字段,自动填充值
|
||||
@@ -22,35 +24,34 @@ public class FieldMetaObjectHandler implements MetaObjectHandler {
|
||||
private final static String UPDATER = "updater";
|
||||
|
||||
private final static String DATA_OPERATION = "dataOperation";
|
||||
private final static String DEPT_ID = "deptId";
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
Date date = new Date();
|
||||
|
||||
//创建者
|
||||
// 创建者
|
||||
strictInsertFill(metaObject, CREATOR, Long.class, user.getId());
|
||||
//创建时间
|
||||
// 创建时间
|
||||
strictInsertFill(metaObject, CREATE_DATE, Date.class, date);
|
||||
|
||||
//更新者
|
||||
// 更新者
|
||||
strictInsertFill(metaObject, UPDATER, Long.class, user.getId());
|
||||
//更新时间
|
||||
// 更新时间
|
||||
strictInsertFill(metaObject, UPDATE_DATE, Date.class, date);
|
||||
|
||||
//数据标识
|
||||
// 数据标识
|
||||
strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.INSERT.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
//更新者
|
||||
// 更新者
|
||||
strictUpdateFill(metaObject, UPDATER, Long.class, SecurityUser.getUserId());
|
||||
//更新时间
|
||||
// 更新时间
|
||||
strictUpdateFill(metaObject, UPDATE_DATE, Date.class, new Date());
|
||||
|
||||
//数据标识
|
||||
// 数据标识
|
||||
strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.UPDATE.getValue());
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -1,8 +1,17 @@
|
||||
package xiaozhi.common.interceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.StringValue;
|
||||
@@ -10,13 +19,6 @@ import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.Select;
|
||||
import org.apache.ibatis.executor.Executor;
|
||||
import org.apache.ibatis.mapping.BoundSql;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.session.ResultHandler;
|
||||
import org.apache.ibatis.session.RowBounds;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据过滤
|
||||
@@ -25,8 +27,10 @@ import java.util.Map;
|
||||
*/
|
||||
public class DataFilterInterceptor implements InnerInterceptor {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
|
||||
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds,
|
||||
ResultHandler resultHandler, BoundSql boundSql) {
|
||||
DataScope scope = getDataScope(parameter);
|
||||
// 不进行数据过滤
|
||||
if (scope == null || StrUtil.isBlank(scope.getSqlFilter())) {
|
||||
@@ -48,7 +52,7 @@ public class DataFilterInterceptor implements InnerInterceptor {
|
||||
// 判断参数里是否有DataScope对象
|
||||
if (parameter instanceof Map) {
|
||||
Map<?, ?> parameterMap = (Map<?, ?>) parameter;
|
||||
for (Map.Entry entry : parameterMap.entrySet()) {
|
||||
for (Map.Entry<?, ?> entry : parameterMap.entrySet()) {
|
||||
if (entry.getValue() != null && entry.getValue() instanceof DataScope) {
|
||||
return (DataScope) entry.getValue();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package xiaozhi.common.service.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
@@ -10,22 +23,11 @@ import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
|
||||
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.page.PageData;
|
||||
import xiaozhi.common.service.BaseService;
|
||||
import xiaozhi.common.utils.ConvertUtils;
|
||||
import org.apache.ibatis.binding.MapperMethod;
|
||||
import org.apache.ibatis.logging.Log;
|
||||
import org.apache.ibatis.logging.LogFactory;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* 基础服务类,所有Service都要继承
|
||||
@@ -45,7 +47,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
* @param isAsc 排序方式
|
||||
*/
|
||||
protected IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
|
||||
//分页参数
|
||||
// 分页参数
|
||||
long curPage = 1;
|
||||
long limit = 10;
|
||||
|
||||
@@ -56,17 +58,17 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
limit = Long.parseLong((String) params.get(Constant.LIMIT));
|
||||
}
|
||||
|
||||
//分页对象
|
||||
// 分页对象
|
||||
Page<T> page = new Page<>(curPage, limit);
|
||||
|
||||
//分页参数
|
||||
// 分页参数
|
||||
params.put(Constant.PAGE, page);
|
||||
|
||||
//排序字段
|
||||
// 排序字段
|
||||
String orderField = (String) params.get(Constant.ORDER_FIELD);
|
||||
String order = (String) params.get(Constant.ORDER);
|
||||
|
||||
//前端字段排序
|
||||
// 前端字段排序
|
||||
if (StringUtils.isNotBlank(orderField) && StringUtils.isNotBlank(order)) {
|
||||
if (Constant.ASC.equalsIgnoreCase(order)) {
|
||||
return page.addOrder(OrderItem.asc(orderField));
|
||||
@@ -75,12 +77,12 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
}
|
||||
}
|
||||
|
||||
//没有排序字段,则不排序
|
||||
// 没有排序字段,则不排序
|
||||
if (StringUtils.isBlank(defaultOrderField)) {
|
||||
return page;
|
||||
}
|
||||
|
||||
//默认排序
|
||||
// 默认排序
|
||||
if (isAsc) {
|
||||
page.addOrder(OrderItem.asc(defaultOrderField));
|
||||
} else {
|
||||
@@ -90,13 +92,13 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
return page;
|
||||
}
|
||||
|
||||
protected <T> PageData<T> getPageData(List<?> list, long total, Class<T> target) {
|
||||
List<T> targetList = ConvertUtils.sourceToTarget(list, target);
|
||||
protected <D> PageData<D> getPageData(List<?> list, long total, Class<D> target) {
|
||||
List<D> targetList = ConvertUtils.sourceToTarget(list, target);
|
||||
|
||||
return new PageData<>(targetList, total);
|
||||
}
|
||||
|
||||
protected <T> PageData<T> getPageData(IPage page, Class<T> target) {
|
||||
protected <D> PageData<D> getPageData(IPage<?> page, Class<D> target) {
|
||||
return getPageData(page.getRecords(), page.getTotal(), target);
|
||||
}
|
||||
|
||||
@@ -126,10 +128,12 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
return SqlHelper.retBool(result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<M> currentMapperClass() {
|
||||
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<T> currentModelClass() {
|
||||
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1);
|
||||
@@ -164,11 +168,11 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
|
||||
/**
|
||||
* 执行批量操作
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
|
||||
return SqlHelper.executeBatch(this.currentModelClass(), this.log, list, batchSize, consumer);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateById(T entity) {
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
package xiaozhi.common.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||
import xiaozhi.common.page.PageData;
|
||||
import xiaozhi.common.service.CrudService;
|
||||
import xiaozhi.common.utils.ConvertUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
||||
|
||||
import xiaozhi.common.page.PageData;
|
||||
import xiaozhi.common.service.CrudService;
|
||||
import xiaozhi.common.utils.ConvertUtils;
|
||||
|
||||
/**
|
||||
* CRUD基础服务类
|
||||
* Copyright (c) 人人开源 All rights reserved.
|
||||
* Website: https://www.renren.io
|
||||
*/
|
||||
public abstract class CrudServiceImpl<M extends BaseMapper<T>, T, D> extends BaseServiceImpl<M, T> implements CrudService<T, D> {
|
||||
public abstract class CrudServiceImpl<M extends BaseMapper<T>, T, D> extends BaseServiceImpl<M, T>
|
||||
implements CrudService<T, D> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<D> currentDtoClass() {
|
||||
return (Class<D>) ReflectionKit.getSuperClassGenericType(getClass(), CrudServiceImpl.class, 2);
|
||||
}
|
||||
@@ -29,8 +33,7 @@ public abstract class CrudServiceImpl<M extends BaseMapper<T>, T, D> extends Bas
|
||||
public PageData<D> page(Map<String, Object> params) {
|
||||
IPage<T> page = baseDao.selectPage(
|
||||
getPage(params, null, false),
|
||||
getWrapper(params)
|
||||
);
|
||||
getWrapper(params));
|
||||
|
||||
return getPageData(page, currentDtoClass());
|
||||
}
|
||||
@@ -56,7 +59,7 @@ public abstract class CrudServiceImpl<M extends BaseMapper<T>, T, D> extends Bas
|
||||
T entity = ConvertUtils.sourceToTarget(dto, currentModelClass());
|
||||
insert(entity);
|
||||
|
||||
//copy主键值到dto
|
||||
// copy主键值到dto
|
||||
BeanUtils.copyProperties(entity, dto);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package xiaozhi.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 转换工具类
|
||||
* Copyright (c) 人人开源 All rights reserved.
|
||||
@@ -20,7 +21,7 @@ public class ConvertUtils {
|
||||
}
|
||||
T targetObject = null;
|
||||
try {
|
||||
targetObject = target.newInstance();
|
||||
targetObject = target.getDeclaredConstructor().newInstance();
|
||||
BeanUtils.copyProperties(source, targetObject);
|
||||
} catch (Exception e) {
|
||||
log.error("convert error ", e);
|
||||
@@ -34,10 +35,10 @@ public class ConvertUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
List targetList = new ArrayList<>(sourceList.size());
|
||||
List<T> targetList = new ArrayList<>(sourceList.size());
|
||||
try {
|
||||
for (Object source : sourceList) {
|
||||
T targetObject = target.newInstance();
|
||||
T targetObject = target.getDeclaredConstructor().newInstance();
|
||||
BeanUtils.copyProperties(source, targetObject);
|
||||
targetList.add(targetObject);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package xiaozhi.common.utils;
|
||||
|
||||
import xiaozhi.common.validator.AssertUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import xiaozhi.common.validator.AssertUtils;
|
||||
|
||||
/**
|
||||
* 树形结构工具类,如:菜单、部门等
|
||||
* Copyright (c) 人人开源 All rights reserved.
|
||||
@@ -17,8 +17,8 @@ public class TreeUtils {
|
||||
/**
|
||||
* 根据pid,构建树节点
|
||||
*/
|
||||
public static <T extends TreeNode> List<T> build(List<T> treeNodes, Long pid) {
|
||||
//pid不能为空
|
||||
public static <T extends TreeNode<T>> List<T> build(List<T> treeNodes, Long pid) {
|
||||
// pid不能为空
|
||||
AssertUtils.isNull(pid, "pid");
|
||||
|
||||
List<T> treeList = new ArrayList<>();
|
||||
@@ -34,7 +34,7 @@ public class TreeUtils {
|
||||
/**
|
||||
* 查找子节点
|
||||
*/
|
||||
private static <T extends TreeNode> T findChildren(List<T> treeNodes, T rootNode) {
|
||||
private static <T extends TreeNode<T>> T findChildren(List<T> treeNodes, T rootNode) {
|
||||
for (T treeNode : treeNodes) {
|
||||
if (rootNode.getId().equals(treeNode.getPid())) {
|
||||
rootNode.getChildren().add(findChildren(treeNodes, treeNode));
|
||||
@@ -46,10 +46,10 @@ public class TreeUtils {
|
||||
/**
|
||||
* 构建树节点
|
||||
*/
|
||||
public static <T extends TreeNode> List<T> build(List<T> treeNodes) {
|
||||
public static <T extends TreeNode<T>> List<T> build(List<T> treeNodes) {
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
//list转map
|
||||
// list转map
|
||||
Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size());
|
||||
for (T treeNode : treeNodes) {
|
||||
nodeMap.put(treeNode.getId(), treeNode);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package xiaozhi.common.validator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.exception.RenException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 校验工具类
|
||||
@@ -73,11 +74,11 @@ public class AssertUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void isMapEmpty(Map map, String... params) {
|
||||
public static void isMapEmpty(Map<?, ?> map, String... params) {
|
||||
isMapEmpty(map, ErrorCode.NOT_NULL, params);
|
||||
}
|
||||
|
||||
public static void isMapEmpty(Map map, Integer code, String... params) {
|
||||
public static void isMapEmpty(Map<?, ?> map, Integer code, String... params) {
|
||||
if (code == null) {
|
||||
throw new RenException(ErrorCode.NOT_NULL, "code");
|
||||
}
|
||||
|
||||
+13
-7
@@ -1,13 +1,21 @@
|
||||
package xiaozhi.modules.admin.contrloler;
|
||||
|
||||
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.PutMapping;
|
||||
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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.page.PageData;
|
||||
import xiaozhi.common.utils.Result;
|
||||
@@ -16,8 +24,6 @@ import xiaozhi.modules.sys.dto.AdminPageUserDTO;
|
||||
import xiaozhi.modules.sys.service.SysUserService;
|
||||
import xiaozhi.modules.sys.vo.AdminPageUserVO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 管理员控制层
|
||||
*
|
||||
@@ -64,7 +70,7 @@ public class AdminController {
|
||||
@Operation(summary = "用户删除")
|
||||
@RequiresPermissions("sys:role:superAdmin")
|
||||
public Result<Void> delete(@PathVariable Long id) {
|
||||
sysUserService.delete(new Long[]{id});
|
||||
sysUserService.delete(new Long[] { id });
|
||||
return new Result<>();
|
||||
}
|
||||
|
||||
@@ -78,7 +84,7 @@ public class AdminController {
|
||||
})
|
||||
public Result<Void> pageDevice(
|
||||
@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
|
||||
//TODO 等设备功能模块写好
|
||||
return new Result<Void>().error(600,"等设备功能模块写好");
|
||||
// TODO 等设备功能模块写好
|
||||
return new Result<Void>().error(600, "等设备功能模块写好");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package xiaozhi.modules.agent.vo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import xiaozhi.modules.agent.entity.AgentTemplateEntity;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class AgentTemplateVO extends AgentTemplateEntity {
|
||||
// 角色音色
|
||||
private String ttsModelName;
|
||||
|
||||
+15
-9
@@ -1,13 +1,23 @@
|
||||
package xiaozhi.modules.device.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.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.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.page.PageData;
|
||||
@@ -22,9 +32,6 @@ import xiaozhi.modules.device.entity.DeviceEntity;
|
||||
import xiaozhi.modules.device.service.DeviceService;
|
||||
import xiaozhi.modules.security.user.SecurityUser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "设备管理")
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
@@ -33,7 +40,6 @@ public class DeviceController {
|
||||
private final DeviceService deviceService;
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
|
||||
@PostMapping("/bind/{deviceCode}")
|
||||
@Operation(summary = "绑定设备")
|
||||
@RequiresPermissions("sys:role:normal")
|
||||
@@ -61,10 +67,10 @@ public class DeviceController {
|
||||
@PostMapping("/unbind")
|
||||
@Operation(summary = "解绑设备")
|
||||
@RequiresPermissions("sys:role:normal")
|
||||
public Result unbindDevice(@RequestBody DeviceUnBindDTO unDeviveBind) {
|
||||
public Result<Void> unbindDevice(@RequestBody DeviceUnBindDTO unDeviveBind) {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
deviceService.unbindDevice(user.getId(), unDeviveBind.getDeviceId());
|
||||
return new Result();
|
||||
return new Result<Void>();
|
||||
}
|
||||
|
||||
@GetMapping("/all")
|
||||
|
||||
@@ -1,31 +1,49 @@
|
||||
package xiaozhi.modules.device.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import xiaozhi.common.page.PageData;
|
||||
import xiaozhi.common.service.BaseService;
|
||||
import xiaozhi.modules.device.dto.DeviceHeaderDTO;
|
||||
import xiaozhi.modules.device.dto.DeviceReportReqDTO;
|
||||
import xiaozhi.modules.device.dto.DeviceReportRespDTO;
|
||||
import xiaozhi.modules.device.entity.DeviceEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DeviceService {
|
||||
|
||||
/**
|
||||
* 根据Mac地址获取设备信息
|
||||
*/
|
||||
* 根据Mac地址获取设备信息
|
||||
*/
|
||||
DeviceEntity getDeviceById(String macAddress);
|
||||
|
||||
DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId, DeviceReportReqDTO deviceReport);
|
||||
/**
|
||||
* 检查设备是否激活
|
||||
*/
|
||||
DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId,
|
||||
DeviceReportReqDTO deviceReport);
|
||||
|
||||
/**
|
||||
* 绑定设备
|
||||
*/
|
||||
DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader);
|
||||
|
||||
/**
|
||||
* 获取用户设备列表
|
||||
*/
|
||||
List<DeviceEntity> getUserDevices(Long userId);
|
||||
|
||||
/**
|
||||
* 解绑设备
|
||||
*/
|
||||
void unbindDevice(Long userId, Long deviceId);
|
||||
|
||||
/**
|
||||
* 管理员设备列表
|
||||
*/
|
||||
PageData<DeviceEntity> adminDeviceList(Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* 设备激活
|
||||
*/
|
||||
Boolean deviceActivation(String activationCode);
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package xiaozhi.modules.security.config;
|
||||
|
||||
import xiaozhi.modules.security.oauth2.Oauth2Filter;
|
||||
import xiaozhi.modules.security.oauth2.Oauth2Realm;
|
||||
import jakarta.servlet.Filter;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.apache.shiro.session.mgt.SessionManager;
|
||||
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
|
||||
@@ -14,9 +15,9 @@ import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import jakarta.servlet.Filter;
|
||||
import xiaozhi.modules.security.oauth2.Oauth2Filter;
|
||||
import xiaozhi.modules.security.oauth2.Oauth2Realm;
|
||||
|
||||
/**
|
||||
* Shiro的配置文件
|
||||
@@ -53,17 +54,19 @@ public class ShiroConfig {
|
||||
shiroFilter.setSecurityManager(securityManager);
|
||||
shiroFilter.setShiroFilterConfiguration(config);
|
||||
|
||||
//oauth过滤
|
||||
// oauth过滤
|
||||
Map<String, Filter> filters = new HashMap<>();
|
||||
filters.put("oauth2", new Oauth2Filter());
|
||||
shiroFilter.setFilters(filters);
|
||||
|
||||
//添加Shiro的内置过滤器
|
||||
/*anon:无需认证就可以访问
|
||||
authc:必须认证了才能让问
|
||||
user:必须拥有,记住我功能,才能访问
|
||||
perms:拥有对某个资源的权限才能访问
|
||||
role:拥有某个角色权限才能访问*/
|
||||
// 添加Shiro的内置过滤器
|
||||
/*
|
||||
* anon:无需认证就可以访问
|
||||
* authc:必须认证了才能让问
|
||||
* user:必须拥有,记住我功能,才能访问
|
||||
* perms:拥有对某个资源的权限才能访问
|
||||
* role:拥有某个角色权限才能访问
|
||||
*/
|
||||
Map<String, String> filterMap = new LinkedHashMap<>();
|
||||
filterMap.put("/ota/**", "anon");
|
||||
filterMap.put("/webjars/**", "anon");
|
||||
@@ -74,7 +77,6 @@ public class ShiroConfig {
|
||||
filterMap.put("/user/captcha", "anon");
|
||||
filterMap.put("/user/login", "anon");
|
||||
filterMap.put("/user/register", "anon");
|
||||
filterMap.put("/ota/**", "anon");
|
||||
filterMap.put("/**", "oauth2");
|
||||
shiroFilter.setFilterChainDefinitionMap(filterMap);
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package xiaozhi.modules.security.oauth2;
|
||||
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
@@ -11,14 +9,17 @@ import org.apache.shiro.web.filter.authc.AuthenticatingFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import xiaozhi.common.constant.Constant;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.utils.HttpContextUtils;
|
||||
import xiaozhi.common.utils.JsonUtils;
|
||||
import xiaozhi.common.utils.Result;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* oauth2过滤器
|
||||
* Copyright (c) 人人开源 All rights reserved.
|
||||
@@ -30,7 +31,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
||||
|
||||
@Override
|
||||
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
|
||||
//获取请求token
|
||||
// 获取请求token
|
||||
String token = getRequestToken((HttpServletRequest) request);
|
||||
|
||||
if (StringUtils.isBlank(token)) {
|
||||
@@ -52,7 +53,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
||||
|
||||
@Override
|
||||
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
|
||||
//获取请求token,如果token不存在,直接返回401
|
||||
// 获取请求token,如果token不存在,直接返回401
|
||||
String token = getRequestToken((HttpServletRequest) request);
|
||||
|
||||
if (StringUtils.isBlank(token)) {
|
||||
@@ -63,7 +64,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
||||
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
|
||||
|
||||
String json = JsonUtils.toJsonString(new Result().error(ErrorCode.UNAUTHORIZED));
|
||||
String json = JsonUtils.toJsonString(new Result<Void>().error(ErrorCode.UNAUTHORIZED));
|
||||
|
||||
httpResponse.getWriter().print(json);
|
||||
|
||||
@@ -74,16 +75,17 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
|
||||
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
|
||||
ServletResponse response) {
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
httpResponse.setContentType("application/json;charset=utf-8");
|
||||
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
|
||||
try {
|
||||
//处理登录失败的异常
|
||||
// 处理登录失败的异常
|
||||
logger.error("onLoginFailure:登录失败!", e);
|
||||
Throwable throwable = e.getCause() == null ? e : e.getCause();
|
||||
Result r = new Result().error(ErrorCode.UNAUTHORIZED, throwable.getMessage());
|
||||
Result<Void> r = new Result<Void>().error(ErrorCode.UNAUTHORIZED, throwable.getMessage());
|
||||
|
||||
String json = JsonUtils.toJsonString(r);
|
||||
httpResponse.getWriter().print(json);
|
||||
@@ -99,7 +101,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
|
||||
*/
|
||||
private String getRequestToken(HttpServletRequest httpRequest) {
|
||||
String token = null;
|
||||
//从header中获取token
|
||||
// 从header中获取token
|
||||
String authorization = httpRequest.getHeader(Constant.AUTHORIZATION);
|
||||
if (StringUtils.isNotBlank(authorization) && authorization.startsWith("Bearer ")) {
|
||||
token = authorization.replace("Bearer ", "");
|
||||
|
||||
+20
-21
@@ -1,23 +1,22 @@
|
||||
package xiaozhi.modules.security.service.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import xiaozhi.common.redis.RedisKeys;
|
||||
import xiaozhi.common.redis.RedisUtils;
|
||||
import xiaozhi.modules.security.oauth2.Oauth2Realm;
|
||||
import xiaozhi.modules.security.service.CaptchaService;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import xiaozhi.common.redis.RedisKeys;
|
||||
import xiaozhi.common.redis.RedisUtils;
|
||||
import xiaozhi.modules.security.service.CaptchaService;
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
@@ -29,10 +28,10 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
@Value("${renren.redis.open}")
|
||||
private boolean open;
|
||||
/**
|
||||
* Local Cache 5分钟过期
|
||||
* Local Cache 5分钟过期
|
||||
*/
|
||||
Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build();
|
||||
private static final Logger logger = LoggerFactory.getLogger(Oauth2Realm.class);
|
||||
Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000)
|
||||
.expireAfterAccess(5, TimeUnit.MINUTES).build();
|
||||
|
||||
@Override
|
||||
public void create(HttpServletResponse response, String uuid) throws IOException {
|
||||
@@ -41,13 +40,13 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expires", 0);
|
||||
|
||||
//生成验证码
|
||||
// 生成验证码
|
||||
SpecCaptcha captcha = new SpecCaptcha(150, 40);
|
||||
captcha.setLen(5);
|
||||
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
||||
captcha.out(response.getOutputStream());
|
||||
|
||||
//保存到缓存
|
||||
// 保存到缓存
|
||||
setCache(uuid, captcha.text());
|
||||
}
|
||||
|
||||
@@ -56,10 +55,10 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
if (StringUtils.isBlank(code)) {
|
||||
return false;
|
||||
}
|
||||
//获取验证码
|
||||
// 获取验证码
|
||||
String captcha = getCache(uuid);
|
||||
|
||||
//效验成功
|
||||
// 效验成功
|
||||
if (code.equalsIgnoreCase(captcha)) {
|
||||
return true;
|
||||
}
|
||||
@@ -80,7 +79,7 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
if (open) {
|
||||
key = RedisKeys.getCaptchaKey(key);
|
||||
String captcha = (String) redisUtils.get(key);
|
||||
//删除验证码
|
||||
// 删除验证码
|
||||
if (captcha != null) {
|
||||
redisUtils.delete(key);
|
||||
}
|
||||
@@ -89,7 +88,7 @@ public class CaptchaServiceImpl implements CaptchaService {
|
||||
}
|
||||
|
||||
String captcha = localCache.getIfPresent(key);
|
||||
//删除验证码
|
||||
// 删除验证码
|
||||
if (captcha != null) {
|
||||
localCache.invalidate(key);
|
||||
}
|
||||
|
||||
+3
-8
@@ -1,17 +1,13 @@
|
||||
package xiaozhi.modules.security.service.impl;
|
||||
|
||||
import xiaozhi.common.user.UserDetail;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import xiaozhi.modules.security.dao.SysUserTokenDao;
|
||||
import xiaozhi.modules.security.entity.SysUserTokenEntity;
|
||||
import xiaozhi.modules.security.service.ShiroService;
|
||||
import xiaozhi.modules.sys.dao.SysUserDao;
|
||||
import xiaozhi.modules.sys.entity.SysUserEntity;
|
||||
import xiaozhi.modules.sys.enums.SuperAdminEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
@@ -19,7 +15,6 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
private final SysUserDao sysUserDao;
|
||||
private final SysUserTokenDao sysUserTokenDao;
|
||||
|
||||
|
||||
@Override
|
||||
public SysUserTokenEntity getByToken(String token) {
|
||||
return sysUserTokenDao.getByToken(token);
|
||||
|
||||
+16
-14
@@ -1,8 +1,11 @@
|
||||
package xiaozhi.modules.security.service.impl;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.exception.RenException;
|
||||
import xiaozhi.common.page.TokenDTO;
|
||||
@@ -17,11 +20,10 @@ import xiaozhi.modules.sys.dto.PasswordDTO;
|
||||
import xiaozhi.modules.sys.dto.SysUserDTO;
|
||||
import xiaozhi.modules.sys.service.SysUserService;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, SysUserTokenEntity> implements SysUserTokenService {
|
||||
public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, SysUserTokenEntity>
|
||||
implements SysUserTokenService {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
/**
|
||||
@@ -31,18 +33,18 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
|
||||
|
||||
@Override
|
||||
public Result<TokenDTO> createToken(Long userId) {
|
||||
//用户token
|
||||
// 用户token
|
||||
String token;
|
||||
|
||||
//当前时间
|
||||
// 当前时间
|
||||
Date now = new Date();
|
||||
//过期时间
|
||||
// 过期时间
|
||||
Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
|
||||
|
||||
//判断是否生成过token
|
||||
// 判断是否生成过token
|
||||
SysUserTokenEntity tokenEntity = baseDao.getByUserId(userId);
|
||||
if (tokenEntity == null) {
|
||||
//生成一个token
|
||||
// 生成一个token
|
||||
token = TokenGenerator.generateValue();
|
||||
|
||||
tokenEntity = new SysUserTokenEntity();
|
||||
@@ -51,12 +53,12 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
|
||||
tokenEntity.setUpdateDate(now);
|
||||
tokenEntity.setExpireDate(expireTime);
|
||||
|
||||
//保存token
|
||||
// 保存token
|
||||
this.insert(tokenEntity);
|
||||
} else {
|
||||
//判断token是否过期
|
||||
// 判断token是否过期
|
||||
if (tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
|
||||
//token过期,重新生成token
|
||||
// token过期,重新生成token
|
||||
token = TokenGenerator.generateValue();
|
||||
} else {
|
||||
token = tokenEntity.getToken();
|
||||
@@ -66,7 +68,7 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
|
||||
tokenEntity.setUpdateDate(now);
|
||||
tokenEntity.setExpireDate(expireTime);
|
||||
|
||||
//更新token
|
||||
// 更新token
|
||||
this.updateById(tokenEntity);
|
||||
}
|
||||
|
||||
@@ -76,7 +78,7 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
|
||||
tokenDTO.setToken(token);
|
||||
tokenDTO.setExpire(EXPIRE);
|
||||
tokenDTO.setClientHash(clientHash);
|
||||
return new Result().ok(tokenDTO);
|
||||
return new Result<TokenDTO>().ok(tokenDTO);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package xiaozhi.modules.sys.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 管理员分页用户的参数DTO
|
||||
*
|
||||
* @author zjy
|
||||
* @since 2025-3-21
|
||||
*/
|
||||
@@ -13,7 +13,6 @@ import lombok.Data;
|
||||
@Schema(description = "音色分页参数")
|
||||
public class AdminPageUserDTO {
|
||||
|
||||
|
||||
@Schema(description = "手机号码")
|
||||
private String mobile;
|
||||
|
||||
|
||||
+14
-13
@@ -1,7 +1,17 @@
|
||||
package xiaozhi.modules.sys.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
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.constant.Constant;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.exception.RenException;
|
||||
@@ -14,14 +24,6 @@ import xiaozhi.modules.sys.dto.SysParamsDTO;
|
||||
import xiaozhi.modules.sys.entity.SysParamsEntity;
|
||||
import xiaozhi.modules.sys.redis.SysParamsRedis;
|
||||
import xiaozhi.modules.sys.service.SysParamsService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
@@ -35,8 +37,7 @@ public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParam
|
||||
public PageData<SysParamsDTO> page(Map<String, Object> params) {
|
||||
IPage<SysParamsEntity> page = baseDao.selectPage(
|
||||
getPage(params, Constant.CREATE_DATE, false),
|
||||
getWrapper(params)
|
||||
);
|
||||
getWrapper(params));
|
||||
|
||||
return getPageData(page, SysParamsDTO.class);
|
||||
}
|
||||
@@ -86,12 +87,12 @@ public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParam
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除Redis数据
|
||||
// 删除Redis数据
|
||||
List<String> paramCodeList = baseDao.getParamCodeList(ids);
|
||||
String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]);
|
||||
sysParamsRedis.delete(paramCodes);
|
||||
|
||||
//删除
|
||||
// 删除
|
||||
deleteBatchIds(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
@@ -114,7 +115,7 @@ public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParam
|
||||
}
|
||||
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
return clazz.getDeclaredConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RenException(ErrorCode.PARAMS_GET_ERROR);
|
||||
}
|
||||
|
||||
+29
-23
@@ -1,11 +1,21 @@
|
||||
package xiaozhi.modules.sys.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.AllArgsConstructor;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
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.constant.Constant;
|
||||
import xiaozhi.common.exception.ErrorCode;
|
||||
import xiaozhi.common.exception.RenException;
|
||||
@@ -22,11 +32,6 @@ import xiaozhi.modules.sys.enums.SuperAdminEnum;
|
||||
import xiaozhi.modules.sys.service.SysUserService;
|
||||
import xiaozhi.modules.sys.vo.AdminPageUserVO;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* 系统用户
|
||||
*/
|
||||
@@ -59,16 +64,16 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
public void save(SysUserDTO dto) {
|
||||
SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);
|
||||
|
||||
//密码强度
|
||||
// 密码强度
|
||||
if (!isStrongPassword(entity.getPassword())) {
|
||||
throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR);
|
||||
}
|
||||
|
||||
//密码加密
|
||||
// 密码加密
|
||||
String password = PasswordUtils.encode(entity.getPassword());
|
||||
entity.setPassword(password);
|
||||
|
||||
//保存用户
|
||||
// 保存用户
|
||||
Long userCount = getUserCount();
|
||||
if (userCount == 0) {
|
||||
entity.setSuperAdmin(SuperAdminEnum.YES.value());
|
||||
@@ -83,9 +88,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除用户
|
||||
// 删除用户
|
||||
baseDao.deleteBatchIds(Arrays.asList(ids));
|
||||
//TODO 除了要删除用户还要删除用户关联的设备,对话,智能体。等此3个功能完善在添加
|
||||
// TODO 除了要删除用户还要删除用户关联的设备,对话,智能体。等此3个功能完善在添加
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,19 +107,18 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
throw new RenException("旧密码输入错误");
|
||||
}
|
||||
|
||||
//新密码强度
|
||||
// 新密码强度
|
||||
if (!isStrongPassword(passwordDTO.getNewPassword())) {
|
||||
throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR);
|
||||
}
|
||||
|
||||
//密码加密
|
||||
// 密码加密
|
||||
String password = PasswordUtils.encode(passwordDTO.getNewPassword());
|
||||
sysUserEntity.setPassword(password);
|
||||
|
||||
updateById(sysUserEntity);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void changePasswordDirectly(Long userId, String password) {
|
||||
@@ -128,7 +132,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String resetPassword(Long userId) {
|
||||
String password = generatePassword();
|
||||
changePasswordDirectly(userId,password);
|
||||
changePasswordDirectly(userId, password);
|
||||
return password;
|
||||
}
|
||||
|
||||
@@ -141,18 +145,18 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
public PageData<AdminPageUserVO> page(AdminPageUserDTO dto) {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(Constant.PAGE, dto.getPage());
|
||||
params.put(Constant.LIMIT,dto.getLimit());
|
||||
params.put(Constant.LIMIT, dto.getLimit());
|
||||
IPage<SysUserEntity> page = baseDao.selectPage(
|
||||
getPage(params, "id", true),
|
||||
//定义查询条件
|
||||
// 定义查询条件
|
||||
new QueryWrapper<SysUserEntity>()
|
||||
//必须按照手机号码查找
|
||||
.eq(StringUtils.isNotBlank(dto.getMobile()),"username",dto.getMobile()));
|
||||
// 必须按照手机号码查找
|
||||
.eq(StringUtils.isNotBlank(dto.getMobile()), "username", dto.getMobile()));
|
||||
List<AdminPageUserVO> list = page.getRecords().stream().map(user -> {
|
||||
AdminPageUserVO adminPageUserVO = new AdminPageUserVO();
|
||||
adminPageUserVO.setUserid(user.getId().toString());
|
||||
adminPageUserVO.setMobile(user.getUsername());
|
||||
//TODO 2. 等设备功能写好,获取对应数据
|
||||
// TODO 2. 等设备功能写好,获取对应数据
|
||||
adminPageUserVO.setDeviceCount("0");
|
||||
return adminPageUserVO;
|
||||
}).toList();
|
||||
@@ -169,11 +173,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
|
||||
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
|
||||
private static final Random random = new Random();
|
||||
|
||||
/**
|
||||
* 生成随机密码
|
||||
*
|
||||
* @return 随机生成的密码
|
||||
*/
|
||||
private String generatePassword(){
|
||||
private String generatePassword() {
|
||||
StringBuilder password = new StringBuilder();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int randomIndex = random.nextInt(CHARACTERS.length());
|
||||
|
||||
+3
-15
@@ -1,31 +1,19 @@
|
||||
package xiaozhi.modules.sys.service.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import xiaozhi.common.redis.RedisUtils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import xiaozhi.modules.security.oauth2.TokenGenerator;
|
||||
import xiaozhi.modules.sys.service.TokenService;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class TokenServiceImpl implements TokenService {
|
||||
private final RedisUtils redisUtils;
|
||||
/**
|
||||
* 3小时无操作过期
|
||||
*/
|
||||
private final static int EXPIRE = 60 * 60 * 3;
|
||||
|
||||
@Override
|
||||
public String createToken(long userId) {
|
||||
//生成一个token
|
||||
// 生成一个token
|
||||
String token = TokenGenerator.generateValue();
|
||||
|
||||
//当前时间
|
||||
Date now = new Date();
|
||||
//过期时间
|
||||
Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ renren:
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
#实体扫描,多个package用逗号或者分号分隔
|
||||
typeAliasesPackage: xiaozhi.modules.*.entity;xiaozhi.modules.*.domain
|
||||
typeAliasesPackage: xiaozhi.modules.*.entity
|
||||
global-config:
|
||||
#数据库相关配置
|
||||
db-config:
|
||||
|
||||
+4
-7
@@ -1,10 +1,5 @@
|
||||
-- 修改字段名
|
||||
ALTER TABLE `ai_agent` RENAME COLUMN `mem_model_id` TO `memory_model_id`;
|
||||
ALTER TABLE `ai_agent_template` RENAME COLUMN `mem_model_id` TO `memory_model_id`;
|
||||
-- 添加字段
|
||||
ALTER TABLE `ai_agent_template` ADD COLUMN `is_default` tinyint(1) NULL DEFAULT 0 COMMENT '是否默认模板:1:是,0:不是' AFTER `sort`;
|
||||
|
||||
-- 初始化智能体模板数据
|
||||
DELETE FROM `ai_agent_template`;
|
||||
INSERT INTO `ai_agent_template` VALUES ('9406648b5cc5fde1b8aa335b6f8b4f76', '小智', '湾湾小何', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', 'd50b06e9b8104d0d9c0f7316d258abcb', 'fcac83266edadd5a3125f06cfee1906b', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的台湾女孩,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 1, 1, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_agent_template` VALUES ('0ca32eb728c949e58b1000b2e401f90c', '小智', '通用男声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 2, 0, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_agent_template` VALUES ('6c7d8e9f0a1b2c3d4e5f6a7b8c9d0s24', '小智', '通用女声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的女生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 3, 0, NULL, NULL, NULL, NULL);
|
||||
@@ -12,6 +7,7 @@ INSERT INTO `ai_agent_template` VALUES ('e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b1', '小
|
||||
INSERT INTO `ai_agent_template` VALUES ('a45b6c7d8e9f0a1b2c3d4e5f6a7b8c92', '小智', '奶气萌娃', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', 'f7a38c03d5644e22b6d84f8923a74c51', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的萌娃,声音可爱,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 5, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
-- 初始化模型配置数据
|
||||
DELETE FROM `ai_model_config`;
|
||||
INSERT INTO `ai_model_config` VALUES ('23e7c9d090ea4d1e9b25f4c8d732a3a1', 'VAD', 'SileroVAD', 'SileroVAD', 1, 1, '{\"SileroVAD\": {\"model_dir\": \"models/snakers4_silero-vad\", \"threshold\": 0.5, \"min_silence_duration_ms\": 700}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_model_config` VALUES ('45f8b0d6dd3d4bfa8a28e6e0f5912d45', 'ASR', 'FunASR', 'FunASR', 1, 1, '{\"FunASR\": {\"type\": \"fun_local\", \"model_dir\": \"models/SenseVoiceSmall\", \"output_dir\": \"tmp/\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_model_config` VALUES ('e2274b90e89ddda85207f55484d8b528', 'Memory', 'nomem', 'nomem', 1, 1, '{\"mem0ai\": {\"type\": \"nomem\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
@@ -24,7 +20,8 @@ INSERT INTO `ai_model_config` VALUES ('896db62c9dd74976ab0e8c14bf924d9d', 'TTS',
|
||||
INSERT INTO `ai_model_config` VALUES ('c4e12f874a3f4aa99f5b2c18e15d407b', 'Intent', 'function_call', 'function_call', 1, 1, '{\"function_call\": {\"type\": \"nointent\", \"functions\": [\"change_role\", \"get_weather\", \"get_news\", \"play_music\"]}}', NULL, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
-- 初始化音色数据
|
||||
INSERT INTO `ai_tts_voice` VALUES ('fcac83266edadd5a3125f06cfee1906b', 'd50b06e9b8104d0d9c0f7316d258abcb', '湾湾小何', 'zh-CN-XiaoxiaoNeural', '中文', 'https://lf3-static.bytednsdoc.com/obj/eden-cn/lm_hz_ihsph/ljhwZthlaukjlkulzlp/portal/bigtts/湾湾小何.mp3', NULL, 1, NULL, NULL, NULL, NULL);
|
||||
DELETE FROM `ai_tts_voice`;
|
||||
INSERT INTO `ai_tts_voice` VALUES ('fcac83266edadd5a3125f06cfee1906b', '896db62c9dd74976ab0e8c14bf924d9d', '湾湾小何', 'zh-CN-XiaoxiaoNeural', '中文', 'https://lf3-static.bytednsdoc.com/obj/eden-cn/lm_hz_ihsph/ljhwZthlaukjlkulzlp/portal/bigtts/湾湾小何.mp3', NULL, 1, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_tts_voice` VALUES ('1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', '896db62c9dd74976ab0e8c14bf924d9d', '通用男声', 'BV002_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV002.mp3', NULL, 2, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_tts_voice` VALUES ('9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', '896db62c9dd74976ab0e8c14bf924d9d', '通用女声', 'BV001_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV001.mp3', NULL, 3, NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `ai_tts_voice` VALUES ('2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', '896db62c9dd74976ab0e8c14bf924d9d', '阳光男生', 'BV056_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV056.mp3', NULL, 4, NULL, NULL, NULL, NULL);
|
||||
@@ -17,9 +17,9 @@ databaseChangeLog:
|
||||
encoding: utf8
|
||||
path: classpath:db/changelog/202503141346.sql
|
||||
- changeSet:
|
||||
id: 202503241020
|
||||
id: 202503241021
|
||||
author: dreamchen
|
||||
changes:
|
||||
- sqlFile:
|
||||
encoding: utf8
|
||||
path: classpath:db/changelog/202503241020.sql
|
||||
path: classpath:db/changelog/202503241021.sql
|
||||
Reference in New Issue
Block a user