From 789f45f709f3e6c48e02b6a7afcccc4650e9aa16 Mon Sep 17 00:00:00 2001 From: sol Date: Tue, 10 Mar 2026 18:11:58 +0800 Subject: [PATCH 1/2] plugin(FeignInterceptor): add GlobalScope --- client/src/generated/system/index.ts | 3 + .../BaseVoMessageEnvelopeEntityObject.ts | 39 ++++++++++ .../system/models/MessageEnvelopeCreateDto.ts | 68 ++++++++++++++++++ .../models/MessageEnvelopeEntityObject.ts | 4 -- .../system/models/MessageEnvelopePageDto.ts | 4 ++ .../system/models/MessageEnvelopeUpdateDto.ts | 72 +++++++++++++++++++ .../src/generated/system/services/Service.ts | 47 ++++++++++++ .../satoken/config/SaTokenInterceptor.java | 2 +- .../common/message/dto/SystemMessageBody.java | 1 - .../message/entity/MessageEnvelopeEntity.java | 1 - .../base/entity/PoiExportHistoryEntity.java | 2 - .../core/base/handler/DataScopeHandler.java | 5 +- .../gateway/filters/ForwardAuthFilter.java | 9 +-- .../model/file/image/dto/ImageCreateDto.java | 1 - .../model/file/image/dto/ImageUpdateDto.java | 1 - .../model/file/video/entity/VideoEntity.java | 2 - .../bgasol/model/system/user/api/UserApi.java | 2 + .../model/system/user/entity/UserEntity.java | 2 - .../interceptor/FeignInterceptor.java | 17 +++-- .../openfeign/interceptor/GlobalScope.java | 12 ++++ 20 files changed, 258 insertions(+), 36 deletions(-) create mode 100644 client/src/generated/system/models/BaseVoMessageEnvelopeEntityObject.ts create mode 100644 client/src/generated/system/models/MessageEnvelopeCreateDto.ts create mode 100644 client/src/generated/system/models/MessageEnvelopeUpdateDto.ts create mode 100644 cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/GlobalScope.java diff --git a/client/src/generated/system/index.ts b/client/src/generated/system/index.ts index 2d36646..f934540 100644 --- a/client/src/generated/system/index.ts +++ b/client/src/generated/system/index.ts @@ -17,6 +17,7 @@ export { BaseVoListRoleEntity } from './models/BaseVoListRoleEntity'; export { BaseVoListUserEntity } from './models/BaseVoListUserEntity'; export { BaseVoListVerificationResult } from './models/BaseVoListVerificationResult'; export { BaseVoMenuEntity } from './models/BaseVoMenuEntity'; +export { BaseVoMessageEnvelopeEntityObject } from './models/BaseVoMessageEnvelopeEntityObject'; export { BaseVoObject } from './models/BaseVoObject'; export { BaseVoPageVoMessageEnvelopeEntityObject } from './models/BaseVoPageVoMessageEnvelopeEntityObject'; export { BaseVoPageVoUserEntity } from './models/BaseVoPageVoUserEntity'; @@ -32,8 +33,10 @@ export type { DepartmentEntity } from './models/DepartmentEntity'; export type { DepartmentUpdateDto } from './models/DepartmentUpdateDto'; export type { ImportResult } from './models/ImportResult'; export { MenuEntity } from './models/MenuEntity'; +export { MessageEnvelopeCreateDto } from './models/MessageEnvelopeCreateDto'; export { MessageEnvelopeEntityObject } from './models/MessageEnvelopeEntityObject'; export { MessageEnvelopePageDto } from './models/MessageEnvelopePageDto'; +export { MessageEnvelopeUpdateDto } from './models/MessageEnvelopeUpdateDto'; export type { PageVoMessageEnvelopeEntityObject } from './models/PageVoMessageEnvelopeEntityObject'; export type { PageVoUserEntity } from './models/PageVoUserEntity'; export type { PermissionEntity } from './models/PermissionEntity'; diff --git a/client/src/generated/system/models/BaseVoMessageEnvelopeEntityObject.ts b/client/src/generated/system/models/BaseVoMessageEnvelopeEntityObject.ts new file mode 100644 index 0000000..02e906f --- /dev/null +++ b/client/src/generated/system/models/BaseVoMessageEnvelopeEntityObject.ts @@ -0,0 +1,39 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { MessageEnvelopeEntityObject } from './MessageEnvelopeEntityObject'; +/** + * 基础响应数据 + */ +export type BaseVoMessageEnvelopeEntityObject = { + /** + * 响应码 + */ + code?: number; + /** + * 响应消息 + */ + message?: string; + data?: MessageEnvelopeEntityObject; + /** + * 响应时间 + */ + time?: string; + /** + * 响应类型 + */ + type?: BaseVoMessageEnvelopeEntityObject.type; +}; +export namespace BaseVoMessageEnvelopeEntityObject { + /** + * 响应类型 + */ + export enum type { + SUCCESS = 'SUCCESS', + WARNING = 'WARNING', + INFO = 'INFO', + ERROR = 'ERROR', + } +} + diff --git a/client/src/generated/system/models/MessageEnvelopeCreateDto.ts b/client/src/generated/system/models/MessageEnvelopeCreateDto.ts new file mode 100644 index 0000000..707262a --- /dev/null +++ b/client/src/generated/system/models/MessageEnvelopeCreateDto.ts @@ -0,0 +1,68 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * 创建消息 + */ +export type MessageEnvelopeCreateDto = { + /** + * 排序 + */ + sort?: number; + /** + * 描述 + */ + description?: string; + /** + * 业务类型: 站内信,小程序通知,邮件 + */ + businessType?: string; + /** + * 接收者类型枚举 + */ + messageRecipientTypeEnum?: MessageEnvelopeCreateDto.messageRecipientTypeEnum; + /** + * 接收者id + */ + recipientId?: string; + /** + * 消息标题 + */ + title?: string; + /** + * 消息内容 + */ + content?: string; + /** + * 处理器: 邮件处理器,小程序通知处理器 + */ + handler?: string; + /** + * 元数据 + */ + metadata?: string; + /** + * 消息状态枚举 + */ + status?: MessageEnvelopeCreateDto.status; +}; +export namespace MessageEnvelopeCreateDto { + /** + * 接收者类型枚举 + */ + export enum messageRecipientTypeEnum { + USER = 'USER', + ROLE = 'ROLE', + DEPARTMENT = 'DEPARTMENT', + } + /** + * 消息状态枚举 + */ + export enum status { + UNREAD = 'UNREAD', + READ = 'READ', + IGNORE = 'IGNORE', + } +} + diff --git a/client/src/generated/system/models/MessageEnvelopeEntityObject.ts b/client/src/generated/system/models/MessageEnvelopeEntityObject.ts index 4f8cc26..26e6e9b 100644 --- a/client/src/generated/system/models/MessageEnvelopeEntityObject.ts +++ b/client/src/generated/system/models/MessageEnvelopeEntityObject.ts @@ -59,10 +59,6 @@ export type MessageEnvelopeEntityObject = { * 消息状态枚举 */ status?: MessageEnvelopeEntityObject.status; - /** - * 消息体 - */ - body?: Record; }; export namespace MessageEnvelopeEntityObject { /** diff --git a/client/src/generated/system/models/MessageEnvelopePageDto.ts b/client/src/generated/system/models/MessageEnvelopePageDto.ts index 54624da..c891370 100644 --- a/client/src/generated/system/models/MessageEnvelopePageDto.ts +++ b/client/src/generated/system/models/MessageEnvelopePageDto.ts @@ -46,6 +46,10 @@ export type MessageEnvelopePageDto = { * 消息状态枚举 */ status?: MessageEnvelopePageDto.status; + /** + * 描述 + */ + description?: string; }; export namespace MessageEnvelopePageDto { /** diff --git a/client/src/generated/system/models/MessageEnvelopeUpdateDto.ts b/client/src/generated/system/models/MessageEnvelopeUpdateDto.ts new file mode 100644 index 0000000..f5f63b9 --- /dev/null +++ b/client/src/generated/system/models/MessageEnvelopeUpdateDto.ts @@ -0,0 +1,72 @@ +/* generated using openapi-typescript-codegen -- do not edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +/** + * 创建消息 + */ +export type MessageEnvelopeUpdateDto = { + /** + * 主键 + */ + id: string; + /** + * 排序 + */ + sort?: number; + /** + * 描述 + */ + description?: string; + /** + * 业务类型: 站内信,小程序通知,邮件 + */ + businessType?: string; + /** + * 接收者类型枚举 + */ + messageRecipientTypeEnum?: MessageEnvelopeUpdateDto.messageRecipientTypeEnum; + /** + * 接收者id + */ + recipientId?: string; + /** + * 消息标题 + */ + title?: string; + /** + * 消息内容 + */ + content?: string; + /** + * 处理器: 邮件处理器,小程序通知处理器 + */ + handler?: string; + /** + * 元数据 + */ + metadata?: string; + /** + * 消息状态枚举 + */ + status?: MessageEnvelopeUpdateDto.status; +}; +export namespace MessageEnvelopeUpdateDto { + /** + * 接收者类型枚举 + */ + export enum messageRecipientTypeEnum { + USER = 'USER', + ROLE = 'ROLE', + DEPARTMENT = 'DEPARTMENT', + } + /** + * 消息状态枚举 + */ + export enum status { + UNREAD = 'UNREAD', + READ = 'READ', + IGNORE = 'IGNORE', + } +} + diff --git a/client/src/generated/system/services/Service.ts b/client/src/generated/system/services/Service.ts index 536783f..0ee2347 100644 --- a/client/src/generated/system/services/Service.ts +++ b/client/src/generated/system/services/Service.ts @@ -11,6 +11,7 @@ import type { BaseVoListPermissionEntity } from '../models/BaseVoListPermissionE import type { BaseVoListRoleEntity } from '../models/BaseVoListRoleEntity'; import type { BaseVoListUserEntity } from '../models/BaseVoListUserEntity'; import type { BaseVoMenuEntity } from '../models/BaseVoMenuEntity'; +import type { BaseVoMessageEnvelopeEntityObject } from '../models/BaseVoMessageEnvelopeEntityObject'; import type { BaseVoPageVoMessageEnvelopeEntityObject } from '../models/BaseVoPageVoMessageEnvelopeEntityObject'; import type { BaseVoPageVoUserEntity } from '../models/BaseVoPageVoUserEntity'; import type { BaseVoPermissionEntity } from '../models/BaseVoPermissionEntity'; @@ -22,7 +23,9 @@ import type { BaseVoVerificationVo } from '../models/BaseVoVerificationVo'; import type { DepartmentCreateDto } from '../models/DepartmentCreateDto'; import type { DepartmentUpdateDto } from '../models/DepartmentUpdateDto'; import type { MenuEntity } from '../models/MenuEntity'; +import type { MessageEnvelopeCreateDto } from '../models/MessageEnvelopeCreateDto'; import type { MessageEnvelopePageDto } from '../models/MessageEnvelopePageDto'; +import type { MessageEnvelopeUpdateDto } from '../models/MessageEnvelopeUpdateDto'; import type { PermissionEntity } from '../models/PermissionEntity'; import type { RoleCreateDto } from '../models/RoleCreateDto'; import type { RoleUpdateDto } from '../models/RoleUpdateDto'; @@ -185,6 +188,50 @@ export class Service { }, }); } + /** + * 更新消息 + * @param requestBody + * @returns BaseVoMessageEnvelopeEntityObject OK + * @throws ApiError + */ + public static updateMessageEnvelope( + requestBody: MessageEnvelopeUpdateDto, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/message-envelope', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `参数校验异常`, + 401: `未登录异常`, + 403: `无权限异常`, + 500: `业务异常`, + }, + }); + } + /** + * 保存消息 + * @param requestBody + * @returns BaseVoMessageEnvelopeEntityObject OK + * @throws ApiError + */ + public static saveMessageEnvelope( + requestBody: MessageEnvelopeCreateDto, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/message-envelope', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `参数校验异常`, + 401: `未登录异常`, + 403: `无权限异常`, + 500: `业务异常`, + }, + }); + } /** * 查询所有部门 * @returns BaseVoListDepartmentEntity OK diff --git a/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenInterceptor.java b/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenInterceptor.java index ef114e9..89ef43d 100644 --- a/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenInterceptor.java +++ b/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenInterceptor.java @@ -10,7 +10,7 @@ public class SaTokenInterceptor extends SaInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String header = request.getHeader(GatewayConfigValues.XFromGateway); - if ("false".equals(header)) { + if (Boolean.FALSE.toString().equals(header)) { // 若是服务内部调用,忽略SA-token的注解校验。直接返回true return true; } diff --git a/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/dto/SystemMessageBody.java b/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/dto/SystemMessageBody.java index c23f638..48cb621 100644 --- a/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/dto/SystemMessageBody.java +++ b/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/dto/SystemMessageBody.java @@ -1,6 +1,5 @@ package com.bgasol.common.message.dto; -import com.bgasol.common.message.dto.MessageBody; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/entity/MessageEnvelopeEntity.java b/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/entity/MessageEnvelopeEntity.java index 3e4d7c8..cda6193 100644 --- a/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/entity/MessageEnvelopeEntity.java +++ b/cloud/common/common-base-model/src/main/java/com/bgasol/common/message/entity/MessageEnvelopeEntity.java @@ -11,7 +11,6 @@ import jakarta.persistence.Transient; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import lombok.experimental.SuperBuilder; @Setter @Getter diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/entity/PoiExportHistoryEntity.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/entity/PoiExportHistoryEntity.java index 9f46716..4a6bff4 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/entity/PoiExportHistoryEntity.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/entity/PoiExportHistoryEntity.java @@ -2,14 +2,12 @@ package com.bgasol.common.core.base.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; -import com.bgasol.common.core.base.entity.BaseEntity; import com.bgasol.model.system.department.entity.DepartmentEntity; import com.bgasol.model.system.user.bo.ScopeField; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.Entity; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.Transient; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/DataScopeHandler.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/DataScopeHandler.java index 41182ea..1d88f74 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/DataScopeHandler.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/DataScopeHandler.java @@ -1,10 +1,8 @@ package com.bgasol.common.core.base.handler; import cn.dev33.satoken.stp.StpUtil; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; import com.bgasol.common.core.base.entity.BaseEntity; -import com.bgasol.common.core.base.exception.BaseException; import com.bgasol.common.core.base.mapper.MyBaseMapper; import com.bgasol.model.system.department.entity.DepartmentEntity; import com.bgasol.model.system.user.api.UserApi; @@ -30,13 +28,11 @@ import net.sf.jsqlparser.statement.select.SelectItem; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.reflect.FieldUtils; -import org.apache.commons.lang3.reflect.TypeUtils; import org.springframework.stereotype.Component; import java.lang.reflect.*; import java.util.Arrays; import java.util.List; -import java.util.Map; import static com.bgasol.common.constant.value.SystemConfigValues.ADMIN_USER_ID; import static com.bgasol.plugin.openfeign.interceptor.FeignInterceptor.InWebRequest; @@ -61,6 +57,7 @@ public class DataScopeHandler implements MultiDataPermissionHandler { } ScopeOptionsBo scopeOption; try { + @SuppressWarnings("unchecked") Class entityClass = (Class) entityFieldCache.tableClassCache.get(table.getName()); if (entityClass == null) { return null; diff --git a/cloud/gateway-9527/src/main/java/com/bgasol/gateway/filters/ForwardAuthFilter.java b/cloud/gateway-9527/src/main/java/com/bgasol/gateway/filters/ForwardAuthFilter.java index bae3d45..c9cba47 100644 --- a/cloud/gateway-9527/src/main/java/com/bgasol/gateway/filters/ForwardAuthFilter.java +++ b/cloud/gateway-9527/src/main/java/com/bgasol/gateway/filters/ForwardAuthFilter.java @@ -5,7 +5,6 @@ import com.bgasol.common.constant.value.GatewayConfigValues; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; -import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @@ -18,19 +17,13 @@ import reactor.core.publisher.Mono; public class ForwardAuthFilter implements GlobalFilter { @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { - // 判断url是否包含"actuator" - if (exchange.getRequest().getURI().getPath().contains("/actuator")) { - // 响应404 - return exchange.getResponse().setComplete(); - } return chain.filter( exchange.mutate().request( exchange.getRequest().mutate() .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()) - .header(GatewayConfigValues.XFromGateway, "true") + .header(GatewayConfigValues.XFromGateway, Boolean.TRUE.toString()) .build() ).build() ); - } } diff --git a/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageCreateDto.java b/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageCreateDto.java index d9247a8..490afb9 100644 --- a/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageCreateDto.java +++ b/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageCreateDto.java @@ -5,7 +5,6 @@ import com.bgasol.model.file.image.entity.ImageEntity; import com.bgasol.model.file.image.mapstruct.ImageMapstruct; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageUpdateDto.java b/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageUpdateDto.java index f0477ce..da70b74 100644 --- a/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageUpdateDto.java +++ b/cloud/model/model-file/src/main/java/com/bgasol/model/file/image/dto/ImageUpdateDto.java @@ -5,7 +5,6 @@ import com.bgasol.model.file.image.entity.ImageEntity; import com.bgasol.model.file.image.mapstruct.ImageMapstruct; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; diff --git a/cloud/model/model-file/src/main/java/com/bgasol/model/file/video/entity/VideoEntity.java b/cloud/model/model-file/src/main/java/com/bgasol/model/file/video/entity/VideoEntity.java index 586c556..0aeb7b5 100644 --- a/cloud/model/model-file/src/main/java/com/bgasol/model/file/video/entity/VideoEntity.java +++ b/cloud/model/model-file/src/main/java/com/bgasol/model/file/video/entity/VideoEntity.java @@ -1,8 +1,6 @@ package com.bgasol.model.file.video.entity; -import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.bgasol.common.core.base.entity.BaseEntity; import com.bgasol.model.file.file.entity.FileEntity; diff --git a/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/api/UserApi.java b/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/api/UserApi.java index 264bfcc..36b8a74 100644 --- a/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/api/UserApi.java +++ b/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/api/UserApi.java @@ -2,6 +2,7 @@ package com.bgasol.model.system.user.api; import com.bgasol.common.constant.value.SystemConfigValues; import com.bgasol.common.core.base.vo.BaseVo; +import com.bgasol.plugin.openfeign.interceptor.GlobalScope; import com.bgasol.model.system.user.dto.UserCreateDto; import com.bgasol.model.system.user.dto.UserUpdateDto; import com.bgasol.model.system.user.entity.UserEntity; @@ -30,6 +31,7 @@ public interface UserApi { BaseVo delete(@PathVariable("ids") String ids); @GetMapping("/{id}") + @GlobalScope BaseVo findById(@PathVariable("id") String id); @GetMapping("findAllOnlineUser") diff --git a/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/entity/UserEntity.java b/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/entity/UserEntity.java index 542049d..671acac 100644 --- a/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/entity/UserEntity.java +++ b/cloud/model/model-system/src/main/java/com/bgasol/model/system/user/entity/UserEntity.java @@ -1,8 +1,6 @@ package com.bgasol.model.system.user.entity; -import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; import com.bgasol.common.core.base.entity.BaseEntity; import com.bgasol.model.system.department.entity.DepartmentEntity; diff --git a/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java index cd43d41..11fe3d8 100644 --- a/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java +++ b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java @@ -6,6 +6,7 @@ import com.bgasol.common.constant.value.GatewayConfigValues; import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; @@ -13,6 +14,7 @@ import org.springframework.web.context.request.RequestContextHolder; @Component public class FeignInterceptor implements RequestInterceptor { + /** * feign拦截器, 在feign请求发出之前,加入一些操作 */ @@ -20,18 +22,15 @@ public class FeignInterceptor implements RequestInterceptor { public void apply(RequestTemplate requestTemplate) { // 添加来自网关的标识 - requestTemplate.header(GatewayConfigValues.XFromGateway, "false"); + requestTemplate.header(GatewayConfigValues.XFromGateway, Boolean.FALSE.toString()); // 添加Same-Token请求头 requestTemplate.header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken()); // 添加用户身份令牌 - if (InWebRequest()) { - // 如果请求来自"UserApi#findById" 则不处理 - if ("UserApi#findById(String)".equals(requestTemplate.methodMetadata().configKey())) { - return; - } - if (StpUtil.isLogin()) { - requestTemplate.header(StpUtil.getTokenName(), StpUtil.getTokenValue()); - } + boolean useToken = InWebRequest() + && StpUtil.isLogin() + && BooleanUtils.isFalse(requestTemplate.methodMetadata().method().isAnnotationPresent(GlobalScope.class)); + if (useToken) { + requestTemplate.header(StpUtil.getTokenName(), StpUtil.getTokenValue()); } } diff --git a/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/GlobalScope.java b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/GlobalScope.java new file mode 100644 index 0000000..9e64acb --- /dev/null +++ b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/GlobalScope.java @@ -0,0 +1,12 @@ +package com.bgasol.plugin.openfeign.interceptor; + +import java.lang.annotation.*; + +/** + * 数据权限字段注解 + */ +@Target(ElementType.METHOD) // 只能标记函数 +@Retention(RetentionPolicy.RUNTIME) // 运行时可用 +@Documented +public @interface GlobalScope { +} From 7420871565568a3f50785f4e1ed8620732255e69 Mon Sep 17 00:00:00 2001 From: sol Date: Thu, 12 Mar 2026 04:48:45 +0800 Subject: [PATCH 2/2] feat(common): add global system logging with trace support --- client/src/generated/file/index.ts | 1 - .../src/generated/file/models/BaseVoObject.ts | 41 ----- .../src/generated/file/services/PoiService.ts | 2 +- client/src/generated/file/services/Service.ts | 42 ++--- client/src/generated/system/index.ts | 1 - .../generated/system/models/BaseVoObject.ts | 41 ----- .../src/generated/system/services/Service.ts | 88 +++++----- client/src/views/pages/Login.vue | 10 +- .../satoken/config/SaTokenConfigure.java | 4 +- cloud/common/common-base-model/pom.xml | 5 + .../core/base/exception/BaseException.java | 32 ++-- .../bgasol/common/core/base/vo/BaseVo.java | 20 +-- .../base/handler/BaseExceptionHandler.java | 34 ++-- ...andler.java => PgSqlExceptionHandler.java} | 19 ++- .../core/base/handler/SaExceptionHandler.java | 11 +- .../RequestLoggingInterceptor.java | 159 +++++++++++------- .../requestLog/mapper/RequestLogMapper.java | 9 + .../requestLog/service/RequestLogService.java | 21 +++ .../src/main/resources/application-web.yml | 3 - .../constant/value/SystemConfigValues.java | 7 + cloud/common/common-util/pom.xml | 12 +- .../requestLog/entity/RequestLogEntity.java | 84 +++++++++ cloud/plugin/plugin-openfeign/pom.xml | 8 + .../interceptor/FeignInterceptor.java | 20 ++- cloud/pom.xml | 1 - cloud/web/web-system-8081/pom.xml | 2 +- .../web/system/user/service/UserService.java | 2 +- .../src/main/resources/application.yml | 2 +- docker/.env | 1 + docker/app.docker-compose.yml | 1 + .../public/system/system_t_request_log.hcl | 109 ++++++++++++ 31 files changed, 496 insertions(+), 296 deletions(-) delete mode 100644 client/src/generated/file/models/BaseVoObject.ts delete mode 100644 client/src/generated/system/models/BaseVoObject.ts rename cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/{PostgreSqlExceptionHandler.java => PgSqlExceptionHandler.java} (90%) create mode 100644 cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/mapper/RequestLogMapper.java create mode 100644 cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/service/RequestLogService.java create mode 100644 cloud/model/model-system/src/main/java/com/bgasol/model/system/requestLog/entity/RequestLogEntity.java create mode 100644 docker/config/atlas/public/system/system_t_request_log.hcl diff --git a/client/src/generated/file/index.ts b/client/src/generated/file/index.ts index 73cb2b5..c7939ce 100644 --- a/client/src/generated/file/index.ts +++ b/client/src/generated/file/index.ts @@ -14,7 +14,6 @@ export { BaseVoListFileEntity } from './models/BaseVoListFileEntity'; export { BaseVoListImageEntity } from './models/BaseVoListImageEntity'; export { BaseVoListVerificationResult } from './models/BaseVoListVerificationResult'; export { BaseVoListVideoEntity } from './models/BaseVoListVideoEntity'; -export { BaseVoObject } from './models/BaseVoObject'; export { BaseVoPageVoFileEntity } from './models/BaseVoPageVoFileEntity'; export { BaseVoPageVoImageEntity } from './models/BaseVoPageVoImageEntity'; export { BaseVoPageVoPoiExportHistoryEntity } from './models/BaseVoPageVoPoiExportHistoryEntity'; diff --git a/client/src/generated/file/models/BaseVoObject.ts b/client/src/generated/file/models/BaseVoObject.ts deleted file mode 100644 index e99be8f..0000000 --- a/client/src/generated/file/models/BaseVoObject.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* generated using openapi-typescript-codegen -- do not edit */ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -/** - * 基础响应数据 - */ -export type BaseVoObject = { - /** - * 响应码 - */ - code?: number; - /** - * 响应消息 - */ - message?: string; - /** - * 响应数据 - */ - data?: Record; - /** - * 响应时间 - */ - time?: string; - /** - * 响应类型 - */ - type?: BaseVoObject.type; -}; -export namespace BaseVoObject { - /** - * 响应类型 - */ - export enum type { - SUCCESS = 'SUCCESS', - WARNING = 'WARNING', - INFO = 'INFO', - ERROR = 'ERROR', - } -} - diff --git a/client/src/generated/file/services/PoiService.ts b/client/src/generated/file/services/PoiService.ts index 592455d..9715d98 100644 --- a/client/src/generated/file/services/PoiService.ts +++ b/client/src/generated/file/services/PoiService.ts @@ -26,7 +26,7 @@ export class PoiService { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } diff --git a/client/src/generated/file/services/Service.ts b/client/src/generated/file/services/Service.ts index 906ddb7..4322aed 100644 --- a/client/src/generated/file/services/Service.ts +++ b/client/src/generated/file/services/Service.ts @@ -43,7 +43,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -65,7 +65,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -87,7 +87,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -109,7 +109,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -131,7 +131,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -153,7 +153,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -175,7 +175,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -197,7 +197,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -219,7 +219,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -242,7 +242,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -270,7 +270,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -293,7 +293,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -316,7 +316,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -339,7 +339,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -362,7 +362,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -385,7 +385,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -408,7 +408,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -431,7 +431,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -454,7 +454,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -477,7 +477,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -500,7 +500,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } diff --git a/client/src/generated/system/index.ts b/client/src/generated/system/index.ts index f934540..a113069 100644 --- a/client/src/generated/system/index.ts +++ b/client/src/generated/system/index.ts @@ -18,7 +18,6 @@ export { BaseVoListUserEntity } from './models/BaseVoListUserEntity'; export { BaseVoListVerificationResult } from './models/BaseVoListVerificationResult'; export { BaseVoMenuEntity } from './models/BaseVoMenuEntity'; export { BaseVoMessageEnvelopeEntityObject } from './models/BaseVoMessageEnvelopeEntityObject'; -export { BaseVoObject } from './models/BaseVoObject'; export { BaseVoPageVoMessageEnvelopeEntityObject } from './models/BaseVoPageVoMessageEnvelopeEntityObject'; export { BaseVoPageVoUserEntity } from './models/BaseVoPageVoUserEntity'; export { BaseVoPermissionEntity } from './models/BaseVoPermissionEntity'; diff --git a/client/src/generated/system/models/BaseVoObject.ts b/client/src/generated/system/models/BaseVoObject.ts deleted file mode 100644 index e99be8f..0000000 --- a/client/src/generated/system/models/BaseVoObject.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* generated using openapi-typescript-codegen -- do not edit */ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ -/** - * 基础响应数据 - */ -export type BaseVoObject = { - /** - * 响应码 - */ - code?: number; - /** - * 响应消息 - */ - message?: string; - /** - * 响应数据 - */ - data?: Record; - /** - * 响应时间 - */ - time?: string; - /** - * 响应类型 - */ - type?: BaseVoObject.type; -}; -export namespace BaseVoObject { - /** - * 响应类型 - */ - export enum type { - SUCCESS = 'SUCCESS', - WARNING = 'WARNING', - INFO = 'INFO', - ERROR = 'ERROR', - } -} - diff --git a/client/src/generated/system/services/Service.ts b/client/src/generated/system/services/Service.ts index 0ee2347..7ea3c6b 100644 --- a/client/src/generated/system/services/Service.ts +++ b/client/src/generated/system/services/Service.ts @@ -57,7 +57,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -79,7 +79,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -101,7 +101,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -123,7 +123,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -140,7 +140,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -162,7 +162,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -184,7 +184,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -206,7 +206,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -228,7 +228,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -245,7 +245,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -267,7 +267,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -289,7 +289,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -311,7 +311,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -328,7 +328,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -350,7 +350,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -374,7 +374,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -396,7 +396,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -418,7 +418,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -440,7 +440,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -463,7 +463,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -480,7 +480,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -503,7 +503,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -520,7 +520,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -543,7 +543,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -560,7 +560,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -583,7 +583,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -600,7 +600,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -623,7 +623,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -640,7 +640,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -663,7 +663,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -680,7 +680,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -703,7 +703,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -720,7 +720,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -743,7 +743,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -766,7 +766,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -783,7 +783,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -806,7 +806,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -829,7 +829,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -846,7 +846,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -869,7 +869,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -892,7 +892,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -915,7 +915,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -938,7 +938,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } @@ -961,7 +961,7 @@ export class Service { 400: `参数校验异常`, 401: `未登录异常`, 403: `无权限异常`, - 500: `业务异常`, + 500: `系统异常`, }, }); } diff --git a/client/src/views/pages/Login.vue b/client/src/views/pages/Login.vue index 8c15f98..1f7a359 100644 --- a/client/src/views/pages/Login.vue +++ b/client/src/views/pages/Login.vue @@ -6,7 +6,6 @@ import {useUser} from "~/pinia/modules/user"; import {ElButton, ElCol, ElForm, ElFormItem, ElImage, ElInput, ElMessage, ElRow, FormInstance} from "element-plus"; import {useFormValidation} from "~/composables/FormValidationHook"; import AppHeader from "~/views/app/layout/AppHeader.vue"; -import {set} from "@vueuse/core"; const loginDto = ref({ username: '', @@ -19,15 +18,15 @@ const imageBase64 = ref(); const getCaptcha = () => { // 获取验证码 Service.getVerificationCode().then((res) => { - if (res.data?.captcha){ + if (res.data?.captcha) { loginDto.value.verificationCode = res.data?.captcha needCaptcha.value = false; - }else{ + } else { needCaptcha.value = true; } loginDto.value.verificationCodeKey = res.data?.verificationId as string imageBase64.value = res.data?.verificationCode as string; - setTimeout(getCaptcha,30 * 1000) + setTimeout(getCaptcha, 30 * 1000) }); }; onMounted(() => { @@ -64,8 +63,9 @@ const login = () => { } }).catch(() => { getCaptcha(); + }).finally(() => { loading.value = false; - }); + }) }; const pageLoading = ref(true); onMounted(() => { diff --git a/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenConfigure.java b/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenConfigure.java index d3a6f12..d3c3a04 100644 --- a/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenConfigure.java +++ b/cloud/common/common-auth/src/main/java/com/bgasol/plugin/satoken/config/SaTokenConfigure.java @@ -38,7 +38,9 @@ public class SaTokenConfigure implements WebMvcConfigurer { } }) .setError(e -> { - throw new BaseException("鉴权失败"); + throw BaseException.builder() + .message("鉴权失败") + .cause(e).build(); }); } diff --git a/cloud/common/common-base-model/pom.xml b/cloud/common/common-base-model/pom.xml index c2bf371..f51989c 100644 --- a/cloud/common/common-base-model/pom.xml +++ b/cloud/common/common-base-model/pom.xml @@ -30,6 +30,11 @@ jakarta.persistence jakarta.persistence-api + + cn.idev.excel + fastexcel + ${fastexcel.version} + \ No newline at end of file diff --git a/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/exception/BaseException.java b/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/exception/BaseException.java index e9f565f..b867b34 100644 --- a/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/exception/BaseException.java +++ b/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/exception/BaseException.java @@ -1,36 +1,30 @@ package com.bgasol.common.core.base.exception; -import com.bgasol.common.core.base.vo.BaseVo; import com.bgasol.common.core.base.vo.ResponseType; +import lombok.Builder; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -/// 自定义通用异常 @Getter @Slf4j public class BaseException extends RuntimeException { - private Throwable throwable; + private final ResponseType responseType; + private final Boolean isPrimary; + private final Integer code; - private final BaseVo baseVo; - - public BaseException(BaseVo baseVo) { - super(baseVo.getMessage()); - this.baseVo = baseVo; + @Builder + public BaseException(String message, Throwable cause, ResponseType responseType, Boolean isPrimary, Integer code) { + super(message, cause); + this.responseType = responseType != null ? responseType : ResponseType.ERROR; + this.isPrimary = isPrimary != null ? isPrimary : false; + this.code = code != null ? code : -1; } public BaseException(String message) { - super(message); - this.baseVo = BaseVo.error(message); + this(message, null, null, null, null); } - public BaseException(String message, Throwable throwable) { - super(message); - this.baseVo = BaseVo.error(message); - this.throwable = throwable; - } - - public BaseException(String message, ResponseType type) { - super(message); - this.baseVo = BaseVo.error(message, type); + public BaseException(String message, Throwable cause) { + this(message, cause, null, null, null); } } diff --git a/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/vo/BaseVo.java b/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/vo/BaseVo.java index 0ffab0b..9d44754 100644 --- a/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/vo/BaseVo.java +++ b/cloud/common/common-base-model/src/main/java/com/bgasol/common/core/base/vo/BaseVo.java @@ -87,30 +87,14 @@ public class BaseVo { .build(); } - /** - * 错误响应 - * - * @param data 响应数据 - * @param message 响应消息 - */ - static public BaseVo error(T data, String message) { - return BaseVo.builder() - .code(500) - .data(data) - .time(new Date()) - .message(message) - .type(ResponseType.ERROR) - .build(); - } - /** * 错误响应 * * @param message 响应消息 * @param type 响应类型 前端可以根据这个类型进行不同的颜色展示 */ - static public BaseVo error(String message, ResponseType type) { - return BaseVo.builder() + static public BaseVo error(String message, ResponseType type) { + return BaseVo.builder() .code(500) .time(new Date()) .message(message) diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/BaseExceptionHandler.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/BaseExceptionHandler.java index e16bceb..9eff84c 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/BaseExceptionHandler.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/BaseExceptionHandler.java @@ -4,24 +4,27 @@ import com.bgasol.common.core.base.exception.BaseException; import com.bgasol.common.core.base.exception.VerificationException; import com.bgasol.common.core.base.vo.BaseVo; import com.bgasol.common.core.base.vo.VerificationResult; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import jakarta.validation.Path; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION; +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION_PRIMARY; + /** * 全局异常处理 */ @@ -30,32 +33,34 @@ import java.util.List; @RestControllerAdvice public class BaseExceptionHandler { - private final ObjectMapper objectMapper; - /** * 处理业务异常 */ @ExceptionHandler(value = BaseException.class) @ApiResponse(description = "业务异常", responseCode = "500") - public BaseVo baseExceptionHandler(BaseException e) { - log.error("业务异常", e); - return e.getBaseVo(); + public BaseVo baseExceptionHandler(BaseException e, HttpServletRequest request) { + if (e.getIsPrimary()) { + request.setAttribute(REQUEST_EXCEPTION_PRIMARY, true); + } + request.setAttribute(REQUEST_EXCEPTION, ExceptionUtils.getStackTrace(e)); + return BaseVo.error(e.getMessage(), e.getResponseType()); } @ExceptionHandler(value = VerificationException.class) @ApiResponse(description = "参数校验异常", responseCode = "400") - public BaseVo> verificationExceptionHandler(VerificationException e) throws JsonProcessingException { + public BaseVo> verificationExceptionHandler(VerificationException e, HttpServletRequest request) { List verificationResults = e.getVerificationResults(); - log.error(objectMapper.writeValueAsString(verificationResults)); + request.setAttribute(REQUEST_EXCEPTION, "参数校验异常"); return BaseVo.code400(verificationResults); } /** * 处理参数校验异常 方法参数级 MethodArgumentNotValidException */ + @SneakyThrows @ExceptionHandler(MethodArgumentNotValidException.class) @ApiResponse(description = "参数校验异常", responseCode = "400") - public BaseVo> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, JsonProcessingException { + public BaseVo> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e, HttpServletRequest request) { BindingResult bindingResult = e.getBindingResult(); List allErrors = bindingResult.getAllErrors(); List verificationResults = new ArrayList<>(); @@ -68,7 +73,7 @@ public class BaseExceptionHandler { verificationResult.setResult(false); verificationResults.add(verificationResult); } - log.error(objectMapper.writeValueAsString(verificationResults)); + request.setAttribute(REQUEST_EXCEPTION, "参数校验异常"); return BaseVo.code400(verificationResults); } @@ -77,8 +82,7 @@ public class BaseExceptionHandler { */ @ExceptionHandler(value = ConstraintViolationException.class) @ApiResponse(description = "参数校验异常", responseCode = "400") - public BaseVo> constraintViolationExceptionHandler(ConstraintViolationException e) throws JsonProcessingException { -// Set> constraintViolations = e.getConstraintViolations(); + public BaseVo> constraintViolationExceptionHandler(ConstraintViolationException e, HttpServletRequest request) { List verificationResults = new ArrayList<>(); for (ConstraintViolation constraintViolation : e.getConstraintViolations()) { VerificationResult verificationResult = new VerificationResult(); @@ -93,7 +97,7 @@ public class BaseExceptionHandler { verificationResult.setResult(false); verificationResults.add(verificationResult); } - log.error(objectMapper.writeValueAsString(verificationResults)); + request.setAttribute(REQUEST_EXCEPTION, "参数校验异常"); return BaseVo.code400(verificationResults); } } diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PostgreSqlExceptionHandler.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PgSqlExceptionHandler.java similarity index 90% rename from cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PostgreSqlExceptionHandler.java rename to cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PgSqlExceptionHandler.java index 5fce755..2682f65 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PostgreSqlExceptionHandler.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/PgSqlExceptionHandler.java @@ -1,38 +1,43 @@ package com.bgasol.common.core.base.handler; import com.bgasol.common.core.base.vo.BaseVo; -import com.bgasol.common.core.base.vo.ResponseType; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.postgresql.util.PSQLException; import org.postgresql.util.ServerErrorMessage; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION; + /** * PostgreSQL 异常处理,转换为友好的中文提示 */ @Slf4j @RestControllerAdvice @RequiredArgsConstructor -public class PostgreSqlExceptionHandler { +public class PgSqlExceptionHandler { private final EntityFieldCache entityFieldCache; @ExceptionHandler(PSQLException.class) @ApiResponse(description = "PostgreSQL异常", responseCode = "500") - public BaseVo handlePSQLException(PSQLException ex) { - logDatabaseError(ex); + public BaseVo handlePSQLException(PSQLException e, HttpServletRequest request) { + logDatabaseError(e); - String errorMsg = ex.getMessage(); - ServerErrorMessage serverError = ex.getServerErrorMessage(); + String errorMsg = e.getMessage(); + ServerErrorMessage serverError = e.getServerErrorMessage(); String tableName = serverError != null ? serverError.getTable() : null; String detail = serverError != null ? serverError.getDetail() : null; String column = serverError != null ? serverError.getColumn() : null; String message = handleMessage(errorMsg, tableName, detail, column); - return BaseVo.error(message, ResponseType.ERROR); + + request.setAttribute(REQUEST_EXCEPTION, ExceptionUtils.getStackTrace(e)); + return BaseVo.error(message); } private String handleMessage(String errorMsg, String tableName, String detail, String column) { diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/SaExceptionHandler.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/SaExceptionHandler.java index 56891aa..53386cb 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/SaExceptionHandler.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/handler/SaExceptionHandler.java @@ -4,10 +4,13 @@ import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotPermissionException; import com.bgasol.common.core.base.vo.BaseVo; import io.swagger.v3.oas.annotations.responses.ApiResponse; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION; + /** * Sa-Token 异常处理 */ @@ -19,8 +22,8 @@ public class SaExceptionHandler { */ @ExceptionHandler(value = NotLoginException.class) @ApiResponse(description = "未登录异常", responseCode = "401") - public BaseVo notLoginExceptionHandler(NotLoginException e) { - log.error("未登录异常", e); + public BaseVo notLoginExceptionHandler(NotLoginException e, HttpServletRequest request) { + request.setAttribute(REQUEST_EXCEPTION, "未登录异常"); return BaseVo.code401(); } @@ -29,8 +32,8 @@ public class SaExceptionHandler { */ @ExceptionHandler(value = NotPermissionException.class) @ApiResponse(description = "无权限异常", responseCode = "403") - public BaseVo notPermissionExceptionHandler(NotPermissionException e) { - log.error("无权限异常", e); + public BaseVo notPermissionExceptionHandler(NotPermissionException e, HttpServletRequest request) { + request.setAttribute(REQUEST_EXCEPTION, "无权限异常"); return BaseVo.code403(); } } diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/interceptor/RequestLoggingInterceptor.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/interceptor/RequestLoggingInterceptor.java index d864e14..d3640bb 100644 --- a/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/interceptor/RequestLoggingInterceptor.java +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/core/base/interceptor/RequestLoggingInterceptor.java @@ -1,20 +1,32 @@ package com.bgasol.common.core.base.interceptor; -import com.bgasol.plugin.websocket.dto.WsSendMessageDto; -import com.fasterxml.jackson.databind.ObjectMapper; +import cn.dev33.satoken.stp.StpUtil; +import com.bgasol.model.system.requestLog.entity.RequestLogEntity; +import com.bgasol.common.requestLog.service.RequestLogService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.redisson.api.RTopic; -import org.redisson.api.RedissonClient; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.lang.NonNull; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; -import static com.bgasol.common.util.WSUtils.GetWSTopic; +import java.lang.reflect.Method; +import java.util.Date; +import java.util.UUID; + +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION; +import static com.bgasol.common.constant.value.SystemConfigValues.REQUEST_EXCEPTION_PRIMARY; +import static com.bgasol.plugin.openfeign.interceptor.FeignInterceptor.SPAN_ID; +import static com.bgasol.plugin.openfeign.interceptor.FeignInterceptor.TRACE_ID; /** * 请求日志拦截器 @@ -22,88 +34,107 @@ import static com.bgasol.common.util.WSUtils.GetWSTopic; */ @Slf4j @Configuration -@RequiredArgsConstructor +@RequiredArgsConstructor(onConstructor_ = {@Lazy}) public class RequestLoggingInterceptor implements HandlerInterceptor { - private static final String START_TIME_ATTRIBUTE = "REQUEST_START_TIME"; - private static final String REQUEST_HANDLER_ATTRIBUTE = "REQUEST_HANDLER"; - private static final String REQUEST_LOG = "REQUEST_LOG"; @Value("${spring.application.name}") private String serviceName; - private final RedissonClient redissonClient; - private final ObjectMapper objectMapper; - @Value("${system.ws.open-request-log}") - private Boolean openWsRequestLog; + @Value("${system.node-name}") + private String nodeName; + @Value("${system.node-ip}") + private String nodeIp; + + private static final String BUSINESS_CONTROLLER = "BUSINESS_CONTROLLER"; + private static final String BUSINESS_METHOD = "BUSINESS_METHOD"; + private static final String START_TIME_ATTRIBUTE = "REQUEST_START_TIME"; + + @Lazy + private final RequestLogService requestLogService; @Override - public boolean preHandle(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) { - long startTime = System.currentTimeMillis(); - String handlerInfo = getHandlerInfo(handler); - - request.setAttribute(START_TIME_ATTRIBUTE, startTime); - request.setAttribute(REQUEST_HANDLER_ATTRIBUTE, handlerInfo); + public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) { + getHandlerInfo(request, handler); + String traceId = request.getHeader(TRACE_ID); + if (ObjectUtils.isEmpty(traceId)) { + request.setAttribute(TRACE_ID, UUID.randomUUID().toString()); + } else { + request.setAttribute(TRACE_ID, traceId); + } + request.setAttribute(SPAN_ID, UUID.randomUUID().toString()); + request.setAttribute(START_TIME_ATTRIBUTE, System.currentTimeMillis()); return true; } @Override - public void afterCompletion(HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) { + public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) { + + String parentSpanId = request.getHeader(SPAN_ID); + String spanId = (String) request.getAttribute(SPAN_ID); + String traceId = (String) request.getAttribute(TRACE_ID); + Long startTime = (Long) request.getAttribute(START_TIME_ATTRIBUTE); - if (startTime == null) { - return; - } + long endTime = System.currentTimeMillis(); String method = request.getMethod(); String uri = request.getRequestURI(); String queryString = request.getQueryString(); - String handlerInfo = (String) request.getAttribute(REQUEST_HANDLER_ATTRIBUTE); - long endTime = System.currentTimeMillis(); int status = response.getStatus(); - - // 获取当前线程id long threadId = Thread.currentThread().getId(); - if (!openWsRequestLog) { - return; - } - try { - RTopic ws = redissonClient.getTopic(GetWSTopic(serviceName)); - String logString = objectMapper.writeValueAsString(new RequestLog(threadId, - serviceName, - method, - uri, - startTime, - endTime, - queryString, - handlerInfo, - status, - ex != null ? ex.getMessage() : "")); - ws.publish(WsSendMessageDto.builder() - .json(logString) - .type(REQUEST_LOG).build()); - } catch (Exception e) { - log.error("日志消息广播异常", e); + + String businessMethod = (String) request.getAttribute(BUSINESS_METHOD); + String businessController = (String) request.getAttribute(BUSINESS_CONTROLLER); + + String errorLog = null; + boolean isPrimaryErr = false; + if (ex != null) { + isPrimaryErr = true; + errorLog = ExceptionUtils.getStackTrace(ex); + log.error(ex.getMessage(), ex); + } else { + if (BooleanUtils.isTrue((Boolean) request.getAttribute(REQUEST_EXCEPTION_PRIMARY))) { + isPrimaryErr = true; + errorLog = (String) request.getAttribute(REQUEST_EXCEPTION); + } } + + requestLogService.insert(RequestLogEntity.builder() + .id(spanId) + .parentId(parentSpanId) + .createTime(new Date(startTime)) + .updateTime(new Date(endTime)) + .traceId(traceId) + .serviceName(serviceName) + .nodeName(nodeName) + .nodeIp(nodeIp) + .method(method) + .uri(uri) + .queryString(queryString) + .status(status) + .threadId(threadId) + .errorLog(errorLog) + .isPrimaryErr(isPrimaryErr) + .businessMethod(businessMethod) + .businessController(businessController) + .userId(StpUtil.isLogin() ? StpUtil.getLoginIdAsString() : null) + .build()); } - private record RequestLog(Long threadId, - String serviceName, - String method, - String uri, - Long startTime, - Long endTime, - String queryString, - String handlerInfo, - Integer status, - String errorMessage) { - } - - private String getHandlerInfo(Object handler) { + private void getHandlerInfo(HttpServletRequest request, Object handler) { if (handler instanceof HandlerMethod handlerMethod) { - String className = handlerMethod.getBeanType().getSimpleName(); - String methodName = handlerMethod.getMethod().getName(); - return className + "." + methodName + "()"; + Class controllerClass = handlerMethod.getBeanType(); + Method method = handlerMethod.getMethod(); + Operation operation = method.getAnnotation(Operation.class); + if (operation != null) { + String summary = operation.summary(); + + request.setAttribute(BUSINESS_METHOD, summary); + } + Tag tag = controllerClass.getAnnotation(Tag.class); + if (tag != null) { + request.setAttribute(BUSINESS_CONTROLLER, tag.name()); + } } - return null; } } diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/mapper/RequestLogMapper.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/mapper/RequestLogMapper.java new file mode 100644 index 0000000..7158f99 --- /dev/null +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/mapper/RequestLogMapper.java @@ -0,0 +1,9 @@ +package com.bgasol.common.requestLog.mapper; + +import com.bgasol.common.core.base.mapper.MyBaseMapper; +import com.bgasol.model.system.requestLog.entity.RequestLogEntity; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface RequestLogMapper extends MyBaseMapper { +} diff --git a/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/service/RequestLogService.java b/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/service/RequestLogService.java new file mode 100644 index 0000000..49ecdd6 --- /dev/null +++ b/cloud/common/common-base-web/src/main/java/com/bgasol/common/requestLog/service/RequestLogService.java @@ -0,0 +1,21 @@ +package com.bgasol.common.requestLog.service; + +import com.bgasol.common.core.base.dto.BasePageDto; +import com.bgasol.common.core.base.service.BaseTreeService; +import com.bgasol.model.system.requestLog.entity.RequestLogEntity; +import com.bgasol.common.requestLog.mapper.RequestLogMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class RequestLogService extends BaseTreeService> { + private final RequestLogMapper requestLogMapper; + + @Override + public RequestLogMapper commonBaseMapper() { + return requestLogMapper; + } +} diff --git a/cloud/common/common-base-web/src/main/resources/application-web.yml b/cloud/common/common-base-web/src/main/resources/application-web.yml index 4c85fb6..a6219c7 100644 --- a/cloud/common/common-base-web/src/main/resources/application-web.yml +++ b/cloud/common/common-base-web/src/main/resources/application-web.yml @@ -3,6 +3,3 @@ server: threads: io: 1 worker: 8 -system: - ws: - open-request-log: false \ No newline at end of file diff --git a/cloud/common/common-constant/src/main/java/com/bgasol/common/constant/value/SystemConfigValues.java b/cloud/common/common-constant/src/main/java/com/bgasol/common/constant/value/SystemConfigValues.java index f3edeaf..16c868d 100644 --- a/cloud/common/common-constant/src/main/java/com/bgasol/common/constant/value/SystemConfigValues.java +++ b/cloud/common/common-constant/src/main/java/com/bgasol/common/constant/value/SystemConfigValues.java @@ -25,4 +25,11 @@ public class SystemConfigValues { public final static String NODE_NAME_KEY = "node-name"; public final static String NODE_IP_KEY = "node-ip"; + + public final static String TRACE_INFO_KEY = "Trace-Info"; + + public final static String REQUEST_EXCEPTION = "REQUEST_EXCEPTION"; + + public final static String REQUEST_EXCEPTION_PRIMARY = "REQUEST_EXCEPTION_PRIMARY"; + } diff --git a/cloud/common/common-util/pom.xml b/cloud/common/common-util/pom.xml index 4fb7f99..33aba0c 100644 --- a/cloud/common/common-util/pom.xml +++ b/cloud/common/common-util/pom.xml @@ -11,6 +11,10 @@ 0.1.55 + 1.6 + 3.18.0 + 1.16.1 + 2.12.0 common-util @@ -19,6 +23,7 @@ org.apache.commons commons-lang3 + ${lang3.version} org.apache.commons @@ -28,20 +33,17 @@ commons-codec commons-codec + ${codec.version} org.apache.commons commons-pool2 + ${pool2.version} com.jcraft jsch ${jsch.version} - - cn.idev.excel - fastexcel - ${fastexcel.version} - \ No newline at end of file diff --git a/cloud/model/model-system/src/main/java/com/bgasol/model/system/requestLog/entity/RequestLogEntity.java b/cloud/model/model-system/src/main/java/com/bgasol/model/system/requestLog/entity/RequestLogEntity.java new file mode 100644 index 0000000..e3af8f2 --- /dev/null +++ b/cloud/model/model-system/src/main/java/com/bgasol/model/system/requestLog/entity/RequestLogEntity.java @@ -0,0 +1,84 @@ +package com.bgasol.model.system.requestLog.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.bgasol.common.core.base.entity.BaseTreeEntity; +import com.bgasol.model.system.user.entity.UserEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.Entity; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Transient; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +@Setter +@Getter +@SuperBuilder +@NoArgsConstructor +@Schema(description = "系统请求日志实体类") +@TableName(value = "system_t_request_log", autoResultMap = true) +@Entity +public class RequestLogEntity extends BaseTreeEntity { + @Schema(description = "全局链路ID") + @TableField("trace_id") + private String traceId; + + @Schema(description = "服务名") + private String serviceName; + + @Schema(description = "节点名") + private String nodeName; + + @Schema(description = "节点IP") + private String nodeIp; + + @Schema(description = "HTTP方法") + @TableField("method") + private String method; + + @Schema(description = "请求URI") + @TableField("uri") + private String uri; + + @Schema(description = "请求参数") + @TableField("query_string") + private String queryString; + + @Schema(description = "HTTP状态码") + @TableField("status") + private Integer status; + + @Schema(description = "线程ID") + @TableField("thread_id") + private Long threadId; + + @Schema(description = "异常堆栈") + @TableField("error_log") + private String errorLog; + + @Schema(description = "是否是重要异常") + @TableField("is_primary_err") + private Boolean isPrimaryErr; + + @Schema(description = "业务方法") + @TableField("business_method") + private String businessMethod; + + @Schema(description = "业务模块/Controller") + @TableField("business_controller") + private String businessController; + + @Schema(description = "用户ID") + @TableField("user_id") + @Transient + private String userId; + + @Schema(description = "用户") + @TableField(exist = false) + @JoinColumn(name = "user_id") + @ManyToOne + private UserEntity userEntity; +} \ No newline at end of file diff --git a/cloud/plugin/plugin-openfeign/pom.xml b/cloud/plugin/plugin-openfeign/pom.xml index 47e8d42..829c2b9 100644 --- a/cloud/plugin/plugin-openfeign/pom.xml +++ b/cloud/plugin/plugin-openfeign/pom.xml @@ -21,5 +21,13 @@ sa-token-core ${sa-token.version} + + org.apache.tomcat.embed + tomcat-embed-core + + + com.fasterxml.jackson.core + jackson-databind + \ No newline at end of file diff --git a/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java index 11fe3d8..4eb1043 100644 --- a/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java +++ b/cloud/plugin/plugin-openfeign/src/main/java/com/bgasol/plugin/openfeign/interceptor/FeignInterceptor.java @@ -5,15 +5,22 @@ import cn.dev33.satoken.stp.StpUtil; import com.bgasol.common.constant.value.GatewayConfigValues; import feign.RequestInterceptor; import feign.RequestTemplate; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; @Slf4j @Component +@RequiredArgsConstructor public class FeignInterceptor implements RequestInterceptor { + public static final String TRACE_ID = "TRACE_ID"; + public static final String SPAN_ID = "SPAN_ID"; /** * feign拦截器, 在feign请求发出之前,加入一些操作 @@ -32,12 +39,23 @@ public class FeignInterceptor implements RequestInterceptor { if (useToken) { requestTemplate.header(StpUtil.getTokenName(), StpUtil.getTokenValue()); } + + // 添加链路信息 + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + if (attributes instanceof ServletRequestAttributes servletAttributes) { + HttpServletRequest request = servletAttributes.getRequest(); + String spanId = (String) request.getAttribute(SPAN_ID); + String traceId = (String) request.getAttribute(TRACE_ID); + requestTemplate.header(SPAN_ID, spanId); + requestTemplate.header(TRACE_ID, traceId); + } } /** * 判断当前请求是否在web请求的下文中 */ public static boolean InWebRequest() { - return RequestContextHolder.getRequestAttributes() != null; + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return attributes instanceof ServletRequestAttributes; } } diff --git a/cloud/pom.xml b/cloud/pom.xml index a04354a..a0c42e3 100644 --- a/cloud/pom.xml +++ b/cloud/pom.xml @@ -41,7 +41,6 @@ UTF-8 UTF-8 UTF-8 - 1.6 1.3.0 diff --git a/cloud/web/web-system-8081/pom.xml b/cloud/web/web-system-8081/pom.xml index a944832..2e02e52 100644 --- a/cloud/web/web-system-8081/pom.xml +++ b/cloud/web/web-system-8081/pom.xml @@ -21,7 +21,7 @@ com.pig4cloud.plugin - captcha-spring-boot-starter + captcha-core ${captcha.version} diff --git a/cloud/web/web-system-8081/src/main/java/com/bgasol/web/system/user/service/UserService.java b/cloud/web/web-system-8081/src/main/java/com/bgasol/web/system/user/service/UserService.java index aa84b4b..4f49524 100644 --- a/cloud/web/web-system-8081/src/main/java/com/bgasol/web/system/user/service/UserService.java +++ b/cloud/web/web-system-8081/src/main/java/com/bgasol/web/system/user/service/UserService.java @@ -71,7 +71,7 @@ public class UserService extends BaseService { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(UserEntity::getUsername, entity.getUsername()); if (userMapper.selectCount(queryWrapper) > 0) { - throw new BaseException("用户名已存在"); + throw BaseException.builder().message("用户名已存在").build(); } String password = entity.getPassword(); if (ObjectUtils.isNotEmpty(password)) { diff --git a/cloud/web/web-system-8081/src/main/resources/application.yml b/cloud/web/web-system-8081/src/main/resources/application.yml index 4687aab..185a706 100644 --- a/cloud/web/web-system-8081/src/main/resources/application.yml +++ b/cloud/web/web-system-8081/src/main/resources/application.yml @@ -6,7 +6,7 @@ system: title: ${SYSTEM_TITLE_NAME:sol} describe: 系统基础服务,包含用户管理权限管理等。 password: - plaintext: true # 是否明文存储密码 + plaintext: ${SYSTEM_PASSWORD_PLAINTEXT:true} # 是否明文存储密码 captcha: is-open: ${SYSTEM_CAPTCHA_IS_OPEN:true} max: ${SYSTEM_CAPTCHA_MAX:11} diff --git a/docker/.env b/docker/.env index 1f721fa..a435458 100644 --- a/docker/.env +++ b/docker/.env @@ -17,6 +17,7 @@ SYSTEM_CAPTCHA_IS_OPEN=true SYSTEM_CAPTCHA_MAX=11 SYSTEM_CAPTCHA_LENGTH=3 SYSTEM_AUTH_ENABLED=true +SYSTEM_PASSWORD_PLAINTEXT=true TZ=Asia/Shanghai diff --git a/docker/app.docker-compose.yml b/docker/app.docker-compose.yml index cac0a37..fd74d13 100644 --- a/docker/app.docker-compose.yml +++ b/docker/app.docker-compose.yml @@ -87,6 +87,7 @@ services: SYSTEM_CAPTCHA_IS_OPEN: ${SYSTEM_CAPTCHA_IS_OPEN} SYSTEM_CAPTCHA_MAX: ${SYSTEM_CAPTCHA_MAX} SYSTEM_CAPTCHA_LENGTH: ${SYSTEM_CAPTCHA_LENGTH} + SYSTEM_PASSWORD_PLAINTEXT: ${SYSTEM_PASSWORD_PLAINTEXT} POSTGRES_HOST: cloud-app-postgres POSTGRES_PORT: 5432 diff --git a/docker/config/atlas/public/system/system_t_request_log.hcl b/docker/config/atlas/public/system/system_t_request_log.hcl new file mode 100644 index 0000000..e76f7e0 --- /dev/null +++ b/docker/config/atlas/public/system/system_t_request_log.hcl @@ -0,0 +1,109 @@ +# --------------------------- +# 请求日志表 +# --------------------------- +table "system_t_request_log" { + schema = schema.public + + column "id" { + type = varchar(50) + null = false + } + column "type" { + type = varchar(50) + null = true + } + column "sort" { + type = int + null = true + } + column "create_time" { + type = timestamp(6) + null = true + default = sql("now()") + } + column "update_time" { + type = timestamp(6) + null = true + } + column "description" { + type = text + null = true + } + + column "parent_id" { + type = varchar(50) + null = true + } + + column "trace_id" { + type = varchar(64) + null = true + } + column "service_name" { + type = varchar(100) + null = true + } + column "node_name" { + type = varchar(100) + null = true + } + column "node_ip" { + type = varchar(50) + null = true + } + column "method" { + type = varchar(10) + null = true + } + column "uri" { + type = varchar(2000) + null = true + } + column "query_string" { + type = text + null = true + } + column "status" { + type = int + null = true + } + column "thread_id" { + type = bigint + null = true + } + column "error_log" { + type = text + null = true + } + column "is_primary_err" { + type = boolean + null = true + } + column "business_method" { + type = varchar(255) + null = true + } + column "business_controller" { + type = varchar(255) + null = true + } + column "user_id" { + type = varchar(255) + null = true + } + + primary_key { + columns = [column.id] + } + + # 索引 + index "idx_request_log_create_time" { + columns = [column.create_time] + } + index "idx_request_log_parent_id" { + columns = [column.parent_id] + } + index "idx_request_log_trace_id" { + columns = [column.trace_id] + } +} \ No newline at end of file