update:优化泛型代码

This commit is contained in:
hrz
2025-03-29 17:49:39 +08:00
parent 81188a0129
commit 630cb13066
26 changed files with 284 additions and 254 deletions
-6
View File
@@ -167,12 +167,6 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- SLF4J + Log4j2 实现(可选) -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies> </dependencies>
<!-- 阿里云maven仓库 --> <!-- 阿里云maven仓库 -->
@@ -6,11 +6,11 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
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.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
/** /**
* 日期转换 * 日期转换
@@ -1,13 +1,13 @@
package xiaozhi.common.exception; package xiaozhi.common.exception;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice; 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) @ExceptionHandler(RenException.class)
public Result handleRenException(RenException ex) { public Result<Void> handleRenException(RenException ex) {
Result result = new Result(); Result<Void> result = new Result<>();
result.error(ex.getCode(), ex.getMsg()); result.error(ex.getCode(), ex.getMsg());
return result; return result;
} }
@ExceptionHandler(DuplicateKeyException.class) @ExceptionHandler(DuplicateKeyException.class)
public Result handleDuplicateKeyException(DuplicateKeyException ex) { public Result<Void> handleDuplicateKeyException(DuplicateKeyException ex) {
Result result = new Result(); Result<Void> result = new Result<>();
result.error(ErrorCode.DB_RECORD_EXISTS); result.error(ErrorCode.DB_RECORD_EXISTS);
return result; return result;
} }
@ExceptionHandler(UnauthorizedException.class) @ExceptionHandler(UnauthorizedException.class)
public Result handleUnauthorizedException(UnauthorizedException ex) { public Result<Void> handleUnauthorizedException(UnauthorizedException ex) {
Result result = new Result(); Result<Void> result = new Result<>();
result.error(ErrorCode.FORBIDDEN); result.error(ErrorCode.FORBIDDEN);
return result; return result;
} }
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public Result handleException(Exception ex) { public Result<Void> handleException(Exception ex) {
log.error(ex.getMessage(), ex); log.error(ex.getMessage(), ex);
return new Result().error(); return new Result<Void>().error();
} }
} }
@@ -1,13 +1,15 @@
package xiaozhi.common.handler; package xiaozhi.common.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import java.util.Date;
import xiaozhi.common.constant.Constant;
import xiaozhi.common.user.UserDetail;
import xiaozhi.modules.security.user.SecurityUser;
import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component; 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 UPDATER = "updater";
private final static String DATA_OPERATION = "dataOperation"; private final static String DATA_OPERATION = "dataOperation";
private final static String DEPT_ID = "deptId";
@Override @Override
public void insertFill(MetaObject metaObject) { public void insertFill(MetaObject metaObject) {
UserDetail user = SecurityUser.getUser(); UserDetail user = SecurityUser.getUser();
Date date = new Date(); Date date = new Date();
//创建者 // 创建者
strictInsertFill(metaObject, CREATOR, Long.class, user.getId()); strictInsertFill(metaObject, CREATOR, Long.class, user.getId());
//创建时间 // 创建时间
strictInsertFill(metaObject, CREATE_DATE, Date.class, date); strictInsertFill(metaObject, CREATE_DATE, Date.class, date);
//更新者 // 更新者
strictInsertFill(metaObject, UPDATER, Long.class, user.getId()); strictInsertFill(metaObject, UPDATER, Long.class, user.getId());
//更新时间 // 更新时间
strictInsertFill(metaObject, UPDATE_DATE, Date.class, date); strictInsertFill(metaObject, UPDATE_DATE, Date.class, date);
//数据标识 // 数据标识
strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.INSERT.getValue()); strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.INSERT.getValue());
} }
@Override @Override
public void updateFill(MetaObject metaObject) { public void updateFill(MetaObject metaObject) {
//更新者 // 更新者
strictUpdateFill(metaObject, UPDATER, Long.class, SecurityUser.getUserId()); strictUpdateFill(metaObject, UPDATER, Long.class, SecurityUser.getUserId());
//更新时间 // 更新时间
strictUpdateFill(metaObject, UPDATE_DATE, Date.class, new Date()); strictUpdateFill(metaObject, UPDATE_DATE, Date.class, new Date());
//数据标识 // 数据标识
strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.UPDATE.getValue()); strictInsertFill(metaObject, DATA_OPERATION, String.class, Constant.DataOperation.UPDATE.getValue());
} }
} }
@@ -1,8 +1,17 @@
package xiaozhi.common.interceptor; 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.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import cn.hutool.core.util.StrUtil;
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue; 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.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.select.PlainSelect; import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select; 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 { public class DataFilterInterceptor implements InnerInterceptor {
@SuppressWarnings("rawtypes")
@Override @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); DataScope scope = getDataScope(parameter);
// 不进行数据过滤 // 不进行数据过滤
if (scope == null || StrUtil.isBlank(scope.getSqlFilter())) { if (scope == null || StrUtil.isBlank(scope.getSqlFilter())) {
@@ -48,7 +52,7 @@ public class DataFilterInterceptor implements InnerInterceptor {
// 判断参数里是否有DataScope对象 // 判断参数里是否有DataScope对象
if (parameter instanceof Map) { if (parameter instanceof Map) {
Map<?, ?> parameterMap = (Map<?, ?>) parameter; Map<?, ?> parameterMap = (Map<?, ?>) parameter;
for (Map.Entry entry : parameterMap.entrySet()) { for (Map.Entry<?, ?> entry : parameterMap.entrySet()) {
if (entry.getValue() != null && entry.getValue() instanceof DataScope) { if (entry.getValue() != null && entry.getValue() instanceof DataScope) {
return (DataScope) entry.getValue(); return (DataScope) entry.getValue();
} }
@@ -1,5 +1,18 @@
package xiaozhi.common.service.impl; 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.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; 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.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService; import xiaozhi.common.service.BaseService;
import xiaozhi.common.utils.ConvertUtils; 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都要继承 * 基础服务类,所有Service都要继承
@@ -45,7 +47,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
* @param isAsc 排序方式 * @param isAsc 排序方式
*/ */
protected IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) { protected IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
//分页参数 // 分页参数
long curPage = 1; long curPage = 1;
long limit = 10; 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)); limit = Long.parseLong((String) params.get(Constant.LIMIT));
} }
//分页对象 // 分页对象
Page<T> page = new Page<>(curPage, limit); Page<T> page = new Page<>(curPage, limit);
//分页参数 // 分页参数
params.put(Constant.PAGE, page); params.put(Constant.PAGE, page);
//排序字段 // 排序字段
String orderField = (String) params.get(Constant.ORDER_FIELD); String orderField = (String) params.get(Constant.ORDER_FIELD);
String order = (String) params.get(Constant.ORDER); String order = (String) params.get(Constant.ORDER);
//前端字段排序 // 前端字段排序
if (StringUtils.isNotBlank(orderField) && StringUtils.isNotBlank(order)) { if (StringUtils.isNotBlank(orderField) && StringUtils.isNotBlank(order)) {
if (Constant.ASC.equalsIgnoreCase(order)) { if (Constant.ASC.equalsIgnoreCase(order)) {
return page.addOrder(OrderItem.asc(orderField)); 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)) { if (StringUtils.isBlank(defaultOrderField)) {
return page; return page;
} }
//默认排序 // 默认排序
if (isAsc) { if (isAsc) {
page.addOrder(OrderItem.asc(defaultOrderField)); page.addOrder(OrderItem.asc(defaultOrderField));
} else { } else {
@@ -90,13 +92,13 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> implements Bas
return page; return page;
} }
protected <T> PageData<T> getPageData(List<?> list, long total, Class<T> target) { protected <D> PageData<D> getPageData(List<?> list, long total, Class<D> target) {
List<T> targetList = ConvertUtils.sourceToTarget(list, target); List<D> targetList = ConvertUtils.sourceToTarget(list, target);
return new PageData<>(targetList, total); 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); 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); return SqlHelper.retBool(result);
} }
@SuppressWarnings("unchecked")
protected Class<M> currentMapperClass() { protected Class<M> currentMapperClass() {
return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 0); return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 0);
} }
@SuppressWarnings("unchecked")
@Override @Override
public Class<T> currentModelClass() { public Class<T> currentModelClass() {
return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), BaseServiceImpl.class, 1); 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) { protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
return SqlHelper.executeBatch(this.currentModelClass(), this.log, list, batchSize, consumer); return SqlHelper.executeBatch(this.currentModelClass(), this.log, list, batchSize, consumer);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean updateById(T entity) { public boolean updateById(T entity) {
@@ -1,26 +1,30 @@
package xiaozhi.common.service.impl; 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.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; 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基础服务类 * CRUD基础服务类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
* Website: https://www.renren.io * 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() { protected Class<D> currentDtoClass() {
return (Class<D>) ReflectionKit.getSuperClassGenericType(getClass(), CrudServiceImpl.class, 2); 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) { public PageData<D> page(Map<String, Object> params) {
IPage<T> page = baseDao.selectPage( IPage<T> page = baseDao.selectPage(
getPage(params, null, false), getPage(params, null, false),
getWrapper(params) getWrapper(params));
);
return getPageData(page, currentDtoClass()); 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()); T entity = ConvertUtils.sourceToTarget(dto, currentModelClass());
insert(entity); insert(entity);
//copy主键值到dto // copy主键值到dto
BeanUtils.copyProperties(entity, dto); BeanUtils.copyProperties(entity, dto);
} }
@@ -1,12 +1,13 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.springframework.beans.BeanUtils;
import lombok.extern.slf4j.Slf4j;
/** /**
* 转换工具类 * 转换工具类
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -20,7 +21,7 @@ public class ConvertUtils {
} }
T targetObject = null; T targetObject = null;
try { try {
targetObject = target.newInstance(); targetObject = target.getDeclaredConstructor().newInstance();
BeanUtils.copyProperties(source, targetObject); BeanUtils.copyProperties(source, targetObject);
} catch (Exception e) { } catch (Exception e) {
log.error("convert error ", e); log.error("convert error ", e);
@@ -34,10 +35,10 @@ public class ConvertUtils {
return null; return null;
} }
List targetList = new ArrayList<>(sourceList.size()); List<T> targetList = new ArrayList<>(sourceList.size());
try { try {
for (Object source : sourceList) { for (Object source : sourceList) {
T targetObject = target.newInstance(); T targetObject = target.getDeclaredConstructor().newInstance();
BeanUtils.copyProperties(source, targetObject); BeanUtils.copyProperties(source, targetObject);
targetList.add(targetObject); targetList.add(targetObject);
} }
@@ -1,12 +1,12 @@
package xiaozhi.common.utils; package xiaozhi.common.utils;
import xiaozhi.common.validator.AssertUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import xiaozhi.common.validator.AssertUtils;
/** /**
* 树形结构工具类,如:菜单、部门等 * 树形结构工具类,如:菜单、部门等
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -17,8 +17,8 @@ public class TreeUtils {
/** /**
* 根据pid,构建树节点 * 根据pid,构建树节点
*/ */
public static <T extends TreeNode> List<T> build(List<T> treeNodes, Long pid) { public static <T extends TreeNode<T>> List<T> build(List<T> treeNodes, Long pid) {
//pid不能为空 // pid不能为空
AssertUtils.isNull(pid, "pid"); AssertUtils.isNull(pid, "pid");
List<T> treeList = new ArrayList<>(); 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) { for (T treeNode : treeNodes) {
if (rootNode.getId().equals(treeNode.getPid())) { if (rootNode.getId().equals(treeNode.getPid())) {
rootNode.getChildren().add(findChildren(treeNodes, treeNode)); 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<T> result = new ArrayList<>();
//list转map // list转map
Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size()); Map<Long, T> nodeMap = new LinkedHashMap<>(treeNodes.size());
for (T treeNode : treeNodes) { for (T treeNode : treeNodes) {
nodeMap.put(treeNode.getId(), treeNode); nodeMap.put(treeNode.getId(), treeNode);
@@ -1,14 +1,15 @@
package xiaozhi.common.validator; 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.collection.CollUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
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;
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); 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) { if (code == null) {
throw new RenException(ErrorCode.NOT_NULL, "code"); throw new RenException(ErrorCode.NOT_NULL, "code");
} }
@@ -1,13 +1,21 @@
package xiaozhi.modules.admin.contrloler; 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.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 +24,6 @@ import xiaozhi.modules.sys.dto.AdminPageUserDTO;
import xiaozhi.modules.sys.service.SysUserService; import xiaozhi.modules.sys.service.SysUserService;
import xiaozhi.modules.sys.vo.AdminPageUserVO; import xiaozhi.modules.sys.vo.AdminPageUserVO;
import java.util.Map;
/** /**
* 管理员控制层 * 管理员控制层
* *
@@ -64,7 +70,7 @@ public class AdminController {
@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) {
sysUserService.delete(new Long[]{id}); sysUserService.delete(new Long[] { id });
return new Result<>(); return new Result<>();
} }
@@ -78,7 +84,7 @@ public class AdminController {
}) })
public Result<Void> pageDevice( public Result<Void> pageDevice(
@Parameter(hidden = true) @RequestParam Map<String, Object> params) { @Parameter(hidden = true) @RequestParam Map<String, Object> params) {
//TODO 等设备功能模块写好 // TODO 等设备功能模块写好
return new Result<Void>().error(600,"等设备功能模块写好"); return new Result<Void>().error(600, "等设备功能模块写好");
} }
} }
@@ -1,9 +1,11 @@
package xiaozhi.modules.agent.vo; package xiaozhi.modules.agent.vo;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import xiaozhi.modules.agent.entity.AgentTemplateEntity; import xiaozhi.modules.agent.entity.AgentTemplateEntity;
@Data @Data
@EqualsAndHashCode(callSuper = true)
public class AgentTemplateVO extends AgentTemplateEntity { public class AgentTemplateVO extends AgentTemplateEntity {
// 角色音色 // 角色音色
private String ttsModelName; private String ttsModelName;
@@ -1,13 +1,23 @@
package xiaozhi.modules.device.controller; 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.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.commons.lang3.StringUtils;
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.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.page.PageData; import xiaozhi.common.page.PageData;
@@ -22,9 +32,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.util.List;
import java.util.Map;
@Tag(name = "设备管理") @Tag(name = "设备管理")
@AllArgsConstructor @AllArgsConstructor
@RestController @RestController
@@ -33,7 +40,6 @@ public class DeviceController {
private final DeviceService deviceService; private final DeviceService deviceService;
private final RedisUtils redisUtils; private final RedisUtils redisUtils;
@PostMapping("/bind/{deviceCode}") @PostMapping("/bind/{deviceCode}")
@Operation(summary = "绑定设备") @Operation(summary = "绑定设备")
@RequiresPermissions("sys:role:normal") @RequiresPermissions("sys:role:normal")
@@ -61,10 +67,10 @@ public class DeviceController {
@PostMapping("/unbind") @PostMapping("/unbind")
@Operation(summary = "解绑设备") @Operation(summary = "解绑设备")
@RequiresPermissions("sys:role:normal") @RequiresPermissions("sys:role:normal")
public Result unbindDevice(@RequestBody DeviceUnBindDTO unDeviveBind) { public Result<Void> unbindDevice(@RequestBody DeviceUnBindDTO unDeviveBind) {
UserDetail user = SecurityUser.getUser(); UserDetail user = SecurityUser.getUser();
deviceService.unbindDevice(user.getId(), unDeviveBind.getDeviceId()); deviceService.unbindDevice(user.getId(), unDeviveBind.getDeviceId());
return new Result(); return new Result<Void>();
} }
@GetMapping("/all") @GetMapping("/all")
@@ -1,31 +1,49 @@
package xiaozhi.modules.device.service; package xiaozhi.modules.device.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.modules.device.dto.DeviceHeaderDTO; import xiaozhi.modules.device.dto.DeviceHeaderDTO;
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.entity.DeviceEntity; import xiaozhi.modules.device.entity.DeviceEntity;
import java.util.List;
import java.util.Map;
public interface DeviceService { public interface DeviceService {
/** /**
* 根据Mac地址获取设备信息 * 根据Mac地址获取设备信息
*/ */
DeviceEntity getDeviceById(String macAddress); 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); DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader);
/**
* 获取用户设备列表
*/
List<DeviceEntity> getUserDevices(Long userId); List<DeviceEntity> getUserDevices(Long userId);
/**
* 解绑设备
*/
void unbindDevice(Long userId, Long deviceId); void unbindDevice(Long userId, Long deviceId);
/**
* 管理员设备列表
*/
PageData<DeviceEntity> adminDeviceList(Map<String, Object> params); PageData<DeviceEntity> adminDeviceList(Map<String, Object> params);
/**
* 设备激活
*/
Boolean deviceActivation(String activationCode); Boolean deviceActivation(String activationCode);
} }
@@ -1,8 +1,9 @@
package xiaozhi.modules.security.config; package xiaozhi.modules.security.config;
import xiaozhi.modules.security.oauth2.Oauth2Filter; import java.util.HashMap;
import xiaozhi.modules.security.oauth2.Oauth2Realm; import java.util.LinkedHashMap;
import jakarta.servlet.Filter; import java.util.Map;
import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor; 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.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.HashMap; import jakarta.servlet.Filter;
import java.util.LinkedHashMap; import xiaozhi.modules.security.oauth2.Oauth2Filter;
import java.util.Map; import xiaozhi.modules.security.oauth2.Oauth2Realm;
/** /**
* Shiro的配置文件 * Shiro的配置文件
@@ -53,17 +54,19 @@ public class ShiroConfig {
shiroFilter.setSecurityManager(securityManager); shiroFilter.setSecurityManager(securityManager);
shiroFilter.setShiroFilterConfiguration(config); shiroFilter.setShiroFilterConfiguration(config);
//oauth过滤 // oauth过滤
Map<String, Filter> filters = new HashMap<>(); Map<String, Filter> filters = new HashMap<>();
filters.put("oauth2", new Oauth2Filter()); filters.put("oauth2", new Oauth2Filter());
shiroFilter.setFilters(filters); shiroFilter.setFilters(filters);
//添加Shiro的内置过滤器 // 添加Shiro的内置过滤器
/*anon:无需认证就可以访问 /*
authc:必须认证了才能让 * anon:无需认证就可以访
user:必须拥有,记住我功能,才能访 * authc:必须认证了才能
perms:拥有对某个资源的权限才能访问 * user:必须拥有,记住我功能,才能访问
role:拥有某个角色权限才能访问*/ * perms:拥有某个资源的权限才能访问
* role:拥有某个角色权限才能访问
*/
Map<String, String> filterMap = new LinkedHashMap<>(); Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/ota/**", "anon"); filterMap.put("/ota/**", "anon");
filterMap.put("/webjars/**", "anon"); filterMap.put("/webjars/**", "anon");
@@ -74,7 +77,6 @@ public class ShiroConfig {
filterMap.put("/user/captcha", "anon"); filterMap.put("/user/captcha", "anon");
filterMap.put("/user/login", "anon"); filterMap.put("/user/login", "anon");
filterMap.put("/user/register", "anon"); filterMap.put("/user/register", "anon");
filterMap.put("/ota/**", "anon");
filterMap.put("/**", "oauth2"); filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap); shiroFilter.setFilterChainDefinitionMap(filterMap);
@@ -1,9 +1,7 @@
package xiaozhi.modules.security.oauth2; package xiaozhi.modules.security.oauth2;
import jakarta.servlet.ServletRequest; import java.io.IOException;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMethod; 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.constant.Constant;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.utils.HttpContextUtils; import xiaozhi.common.utils.HttpContextUtils;
import xiaozhi.common.utils.JsonUtils; import xiaozhi.common.utils.JsonUtils;
import xiaozhi.common.utils.Result; import xiaozhi.common.utils.Result;
import java.io.IOException;
/** /**
* oauth2过滤器 * oauth2过滤器
* Copyright (c) 人人开源 All rights reserved. * Copyright (c) 人人开源 All rights reserved.
@@ -30,7 +31,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
@Override @Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
//获取请求token // 获取请求token
String token = getRequestToken((HttpServletRequest) request); String token = getRequestToken((HttpServletRequest) request);
if (StringUtils.isBlank(token)) { if (StringUtils.isBlank(token)) {
@@ -52,7 +53,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
@Override @Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
//获取请求token,如果token不存在,直接返回401 // 获取请求token,如果token不存在,直接返回401
String token = getRequestToken((HttpServletRequest) request); String token = getRequestToken((HttpServletRequest) request);
if (StringUtils.isBlank(token)) { 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-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); 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); httpResponse.getWriter().print(json);
@@ -74,16 +75,17 @@ public class Oauth2Filter extends AuthenticatingFilter {
} }
@Override @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; HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setContentType("application/json;charset=utf-8"); httpResponse.setContentType("application/json;charset=utf-8");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
try { try {
//处理登录失败的异常 // 处理登录失败的异常
logger.error("onLoginFailure:登录失败!", e); logger.error("onLoginFailure:登录失败!", e);
Throwable throwable = e.getCause() == null ? e : e.getCause(); 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); String json = JsonUtils.toJsonString(r);
httpResponse.getWriter().print(json); httpResponse.getWriter().print(json);
@@ -99,7 +101,7 @@ public class Oauth2Filter extends AuthenticatingFilter {
*/ */
private String getRequestToken(HttpServletRequest httpRequest) { private String getRequestToken(HttpServletRequest httpRequest) {
String token = null; String token = null;
//从header中获取token // 从header中获取token
String authorization = httpRequest.getHeader(Constant.AUTHORIZATION); String authorization = httpRequest.getHeader(Constant.AUTHORIZATION);
if (StringUtils.isNotBlank(authorization) && authorization.startsWith("Bearer ")) { if (StringUtils.isNotBlank(authorization) && authorization.startsWith("Bearer ")) {
token = authorization.replace("Bearer ", ""); token = authorization.replace("Bearer ", "");
@@ -1,23 +1,22 @@
package xiaozhi.modules.security.service.impl; 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.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.wf.captcha.SpecCaptcha; import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha; 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.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import xiaozhi.common.redis.RedisKeys;
import org.springframework.beans.factory.annotation.Value; import xiaozhi.common.redis.RedisUtils;
import org.springframework.stereotype.Service; import xiaozhi.modules.security.service.CaptchaService;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/** /**
* 验证码 * 验证码
@@ -29,10 +28,10 @@ public class CaptchaServiceImpl implements CaptchaService {
@Value("${renren.redis.open}") @Value("${renren.redis.open}")
private boolean open; private boolean open;
/** /**
* Local Cache 5分钟过期 * Local Cache 5分钟过期
*/ */
Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build(); Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000)
private static final Logger logger = LoggerFactory.getLogger(Oauth2Realm.class); .expireAfterAccess(5, TimeUnit.MINUTES).build();
@Override @Override
public void create(HttpServletResponse response, String uuid) throws IOException { 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.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0); response.setDateHeader("Expires", 0);
//生成验证码 // 生成验证码
SpecCaptcha captcha = new SpecCaptcha(150, 40); SpecCaptcha captcha = new SpecCaptcha(150, 40);
captcha.setLen(5); captcha.setLen(5);
captcha.setCharType(Captcha.TYPE_DEFAULT); captcha.setCharType(Captcha.TYPE_DEFAULT);
captcha.out(response.getOutputStream()); captcha.out(response.getOutputStream());
//保存到缓存 // 保存到缓存
setCache(uuid, captcha.text()); setCache(uuid, captcha.text());
} }
@@ -56,10 +55,10 @@ public class CaptchaServiceImpl implements CaptchaService {
if (StringUtils.isBlank(code)) { if (StringUtils.isBlank(code)) {
return false; return false;
} }
//获取验证码 // 获取验证码
String captcha = getCache(uuid); String captcha = getCache(uuid);
//效验成功 // 效验成功
if (code.equalsIgnoreCase(captcha)) { if (code.equalsIgnoreCase(captcha)) {
return true; return true;
} }
@@ -80,7 +79,7 @@ public class CaptchaServiceImpl implements CaptchaService {
if (open) { if (open) {
key = RedisKeys.getCaptchaKey(key); key = RedisKeys.getCaptchaKey(key);
String captcha = (String) redisUtils.get(key); String captcha = (String) redisUtils.get(key);
//删除验证码 // 删除验证码
if (captcha != null) { if (captcha != null) {
redisUtils.delete(key); redisUtils.delete(key);
} }
@@ -89,7 +88,7 @@ public class CaptchaServiceImpl implements CaptchaService {
} }
String captcha = localCache.getIfPresent(key); String captcha = localCache.getIfPresent(key);
//删除验证码 // 删除验证码
if (captcha != null) { if (captcha != null) {
localCache.invalidate(key); localCache.invalidate(key);
} }
@@ -1,17 +1,13 @@
package xiaozhi.modules.security.service.impl; 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.dao.SysUserTokenDao;
import xiaozhi.modules.security.entity.SysUserTokenEntity; import xiaozhi.modules.security.entity.SysUserTokenEntity;
import xiaozhi.modules.security.service.ShiroService; import xiaozhi.modules.security.service.ShiroService;
import xiaozhi.modules.sys.dao.SysUserDao; import xiaozhi.modules.sys.dao.SysUserDao;
import xiaozhi.modules.sys.entity.SysUserEntity; 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 @AllArgsConstructor
@Service @Service
@@ -19,7 +15,6 @@ public class ShiroServiceImpl implements ShiroService {
private final SysUserDao sysUserDao; private final SysUserDao sysUserDao;
private final SysUserTokenDao sysUserTokenDao; private final SysUserTokenDao sysUserTokenDao;
@Override @Override
public SysUserTokenEntity getByToken(String token) { public SysUserTokenEntity getByToken(String token) {
return sysUserTokenDao.getByToken(token); return sysUserTokenDao.getByToken(token);
@@ -1,8 +1,11 @@
package xiaozhi.modules.security.service.impl; package xiaozhi.modules.security.service.impl;
import java.util.Date;
import org.springframework.stereotype.Service;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; import xiaozhi.common.exception.RenException;
import xiaozhi.common.page.TokenDTO; 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.dto.SysUserDTO;
import xiaozhi.modules.sys.service.SysUserService; import xiaozhi.modules.sys.service.SysUserService;
import java.util.Date;
@AllArgsConstructor @AllArgsConstructor
@Service @Service
public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, SysUserTokenEntity> implements SysUserTokenService { public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, SysUserTokenEntity>
implements SysUserTokenService {
private final SysUserService sysUserService; private final SysUserService sysUserService;
/** /**
@@ -31,18 +33,18 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
@Override @Override
public Result<TokenDTO> createToken(Long userId) { public Result<TokenDTO> createToken(Long userId) {
//用户token // 用户token
String token; String token;
//当前时间 // 当前时间
Date now = new Date(); Date now = new Date();
//过期时间 // 过期时间
Date expireTime = new Date(now.getTime() + EXPIRE * 1000); Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
//判断是否生成过token // 判断是否生成过token
SysUserTokenEntity tokenEntity = baseDao.getByUserId(userId); SysUserTokenEntity tokenEntity = baseDao.getByUserId(userId);
if (tokenEntity == null) { if (tokenEntity == null) {
//生成一个token // 生成一个token
token = TokenGenerator.generateValue(); token = TokenGenerator.generateValue();
tokenEntity = new SysUserTokenEntity(); tokenEntity = new SysUserTokenEntity();
@@ -51,12 +53,12 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
tokenEntity.setUpdateDate(now); tokenEntity.setUpdateDate(now);
tokenEntity.setExpireDate(expireTime); tokenEntity.setExpireDate(expireTime);
//保存token // 保存token
this.insert(tokenEntity); this.insert(tokenEntity);
} else { } else {
//判断token是否过期 // 判断token是否过期
if (tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) { if (tokenEntity.getExpireDate().getTime() < System.currentTimeMillis()) {
//token过期,重新生成token // token过期,重新生成token
token = TokenGenerator.generateValue(); token = TokenGenerator.generateValue();
} else { } else {
token = tokenEntity.getToken(); token = tokenEntity.getToken();
@@ -66,7 +68,7 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
tokenEntity.setUpdateDate(now); tokenEntity.setUpdateDate(now);
tokenEntity.setExpireDate(expireTime); tokenEntity.setExpireDate(expireTime);
//更新token // 更新token
this.updateById(tokenEntity); this.updateById(tokenEntity);
} }
@@ -76,7 +78,7 @@ public class SysUserTokenServiceImpl extends BaseServiceImpl<SysUserTokenDao, Sy
tokenDTO.setToken(token); tokenDTO.setToken(token);
tokenDTO.setExpire(EXPIRE); tokenDTO.setExpire(EXPIRE);
tokenDTO.setClientHash(clientHash); tokenDTO.setClientHash(clientHash);
return new Result().ok(tokenDTO); return new Result<TokenDTO>().ok(tokenDTO);
} }
@Override @Override
@@ -1,11 +1,11 @@
package xiaozhi.modules.sys.dto; package xiaozhi.modules.sys.dto;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
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
*/ */
@@ -13,7 +13,6 @@ import lombok.Data;
@Schema(description = "音色分页参数") @Schema(description = "音色分页参数")
public class AdminPageUserDTO { public class AdminPageUserDTO {
@Schema(description = "手机号码") @Schema(description = "手机号码")
private String mobile; private String mobile;
@@ -1,7 +1,17 @@
package xiaozhi.modules.sys.service.impl; 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.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import xiaozhi.common.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; 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.entity.SysParamsEntity;
import xiaozhi.modules.sys.redis.SysParamsRedis; import xiaozhi.modules.sys.redis.SysParamsRedis;
import xiaozhi.modules.sys.service.SysParamsService; 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) { public PageData<SysParamsDTO> page(Map<String, Object> params) {
IPage<SysParamsEntity> page = baseDao.selectPage( IPage<SysParamsEntity> page = baseDao.selectPage(
getPage(params, Constant.CREATE_DATE, false), getPage(params, Constant.CREATE_DATE, false),
getWrapper(params) getWrapper(params));
);
return getPageData(page, SysParamsDTO.class); return getPageData(page, SysParamsDTO.class);
} }
@@ -86,12 +87,12 @@ public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParam
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long[] ids) { public void delete(Long[] ids) {
//删除Redis数据 // 删除Redis数据
List<String> paramCodeList = baseDao.getParamCodeList(ids); List<String> paramCodeList = baseDao.getParamCodeList(ids);
String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]); String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]);
sysParamsRedis.delete(paramCodes); sysParamsRedis.delete(paramCodes);
//删除 // 删除
deleteBatchIds(Arrays.asList(ids)); deleteBatchIds(Arrays.asList(ids));
} }
@@ -114,7 +115,7 @@ public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParam
} }
try { try {
return clazz.newInstance(); return clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) { } catch (Exception e) {
throw new RenException(ErrorCode.PARAMS_GET_ERROR); throw new RenException(ErrorCode.PARAMS_GET_ERROR);
} }
@@ -1,11 +1,21 @@
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.HashMap;
import lombok.AllArgsConstructor; 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.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.constant.Constant; import xiaozhi.common.constant.Constant;
import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException; 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.service.SysUserService;
import xiaozhi.modules.sys.vo.AdminPageUserVO; 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) { public void save(SysUserDTO dto) {
SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class); SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);
//密码强度 // 密码强度
if (!isStrongPassword(entity.getPassword())) { if (!isStrongPassword(entity.getPassword())) {
throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR); throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR);
} }
//密码加密 // 密码加密
String password = PasswordUtils.encode(entity.getPassword()); String password = PasswordUtils.encode(entity.getPassword());
entity.setPassword(password); entity.setPassword(password);
//保存用户 // 保存用户
Long userCount = getUserCount(); Long userCount = getUserCount();
if (userCount == 0) { if (userCount == 0) {
entity.setSuperAdmin(SuperAdminEnum.YES.value()); entity.setSuperAdmin(SuperAdminEnum.YES.value());
@@ -83,9 +88,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long[] ids) { public void delete(Long[] ids) {
//删除用户 // 删除用户
baseDao.deleteBatchIds(Arrays.asList(ids)); baseDao.deleteBatchIds(Arrays.asList(ids));
//TODO 除了要删除用户还要删除用户关联的设备,对话,智能体。等此3个功能完善在添加 // TODO 除了要删除用户还要删除用户关联的设备,对话,智能体。等此3个功能完善在添加
} }
@Override @Override
@@ -102,19 +107,18 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
throw new RenException("旧密码输入错误"); throw new RenException("旧密码输入错误");
} }
//新密码强度 // 新密码强度
if (!isStrongPassword(passwordDTO.getNewPassword())) { if (!isStrongPassword(passwordDTO.getNewPassword())) {
throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR); throw new RenException(ErrorCode.PASSWORD_WEAK_ERROR);
} }
//密码加密 // 密码加密
String password = PasswordUtils.encode(passwordDTO.getNewPassword()); String password = PasswordUtils.encode(passwordDTO.getNewPassword());
sysUserEntity.setPassword(password); sysUserEntity.setPassword(password);
updateById(sysUserEntity); updateById(sysUserEntity);
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void changePasswordDirectly(Long userId, String password) { public void changePasswordDirectly(Long userId, String password) {
@@ -128,7 +132,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public String resetPassword(Long userId) { public String resetPassword(Long userId) {
String password = generatePassword(); String password = generatePassword();
changePasswordDirectly(userId,password); changePasswordDirectly(userId, password);
return password; return password;
} }
@@ -141,18 +145,18 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
public PageData<AdminPageUserVO> page(AdminPageUserDTO dto) { public PageData<AdminPageUserVO> page(AdminPageUserDTO 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<SysUserEntity> page = baseDao.selectPage( IPage<SysUserEntity> page = baseDao.selectPage(
getPage(params, "id", true), getPage(params, "id", true),
//定义查询条件 // 定义查询条件
new QueryWrapper<SysUserEntity>() 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 -> { List<AdminPageUserVO> list = page.getRecords().stream().map(user -> {
AdminPageUserVO adminPageUserVO = new AdminPageUserVO(); AdminPageUserVO adminPageUserVO = new AdminPageUserVO();
adminPageUserVO.setUserid(user.getId().toString()); adminPageUserVO.setUserid(user.getId().toString());
adminPageUserVO.setMobile(user.getUsername()); adminPageUserVO.setMobile(user.getUsername());
//TODO 2. 等设备功能写好,获取对应数据 // TODO 2. 等设备功能写好,获取对应数据
adminPageUserVO.setDeviceCount("0"); adminPageUserVO.setDeviceCount("0");
return adminPageUserVO; return adminPageUserVO;
}).toList(); }).toList();
@@ -169,11 +173,13 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()"; private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
private static final Random random = new Random(); private static final Random random = new Random();
/** /**
* 生成随机密码 * 生成随机密码
*
* @return 随机生成的密码 * @return 随机生成的密码
*/ */
private String generatePassword(){ private String generatePassword() {
StringBuilder password = new StringBuilder(); StringBuilder password = new StringBuilder();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
int randomIndex = random.nextInt(CHARACTERS.length()); int randomIndex = random.nextInt(CHARACTERS.length());
@@ -1,31 +1,19 @@
package xiaozhi.modules.sys.service.impl; package xiaozhi.modules.sys.service.impl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import xiaozhi.common.redis.RedisUtils;
import lombok.AllArgsConstructor;
import xiaozhi.modules.security.oauth2.TokenGenerator; import xiaozhi.modules.security.oauth2.TokenGenerator;
import xiaozhi.modules.sys.service.TokenService; import xiaozhi.modules.sys.service.TokenService;
import java.util.Date;
@AllArgsConstructor @AllArgsConstructor
@Service @Service
public class TokenServiceImpl implements TokenService { public class TokenServiceImpl implements TokenService {
private final RedisUtils redisUtils;
/**
* 3小时无操作过期
*/
private final static int EXPIRE = 60 * 60 * 3;
@Override @Override
public String createToken(long userId) { public String createToken(long userId) {
//生成一个token // 生成一个token
String token = TokenGenerator.generateValue(); String token = TokenGenerator.generateValue();
//当前时间
Date now = new Date();
//过期时间
Date expireTime = new Date(now.getTime() + EXPIRE * 1000);
return token; return token;
} }
} }
@@ -47,7 +47,7 @@ renren:
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml mapper-locations: classpath*:/mapper/**/*.xml
#实体扫描,多个package用逗号或者分号分隔 #实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: xiaozhi.modules.*.entity;xiaozhi.modules.*.domain typeAliasesPackage: xiaozhi.modules.*.entity
global-config: global-config:
#数据库相关配置 #数据库相关配置
db-config: db-config:
@@ -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 ('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 ('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); 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); 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 ('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 ('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); 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_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 ('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 ('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); 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 encoding: utf8
path: classpath:db/changelog/202503141346.sql path: classpath:db/changelog/202503141346.sql
- changeSet: - changeSet:
id: 202503241020 id: 202503241021
author: dreamchen author: dreamchen
changes: changes:
- sqlFile: - sqlFile:
encoding: utf8 encoding: utf8
path: classpath:db/changelog/202503241020.sql path: classpath:db/changelog/202503241021.sql