Parcourir la source

feat(user): 新增用户信息更新接口

- 在 WeChatController 中添加 `/update_user_info` 接口,支持通过 JSON 请求体更新用户信息
- 支持从请求头或请求体中解析 token 并验证用户身份
- 更新 UserInfo 实体中的性别字段类型为 Gender 枚举,并使用自定义 TypeHandler 处理数据库映射
- 完善 DEVELOPMENT_GUIDELINES.md 中关于返回结构、分页、异常处理和依赖配置的说明
- 调整 application.yml 中微信配置项,移除 TODO 标记并保留预览号配置
- 优化全局异常处理逻辑,明确各异常类型的返回码与消息格式
- 更新 Knife4j 和 Thymeleaf 相关配置说明,增强文档可读性与准确性
mcbaiyun il y a 2 mois
Parent
commit
02ebeeae77

+ 13 - 10
docs/DEVELOPMENT_GUIDELINES.md

@@ -18,22 +18,25 @@
 
 4. 控制器与返回结构
 - 全局统一返回类型为 `work.baiyun.chronicdiseaseapp.common.R<T>`。
-- `R` 提供 `success` / `fail` 静态方法,包含 `code`、`message`、`data` 字段。
-- Controller 层尽量返回 `R<T>`,业务异常与验证异常由全局异常处理器处理
+- `R` 提供 `success` / `fail` 静态方法,包含 `code`、`message`、`data` 字段;`success`/`fail` 有带/不带 `data` 的重载方法,返回类型以 `R<Void>` 表示无数据的情况
+- 推荐 Controller 层返回 `R<T>`。业务异常与参数校验异常由全局异常处理器 `work.baiyun.chronicdiseaseapp.exception.CustomExceptionHandler` 处理;文中有更多异常类型及其返回码的说明(见“异常处理”一节)
 
 5. 分页
-- 分页封装使用 `work.baiyun.chronicdiseaseapp.common.Page<T>`,构造器接受 `pageNum`, `pageSize`, `list`,并使用 `PageInfo` 获取 total。
+- 分页封装使用 `work.baiyun.chronicdiseaseapp.common.Page<T>`,构造器接受 `pageNum`, `pageSize`, `list`,并使用 `com.github.pagehelper.PageInfo` 从 `list` 中获取 `total`。注意:传入的 `list` 应当是经过 PageHelper 分页查询后的结果(例如在 mapper 层调用 PageHelper.startPage(...) 之后的查询结果)
 
 6. 异常处理
-- 使用自定义 `CustomException` 抛出业务异常。
-- 全局异常处理器 `CustomExceptionHandler`(使用 `@RestControllerAdvice`)统一处理:
-  - 参数校验异常:`BindException`、`ConstraintViolationException` → 返回验证失败信息(合并消息)
-  - 自定义异常:`CustomException` → 返回自定义消息
-  - 其他异常:打印堆栈并返回通用错误码/信息(参考 `ExceptionResultCode`)
+- 业务异常:项目使用 `work.baiyun.chronicdiseaseapp.exception.CustomException`(继承自 `Exception`)来表示可控的业务错误,直接抛出 `new CustomException("...")` 即可。
+- 全局异常处理器为 `work.baiyun.chronicdiseaseapp.exception.CustomExceptionHandler`,已使用 `@RestControllerAdvice`,并按类型处理:
+  - `BindException`:从 `BindingResult` 拼接 `ObjectError` 的 `defaultMessage`,以 `R.fail(ExceptionResultCode.VALID_EXCEPTION.getCode(), <merged message>)` 返回;
+  - `ConstraintViolationException`:收集 `ConstraintViolation::getMessage` 并合并为逗号分隔字符串,返回 `R.fail(ExceptionResultCode.VALID_EXCEPTION.getCode(), <message>)`;
+  - `CustomException`:返回 `R.fail(ExceptionResultCode.EXCEPTION.getCode(), customException.getMessage())`;
+  - `Exception`(兜底):使用 SLF4J 记录错误日志(logger.error("Unhandled exception", exception)),并返回 `R.fail(ExceptionResultCode.EXCEPTION.getCode(), ExceptionResultCode.EXCEPTION.getMsg())`。
+
+注意:当前 `CustomException` 继承自已检查异常 `Exception`(非 `RuntimeException`),在 Service/Controller 中抛出时须显式声明或在方法签名中处理;如需改为运行时异常以简化调用栈,可以考虑改为继承 `RuntimeException`(这是可选的 API 设计决策)。
 
 7. 依赖与自动配置
