wwh недель назад: 3
Родитель
Сommit
df391a9b7a
21 измененных файлов с 160 добавлено и 87 удалено
  1. 3 1
      huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AgentController.java
  2. 5 2
      huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AiProxyController.java
  3. 30 9
      huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AuthController.java
  4. 4 0
      huimv-employment/fe-common/pom.xml
  5. 6 12
      huimv-employment/fe-common/src/main/java/com/huimv/employment/common/web/R.java
  6. 4 0
      huimv-employment/fe-service/pom.xml
  7. 6 5
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/agent/dto/AgentMessageRequest.java
  8. 7 7
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/agent/dto/AgentMessageResponse.java
  9. 2 12
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/PasswordAuthService.java
  10. 10 11
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/LoginResponse.java
  11. 28 3
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/MpUserInfoResponse.java
  12. 5 2
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordLoginRequest.java
  13. 4 1
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordPublicKeyResponse.java
  14. 7 1
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordResetRequest.java
  15. 7 3
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordSetRequest.java
  16. 5 1
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordStatusResponse.java
  17. 6 4
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsLoginRequest.java
  18. 5 6
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsSendRequest.java
  19. 5 6
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsSendResponse.java
  20. 5 1
      huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/WechatLoginRequest.java
  21. 6 0
      huimv-employment/pom.xml

+ 3 - 1
huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AgentController.java

@@ -34,7 +34,9 @@ public class AgentController {
34 34
     }
35 35
 
36 36
     @PostMapping("/messages")
