Prechádzať zdrojové kódy

去掉无用得注释

hmy 2 týždňov pred
rodič
commit
274feba50b
45 zmenil súbory, kde vykonal 300 pridanie a 481 odobranie
  1. 2 2
      xdz-framework/xdz-common/src/main/java/com/xindazhou/framework/common/enums/DocumentEnum.java
  2. 1 1
      xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialUserRespDTO.java
  3. 1 1
      xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxJsapiSignatureRespDTO.java
  4. 1 6
      xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxaOrderNotifyConfirmReceiveReqDTO.java
  5. 1 7
      xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxaOrderUploadShippingInfoReqDTO.java
  6. 6 30
      xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/enums/SocialTypeEnum.java
  7. 1 16
      xdz-framework/xdz-spring-boot-starter-biz-tenant/src/main/java/com/xindazhou/framework/tenant/package-info.java
  8. 1 5
      xdz-framework/xdz-spring-boot-starter-protection/src/main/java/com/xindazhou/framework/signature/package-info.java
  9. 119 117
      xdz-framework/xdz-spring-boot-starter-test/src/main/java/com/xindazhou/framework/test/core/util/RandomUtils.java
  10. 1 9
      xdz-framework/xdz-spring-boot-starter-web/src/main/java/com/xindazhou/framework/swagger/config/Knife4jOpenApiCustomizer.java
  11. 1 7
      xdz-framework/xdz-spring-boot-starter-web/src/main/java/com/xindazhou/framework/xss/core/clean/JsoupXssCleaner.java
  12. 1 1
      xdz-framework/xdz-spring-boot-starter-websocket/src/main/java/com/xindazhou/framework/websocket/core/session/WebSocketSessionHandlerDecorator.java
  13. 2 2
      xdz-module-business/xdz-module-business-api/src/main/java/com/xindazhou/business/api/social/SocialClientApi.java
  14. 1 1
      xdz-module-business/xdz-module-business-api/src/main/java/com/xindazhou/business/api/user/dto/AdminUserRespDTO.java
  15. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/auth/vo/AuthPermissionInfoRespVO.java
  16. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/file/vo/file/FileCreateReqVO.java
  17. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/file/vo/file/FileRespVO.java
  18. 2 2
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/OAuth2OpenController.java
  19. 2 2
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java
  20. 2 2
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/client/OAuth2ClientSaveReqVO.java
  21. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java
  22. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java
  23. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/SmsCallbackController.java
  24. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/vo/channel/SmsChannelRespVO.java
  25. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/vo/channel/SmsChannelSaveReqVO.java
  26. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/socail/vo/user/SocialUserRespVO.java
  27. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/tenant/vo/tenant/TenantRespVO.java
  28. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java
  29. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/profile/UserProfileRespVO.java
  30. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java
  31. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/user/UserRespVO.java
  32. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/user/UserSaveReqVO.java
  33. 115 198
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/framework/file/core/client/s3/S3FileClient.java
  34. 8 35
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/framework/file/core/client/s3/S3FileClientConfig.java
  35. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/service/codegen/inner/CodegenBuilder.java
  36. 1 1
      xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/service/oauth2/OAuth2GrantServiceImpl.java
  37. 1 1
      xdz-module-user/xdz-module-user-api/src/main/java/com/xindazhou/user/api/user/dto/MemberUserRespDTO.java
  38. 2 2
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/level/vo/level/MemberLevelBaseVO.java
  39. 4 7
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/level/vo/level/MemberLevelSimpleRespVO.java
  40. 1 2
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/user/vo/MemberUserBaseVO.java
  41. 1 1
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java
  42. 2 2
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/level/vo/level/AppMemberLevelRespVO.java
  43. 1 1
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/social/vo/AppSocialUserRespVO.java
  44. 2 2
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/user/vo/AppMemberUserInfoRespVO.java
  45. 1 2
      xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/user/vo/AppMemberUserUpdateReqVO.java

+ 2 - 2
xdz-framework/xdz-common/src/main/java/com/xindazhou/framework/common/enums/DocumentEnum.java