-- 项目使用 Spring Boot,并排除了 Thymeleaf 的自动配置(见 `SpringAPP`)。
-- 使用 Knife4j(API 文档)注解 `@EnableKnife4j`
+- 项目使用 Spring Boot,启动类 `work.baiyun.chronicdiseaseapp.SpringAPP` 标注了 `@SpringBootApplication(exclude = {ThymeleafAutoConfiguration.class})`,因此 Thymeleaf 自动配置被显式排除;如使用模板相关功能需要移除该排除项
+- 使用 Knife4j(API 文档)并在启动类上加了 `@EnableKnife4j` 注解以启用扩展功能
 
 8. 注解与校验
 - 参数校验使用 Jakarta Validation(见 `ConstraintViolationException` 的处理),并在 Controller/DTO 上使用注解进行字段校验。

+ 56 - 0
src/main/java/work/baiyun/chronicdiseaseapp/controller/WeChatController.java

@@ -142,4 +142,60 @@ public class WeChatController {
 
         return R.success(200, "ok", out);
     }
+
+    @PostMapping(path = "/update_user_info", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
+    public R<?> updateUserInfo(@RequestBody(required = false) work.baiyun.chronicdiseaseapp.model.vo.UpdateUserInfoRequest req,
+                               HttpServletRequest request) {
+        // resolve userId same as getUserInfo
+        Object attr = request.getAttribute("currentUserId");
+        Long userId = null;
+        if (attr instanceof Long) {
+            userId = (Long) attr;
+        } else if (attr instanceof Integer) {
+            userId = ((Integer) attr).longValue();
+        }
+
+        if (userId == null) {
+            String token = null;
+            if (request.getHeader("X-Token") != null && !request.getHeader("X-Token").isEmpty()) {
+                token = request.getHeader("X-Token");
+            } else if (request.getHeader("token") != null && !request.getHeader("token").isEmpty()) {
+                token = request.getHeader("token");
+            } else if (req != null && req.getToken() != null && !req.getToken().isEmpty()) {
+                token = req.getToken();
+            }
+
+            if (token == null || token.isEmpty()) {
+                return R.fail(401, "Missing token");
+            }
+
+            userId = tokenService.validateToken(token);
+            if (userId == null) {
+                return R.fail(401, "Invalid or expired token");
+            }
+        }
+
+        UserInfo ui = userInfoMapper.selectById(userId);
+        if (ui == null) {
+            return R.fail(404, "User not found");
+        }
+
+        if (req != null) {
+            if (req.getAvatar() != null) ui.setAvatar(req.getAvatar());
+            if (req.getNickname() != null) ui.setNickname(req.getNickname());
+            if (req.getPhone() != null) ui.setPhone(req.getPhone());
+            if (req.getAge() != null) ui.setAge(req.getAge());
+            if (req.getAddress() != null) ui.setAddress(req.getAddress());
+            if (req.getSex() != null) {
+                try {
+                    ui.setSex(work.baiyun.chronicdiseaseapp.enums.Gender.fromCode(req.getSex()));
+                } catch (IllegalArgumentException e) {
+                    return R.fail(400, "Invalid sex value");
+                }
+            }
+            userInfoMapper.updateById(ui);
+        }
+
+        return R.success(200, "ok");
+    }
 }

+ 35 - 0
src/main/java/work/baiyun/chronicdiseaseapp/enums/Gender.java