37
-    @Operation(summary = "发送消息并获取 AI 回复")
37
+    @Operation(summary = "发送消息并获取 AI 回复",
38
+            description = "向智能体发送用户消息,返回 AI 回复文本及会话 ID。"
39
+                    + "conversationId 不传时服务端自动生成,后续多轮对话传入同一 ID 以保持上下文。")
38 40
     public R<AgentMessageResponse> sendMessage(@Validated @RequestBody AgentMessageRequest request) {
39 41
         LoginUser loginUser = LoginUserHolder.require();
40 42
         AgentMessageResponse response = agentChatService.chat(

+ 5 - 2
huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AiProxyController.java

@@ -37,13 +37,16 @@ public class AiProxyController {
37 37
     }
38 38
 
39 39
     @GetMapping("/models")
40
-    @Operation(summary = "获取可用模型列表(OpenAI 兼容)")
40
+    @Operation(summary = "获取可用模型列表", description = "OpenAI 兼容 GET /v1/models,透传上游 KB 服务响应。")
41 41
     public ResponseEntity<byte[]> models() {
42 42
         return kbOpenAiProxyService.listModels();
43 43
     }
44 44
 
45 45
     @PostMapping(value = "/chat/completions", consumes = MediaType.APPLICATION_JSON_VALUE)
46
-    @Operation(summary = "对话补全(OpenAI 兼容,支持 SSE 流式)")
46
+    @Operation(summary = "对话补全(OpenAI 兼容)",
47
+            description = "请求/响应体与 OpenAI Chat Completions 规范一致,透传上游 KB 服务。"
48
+                    + "请求体示例:{\"model\":\"gpt-4\",\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}],\"stream\":false}"
49
+                    + ";stream=true 时返回 text/event-stream SSE 流式响应。")
47 50
     public void chatCompletions(HttpServletRequest request, HttpServletResponse response) throws IOException {
48 51
         byte[] body = StreamUtils.copyToByteArray(request.getInputStream());
49 52
         if (kbOpenAiProxyService.isStreamRequest(body)) {

+ 30 - 9
huimv-employment/fe-api/src/main/java/com/huimv/employment/controller/mp/AuthController.java

@@ -27,10 +27,14 @@ import org.springframework.web.bind.annotation.RestController;
27 27
 
28 28
 /**
29 29
  * 小程序端认证:短信 / 微信 / 可选账密(登录后设置)。
30
+ * <p>
31
+ * 登录成功后返回 JWT,后续请求 Header 携带 {@code Authorization: Bearer <token>}。
32
+ * 账密相关密码字段须先调用 {@code GET /password/public-key} 获取 RSA 公钥,前端加密后再提交。
33
+ * </p>
30 34
  */
31 35
 @RestController
32 36
 @RequestMapping("/api/v1/mp/auth")
33
-@Tag(name = "认证", description = "登录与账密管理,除 set/status 外均为匿名访问")
37
+@Tag(name = "认证", description = "短信/微信/账密登录与密码管理。除 password/set、password/status 外均为匿名访问")
34 38
 public class AuthController {
35 39
 
36 40
     private final AuthService authService;
@@ -42,37 +46,51 @@ public class AuthController {
42 46
     }
43 47
 
44 48
     @PostMapping("/sms/send")
45
-    @Operation(summary = "发送登录验证码")
49
+    @Operation(summary = "发送登录验证码",
50
+            description = "向指定手机号发送 6 位登录验证码,同一号码 60 秒内不可重复发送。"
51
+                    + "Mock 模式(fe.sms.mock-enabled=true)下不实际发短信,验证码固定为 123456。"
52
+                    + "须携带 userType,决定登录后的小程序端身份(enterprise / worker)。")
46 53
     public R<SmsSendResponse> sendSmsCode(@Validated @RequestBody SmsSendRequest request) {
47 54
         return R.ok(authService.sendLoginCode(request));
48 55
     }
49 56
 
50 57
     @PostMapping("/sms/login")
51
-    @Operation(summary = "短信验证码登录")
58
+    @Operation(summary = "短信验证码登录",
59
+            description = "校验验证码后登录或自动注册,返回 JWT 及用户基本信息。"
60
+                    + "登录成功后建议调用 GET /api/v1/mp/getInfo 查询登记状态。")
52 61
     public R<LoginResponse> loginBySms(@Validated @RequestBody SmsLoginRequest request) {
53 62
         return R.ok(authService.loginBySms(request));
54 63
     }
55 64
 
56 65
     @PostMapping("/wechat/login")
57
-    @Operation(summary = "微信小程序 code 登录")
66
+    @Operation(summary = "微信小程序 code 登录",
67
+            description = "使用 wx.login 获取的 code 换取 openid 并登录。"
68
+                    + "Mock 模式(fe.wechat.miniapp.mock-enabled=true)下 code 可为任意非空字符串。"
69
+                    + "短信用户与微信用户一期未做账号合并,openid 与手机号分别建号。")
58 70
     public R<LoginResponse> loginByWechat(@Validated @RequestBody WechatLoginRequest request) {
59 71
         return R.ok(authService.loginByWechat(request));
60 72
     }
61 73
 
62 74
     @GetMapping("/password/public-key")
63
-    @Operation(summary = "获取 RSA 公钥(前端加密密码)")
75
+    @Operation(summary = "获取 RSA 公钥",
76
+            description = "返回 PEM 格式 RSA 公钥,前端用于加密密码后再调用 login/set/reset 接口。"
77
+                    + "明文密码不在网络传输,服务端解密后 BCrypt 入库。")
64 78
     public R<PasswordPublicKeyResponse> passwordPublicKey() {
65 79
         return R.ok(passwordAuthService.getPublicKey());
66 80
     }
67 81
 
68 82
     @PostMapping("/password/login")
69
-    @Operation(summary = "用户名/手机号 + 密码登录")
83
+    @Operation(summary = "用户名/手机号 + 密码登录",
84
+            description = "account 支持用户名或手机号;encryptedPassword 为 RSA 加密后的 Base64 字符串。"
85
+                    + "连续密码错误 5 次将锁定账号 30 分钟。")
70 86
     public R<LoginResponse> loginByPassword(@Validated @RequestBody PasswordLoginRequest request) {
71 87
         return R.ok(passwordAuthService.loginByPassword(request));
72 88
     }
73 89
 
74 90
     @PostMapping("/password/set")
75
-    @Operation(summary = "设置或修改登录密码(需 JWT)")
91
+    @Operation(summary = "设置或修改登录密码",
92
+            description = "需 JWT 鉴权。首次设密须传 username(全局唯一)及 encryptedPassword、encryptedConfirmPassword。"
93
+                    + "已设密用户改密须额外传 encryptedOldPassword。所有密码字段均为 RSA 加密 Base64。")
76 94
     @SecurityRequirement(name = "Authorization")
77 95
     public R<Void> setPassword(@Validated @RequestBody PasswordSetRequest request) {
78 96
         LoginUser loginUser = LoginUserHolder.require();
@@ -81,14 +99,17 @@ public class AuthController {
81 99
     }
82 100
 
83 101
     @PostMapping("/password/reset")
84
-    @Operation(summary = "短信验证码重置密码")
102
+    @Operation(summary = "短信验证码重置密码",
103
+            description = "忘记密码场景:先调用 POST /sms/send 获取验证码,再提交手机号、验证码及新密码(RSA 加密)。"
104
+                    + "手机号须为已注册账号。")
85 105
     public R<Void> resetPassword(@Validated @RequestBody PasswordResetRequest request) {
86 106
         passwordAuthService.resetPassword(request);
87 107
         return R.ok();
88 108
     }
89 109
 
90 110
     @GetMapping("/password/status")
91
-    @Operation(summary = "查询是否已设置登录密码")
111
+    @Operation(summary = "查询是否已设置登录密码",
112
+            description = "需 JWT 鉴权。返回 passwordSet 及 usernameMask(已设密时)。")
92 113
     @SecurityRequirement(name = "Authorization")
93 114
     public R<PasswordStatusResponse> passwordStatus() {
94 115
         LoginUser loginUser = LoginUserHolder.require();

+ 4 - 0
huimv-employment/fe-common/pom.xml

@@ -18,5 +18,9 @@
18 18
             <groupId>org.springframework.security</groupId>
19 19
             <artifactId>spring-security-crypto</artifactId>
20 20
         </dependency>
21
+        <dependency>
22
+            <groupId>io.swagger.core.v3</groupId>
23
+            <artifactId>swagger-annotations</artifactId>
24
+        </dependency>
21 25
     </dependencies>
22 26
 </project>

+ 6 - 12
huimv-employment/fe-common/src/main/java/com/huimv/employment/common/web/R.java

@@ -1,30 +1,24 @@
1 1
 package com.huimv.employment.common.web;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import java.io.Serializable;
4 6
 
5 7
 /**
6 8
  * 统一 API 响应体,与技术方案 §6.1 约定一致。
7
- * <p>
8
- * 响应格式:{@code {"code": 200, "msg": "success", "data": { ... }}}
9
- * </p>
10
- * <ul>
11
- *   <li>{@code code=200} — 成功</li>
12
- *   <li>{@code code≠200} — 失败,msg 为错误提示</li>
13
- * </ul>
14
- *
15
- * @param <T> data 字段的类型
16 9
  */
10
+@Schema(description = "统一响应体")
17 11
 public class R<T> implements Serializable {
18 12
 
19 13
     private static final long serialVersionUID = 1L;
20 14
 
21
-    /** 业务状态码,200 表示成功 */
15
+    @Schema(description = "业务状态码,200 表示成功", example = "200")
22 16
     private int code;
23 17
 
24
-    /** 提示信息,成功时为 "success",失败时为具体错误描述 */
18
+    @Schema(description = "提示信息", example = "success")
25 19
     private String msg;
26 20
 
27
-    /** 业务数据载荷,失败时通常为 null */
21
+    @Schema(description = "业务数据")
28 22
     private T data;
29 23
 
30 24
     public R() {

+ 4 - 0
huimv-employment/fe-service/pom.xml

@@ -48,5 +48,9 @@
48 48
             <groupId>com.github.binarywang</groupId>
49 49
             <artifactId>weixin-java-miniapp</artifactId>
50 50
         </dependency>
51
+        <dependency>
52
+            <groupId>io.swagger.core.v3</groupId>
53
+            <artifactId>swagger-annotations</artifactId>
54
+        </dependency>
51 55
     </dependencies>
52 56
 </project>

+ 6 - 5
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/agent/dto/AgentMessageRequest.java

@@ -1,18 +1,19 @@
1 1
 package com.huimv.employment.service.agent.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 
5
-/**
6
- * 小程序智能体对话请求。
7
- */
7
+@Schema(description = "智能体对话请求")
8 8
 public class AgentMessageRequest {
9 9
 
10
-    /** 企业 ID(可选,预留多企业场景) */
10
+    @Schema(description = "企业 ID(可选,预留多企业场景)", example = "1")
11 11
     private Long enterpriseId;
12 12
 
13
-    /** 会话 ID,不传则自动生成 */
13
+    @Schema(description = "会话 ID,不传则自动生成", example = "conv-abc123")
14 14
     private String conversationId;
15 15
 
16
+    @Schema(description = "用户消息内容", example = "帮我起草一份临时工用工协议", requiredMode = Schema.RequiredMode.REQUIRED)
16 17
     @NotBlank(message = "消息内容不能为空")
17 18
     private String message;
18 19
 

+ 7 - 7
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/agent/dto/AgentMessageResponse.java

@@ -1,20 +1,20 @@
1 1
 package com.huimv.employment.service.agent.dto;
2 2
 
3
-/**
4
- * 小程序智能体对话响应。
5
- */
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+@Schema(description = "智能体对话响应")
6 6
 public class AgentMessageResponse {
7 7
 
8
-    /** AI 回复文本 */
8
+    @Schema(description = "AI 回复文本", example = "好的,请提供用工岗位、工时和薪资等信息。")
9 9
     private String reply;
10 10
 
11
-    /** 会话 ID */
11
+    @Schema(description = "会话 ID", example = "conv-abc123")
12 12
     private String conversationId;
13 13
 
14
-    /** 下一步动作(如 show_employment_draft),一期可为空 */
14
+    @Schema(description = "下一步动作(如 show_employment_draft),一期可为空")
15 15
     private String nextAction;
16 16
 
17
-    /** 关联草稿 ID,一期可为空 */
17
+    @Schema(description = "关联草稿 ID,一期可为空")
18 18
     private String draftId;
19 19
 
20 20
     public String getReply() {

+ 2 - 12
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/PasswordAuthService.java

@@ -3,20 +3,10 @@ package com.huimv.employment.service.auth;
3 3
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
4 4
 import com.huimv.employment.common.exception.BizException;
5 5
 import com.huimv.employment.common.exception.ErrorCode;
6
-import com.huimv.employment.common.util.AesUtils;
7
-import com.huimv.employment.common.util.MobileUtils;
8
-import com.huimv.employment.common.util.PasswordPolicyUtils;
9
-import com.huimv.employment.common.util.PasswordUtils;
10
-import com.huimv.employment.common.util.RsaUtils;
11
-import com.huimv.employment.common.util.UsernameUtils;
6
+import com.huimv.employment.common.util.*;
12 7
 import com.huimv.employment.dao.entity.FeUser;
13 8
 import com.huimv.employment.dao.mapper.FeUserMapper;
14
-import com.huimv.employment.service.auth.dto.LoginResponse;
15
-import com.huimv.employment.service.auth.dto.PasswordLoginRequest;
16
-import com.huimv.employment.service.auth.dto.PasswordPublicKeyResponse;
17
-import com.huimv.employment.service.auth.dto.PasswordResetRequest;
18
-import com.huimv.employment.service.auth.dto.PasswordSetRequest;
19
-import com.huimv.employment.service.auth.dto.PasswordStatusResponse;
9
+import com.huimv.employment.service.auth.dto.*;
20 10
 import com.huimv.employment.service.config.SecurityProperties;
21 11
 import com.huimv.employment.service.sms.SmsCodeService;
22 12
 import org.springframework.stereotype.Service;

+ 10 - 11
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/LoginResponse.java

@@ -1,33 +1,32 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 /**
4 6
  * 登录成功响应体。
5
- * <p>
6
- * 客户端拿到 {@link #token} 后,后续请求在 Header 携带:
7
- * {@code Authorization: Bearer <token>}
8
- * </p>
9 7
  */
8
+@Schema(description = "登录成功响应")
10 9
 public class LoginResponse {
11 10
 
12
-    /** JWT 访问令牌 */
11
+    @Schema(description = "JWT 访问令牌,后续请求 Header 携带 Authorization: Bearer <token>", example = "eyJhbGciOiJIUzI1NiIs...")
13 12
     private String token;
14 13
 
15
-    /** Token 有效时长(秒),默认 7200(2 小时) */
14
+    @Schema(description = "Token 有效时长(秒)", example = "7200")
16 15
     private long expiresIn;
17 16
 
18
-    /** 用户 ID,对应 fe_user.id */
17
+    @Schema(description = "用户 ID", example = "1001")
19 18
     private Long userId;
20 19
 
21
-    /** 用户类型:enterprise / worker */
20
+    @Schema(description = "用户类型:enterprise / worker", example = "enterprise")
22 21
     private String userType;
23 22
 
24
-    /** 脱敏手机号,如 138****8000 */
23
+    @Schema(description = "脱敏手机号", example = "138****8000")
25 24
     private String mobileMask;
26 25
 
27
-    /** 用户昵称,可空 */
26
+    @Schema(description = "用户昵称,可空", example = "张三")
28 27
     private String nickname;
29 28
 
30
-    /** 是否已设置登录密码 */
29
+    @Schema(description = "是否已设置登录密码", example = "false")
31 30
     private boolean passwordSet;
32 31
 
33 32
     public String getToken() {

+ 28 - 3
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/MpUserInfoResponse.java

@@ -1,21 +1,26 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 /**
4 6
  * 小程序当前用户信息,含登记状态及企业/临时工详情。
5 7
  */
8
+@Schema(description = "小程序用户信息(含登记状态)")
6 9
 public class MpUserInfoResponse {
7 10
 
8
-    /** 用户类型:enterprise / worker */
11
+    @Schema(description = "用户类型:enterprise / worker", example = "enterprise")
9 12
     private String userType;
10 13
 
11
-    /** 是否已完成登记 */
14
+    @Schema(description = "是否已完成档案登记", example = "false")
12 15
     private boolean registered;
13 16
 
14
-    /** 登录账号手机号脱敏 */
17
+    @Schema(description = "登录账号手机号脱敏", example = "138****8000")
15 18
     private String mobileMask;
16 19
 
20
+    @Schema(description = "企业登记信息(userType=enterprise 且已登记时有值)")
17 21
     private EnterpriseInfo enterprise;
18 22
 
23
+    @Schema(description = "临时工登记信息(userType=worker 且已登记时有值)")
19 24
     private WorkerInfo worker;
20 25
 
21 26
     public String getUserType() {
@@ -59,24 +64,34 @@ public class MpUserInfoResponse {
59 64
     }
60 65
 
61 66
     /** 企业登记信息 */
67
+    @Schema(description = "企业登记详情")
62 68
     public static class EnterpriseInfo {
63 69
 
70
+        @Schema(description = "企业 ID", example = "1")
64 71
         private Long enterpriseId;
65 72
 
73
+        @Schema(description = "企业编号")
66 74
         private String enterpriseCode;
67 75
 
76
+        @Schema(description = "企业名称")
68 77
         private String name;
69 78
 
79
+        @Schema(description = "统一社会信用代码")
70 80
         private String creditCode;
71 81
 
82
+        @Schema(description = "法人姓名")
72 83
         private String legalPerson;
73 84
 
85
+        @Schema(description = "注册地址")
74 86
         private String registeredAddress;
75 87
 
88
+        @Schema(description = "联系人姓名")
76 89
         private String contactName;
77 90
 
91
+        @Schema(description = "联系人手机号脱敏")
78 92
         private String contactMobileMask;
79 93
 
94
+        @Schema(description = "认证状态")
80 95
         private String authStatus;
81 96
 
82 97
         public Long getEnterpriseId() {
@@ -153,24 +168,34 @@ public class MpUserInfoResponse {
153 168
     }
154 169
 
155 170
     /** 临时工登记信息 */
171
+    @Schema(description = "临时工登记详情")
156 172
     public static class WorkerInfo {
157 173
 
174
+        @Schema(description = "临时工 ID", example = "1")
158 175
         private Long workerId;
159 176
 
177
+        @Schema(description = "临时工编号")
160 178
         private String workerNo;
161 179
 
180
+        @Schema(description = "真实姓名")
162 181
         private String realName;
163 182
 
183
+        @Schema(description = "手机号脱敏")
164 184
         private String mobileMask;
165 185
 
186
+        @Schema(description = "身份证号脱敏")
166 187
         private String idCardNoMask;
167 188
 
189
+        @Schema(description = "银行卡号脱敏")
168 190
         private String bankAccountMask;
169 191
 
192
+        @Schema(description = "开户银行")
170 193
         private String bankName;
171 194
 
195
+        @Schema(description = "开户支行")
172 196
         private String bankBranch;
173 197
 
198
+        @Schema(description = "实名认证状态")
174 199
         private String verifyStatus;
175 200
 
176 201
         public Long getWorkerId() {

+ 5 - 2
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordLoginRequest.java

@@ -1,14 +1,17 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 
5
-/** {@code POST /api/v1/mp/auth/password/login} */
7
+@Schema(description = "账密登录请求")
6 8
 public class PasswordLoginRequest {
7 9
 
10
+    @Schema(description = "登录账号,支持用户名或手机号", example = "zhangsan", requiredMode = Schema.RequiredMode.REQUIRED)
8 11
     @NotBlank(message = "账号不能为空")
9 12
     private String account;
10 13
 
11
-    /** 前端 RSA 加密后的密码(Base64) */
14
+    @Schema(description = "RSA 公钥加密后的密码(Base64),须先调用 GET /auth/password/public-key 获取公钥", requiredMode = Schema.RequiredMode.REQUIRED)
12 15
     @NotBlank(message = "密码不能为空")
13 16
     private String encryptedPassword;
14 17
 

+ 4 - 1
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordPublicKeyResponse.java

@@ -1,8 +1,11 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
-/** RSA 公钥响应 */
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+@Schema(description = "RSA 公钥响应")
4 6
 public class PasswordPublicKeyResponse {
5 7
 
8
+    @Schema(description = "PEM 格式 RSA 公钥,前端用于加密密码后再提交", example = "-----BEGIN PUBLIC KEY-----\\nMIIBIjANBg...")
6 9
     private String publicKey;
7 10
 
8 11
     public PasswordPublicKeyResponse() {

+ 7 - 1
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordResetRequest.java

@@ -1,21 +1,27 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 import javax.validation.constraints.Pattern;
5 7
 
6
-/** {@code POST /api/v1/mp/auth/password/reset} */
8
+@Schema(description = "短信验证码重置密码请求")
7 9
 public class PasswordResetRequest {
8 10
 
11
+    @Schema(description = "已注册手机号", example = "13800138000", requiredMode = Schema.RequiredMode.REQUIRED)
9 12
     @NotBlank(message = "手机号不能为空")
10 13
     @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
11 14
     private String mobile;
12 15
 
16
+    @Schema(description = "短信验证码", example = "123456", requiredMode = Schema.RequiredMode.REQUIRED)
13 17
     @NotBlank(message = "验证码不能为空")
14 18
     private String code;
15 19
 
20
+    @Schema(description = "新密码(RSA 加密 Base64)", requiredMode = Schema.RequiredMode.REQUIRED)
16 21
     @NotBlank(message = "密码不能为空")
17 22
     private String encryptedPassword;
18 23
 
24
+    @Schema(description = "确认新密码(RSA 加密 Base64)", requiredMode = Schema.RequiredMode.REQUIRED)
19 25
     @NotBlank(message = "确认密码不能为空")
20 26
     private String encryptedConfirmPassword;
21 27
 

+ 7 - 3
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordSetRequest.java

@@ -1,20 +1,24 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 
5
-/** {@code POST /api/v1/mp/auth/password/set} */
7
+@Schema(description = "设置或修改登录密码请求(需 JWT)")
6 8
 public class PasswordSetRequest {
7 9
 
8
-    /** 首次设密必填;改密时可不传 */
10
+    @Schema(description = "登录用户名,首次设密必填;改密时可不传", example = "zhangsan")
9 11
     private String username;
10 12
 
13
+    @Schema(description = "新密码(RSA 加密 Base64)", requiredMode = Schema.RequiredMode.REQUIRED)
11 14
     @NotBlank(message = "密码不能为空")
12 15
     private String encryptedPassword;
13 16
 
17
+    @Schema(description = "确认新密码(RSA 加密 Base64),须与新密码明文一致", requiredMode = Schema.RequiredMode.REQUIRED)
14 18
     @NotBlank(message = "确认密码不能为空")
15 19
     private String encryptedConfirmPassword;
16 20
 
17
-    /** 改密时必填(RSA 加密) */
21
+    @Schema(description = "旧密码(RSA 加密 Base64),已设密用户改密时必填")
18 22
     private String encryptedOldPassword;
19 23
 
20 24
     public String getUsername() {

+ 5 - 1
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/PasswordStatusResponse.java

@@ -1,10 +1,14 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
-/** 账密设置状态 */
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
5
+@Schema(description = "账密设置状态")
4 6
 public class PasswordStatusResponse {
5 7
 
8
+    @Schema(description = "是否已设置登录密码", example = "true")
6 9
     private boolean passwordSet;
7 10
 
11
+    @Schema(description = "用户名脱敏,未设密时为 null", example = "zha***")
8 12
     private String usernameMask;
9 13
 
10 14
     public boolean isPasswordSet() {

+ 6 - 4
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsLoginRequest.java

@@ -1,24 +1,26 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 import javax.validation.constraints.Pattern;
5 7
 
6 8
 /**
7 9
  * 短信验证码登录请求体。
8
- * <p>对应接口:{@code POST /api/v1/mp/auth/sms/login}</p>
9 10
  */
11
+@Schema(description = "短信验证码登录请求")
10 12
 public class SmsLoginRequest {
11 13
 
12
-    /** 手机号,须与发送验证码时一致 */
14
+    @Schema(description = "手机号,须与发送验证码时一致", example = "13800138000", requiredMode = Schema.RequiredMode.REQUIRED)
13 15
     @NotBlank(message = "手机号不能为空")
14 16
     @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
15 17
     private String mobile;
16 18
 
17
-    /** 短信验证码,Mock 模式下固定为 123456 */
19
+    @Schema(description = "短信验证码;Mock 模式下固定为 123456", example = "123456", requiredMode = Schema.RequiredMode.REQUIRED)
18 20
     @NotBlank(message = "验证码不能为空")
19 21
     private String code;
20 22
 
21
-    /** 用户类型:enterprise(企业主)或 worker(临时工) */
23
+    @Schema(description = "用户类型:enterprise 或 worker", example = "enterprise", requiredMode = Schema.RequiredMode.REQUIRED)
22 24
     @NotBlank(message = "用户类型不能为空")
23 25
     @Pattern(regexp = "^(enterprise|worker)$", message = "用户类型只能是 enterprise 或 worker")
24 26
     private String userType;

+ 5 - 6
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsSendRequest.java

@@ -1,23 +1,22 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 import javax.validation.constraints.Pattern;
5 7
 
6 8
 /**
7 9
  * 发送登录验证码请求体。
8
- * <p>对应接口:{@code POST /api/v1/mp/auth/sms/send}</p>
9 10
  */
11
+@Schema(description = "发送登录验证码请求")
10 12
 public class SmsSendRequest {
11 13
 
12
-    /** 手机号,11 位中国大陆号码 */
14
+    @Schema(description = "手机号,11 位中国大陆号码", example = "13800138000", requiredMode = Schema.RequiredMode.REQUIRED)
13 15
     @NotBlank(message = "手机号不能为空")
14 16
     @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
15 17
     private String mobile;
16 18
 
17
-    /**
18
-     * 用户类型,决定登录后的小程序端身份与菜单权限。
19
-     * enterprise=企业主;worker=临时工。
20
-     */
19
+    @Schema(description = "用户类型:enterprise=企业主,worker=临时工", example = "enterprise", requiredMode = Schema.RequiredMode.REQUIRED)
21 20
     @NotBlank(message = "用户类型不能为空")
22 21
     @Pattern(regexp = "^(enterprise|worker)$", message = "用户类型只能是 enterprise 或 worker")
23 22
     private String userType;

+ 5 - 6
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/SmsSendResponse.java

@@ -1,18 +1,17 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 /**
4 6
  * 发送验证码成功响应体。
5
- * <p>告知前端当前是否 Mock 模式及验证码有效期,便于 UI 展示相应提示。</p>
6 7
  */
8
+@Schema(description = "发送验证码响应")
7 9
 public class SmsSendResponse {
8 10
 
9
-    /**
10
-     * 是否 Mock 模式。
11
-     * true 时前端可提示「测试环境,验证码为 123456」。
12
-     */
11
+    @Schema(description = "是否 Mock 模式;true 时前端可提示「测试环境,验证码为 123456」", example = "true")
13 12
     private boolean mockEnabled;
14 13
 
15
-    /** 验证码有效时长(秒),默认 300 */
14
+    @Schema(description = "验证码有效时长(秒)", example = "300")
16 15
     private int expireSeconds;
17 16
 
18 17
     public SmsSendResponse() {

+ 5 - 1
huimv-employment/fe-service/src/main/java/com/huimv/employment/service/auth/dto/WechatLoginRequest.java

@@ -1,14 +1,18 @@
1 1
 package com.huimv.employment.service.auth.dto;
2 2
 
3
+import io.swagger.v3.oas.annotations.media.Schema;
4
+
3 5
 import javax.validation.constraints.NotBlank;
4 6
 import javax.validation.constraints.Pattern;
5 7
 
6
-/** {@code POST /api/v1/mp/auth/wechat/login} */
8
+@Schema(description = "微信小程序登录请求")
7 9
 public class WechatLoginRequest {
8 10
 
11
+    @Schema(description = "wx.login 返回的临时 code", example = "081abcXYZ", requiredMode = Schema.RequiredMode.REQUIRED)
9 12
     @NotBlank(message = "微信 code 不能为空")
10 13
     private String code;
11 14
 
15
+    @Schema(description = "用户类型:enterprise 或 worker", example = "worker", requiredMode = Schema.RequiredMode.REQUIRED)
12 16
     @NotBlank(message = "用户类型不能为空")
13 17
     @Pattern(regexp = "^(enterprise|worker)$", message = "用户类型只能是 enterprise 或 worker")
14 18
     private String userType;

+ 6 - 0
huimv-employment/pom.xml

@@ -38,6 +38,7 @@
38 38
         <redisson.version>3.23.5</redisson.version>
39 39
         <wxjava.version>4.6.0</wxjava.version>
40 40
         <aliyun-dysmsapi.version>4.1.1</aliyun-dysmsapi.version>
41
+        <swagger-annotations.version>2.2.22</swagger-annotations.version>
41 42
     </properties>
42 43
 
43 44
     <dependencyManagement>
@@ -107,6 +108,11 @@
107 108
                 <artifactId>dysmsapi20170525</artifactId>
108 109
                 <version>${aliyun-dysmsapi.version}</version>
109 110
             </dependency>
111
+            <dependency>
112
+                <groupId>io.swagger.core.v3</groupId>
113
+                <artifactId>swagger-annotations</artifactId>
114
+                <version>${swagger-annotations.version}</version>
115
+            </dependency>
110 116
         </dependencies>
111 117
     </dependencyManagement>
112 118
 </project>