@@ -12,8 +12,8 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum DocumentEnum {
 
-    REDIS_INSTALL("", "Redis 安装文档"),
-    TENANT("https://doc.narutohuo.cn", "SaaS 多租户文档");
+    REDIS_INSTALL("", ""),
+    TENANT("", "");
 
     private final String url;
     private final String memo;

+ 1 - 1
xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialUserRespDTO.java

@@ -17,7 +17,7 @@ public class SocialUserRespDTO {
     @Schema(description = "社交用户的昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz")
     private String nickname;
 
-    @Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/1.jpg")
+    @Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED)
     private String avatar;
 
     @Schema(description = "关联的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")

+ 1 - 1
xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxJsapiSignatureRespDTO.java

@@ -16,7 +16,7 @@ public class SocialWxJsapiSignatureRespDTO {
     @Schema(description = "时间戳", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789")
     private Long timestamp;
 
-    @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn")
+    @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     private String url;
 
     @Schema(description = "签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "zsw")

+ 1 - 6
xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxaOrderNotifyConfirmReceiveReqDTO.java

@@ -6,12 +6,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 
-/**
- * 小程序订单上传购物详情
- *
- * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/shopping-order/normal-shopping-detail/uploadShoppingInfo.html">上传购物详情</a>
- * @author xdz
- */
+
 @Data
 public class SocialWxaOrderNotifyConfirmReceiveReqDTO {
 

+ 1 - 7
xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/core/dto/SocialWxaOrderUploadShippingInfoReqDTO.java

@@ -4,12 +4,7 @@ import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
-/**
- * 小程序订单上传购物详情
- *
- * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/shopping-order/normal-shopping-detail/uploadShoppingInfo.html">上传购物详情</a>
- * @author xdz
- */
+
 @Data
 public class SocialWxaOrderUploadShippingInfoReqDTO {
 
@@ -50,7 +45,6 @@ public class SocialWxaOrderUploadShippingInfoReqDTO {
     /**
      * 物流公司编号
      *
-     * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/industry/express/business/express_search.html#%E8%8E%B7%E5%8F%96%E8%BF%90%E5%8A%9Bid%E5%88%97%E8%A1%A8get-delivery-list">物流查询插件简介</a>
      */
     private String expressCompany;
     /**

+ 6 - 30
xdz-framework/xdz-spring-boot-starter-biz-social/src/main/java/com/xindazhou/framework/social/enums/SocialTypeEnum.java

@@ -18,42 +18,18 @@ public enum SocialTypeEnum implements ArrayValuable<Integer> {
 
      */
     GITEE(10, "GITEE"),
-    /**
-     * 钉钉
-     *
-     * @see <a href="https://developers.dingtalk.com/document/app/obtain-identity-credentials">接入文档</a>
-     */
+     
     DINGTALK(20, "DINGTALK"),
 
-    /**
-     * 企业微信
-     *
-     * @see <a href="https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html">接入文档</a>
-     */
+    
     WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"),
-    /**
-     * 微信公众平台 - 移动端 H5
-     *
-     * @see <a href="https://www.cnblogs.com/juewuzhe/p/11905461.html">接入文档</a>
-     */
+    
     WECHAT_MP(31, "WECHAT_MP"),
-    /**
-     * 微信开放平台 - 网站应用 PC 端扫码授权登录
-     *
-     * @see <a href="https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证">接入文档</a>
-     */
+    
     WECHAT_OPEN(32, "WECHAT_OPEN"),
-    /**
-     * 微信小程序
-     *
-     * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html">接入文档</a>
-     */
+    
     WECHAT_MINI_PROGRAM(34, "WECHAT_MINI_PROGRAM"),
-    /**
-     * 支付宝小程序
-     *
-     * @see <a href="https://opendocs.alipay.com/mini/05dxgc?pathHash=1a3ecb13">接入文档</a>
-     */
+     
     ALIPAY_MINI_PROGRAM(40, "ALIPAY"),
     ;
 

+ 1 - 16
xdz-framework/xdz-spring-boot-starter-biz-tenant/src/main/java/com/xindazhou/framework/tenant/package-info.java

@@ -1,17 +1,2 @@
-/**
- * 多租户,支持如下层面:
- * 1. DB:基于 MyBatis Plus 多租户的功能实现。
- * 2. Redis:通过在 Redis Key 上拼接租户编号的方式,进行隔离。
- * 3. Web:请求 HTTP API 时,解析 Header 的 tenant-id 租户编号,添加到租户上下文。
- * 4. Security:校验当前登陆的用户,是否越权访问其它租户的数据。
- * 5. Job:在 JobHandler 执行任务时,会按照每个租户,都独立并行执行一次。
- * 6. MQ:在 Producer 发送消息时,Header 带上 tenant-id 租户编号;在 Consumer 消费消息时,将 Header 的 tenant-id 租户编号,添加到租户上下文。
- * 7. Async:异步需要保证 ThreadLocal 的传递性,通过使用阿里开源的 TransmittableThreadLocal 实现。相关的改造点,可见:
- *      1)Spring Async:
- *          {@link com.xindazhou.framework.quartz.config.XdzAsyncAutoConfiguration#threadPoolTaskExecutorBeanPostProcessor()}
- *      2)Spring Security:
- *          TransmittableThreadLocalSecurityContextHolderStrategy
- *          和 XdzSecurityAutoConfiguration#securityContextHolderMethodInvokingFactoryBean() 方法
- *
- */
+ 
 package com.xindazhou.framework.tenant;

+ 1 - 5
xdz-framework/xdz-spring-boot-starter-protection/src/main/java/com/xindazhou/framework/signature/package-info.java

@@ -1,6 +1,2 @@
-/**
- * HTTP API 签名,校验安全性
- *
- * @see <a href="https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3>微信支付 —— 安全规范</a>
- */
+
 package com.xindazhou.framework.signature;

+ 119 - 117
xdz-framework/xdz-spring-boot-starter-test/src/main/java/com/xindazhou/framework/test/core/util/RandomUtils.java

@@ -25,122 +25,124 @@ import java.util.stream.Stream;
  */
 public class RandomUtils {
 
-    private static final int RANDOM_STRING_LENGTH = 10;
-
-    private static final int TINYINT_MAX = 127;
-
-    private static final int RANDOM_DATE_MAX = 30;
-
-    private static final int RANDOM_COLLECTION_LENGTH = 5;
-
-    private static final PodamFactory PODAM_FACTORY = new PodamFactoryImpl();
-
-    static {
-        // 字符串
-        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(String.class,
-                (dataProviderStrategy, attributeMetadata, map) -> randomString());
-        // Integer
-        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Integer.class, (dataProviderStrategy, attributeMetadata, map) -> {
-            // 如果是 status 的字段,返回 0 或 1
-            if ("status".equals(attributeMetadata.getAttributeName())) {
-                return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
-            }
-            // 如果是 type、status 结尾的字段,返回 tinyint 范围
-            if (StrUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(),
-                    "type", "status", "category", "scope", "result")) {
-                return RandomUtil.randomInt(0, TINYINT_MAX + 1);
-            }
-            return RandomUtil.randomInt();
-        });
-        // LocalDateTime
-        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(LocalDateTime.class,
-                (dataProviderStrategy, attributeMetadata, map) -> randomLocalDateTime());
-        // Boolean
-        PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class, (dataProviderStrategy, attributeMetadata, map) -> {
-            // 如果是 deleted 的字段,返回非删除
-            if ("deleted".equals(attributeMetadata.getAttributeName())) {
-                return false;
-            }
-            return RandomUtil.randomBoolean();
-        });
-    }
-
-    public static String randomString() {
-        return RandomUtil.randomString(RANDOM_STRING_LENGTH);
-    }
-
-    public static Long randomLongId() {
-        return RandomUtil.randomLong(0, Long.MAX_VALUE);
-    }
-
-    public static Integer randomInteger() {
-        return RandomUtil.randomInt(0, Integer.MAX_VALUE);
-    }
-
-    public static Date randomDate() {
-        return RandomUtil.randomDay(0, RANDOM_DATE_MAX);
-    }
-
-    public static LocalDateTime randomLocalDateTime() {
-        // 设置 Nano 为零的原因,避免 MySQL、H2 存储不到时间戳
-        return LocalDateTimeUtil.of(randomDate()).withNano(0);
-    }
-
-    public static Short randomShort() {
-        return (short) RandomUtil.randomInt(0, Short.MAX_VALUE);
-    }
-
-    public static <T> Set<T> randomSet(Class<T> clazz) {
-        return Stream.iterate(0, i -> i).limit(RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH))
-                .map(i -> randomPojo(clazz)).collect(Collectors.toSet());
-    }
-
-    public static Integer randomCommonStatus() {
-        return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
-    }
-
-    public static String randomEmail() {
-        return randomString() + "@qq.com";
-    }
-
-    public static String randomMobile() {
-        return "13800138" + RandomUtil.randomNumbers(3);
-    }
-
-    public static String randomURL() {
-        return "https://www.narutohuo.cn/" + randomString();
-    }
-
-    @SafeVarargs
-    public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
-        T pojo = PODAM_FACTORY.manufacturePojo(clazz);
-        // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
-        if (ArrayUtil.isNotEmpty(consumers)) {
-            Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
-        }
-        return pojo;
-    }
-
-    @SafeVarargs
-    public static <T> T randomPojo(Class<T> clazz, Type type, Consumer<T>... consumers) {
-        T pojo = PODAM_FACTORY.manufacturePojo(clazz, type);
-        // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
-        if (ArrayUtil.isNotEmpty(consumers)) {
-            Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
-        }
-        return pojo;
-    }
-
-    @SafeVarargs
-    public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) {
-        int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH);
-        return randomPojoList(clazz, size, consumers);
-    }
-
-    @SafeVarargs
-    public static <T> List<T> randomPojoList(Class<T> clazz, int size, Consumer<T>... consumers) {
-        return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers))
-                .collect(Collectors.toList());
-    }
+	private static final int RANDOM_STRING_LENGTH = 10;
+
+	private static final int TINYINT_MAX = 127;
+
+	private static final int RANDOM_DATE_MAX = 30;
+
+	private static final int RANDOM_COLLECTION_LENGTH = 5;
+
+	private static final PodamFactory PODAM_FACTORY = new PodamFactoryImpl();
+
+	static {
+		// 字符串
+		PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(String.class,
+				(dataProviderStrategy, attributeMetadata, map) -> randomString());
+		// Integer
+		PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Integer.class,
+				(dataProviderStrategy, attributeMetadata, map) -> {
+					// 如果是 status 的字段,返回 0 或 1
+					if ("status".equals(attributeMetadata.getAttributeName())) {
+						return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
+					}
+					// 如果是 type、status 结尾的字段,返回 tinyint 范围
+					if (StrUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(), "type", "status", "category",
+							"scope", "result")) {
+						return RandomUtil.randomInt(0, TINYINT_MAX + 1);
+					}
+					return RandomUtil.randomInt();
+				});
+		// LocalDateTime
+		PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(LocalDateTime.class,
+				(dataProviderStrategy, attributeMetadata, map) -> randomLocalDateTime());
+		// Boolean
+		PODAM_FACTORY.getStrategy().addOrReplaceTypeManufacturer(Boolean.class,
+				(dataProviderStrategy, attributeMetadata, map) -> {
+					// 如果是 deleted 的字段,返回非删除
+					if ("deleted".equals(attributeMetadata.getAttributeName())) {
+						return false;
+					}
+					return RandomUtil.randomBoolean();
+				});
+	}
+
+	public static String randomString() {
+		return RandomUtil.randomString(RANDOM_STRING_LENGTH);
+	}
+
+	public static Long randomLongId() {
+		return RandomUtil.randomLong(0, Long.MAX_VALUE);
+	}
+
+	public static Integer randomInteger() {
+		return RandomUtil.randomInt(0, Integer.MAX_VALUE);
+	}
+
+	public static Date randomDate() {
+		return RandomUtil.randomDay(0, RANDOM_DATE_MAX);
+	}
+
+	public static LocalDateTime randomLocalDateTime() {
+		// 设置 Nano 为零的原因,避免 MySQL、H2 存储不到时间戳
+		return LocalDateTimeUtil.of(randomDate()).withNano(0);
+	}
+
+	public static Short randomShort() {
+		return (short) RandomUtil.randomInt(0, Short.MAX_VALUE);
+	}
+
+	public static <T> Set<T> randomSet(Class<T> clazz) {
+		return Stream.iterate(0, i -> i).limit(RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH))
+				.map(i -> randomPojo(clazz)).collect(Collectors.toSet());
+	}
+
+	public static Integer randomCommonStatus() {
+		return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
+	}
+
+	public static String randomEmail() {
+		return randomString() + "@qq.com";
+	}
+
+	public static String randomMobile() {
+		return "13800138" + RandomUtil.randomNumbers(3);
+	}
+
+	public static String randomURL() {
+		return randomString();
+	}
+
+	@SafeVarargs
+	public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
+		T pojo = PODAM_FACTORY.manufacturePojo(clazz);
+		// 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
+		if (ArrayUtil.isNotEmpty(consumers)) {
+			Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
+		}
+		return pojo;
+	}
+
+	@SafeVarargs
+	public static <T> T randomPojo(Class<T> clazz, Type type, Consumer<T>... consumers) {
+		T pojo = PODAM_FACTORY.manufacturePojo(clazz, type);
+		// 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
+		if (ArrayUtil.isNotEmpty(consumers)) {
+			Arrays.stream(consumers).forEach(consumer -> consumer.accept(pojo));
+		}
+		return pojo;
+	}
+
+	@SafeVarargs
+	public static <T> List<T> randomPojoList(Class<T> clazz, Consumer<T>... consumers) {
+		int size = RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH);
+		return randomPojoList(clazz, size, consumers);
+	}
+
+	@SafeVarargs
+	public static <T> List<T> randomPojoList(Class<T> clazz, int size, Consumer<T>... consumers) {
+		return Stream.iterate(0, i -> i).limit(size).map(o -> randomPojo(clazz, consumers))
+				.collect(Collectors.toList());
+	}
 
 }