@@ -0,0 +1,35 @@
+package work.baiyun.chronicdiseaseapp.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+
+/**
+ * 性别枚举,数据库存储为整数:1=男, 2=女
+ */
+public enum Gender {
+    MALE(1, "男"),
+    FEMALE(2, "女");
+
+    @EnumValue
+    private final int code;
+    private final String description;
+
+    Gender(int code, String description) {
+        this.code = code;
+        this.description = description;
+    }
+
+    public int getCode() { return code; }
+
+    public String getDescription() { return description; }
+
+    @Override
+    public String toString() { return description; }
+
+    public static Gender fromCode(int code) {
+        for (Gender g : Gender.values()) {
+            if (g.code == code) return g;
+        }
+        throw new IllegalArgumentException("Unknown Gender code: " + code);
+    }
+}
+

+ 42 - 0
src/main/java/work/baiyun/chronicdiseaseapp/handler/GenderTypeHandler.java

@@ -0,0 +1,42 @@
+package work.baiyun.chronicdiseaseapp.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedTypes;
+import work.baiyun.chronicdiseaseapp.enums.Gender;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@MappedTypes(Gender.class)
+public class GenderTypeHandler extends BaseTypeHandler<Gender> {
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Gender parameter, JdbcType jdbcType) throws SQLException {
+        ps.setInt(i, parameter.getCode());
+    }
+
+    @Override
+    public Gender getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        int code = rs.getInt(columnName);
+        if (rs.wasNull()) return null;
+        return Gender.fromCode(code);
+    }
+
+    @Override
+    public Gender getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        int code = rs.getInt(columnIndex);
+        if (rs.wasNull()) return null;
+        return Gender.fromCode(code);
+    }
+
+    @Override
+    public Gender getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        int code = cs.getInt(columnIndex);
+        if (cs.wasNull()) return null;
+        return Gender.fromCode(code);
+    }
+}
+

+ 2 - 1
src/main/java/work/baiyun/chronicdiseaseapp/model/po/UserInfo.java

@@ -34,7 +34,8 @@ public class UserInfo extends BaseEntity {
     private String nickname;
     /** 性别;性别 */
     @Schema(description = "性别(可选)")
-    private String sex;
+    @TableField(typeHandler = work.baiyun.chronicdiseaseapp.handler.GenderTypeHandler.class)
+    private work.baiyun.chronicdiseaseapp.enums.Gender sex;
     /** 手机号;手机号 */
     @Schema(description = "手机号(可选)")
     private String phone;

+ 24 - 0
src/main/java/work/baiyun/chronicdiseaseapp/model/vo/UpdateUserInfoRequest.java

@@ -0,0 +1,24 @@
+package work.baiyun.chronicdiseaseapp.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "更新用户信息请求")
+public class UpdateUserInfoRequest {
+    @Schema(description = "头像(可选)")
+    private String avatar;
+    @Schema(description = "昵称(可选)")
+    private String nickname;
+    @Schema(description = "手机号(可选)")
+    private String phone;
+    @Schema(description = "性别(可选),1=男,2=女")
+    private Integer sex;
+    @Schema(description = "年龄(可选)")
+    private Integer age;
+    @Schema(description = "地址(可选)")
+    private String address;
+    @Schema(description = "兼容:token(可选)")
+    private String token;
+}
+

+ 10 - 2
src/main/resources/application.yml

@@ -1,5 +1,8 @@
 server:
   port: 8080
+#  ssl:
+#    certificate: classpath:cert/fullchain.pem
+#    certificate-private-key: classpath:cert/privkey.pem
 # 配置⽇志输出级别
 logging:
   level:
@@ -44,6 +47,11 @@ knife4j:
   setting:
     language: zh_cn
 # 微信小程序配置
+# (测试号)
+#wechat:
+#  appid: wxca3790d0cfe94e8f
+#  secret: b7865d568205b4c224c40a430c70275f
+# (预览号)
 wechat:
-  appid: wx334b14b3d0bb1547 # TODO: replace with your AppID
-  secret: 0b42a3e4becb7817d08e44e91e2824dd # TODO: replace with your AppSecret
+  appid:  wx334b14b3d0bb1547
+  secret:  0b42a3e4becb7817d08e44e91e2824dd

