Merge branch 'master' of https://gitee.com/youlaiorg/youlai-boot into feature/noticews

# Conflicts:
#	src/main/java/com/youlai/boot/module/websocket/service/OnlineUserService.java
This commit is contained in:
胡少翔
2024-09-14 10:47:07 +08:00
20 changed files with 82 additions and 38 deletions

View File

@@ -396,7 +396,7 @@ INSERT INTO `sys_user_role` VALUES (3, 3);
-- ---------------------------- -- ----------------------------
-- Table structure for sys_user_role -- Table structure for sys_log
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_log`; DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` ( CREATE TABLE `sys_log` (

View File

@@ -1,9 +1,11 @@
package com.youlai.boot.common.base; package com.youlai.boot.common.base;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/** /**
* 基础分页请求对象 * 基础分页请求对象
* *
@@ -12,7 +14,11 @@ import lombok.Data;
*/ */
@Data @Data
@Schema @Schema
public class BasePageQuery { public class BasePageQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "页码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "页码", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private int pageNum = 1; private int pageNum = 1;

View File

@@ -273,7 +273,8 @@ public class CodegenServiceImpl implements CodegenService {
for (String tableName : tableNames) { for (String tableName : tableNames) {
generateAndZipCode(tableName, zip); generateAndZipCode(tableName, zip);
} }
// 确保所有压缩数据写入输出流,避免数据残留在内存缓冲区引发的数据不完整
zip.finish();
return outputStream.toByteArray(); return outputStream.toByteArray();
} catch (IOException e) { } catch (IOException e) {

View File

@@ -51,9 +51,10 @@ public class WebsocketController {
*/ */
@MessageMapping("/sendToUser/{username}") @MessageMapping("/sendToUser/{username}")
public void sendToUser(Principal principal, @DestinationVariable String username, String message) { public void sendToUser(Principal principal, @DestinationVariable String username, String message) {
// 发送人
String sender = principal.getName(); // 发送人 String sender = principal.getName();
String receiver = username; // 接收人 // 接收人
String receiver = username;
log.info("发送人:{}; 接收人:{}", sender, receiver); log.info("发送人:{}; 接收人:{}", sender, receiver);
// 发送消息给指定用户,拼接后路径 /user/{receiver}/queue/greeting // 发送消息给指定用户,拼接后路径 /user/{receiver}/queue/greeting

View File

@@ -1,9 +0,0 @@
package com.youlai.boot.module.websocket.service;
public interface WebsocketService {
void addUser(String username);
void removeUser(String username) ;
}

View File

@@ -34,10 +34,10 @@ public class LogController {
@Operation(summary = "日志分页列表") @Operation(summary = "日志分页列表")
@GetMapping("/page") @GetMapping("/page")
public PageResult<LogPageVO> listPagedLogs( public PageResult<LogPageVO> getLogPage(
LogPageQuery queryParams LogPageQuery queryParams
) { ) {
Page<LogPageVO> result = logService.listPagedLogs(queryParams); Page<LogPageVO> result = logService.getLogPage(queryParams);
return PageResult.success(result); return PageResult.success(result);
} }

View File

@@ -99,7 +99,7 @@ public class UserController {
@Operation(summary = "删除用户") @Operation(summary = "删除用户")
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@PreAuthorize("@ss.hasPerm('sys:user:delete')") @PreAuthorize("@ss.hasPerm('sys:user:delete')")
public Result<?> deleteUsers( public Result<Void> deleteUsers(
@Parameter(description = "用户ID多个以英文逗号(,)分割") @PathVariable String ids @Parameter(description = "用户ID多个以英文逗号(,)分割") @PathVariable String ids
) { ) {
boolean result = userService.deleteUsers(ids); boolean result = userService.deleteUsers(ids);
@@ -108,7 +108,7 @@ public class UserController {
@Operation(summary = "修改用户状态") @Operation(summary = "修改用户状态")
@PatchMapping(value = "/{userId}/status") @PatchMapping(value = "/{userId}/status")
public Result<?> updateUserStatus( public Result<Void> updateUserStatus(
@Parameter(description = "用户ID") @PathVariable Long userId, @Parameter(description = "用户ID") @PathVariable Long userId,
@Parameter(description = "用户状态(1:启用;0:禁用)") @RequestParam Integer status @Parameter(description = "用户状态(1:启用;0:禁用)") @RequestParam Integer status
) { ) {
@@ -144,7 +144,7 @@ public class UserController {
@Operation(summary = "导入用户") @Operation(summary = "导入用户")
@PostMapping("/import") @PostMapping("/import")
public Result<?> importUsers(MultipartFile file) throws IOException { public Result<String> importUsers(MultipartFile file) throws IOException {
UserImportListener listener = new UserImportListener(); UserImportListener listener = new UserImportListener();
String msg = ExcelUtils.importExcel(file.getInputStream(), UserImportDTO.class, listener); String msg = ExcelUtils.importExcel(file.getInputStream(), UserImportDTO.class, listener);
return Result.success(msg); return Result.success(msg);

View File

@@ -3,11 +3,33 @@ package com.youlai.boot.system.event;
import lombok.Getter; import lombok.Getter;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
/**
* 用户连接事件
*
* @author Ray
* @since 2.3.0
*/
@Getter @Getter
public class UserConnectionEvent extends ApplicationEvent { public class UserConnectionEvent extends ApplicationEvent {
/**
* 用户名
*/
private final String username; private final String username;
/**
* 是否连接
*/
private final boolean connected; private final boolean connected;
/**
* 用户连接事件
*
* @param source 事件源
* @param username 用户名
* @param connected 是否连接
*/
public UserConnectionEvent(Object source, String username, boolean connected) { public UserConnectionEvent(Object source, String username, boolean connected) {
super(source); super(source);
this.username = username; this.username = username;

View File

@@ -28,7 +28,7 @@ public interface LogMapper extends BaseMapper<Log> {
* @param queryParams * @param queryParams
* @return * @return
*/ */
Page<LogPageVO> listPagedLogs(Page<LogPageVO> page, LogPageQuery queryParams); Page<LogPageVO> getLogPage(Page<LogPageVO> page, LogPageQuery queryParams);
/** /**
* 统计浏览数(PV) * 统计浏览数(PV)

View File

@@ -7,6 +7,12 @@ import lombok.Setter;
import java.util.List; import java.util.List;
/**
* 访问趋势VO
*
* @author Ray
* @since 2.3.0
*/
@Schema(description = "访问趋势VO") @Schema(description = "访问趋势VO")
@Getter @Getter
@Setter @Setter

View File

@@ -25,7 +25,7 @@ public interface LogService extends IService<Log> {
* @param queryParams 查询参数 * @param queryParams 查询参数
* @return * @return
*/ */
Page<LogPageVO> listPagedLogs(LogPageQuery queryParams); Page<LogPageVO> getLogPage(LogPageQuery queryParams);
/** /**

View File

@@ -36,8 +36,8 @@ public class LogServiceImpl extends ServiceImpl<LogMapper, Log>
* @return * @return
*/ */
@Override @Override
public Page<LogPageVO> listPagedLogs(LogPageQuery queryParams) { public Page<LogPageVO> getLogPage(LogPageQuery queryParams) {
return this.baseMapper.listPagedLogs(new Page<>(queryParams.getPageNum(), queryParams.getPageSize()), return this.baseMapper.getLogPage(new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
queryParams); queryParams);
} }

View File

@@ -268,9 +268,32 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
roleMenuService.refreshRolePermsCache(); roleMenuService.refreshRolePermsCache();
} }
} }
// 修改菜单如果有子菜单,则更新子菜单的树路径
updateChildrenTreePath(entity.getId(), treePath);
return result; return result;
} }
/**
* 更新子菜单树路径
* @param id 当前菜单ID
* @param treePath 当前菜单树路径
*/
private void updateChildrenTreePath(Long id, String treePath) {
List<Menu> children = this.list(new LambdaQueryWrapper<Menu>().eq(Menu::getParentId, id));
if (CollectionUtil.isNotEmpty(children)) {
// 子菜单的树路径等于父菜单的树路径加上父菜单ID
String childTreePath = treePath + "," + id;
this.update(new LambdaUpdateWrapper<Menu>()
.eq(Menu::getParentId, id)
.set(Menu::getTreePath, childTreePath)
);
for (Menu child : children) {
// 递归更新子菜单
updateChildrenTreePath(child.getId(), childTreePath);
}
}
}
/** /**
* 部门路径生成 * 部门路径生成
* *

View File

@@ -20,7 +20,6 @@ spring:
port: 6379 port: 6379
# 如果Redis 服务未设置密码需要将password删掉或注释而不是设置为空字符串 # 如果Redis 服务未设置密码需要将password删掉或注释而不是设置为空字符串
password: 123456 password: 123456
timeout: 10s timeout: 10s
lettuce: lettuce:
pool: pool:
@@ -152,7 +151,7 @@ springdoc:
- com.youlai.boot.system.controller - com.youlai.boot.system.controller
- com.youlai.boot.module.auth.controller - com.youlai.boot.module.auth.controller
- com.youlai.boot.module.file.controller - com.youlai.boot.module.file.controller
- com.youlai.boot.module.generator.controller - com.youlai.boot.module.codegen.controller
default-flat-param-object: true default-flat-param-object: true
# knife4j 接口文档配置 # knife4j 接口文档配置

View File

@@ -56,7 +56,6 @@ mybatis-plus:
# 这个配置会将执行的sql打印出来在开发或测试的时候可以用 # 这个配置会将执行的sql打印出来在开发或测试的时候可以用
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 安全配置 # 安全配置
security: security:
# JWT 配置 # JWT 配置
@@ -136,7 +135,7 @@ springdoc:
- com.youlai.boot.system.controller - com.youlai.boot.system.controller
- com.youlai.boot.module.auth.controller - com.youlai.boot.module.auth.controller
- com.youlai.boot.module.file.controller - com.youlai.boot.module.file.controller
- com.youlai.boot.module.generator.controller - com.youlai.boot.module.codegen.controller
default-flat-param-object: true default-flat-param-object: true
# knife4j 接口文档配置 # knife4j 接口文档配置

View File

@@ -5,7 +5,7 @@
<mapper namespace="com.youlai.boot.system.mapper.LogMapper"> <mapper namespace="com.youlai.boot.system.mapper.LogMapper">
<!-- 日志分页列表 --> <!-- 日志分页列表 -->
<select id="listPagedLogs" resultType="com.youlai.boot.system.model.vo.LogPageVO"> <select id="getLogPage" resultType="com.youlai.boot.system.model.vo.LogPageVO">
SELECT SELECT
t1.id, t1.id,
t1.module, t1.module,

View File

@@ -43,7 +43,7 @@ public class ${entityName}Controller {
@Operation(summary = "新增${businessName}") @Operation(summary = "新增${businessName}")
@PostMapping @PostMapping
@PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:add')") @PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:add')")
public Result save${entityName}(@RequestBody @Valid ${entityName}Form formData ) { public Result<Void> save${entityName}(@RequestBody @Valid ${entityName}Form formData ) {
boolean result = ${lowerFirstEntityName}Service.save${entityName}(formData); boolean result = ${lowerFirstEntityName}Service.save${entityName}(formData);
return Result.judge(result); return Result.judge(result);
} }
@@ -61,7 +61,7 @@ public class ${entityName}Controller {
@Operation(summary = "修改${businessName}") @Operation(summary = "修改${businessName}")
@PutMapping(value = "/{id}") @PutMapping(value = "/{id}")
@PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:edit')") @PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:edit')")
public Result update${entityName}( public Result<Void> update${entityName}(
@Parameter(description = "$!{businessName}ID") @PathVariable Long id, @Parameter(description = "$!{businessName}ID") @PathVariable Long id,
@RequestBody @Validated ${entityName}Form formData @RequestBody @Validated ${entityName}Form formData
) { ) {
@@ -72,7 +72,7 @@ public class ${entityName}Controller {
@Operation(summary = "删除${businessName}") @Operation(summary = "删除${businessName}")
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
@PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:delete')") @PreAuthorize("@ss.hasPerm('${moduleName}:${lowerFirstEntityName}:delete')")
public Result delete${entityName}s( public Result<Void> delete${entityName}s(
@Parameter(description = "$!{businessName}ID多个以英文逗号(,)分割") @PathVariable String ids @Parameter(description = "$!{businessName}ID多个以英文逗号(,)分割") @PathVariable String ids
) { ) {
boolean result = ${lowerFirstEntityName}Service.delete${entityName}s(ids); boolean result = ${lowerFirstEntityName}Service.delete${entityName}s(ids);

View File

@@ -177,8 +177,6 @@
<el-input <el-input
v-model="formData.$fieldConfig.fieldName" v-model="formData.$fieldConfig.fieldName"
placeholder="$fieldConfig.fieldComment" placeholder="$fieldConfig.fieldComment"
clearable
@keyup.enter="handleQuery()"
/> />
#elseif($fieldConfig.formType == "SELECT") #elseif($fieldConfig.formType == "SELECT")
#if($fieldConfig.dictType != "") #if($fieldConfig.dictType != "")

View File

@@ -1,6 +1,6 @@
package ${packageName}.${moduleName}.${subpackageName}; package ${packageName}.${moduleName}.${subpackageName};
import com.youlai.boot.common.base.BasePageQuery; import ${packageName}.common.base.BasePageQuery;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -23,8 +23,6 @@ import java.math.BigDecimal;
@Setter @Setter
public class ${entityName}Query extends BasePageQuery { public class ${entityName}Query extends BasePageQuery {
private static final long serialVersionUID = 1L;
#if($fieldConfigs) #if($fieldConfigs)
#foreach($fieldConfig in ${fieldConfigs}) #foreach($fieldConfig in ${fieldConfigs})
#if($fieldConfig.isShowInQuery) #if($fieldConfig.isShowInQuery)