+ 1 - 9
xdz-framework/xdz-spring-boot-starter-web/src/main/java/com/xindazhou/framework/swagger/config/Knife4jOpenApiCustomizer.java

@@ -24,15 +24,7 @@ import java.lang.annotation.Annotation;
 import java.util.*;
 import java.util.stream.Collectors;
 
-/**
- * 增强扩展属性支持
- *
- * 参考 <a href="https://github.com/xiaoymin/knife4j/issues/913">Spring Boot 3.4 以上版本 /v3/api-docs 解决接口报错,依赖修复</a>
- *
- * @since 4.1.0
- * @author <a href="xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
- * 2022/12/11 22:40
- */
+ 
 @Primary
 @Configuration
 @Slf4j

+ 1 - 7
xdz-framework/xdz-spring-boot-starter-web/src/main/java/com/xindazhou/framework/xss/core/clean/JsoupXssCleaner.java

@@ -45,13 +45,7 @@ public class JsoupXssCleaner implements XssCleaner {
         // 支持img 为base64
         relaxedSafelist.addProtocols("img", "src", "data");
 
-        // 保留相对路径, 保留相对路径时,必须提供对应的 baseUri 属性,否则依然会被删除
-        // WHITELIST.preserveRelativeLinks(false);
-
-        // 移除 a 标签和 img 标签的一些协议限制,这会导致 xss 防注入失效,如 <img src=javascript:alert("xss")>
-        // 虽然可以重写 WhiteList#isSafeAttribute 来处理,但是有隐患,所以暂时不支持相对路径
-        // WHITELIST.removeProtocols("a", "href", "ftp", "http", "https", "mailto");
-        // WHITELIST.removeProtocols("img", "src", "http", "https");
+        
         return relaxedSafelist;
     }
 