+ 59 - 0
src/main/resources/cert/fullchain.pem

@@ -0,0 +1,59 @@
+-----BEGIN CERTIFICATE-----
+MIIE9jCCA96gAwIBAgISBfQVL7PiV1AgCWHsplyk+vYjMA0GCSqGSIb3DQEBCwUA
+MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
+EwNSMTIwHhcNMjUxMDA0MTY0NTM3WhcNMjYwMTAyMTY0NTM2WjAYMRYwFAYDVQQD
+DA0qLmJhaXl1bi53b3JrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+r0OdwoAgXGhqGrW9rZmLHwV8slTZKCJof5Q+nlsdrfdS3CijUv5NjsElHbEKMAFh
+32FsYvg6UmvQcV4xaAmvQgDcfXIgvGr2jkThyJ8GqFuZBmFH2vkFHbQFH9lWxmbS
+0bfcxbT/wpESDf+L1f+aSyjwiB02yAJtI8nTPGGiIMY8TPaOxblWOlKFG9Xh5kHw
+60Zp5HBfbQk0cCsoubf0K45poPnKdWoOwHPvPZDLi+/p345rs6GkGcBJit7PdARB
+HjNsftcdTpKklDzhq6UaQYtXsFqCFZHNid8oOFFH0KV1b3UcwOwRQVWQ4lI1yNG6
+/mLvU4riaQ0BV2Nf3TsozwIDAQABo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgWgMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
+DgQWBBRPbJ5FDo6Z/Z0eiSRxVrZ75bUSPzAfBgNVHSMEGDAWgBQAtSnyLY5vMeib
+TK14Pvrc6QzR0jAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAKGF2h0dHA6Ly9y
+MTIuaS5sZW5jci5vcmcvMBgGA1UdEQQRMA+CDSouYmFpeXVuLndvcmswEwYDVR0g
+BAwwCjAIBgZngQwBAgEwLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDovL3IxMi5jLmxl
+bmNyLm9yZy8zNi5jcmwwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgDtPEvW6AbC
+pKIAV9vLJOI4Ad9RL+3EhsVwDyDdtz4/4AAAAZmwUuezAAAEAwBHMEUCIDKpaHZi
+xce8094UakB9oDk2tb7ESPngtXolV2cZqb5HAiEA9QDq56DGkuQIBaNEvjYTu81/
+eYneHmZy0mspXN205DkAdgAZhtTHKKpv/roDb3gqTQGRqs4tcjEPrs5dcEEtJUzH
+1AAAAZmwUu+PAAAEAwBHMEUCIQC/HwZ7dAoARATA3j8OBwBXc1pjzZOJVgUscacF
+I4/4WAIgOlJIMiy5TQrGvj4dzcX+jqpOhQRpvkaVK7JOEUK4pk0wDQYJKoZIhvcN
+AQELBQADggEBAIJxyUsoTI8tMSaJ3D9x8KOtJfRtvF15cartqrBRmmELxETXBmMB
+cOqsRKnihlJVqP4riQ5ERXw20/rlNwMVVV5OXo57LKLsyFyIn1NUr0a9Hu4DEsHx
+vd7f1g8yv/UrwYqpuWYw7gR3O2o0eAG0wypd8MmGy+V5jrsT5ec5h4lRaHt8UGZc
+hwpopf5DTzdZ1DYtAmXQBZ6em0vnMKHK3S/JhTtM3d+SXpMnqqOJaBZ0ScJtyThq
+PYvVLdj83l92AJAamwhqX7DNde7jV5V/N0QVvHri7wxqcU9/t/NLfEmc8lEuZFXc
+7Q53TFjsKDDmAtZVeCdirsn0fIA/kJQJIUE=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIFBjCCAu6gAwIBAgIRAMISMktwqbSRcdxA9+KFJjwwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
+WhcNMjcwMzEyMjM1OTU5WjAzMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
+RW5jcnlwdDEMMAoGA1UEAxMDUjEyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA2pgodK2+lP474B7i5Ut1qywSf+2nAzJ+Npfs6DGPpRONC5kuHs0BUT1M
+5ShuCVUxqqUiXXL0LQfCTUA83wEjuXg39RplMjTmhnGdBO+ECFu9AhqZ66YBAJpz
+kG2Pogeg0JfT2kVhgTU9FPnEwF9q3AuWGrCf4yrqvSrWmMebcas7dA8827JgvlpL
+Thjp2ypzXIlhZZ7+7Tymy05v5J75AEaz/xlNKmOzjmbGGIVwx1Blbzt05UiDDwhY
+XS0jnV6j/ujbAKHS9OMZTfLuevYnnuXNnC2i8n+cF63vEzc50bTILEHWhsDp7CH4
+WRt/uTp8n1wBnWIEwii9Cq08yhDsGwIDAQABo4H4MIH1MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgwBgEB
+/wIBADAdBgNVHQ4EFgQUALUp8i2ObzHom0yteD763OkM0dIwHwYDVR0jBBgwFoAU
+ebRZ5nu25eQBc4AIiMgaWPbpm24wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAC
+hhZodHRwOi8veDEuaS5sZW5jci5vcmcvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMCcG
+A1UdHwQgMB4wHKAaoBiGFmh0dHA6Ly94MS5jLmxlbmNyLm9yZy8wDQYJKoZIhvcN
+AQELBQADggIBAI910AnPanZIZTKS3rVEyIV29BWEjAK/duuz8eL5boSoVpHhkkv3
+4eoAeEiPdZLj5EZ7G2ArIK+gzhTlRQ1q4FKGpPPaFBSpqV/xbUb5UlAXQOnkHn3m
+FVj+qYv87/WeY+Bm4sN3Ox8BhyaU7UAQ3LeZ7N1X01xxQe4wIAAE3JVLUCiHmZL+
+qoCUtgYIFPgcg350QMUIWgxPXNGEncT921ne7nluI02V8pLUmClqXOsCwULw+PVO
+ZCB7qOMxxMBoCUeL2Ll4oMpOSr5pJCpLN3tRA2s6P1KLs9TSrVhOk+7LX28NMUlI
+usQ/nxLJID0RhAeFtPjyOCOscQBA53+NRjSCak7P4A5jX7ppmkcJECL+S0i3kXVU
+y5Me5BbrU8973jZNv/ax6+ZK6TM8jWmimL6of6OrX7ZU6E2WqazzsFrLG3o2kySb
+zlhSgJ81Cl4tv3SbYiYXnJExKQvzf83DYotox3f0fwv7xln1A2ZLplCb0O+l/AK0
+YE0DS2FPxSAHi0iwMfW2nNHJrXcY3LLHD77gRgje4Eveubi2xxa+Nmk/hmhLdIET
+iVDFanoCrMVIpQ59XWHkzdFmoHXHBV7oibVjGSO7ULSQ7MJ1Nz51phuDJSgAIU7A
+0zrLnOrAj/dfrlEWRhCvAgbuwLZX1A2sjNjXoPOHbsPiy+lO1KF8/XY7
+-----END CERTIFICATE-----