+ 1 - 1
xdz-framework/xdz-spring-boot-starter-websocket/src/main/java/com/xindazhou/framework/websocket/core/session/WebSocketSessionHandlerDecorator.java

@@ -35,7 +35,7 @@ public class WebSocketSessionHandlerDecorator extends WebSocketHandlerDecorator
 
     @Override
     public void afterConnectionEstablished(WebSocketSession session) {
-        // 实现 session 支持并发,可参考 https://blog.csdn.net/abu935009066/article/details/131218149
+        
         session = new ConcurrentWebSocketSessionDecorator(session, SEND_TIME_LIMIT, BUFFER_SIZE_LIMIT);
         // 添加到 WebSocketSessionManager 中
         sessionManager.addSession(session);

+ 2 - 2
xdz-module-business/xdz-module-business-api/src/main/java/com/xindazhou/business/api/social/SocialClientApi.java

@@ -28,7 +28,7 @@ public interface SocialClientApi {
     @Parameters({
             @Parameter(name = "socialType", description = "社交平台的类型", example = "1", required = true),
             @Parameter(name = "userType", description = "用户类型", example = "1", required = true),
-            @Parameter(name = "redirectUri", description = "重定向 URL", example = "https://www.narutohuo.cn", required = true)
+            @Parameter(name = "redirectUri", description = "重定向 URL", example = "", required = true)
     })
     CommonResult<String> getAuthorizeUrl(@RequestParam("socialType") Integer socialType,
                                          @RequestParam("userType") Integer userType,
@@ -38,7 +38,7 @@ public interface SocialClientApi {
     @Operation(summary = "创建微信公众号 JS SDK 初始化所需的签名")
     @Parameters({
             @Parameter(name = "userType", description = "用户类型", example = "1", required = true),
-            @Parameter(name = "url", description = "访问 URL", example = "https://www.narutohuo.cn", required = true)
+            @Parameter(name = "url", description = "访问 URL", example = "", required = true)
     })
     CommonResult<SocialWxJsapiSignatureRespDTO> createWxMpJsapiSignature(@RequestParam("userType") Integer userType,
                                                                          @RequestParam("url") String url);

+ 1 - 1
xdz-module-business/xdz-module-business-api/src/main/java/com/xindazhou/business/api/user/dto/AdminUserRespDTO.java

@@ -28,7 +28,7 @@ public class AdminUserRespDTO implements VO {
     @Schema(description = "手机号码", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
     private String mobile;
 
-    @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/1.png")
+    @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "/1.png")
     private String avatar;
 
 }

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/auth/vo/AuthPermissionInfoRespVO.java

@@ -41,7 +41,7 @@ public class AuthPermissionInfoRespVO {
         @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz")
         private String nickname;
 
-        @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xx.jpg")
+        @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xx.jpg")
         private String avatar;
 
         @Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/file/vo/file/FileCreateReqVO.java

@@ -21,7 +21,7 @@ public class FileCreateReqVO {
     private String name;
 
     @NotNull(message = "文件 URL不能为空")
-    @Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xdz.jpg")
     private String url;
 
     @Schema(description = "文件 MIME 类型", example = "application/octet-stream")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/file/vo/file/FileRespVO.java

@@ -21,7 +21,7 @@ public class FileRespVO {
     @Schema(description = "原文件名", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz.jpg")
     private String name;
 
-    @Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xdz.jpg")
     private String url;
 
     @Schema(description = "文件MIME类型", example = "application/octet-stream")

+ 2 - 2
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/OAuth2OpenController.java

@@ -87,7 +87,7 @@ public class OAuth2OpenController {
     @Parameters({
             @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"),
             @Parameter(name = "code", description = "授权范围", example = "userinfo.read"),
-            @Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.narutohuo.cn"),
+            @Parameter(name = "redirect_uri", description = "重定向 URI", example = ""),
             @Parameter(name = "state", description = "状态", example = "1"),
             @Parameter(name = "username", example = "tudou"),
             @Parameter(name = "password", example = "cai"), // 多个使用空格分隔
@@ -209,7 +209,7 @@ public class OAuth2OpenController {
             @Parameter(name = "response_type", required = true, description = "响应类型", example = "code"),
             @Parameter(name = "client_id", required = true, description = "客户端编号", example = "tudou"),
             @Parameter(name = "scope", description = "授权范围", example = "userinfo.read"), // 使用 Map<String, Boolean> 格式,Spring MVC 暂时不支持这么接收参数
-            @Parameter(name = "redirect_uri", required = true, description = "重定向 URI", example = "https://www.narutohuo.cn"),
+            @Parameter(name = "redirect_uri", required = true, description = "重定向 URI", example = ""),
             @Parameter(name = "auto_approve", required = true, description = "用户是否接受", example = "true"),
             @Parameter(name = "state", example = "1")
     })

+ 2 - 2
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/client/OAuth2ClientRespVO.java

@@ -22,7 +22,7 @@ public class OAuth2ClientRespVO {
     @Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
     private String name;
 
-    @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xx.png")
+    @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xx.png")
     private String logo;
 
     @Schema(description = "应用描述", example = "我是一个应用")
@@ -37,7 +37,7 @@ public class OAuth2ClientRespVO {
     @Schema(description = "刷新令牌的有效期", requiredMode = Schema.RequiredMode.REQUIRED, example = "8640000")
     private Integer refreshTokenValiditySeconds;
 
-    @Schema(description = "可重定向的 URI 地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn")
+    @Schema(description = "可重定向的 URI 地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     private List<String> redirectUris;
 
     @Schema(description = "授权类型,参见 OAuth2GrantTypeEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "password")

+ 2 - 2
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/client/OAuth2ClientSaveReqVO.java

@@ -30,7 +30,7 @@ public class OAuth2ClientSaveReqVO {
     @NotNull(message = "应用名不能为空")
     private String name;
 
-    @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xx.png")
+    @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xx.png")
     @NotNull(message = "应用图标不能为空")
     @URL(message = "应用图标的地址不正确")
     private String logo;
@@ -50,7 +50,7 @@ public class OAuth2ClientSaveReqVO {
     @NotNull(message = "刷新令牌的有效期不能为空")
     private Integer refreshTokenValiditySeconds;
 
-    @Schema(description = "可重定向的 URI 地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn")
+    @Schema(description = "可重定向的 URI 地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     @NotNull(message = "可重定向的 URI 地址不能为空")
     private List<@NotEmpty(message = "重定向的 URI 不能为空") @URL(message = "重定向的 URI 格式不正确") String> redirectUris;
 

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/open/OAuth2OpenAuthorizeInfoRespVO.java

@@ -30,7 +30,7 @@ public class OAuth2OpenAuthorizeInfoRespVO {
         @Schema(description = "应用名", requiredMode = Schema.RequiredMode.REQUIRED, example = "土豆")
         private String name;
 
-        @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xx.png")
+        @Schema(description = "应用图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "/xx.png")
         private String logo;
 
     }

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/oauth2/vo/user/OAuth2UserInfoRespVO.java

@@ -30,7 +30,7 @@ public class OAuth2UserInfoRespVO {
     @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
     private Integer sex;
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", example = "/xxx.png")
     private String avatar;
 
     /**

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/SmsCallbackController.java

@@ -26,7 +26,7 @@ public class SmsCallbackController {
     @PostMapping("/aliyun")
     @PermitAll
     @TenantIgnore
-    @Operation(summary = "阿里云短信的回调", description = "参见 https://help.aliyun.com/document_detail/120998.html 文档")
+    @Operation(summary = "阿里云短信的回调", description = "")
     public CommonResult<Boolean> receiveAliyunSmsStatus(HttpServletRequest request) throws Throwable {
         String text = ServletUtils.getBody(request);
         smsSendService.receiveSmsStatus(SmsChannelEnum.ALIYUN.getCode(), text);

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/vo/channel/SmsChannelRespVO.java

@@ -35,7 +35,7 @@ public class SmsChannelRespVO {
     @Schema(description = "短信 API 的密钥", example = "yuanma")
     private String apiSecret;
 
-    @Schema(description = "短信发送回调 URL", example = "https://www.narutohuo.cn")
+    @Schema(description = "短信发送回调 URL", example = "")
     @URL(message = "回调 URL 格式不正确")
     private String callbackUrl;
 

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/sms/vo/channel/SmsChannelSaveReqVO.java

@@ -35,7 +35,7 @@ public class SmsChannelSaveReqVO {
     @Schema(description = "短信 API 的密钥", example = "yuanma")
     private String apiSecret;
 
-    @Schema(description = "短信发送回调 URL", example = "http://www.narutohuo.cn")
+    @Schema(description = "短信发送回调 URL", example = "")
     @URL(message = "回调 URL 格式不正确")
     private String callbackUrl;
 

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/socail/vo/user/SocialUserRespVO.java

@@ -27,7 +27,7 @@ public class SocialUserRespVO {
     @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz")
     private String nickname;
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", example = "/xxx.png")
     private String avatar;
 
     @Schema(description = "原始用户数据,一般是 JSON 格式", requiredMode = Schema.RequiredMode.REQUIRED, example = "{}")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/tenant/vo/tenant/TenantRespVO.java

@@ -37,7 +37,7 @@ public class TenantRespVO {
     @DictFormat(DictTypeConstants.COMMON_STATUS)
     private Integer status;
 
-    @Schema(description = "绑定域名数组", example = "https://www.narutohuo.cn")
+    @Schema(description = "绑定域名数组", example = "")
     private List<String> websites;
 
     @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java

@@ -35,7 +35,7 @@ public class TenantSaveReqVO {
     @NotNull(message = "租户状态")
     private Integer status;
 
-    @Schema(description = "绑定域名数组", example = "https://www.narutohuo.cn")
+    @Schema(description = "绑定域名数组", example = "")
     private List<String> websites;
 
     @Schema(description = "租户套餐编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/profile/UserProfileRespVO.java

@@ -31,7 +31,7 @@ public class UserProfileRespVO {
     @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
     private Integer sex;
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", example = "/xxx.png")
     private String avatar;
 
     @Schema(description = "最后登录 IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.1")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/profile/UserProfileUpdateReqVO.java

@@ -29,7 +29,7 @@ public class UserProfileUpdateReqVO {
     @Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
     private Integer sex;
 
-    @Schema(description = "角色头像", example = "https://www.narutohuo.cn/1.png")
+    @Schema(description = "角色头像", example = "/1.png")
     @URL(message = "头像地址格式不正确")
     private String avatar;
 

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/user/UserRespVO.java

@@ -53,7 +53,7 @@ public class UserRespVO{
     @DictFormat(DictTypeConstants.USER_SEX)
     private Integer sex;
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", example = "/xxx.png")
     private String avatar;
 
     @Schema(description = "状态,参见 CommonStatusEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/controller/admin/user/vo/user/UserSaveReqVO.java

@@ -60,7 +60,7 @@ public class UserSaveReqVO {
     @DiffLogField(name = "用户性别", function = SexParseFunction.NAME)
     private Integer sex;
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", example = "/xxx.png")
     @DiffLogField(name = "用户头像")
     private String avatar;
 

+ 115 - 198
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/framework/file/core/client/s3/S3FileClient.java

@@ -31,203 +31,120 @@ import java.time.Duration;
  */
 public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
 
-    private static final Duration EXPIRATION_DEFAULT = Duration.ofHours(24);
-
-    private S3Client client;
-    private S3Presigner presigner;
-
-    public S3FileClient(Long id, S3FileClientConfig config) {
-        super(id, config);
-    }
-
-    @Override
-    protected void doInit() {
-        // 补全 domain
-        if (StrUtil.isEmpty(config.getDomain())) {
-            config.setDomain(buildDomain());
-        }
-        // 初始化 S3 客户端
-        // 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
-        String regionStr = resolveRegion();
-        Region region = Region.of(regionStr);
-        AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
-                AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret()));
-        URI endpoint = URI.create(buildEndpoint());
-        S3Configuration serviceConfiguration = S3Configuration.builder() // Path-style 访问
-                .pathStyleAccessEnabled(Boolean.TRUE.equals(config.getEnablePathStyleAccess()))
-                .chunkedEncodingEnabled(false) 
-                .build();
-        client = S3Client.builder()
-                .credentialsProvider(credentialsProvider)
-                .region(region)
-                .endpointOverride(endpoint)
-                .serviceConfiguration(serviceConfiguration)
-                .build();
-        presigner = S3Presigner.builder()
-                .credentialsProvider(credentialsProvider)
-                .region(region)
-                .endpointOverride(endpoint)
-                .serviceConfiguration(serviceConfiguration)
-                .build();
-    }
-
-    @Override
-    public String upload(byte[] content, String path, String type) {
-        // 构造 PutObjectRequest
-        PutObjectRequest putRequest = PutObjectRequest.builder()
-                .bucket(config.getBucket())
-                .key(path)
-                .contentType(type)
-                .contentLength((long) content.length)
-                .build();
-        // 上传文件
-        client.putObject(putRequest, RequestBody.fromBytes(content));
-        // 拼接返回路径
-        return presignGetUrl(path, null);
-    }
-
-    @Override
-    public void delete(String path) {
-        DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder()
-                .bucket(config.getBucket())
-                .key(path)
-                .build();
-        client.deleteObject(deleteRequest);
-    }
-
-    @Override
-    public byte[] getContent(String path) {
-        GetObjectRequest getRequest = GetObjectRequest.builder()
-                .bucket(config.getBucket())
-                .key(path)
-                .build();
-        return IoUtil.readBytes(client.getObject(getRequest));
-    }
-
-    @Override
-    public String presignPutUrl(String path) {
-        return presigner.presignPutObject(PutObjectPresignRequest.builder()
-                .signatureDuration(EXPIRATION_DEFAULT)
-                .putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build())
-                .url().toString();
-    }
-
-    @Override
-    public String presignGetUrl(String url, Integer expirationSeconds) {
-        // 1. 将 url 转换为 path
-        String path = StrUtil.removePrefix(url, config.getDomain() + "/");
-        path = HttpUtils.decodeUtf8(HttpUtils.removeUrlQuery(path));
-
-        // 2.1 情况一:公开访问:无需签名
-        // 考虑到老版本的兼容,所以必须是 config.getEnablePublicAccess() 为 false 时,才进行签名
-        if (!BooleanUtil.isFalse(config.getEnablePublicAccess())) {
-            return config.getDomain() + "/" + path;
-        }
-
-        // 2.2 情况二:私有访问:生成 GET 预签名 URL
-        String finalPath = path;
-        Duration expiration = expirationSeconds != null ? Duration.ofSeconds(expirationSeconds) : EXPIRATION_DEFAULT;
-        URL signedUrl = presigner.presignGetObject(GetObjectPresignRequest.builder()
-                .signatureDuration(expiration)
-                .getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build())
-                .url();
-        return signedUrl.toString();
-    }
-
-    /**
-     * 基于 bucket + endpoint 构建访问的 Domain 地址
-     *
-     * @return Domain 地址
-     */
-    private String buildDomain() {
-        // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
-        if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
-            return StrUtil.format("{}/{}", config.getEndpoint(), config.getBucket());
-        }
-        // 阿里云、腾讯云、华为云都适合。七牛云比较特殊,必须有自定义域名
-        return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
-    }
-
-    /**
-     * 节点地址补全协议头
-     *
-     * @return 节点地址
-     */
-    private String buildEndpoint() {
-        // 如果已经是 http 或者 https,则不进行拼接
-        if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
-            return config.getEndpoint();
-        }
-        return StrUtil.format("https://{}", config.getEndpoint());
-    }
-
-    /**
-     * 解析 AWS 区域
-     * 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
-     *
-     * @return 区域字符串
-     */
-    private String resolveRegion() {
-        // 1. 如果配置了 region,直接使用
-        if (StrUtil.isNotEmpty(config.getRegion())) {
-            return config.getRegion();
-        }
-
-        // 2.1 尝试从 endpoint 中解析 region
-        String endpoint = config.getEndpoint();
-        if (StrUtil.isEmpty(endpoint)) {
-            return "us-east-1";
-        }
-
-        // 2.2 移除协议头(http:// 或 https://)
-        String host = endpoint;
-        if (HttpUtil.isHttp(endpoint) || HttpUtil.isHttps(endpoint)) {
-            try {
-                host = URI.create(endpoint).getHost();
-            } catch (Exception e) {
-                // 解析失败,使用默认值
-                return "us-east-1";
-            }
-        }
-        if (StrUtil.isEmpty(host)) {
-            return "us-east-1";
-        }
-
-        // 3.1 AWS S3 格式:s3.us-west-2.amazonaws.com 或 s3.amazonaws.com
-        if (host.contains("amazonaws.com")) {
-            // 匹配 s3.{region}.amazonaws.com 格式
-            if (host.startsWith("s3.") && host.contains(".amazonaws.com")) {
-                String regionPart = host.substring(3, host.indexOf(".amazonaws.com"));
-                if (StrUtil.isNotEmpty(regionPart) && !regionPart.equals("accelerate")) {
-                    return regionPart;
-                }
-            }
-            // s3.amazonaws.com 或 s3-accelerate.amazonaws.com 使用默认值
-            return "us-east-1";
-        }
-        // 3.2 阿里云 OSS 格式:oss-cn-beijing.aliyuncs.com
-        if (host.contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
-            // 匹配 oss-{region}.aliyuncs.com 格式
-            if (host.startsWith("oss-") && host.contains("." + S3FileClientConfig.ENDPOINT_ALIYUN)) {
-                String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_ALIYUN));
-                if (StrUtil.isNotEmpty(regionPart)) {
-                    return regionPart;
-                }
-            }
-        }
-        // 3.3 腾讯云 COS 格式:cos.ap-shanghai.myqcloud.com
-        if (host.contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
-            // 匹配 cos.{region}.myqcloud.com 格式
-            if (host.startsWith("cos.") && host.contains("." + S3FileClientConfig.ENDPOINT_TENCENT)) {
-                String regionPart = host.substring(4, host.indexOf("." + S3FileClientConfig.ENDPOINT_TENCENT));
-                if (StrUtil.isNotEmpty(regionPart)) {
-                    return regionPart;
-                }
-            }
-        }
-
-        // 3.4 其他情况(MinIO、七牛云等)使用默认值
-        return "us-east-1";
-    }
+	private static final Duration EXPIRATION_DEFAULT = Duration.ofHours(24);
+
+	private S3Client client;
+	private S3Presigner presigner;
+
+	public S3FileClient(Long id, S3FileClientConfig config) {
+		super(id, config);
+	}
+
+	@Override
+	protected void doInit() {
+		// 补全 domain
+		if (StrUtil.isEmpty(config.getDomain())) {
+			config.setDomain(buildDomain());
+		}
+		// 初始化 S3 客户端
+		// 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
+		String regionStr = resolveRegion();
+		Region region = Region.of(regionStr);
+		AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider
+				.create(AwsBasicCredentials.create(config.getAccessKey(), config.getAccessSecret()));
+		URI endpoint = URI.create(buildEndpoint());
+		S3Configuration serviceConfiguration = S3Configuration.builder() // Path-style 访问
+				.pathStyleAccessEnabled(Boolean.TRUE.equals(config.getEnablePathStyleAccess()))
+				.chunkedEncodingEnabled(false).build();
+		client = S3Client.builder().credentialsProvider(credentialsProvider).region(region).endpointOverride(endpoint)
+				.serviceConfiguration(serviceConfiguration).build();
+		presigner = S3Presigner.builder().credentialsProvider(credentialsProvider).region(region)
+				.endpointOverride(endpoint).serviceConfiguration(serviceConfiguration).build();
+	}
+
+	@Override
+	public String upload(byte[] content, String path, String type) {
+		// 构造 PutObjectRequest
+		PutObjectRequest putRequest = PutObjectRequest.builder().bucket(config.getBucket()).key(path).contentType(type)
+				.contentLength((long) content.length).build();
+		// 上传文件
+		client.putObject(putRequest, RequestBody.fromBytes(content));
+		// 拼接返回路径
+		return presignGetUrl(path, null);
+	}
+
+	@Override
+	public void delete(String path) {
+		DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder().bucket(config.getBucket()).key(path).build();
+		client.deleteObject(deleteRequest);
+	}
+
+	@Override
+	public byte[] getContent(String path) {
+		GetObjectRequest getRequest = GetObjectRequest.builder().bucket(config.getBucket()).key(path).build();
+		return IoUtil.readBytes(client.getObject(getRequest));
+	}
+
+	@Override
+	public String presignPutUrl(String path) {
+		return presigner.presignPutObject(PutObjectPresignRequest.builder().signatureDuration(EXPIRATION_DEFAULT)
+				.putObjectRequest(b -> b.bucket(config.getBucket()).key(path)).build()).url().toString();
+	}
+
+	@Override
+	public String presignGetUrl(String url, Integer expirationSeconds) {
+		// 1. 将 url 转换为 path
+		String path = StrUtil.removePrefix(url, config.getDomain() + "/");
+		path = HttpUtils.decodeUtf8(HttpUtils.removeUrlQuery(path));
+
+		// 2.1 情况一:公开访问:无需签名
+		// 考虑到老版本的兼容,所以必须是 config.getEnablePublicAccess() 为 false 时,才进行签名
+		if (!BooleanUtil.isFalse(config.getEnablePublicAccess())) {
+			return config.getDomain() + "/" + path;
+		}
+
+		// 2.2 情况二:私有访问:生成 GET 预签名 URL
+		String finalPath = path;
+		Duration expiration = expirationSeconds != null ? Duration.ofSeconds(expirationSeconds) : EXPIRATION_DEFAULT;
+		URL signedUrl = presigner.presignGetObject(GetObjectPresignRequest.builder().signatureDuration(expiration)
+				.getObjectRequest(b -> b.bucket(config.getBucket()).key(finalPath)).build()).url();
+		return signedUrl.toString();
+	}
+
+	/**
+	 * 基于 bucket + endpoint 构建访问的 Domain 地址
+	 *
+	 * @return Domain 地址
+	 */
+	private String buildDomain() {
+		// 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO
+		if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
+			return StrUtil.format("{}/{}", config.getEndpoint(), config.getBucket());
+		}
+		// 阿里云、腾讯云、华为云都适合。七牛云比较特殊,必须有自定义域名
+		return StrUtil.format("https://{}.{}", config.getBucket(), config.getEndpoint());
+	}
+
+	/**
+	 * 节点地址补全协议头
+	 *
+	 * @return 节点地址
+	 */
+	private String buildEndpoint() {
+		// 如果已经是 http 或者 https,则不进行拼接
+		if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) {
+			return config.getEndpoint();
+		}
+		return StrUtil.format("https://{}", config.getEndpoint());
+	}
+
+	/**
+	 * 解析 AWS 区域 优先级:配置的 region > 从 endpoint 解析的 region > 默认值 us-east-1
+	 *
+	 * @return 区域字符串
+	 */
+	private String resolveRegion() {
+		return "";
+	}
 
 }

+ 8 - 35
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/framework/file/core/client/s3/S3FileClientConfig.java

@@ -17,31 +17,15 @@ import jakarta.validation.constraints.NotNull;
 @Data
 public class S3FileClientConfig implements FileClientConfig {
 
-    public static final String ENDPOINT_QINIU = "qiniucs.com";
+  
     public static final String ENDPOINT_ALIYUN = "aliyuncs.com";
-    public static final String ENDPOINT_TENCENT = "myqcloud.com";
-    public static final String ENDPOINT_VOLCES = "volces.com"; // 火山云(字节)
+   
 
-    /**
-     * 节点地址
-     * 1. MinIO:https://www.narutohuo.cn/Spring-Boot/MinIO 。例如说,http://127.0.0.1:9000
-     * 2. 阿里云:https://help.aliyun.com/document_detail/31837.html
-     * 3. 腾讯云:https://cloud.tencent.com/document/product/436/6224
-     * 4. 七牛云:https://developer.qiniu.com/kodo/4088/s3-access-domainname
-     * 5. 华为云:https://console.huaweicloud.com/apiexplorer/#/endpoint/OBS
-     * 6. 火山云:https://www.volcengine.com/docs/6349/107356
-     */
+
+  
     @NotNull(message = "endpoint 不能为空")
     private String endpoint;
-    /**
-     * 自定义域名
-     * 1. MinIO:通过 Nginx 配置
-     * 2. 阿里云:https://help.aliyun.com/document_detail/31836.html
-     * 3. 腾讯云:https://cloud.tencent.com/document/product/436/11142
-     * 4. 七牛云:https://developer.qiniu.com/kodo/8556/set-the-custom-source-domain-name
-     * 5. 华为云:https://support.huaweicloud.com/usermanual-obs/obs_03_0032.html
-     * 6. 火山云:https://www.volcengine.com/docs/6349/128983
-     */
+   
     @URL(message = "domain 必须是 URL 格式")
     private String domain;
     /**
@@ -50,15 +34,7 @@ public class S3FileClientConfig implements FileClientConfig {
     @NotNull(message = "bucket 不能为空")
     private String bucket;
 
-    /**
-     * 访问 Key
-     * 1. MinIO:https://www.narutohuo.cn/Spring-Boot/MinIO
-     * 2. 阿里云:https://ram.console.aliyun.com/manage/ak
-     * 3. 腾讯云:https://console.cloud.tencent.com/cam/capi
-     * 4. 七牛云:https://portal.qiniu.com/user/key
-     * 5. 华为云:https://support.huaweicloud.com/qs-obs/obs_qs_0005.html
-     * 6. 火山云:https://console.volcengine.com/iam/keymanage/
-     */
+
     @NotNull(message = "accessKey 不能为空")
     private String accessKey;
     /**
@@ -84,7 +60,7 @@ public class S3FileClientConfig implements FileClientConfig {
 
     /**
      * 区域
-     * 1. AWS S3:https://docs.aws.amazon.com/general/latest/gr/s3.html 例如说,us-east-1、us-west-2
+   
      * 2. MinIO:可以填任意值,通常使用 us-east-1
      * 3. 阿里云:不需要填写,会自动识别
      * 4. 腾讯云:不需要填写,会自动识别
@@ -98,10 +74,7 @@ public class S3FileClientConfig implements FileClientConfig {
     @AssertTrue(message = "domain 不能为空")
     @JsonIgnore
     public boolean isDomainValid() {
-        // 如果是七牛,必须带有 domain
-        if (StrUtil.contains(endpoint, ENDPOINT_QINIU) && StrUtil.isEmpty(domain)) {
-            return false;
-        }
+        
         return true;
     }
 

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/service/codegen/inner/CodegenBuilder.java

@@ -203,7 +203,7 @@ public class CodegenBuilder {
         }
         // url
         if (StrUtil.endWithIgnoreCase(column.getColumnName(), "url")) {
-            column.setExample("https://www.narutohuo.cn");
+            column.setExample("");
             return;
         }
         // reason

+ 1 - 1
xdz-module-business/xdz-module-business-server/src/main/java/com/xindazhou/business/service/oauth2/OAuth2GrantServiceImpl.java

@@ -86,7 +86,7 @@ public class OAuth2GrantServiceImpl implements OAuth2GrantService {
 
     @Override
     public OAuth2AccessTokenDO grantClientCredentials(String clientId, List<String> scopes) {
-        // 特殊:https://yuanbao.tencent.com/bot/app/share/chat/wFj642xSZHHx
+        
         return oauth2TokenService.createAccessToken(0L, UserTypeEnum.ADMIN.getValue(), clientId, scopes);
     }
 

+ 1 - 1
xdz-module-user/xdz-module-user-api/src/main/java/com/xindazhou/user/api/user/dto/MemberUserRespDTO.java

@@ -18,7 +18,7 @@ public class MemberUserRespDTO {
     @Schema(description = "帐号状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Integer status; // 参见 CommonStatusEnum 枚举
 
-    @Schema(description = "用户头像", example = "https://www.narutohuo.cn/xxx.jpg")
+    @Schema(description = "用户头像", example = "")
     private String avatar;
 
     @Schema(description = "手机号", example = "15601691300")

+ 2 - 2
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/level/vo/level/MemberLevelBaseVO.java

@@ -37,11 +37,11 @@ public class MemberLevelBaseVO {
     @Range(min = 0, max = 100, message = "享受折扣的范围为 0-100")
     private Integer discountPercent;
 
-    @Schema(description = "等级图标", example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "等级图标", example = "")
     @URL(message = "等级图标必须是 URL 格式")
     private String icon;
 
-    @Schema(description = "等级背景图", example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "等级背景图", example = "")
     @URL(message = "等级背景图必须是 URL 格式")
     private String backgroundUrl;
 

+ 4 - 7
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/level/vo/level/MemberLevelSimpleRespVO.java

@@ -9,13 +9,10 @@ import lombok.ToString;
 @ToString(callSuper = true)
 public class MemberLevelSimpleRespVO {
 
-    @Schema(description = "编号", example = "6103")
-    private Long id;
+	@Schema(description = "编号", example = "6103")
+	private Long id;
 
-    @Schema(description = "等级名称", example = "xdz")
-    private String name;
-
-    @Schema(description = "等级图标", example = "https://www.narutohuo.cn/xdz.jpg")
-    private String icon;
+	@Schema(description = "等级名称", example = "xdz")
+	private String name;
 
 }

+ 1 - 2
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/admin/user/vo/MemberUserBaseVO.java

@@ -30,8 +30,7 @@ public class MemberUserBaseVO {
     @NotNull(message = "用户昵称不能为空")
     private String nickname;
 
-    @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/x.png")
-    @URL(message = "头像必须是 URL 格式")
+    @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "头像必须是 URL 格式")
     private String avatar;
 
     @Schema(description = "用户昵称", example = "李四")

+ 1 - 1
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java

@@ -22,7 +22,7 @@ public class AuthWeixinJsapiSignatureRespVO {
     @Schema(description = "时间戳", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
     private Long timestamp;
 
-    @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn")
+    @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     private String url;
 
     @Schema(description = "签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "阿巴阿巴")

+ 2 - 2
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/level/vo/level/AppMemberLevelRespVO.java

@@ -19,10 +19,10 @@ public class AppMemberLevelRespVO {
     @Schema(description = "享受折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "98")
     private Integer discountPercent;
 
-    @Schema(description = "等级图标", example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "等级图标", example = "")
     private String icon;
 
-    @Schema(description = "等级背景图", example = "https://www.narutohuo.cn/xdz.jpg")
+    @Schema(description = "等级背景图", example = "")
     private String backgroundUrl;
 
 }

+ 1 - 1
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/social/vo/AppSocialUserRespVO.java

@@ -13,7 +13,7 @@ public class AppSocialUserRespVO {
     @Schema(description = "社交用户的昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz")
     private String nickname;
 
-    @Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/1.png")
+    @Schema(description = "社交用户的头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     private String avatar;
 
 }

+ 2 - 2
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/user/vo/AppMemberUserInfoRespVO.java

@@ -17,7 +17,7 @@ public class AppMemberUserInfoRespVO {
     @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "xdz")
     private String nickname;
 
-    @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/xxx.png")
+    @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "")
     private String avatar;
 
     @Schema(description = "用户手机号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@@ -51,7 +51,7 @@ public class AppMemberUserInfoRespVO {
         @Schema(description = "等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
         private Integer level;
 
-        @Schema(description = "等级图标", example = "https://www.narutohuo.cn/xdz.jpg")
+        @Schema(description = "等级图标", example = "")
         private String icon;
 
     }

+ 1 - 2
xdz-module-user/xdz-module-user-server/src/main/java/com/xindazhou/user/controller/app/user/vo/AppMemberUserUpdateReqVO.java

@@ -13,8 +13,7 @@ public class AppMemberUserUpdateReqVO {
     @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
     private String nickname;
 
-    @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.narutohuo.cn/x.png")
-    @URL(message = "头像必须是 URL 格式")
+    @Schema(description = "头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "头像必须是 URL 格式")
     private String avatar;
 
     @Schema(description = "性别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")