+ 27 - 0
src/main/resources/cert/privkey.pem

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAr0OdwoAgXGhqGrW9rZmLHwV8slTZKCJof5Q+nlsdrfdS3Cij
+Uv5NjsElHbEKMAFh32FsYvg6UmvQcV4xaAmvQgDcfXIgvGr2jkThyJ8GqFuZBmFH
+2vkFHbQFH9lWxmbS0bfcxbT/wpESDf+L1f+aSyjwiB02yAJtI8nTPGGiIMY8TPaO
+xblWOlKFG9Xh5kHw60Zp5HBfbQk0cCsoubf0K45poPnKdWoOwHPvPZDLi+/p345r
+s6GkGcBJit7PdARBHjNsftcdTpKklDzhq6UaQYtXsFqCFZHNid8oOFFH0KV1b3Uc
+wOwRQVWQ4lI1yNG6/mLvU4riaQ0BV2Nf3TsozwIDAQABAoIBAQCM5EJSNUXOg3Go
+fyk4ARLBoVuY0HSxutdemAGus3isfQHzUgfZk+0tMT9xGv0hkjrnpB3JgdsAnwM1
+347AH+jvmlmlzrVaQnJp9B29dXmYpeniIxnsgfsG4cysyb7kR4x6Yt/rX5GrC4wE
+DMaRBaU3fnW+Nh3vs2OhPYG+LI504RHOMVTvfGOtU4wQVgE3EVpkdTyDF2CS98/f
+qYJiynEj3fMQqtjXynd5DhXDUYSXRRfYhE1njykQB+0IauXzUsXv3ceC9kSPZm5U
+J6gdPssNhr5R7y13Um8a0fmsTQjfpBH06O3JMqyS5aC+UiJUMPCjCj6D23O8/tP6
+xEGqQ4ShAoGBAOTHcwwa7IWRVSml1kMbENVLjIckguvMbRMQefghVbNQWHcSFnfC
+UfkVS0Ras84vFSMAbpQzQkloNOhnnU/9giPAp8Y9/oeyeIdcjQGbXrSMWkN7Xlw7
+YoD/oK5ODkO1FA4JFtrLpO3rFD9jpbXvL0G5EhCA9vaKgXjPICOjRwktAoGBAMQe
+HW70V4TeSelUXPKPeFEQ3l0VFHto+velWKpYTBOTvyLxU0VQedXIXVO+sfUZKwP9
+8z6r/E1YMH0RBk1ER8x1ELI9+u5oXdepIQi4fChYQaPDQP7PtXpOpWQOp0iyQXQH
+Z/t4dBsWkeyAlYWreefJoGXHx+qVljz5a+75EX9rAoGBAMSfGiSMOz0sQ9owei5g
+Y549eQBpA9AueIwK/BiiZapf4jgrpn2014jQoUiU/7Wzx2G2rFLYnx7B3b7j1lL6
+GNArcsYxX8E2RNppU5LO+p0Hh0g6DkYMj8M4b9t+oEnWpe7OJwNSRGRqRpOYS8JK
+V/4PVhQzEo2fSlkPAps+Z/3dAoGAF1mqkXpgLT62OCTGSE8SuTwz7YtD/Amcz/2M
+2ANZU39k44kuK/OP/gc0LXNoBtGvUHNdEdoyWRcl9s4fHPYDQnGxwjck+FvOyI2n
+lD068ybG8fOeenhKmDxi7s3b1wj6SBFVrRhDYrJGP41zwA2RnypfgZ7Oy7xxveLI
+mhRno+8CgYEAucKPixz7ZK2I+ST/9KhskSPOImxsXEPP2I8OMbq2dGQT+5f9H0qt
+0HLT53eyGM7ovqWgax8a8yeR7v4gwT+9qhX4ATM741bm/r7DhOwP7lpNVe5wuSgh
+Kmn9NSfDuNp/ozePoy9pEE5pMVyhxoH4tEQwydjLih+V13HaxlLWzgM=
+-----END RSA PRIVATE KEY-----

+ 10 - 2
target/classes/application.yml

@@ -1,5 +1,8 @@
 server:
   port: 8080
+#  ssl:
+#    certificate: classpath:cert/fullchain.pem
+#    certificate-private-key: classpath:cert/privkey.pem
 # 配置⽇志输出级别
 logging:
   level:
@@ -44,6 +47,11 @@ knife4j:
   setting:
     language: zh_cn
 # 微信小程序配置
+# (测试号)
+#wechat:
+#  appid: wxca3790d0cfe94e8f
+#  secret: b7865d568205b4c224c40a430c70275f
+# (预览号)
 wechat:
-  appid: wx334b14b3d0bb1547 # TODO: replace with your AppID
-  secret: 0b42a3e4becb7817d08e44e91e2824dd # TODO: replace with your AppSecret
+  appid:  wx334b14b3d0bb1547
+  secret:  0b42a3e4becb7817d08e44e91e2824dd