|
|
@@ -4,6 +4,10 @@ import javax.annotation.Resource;
|
|
|
|
|
|
import com.etotem.cfc.common.Result;
|
|
|
import com.etotem.cfc.service.BindInviteService;
|
|
|
+import com.etotem.cfc.service.MembershipService;
|
|
|
+import com.etotem.cfc.service.PlannerCertificationGuard;
|
|
|
+import com.etotem.cfc.service.PlannerCertificationService;
|
|
|
+import com.etotem.cfc.util.ParamUtils;
|
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
|
|
|
|
@@ -19,6 +23,12 @@ public class BindInviteController {
|
|
|
@Resource
|
|
|
private BindInviteService bindInviteService;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private MembershipService membershipService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private PlannerCertificationGuard plannerCertificationGuard;
|
|
|
+
|
|
|
/**
|
|
|
* 生成绑定邀请
|
|
|
*/
|
|
|
@@ -39,4 +49,53 @@ public class BindInviteController {
|
|
|
Map<String, Object> result = bindInviteService.validateToken(token);
|
|
|
return Result.success(result);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 家庭主账号通过邀请令牌确认绑定规划师。
|
|
|
+ * 语义对齐 BindController#acceptBind(/api/bind/accept):家庭校验 → 规划师认证闸门 → 落库绑定。
|
|
|
+ */
|
|
|
+ @Operation(summary = "家庭主账号确认绑定规划师(邀请令牌)")
|
|
|
+ @PostMapping("/confirm")
|
|
|
+ public Result<Boolean> confirmBind(@RequestAttribute("userId") Long userId,
|
|
|
+ @RequestBody(required = false) Map<String, Object> body) {
|
|
|
+ if (userId == null) {
|
|
|
+ return Result.error("请先登录");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Long familyId = membershipService.getUserFamilyId(userId);
|
|
|
+ if (familyId == null) {
|
|
|
+ return Result.noFamily("请先创建或加入家庭");
|
|
|
+ }
|
|
|
+ Long guideId = ParamUtils.getLong(body != null ? body.get("guideId") : null);
|
|
|
+ if (guideId == null) {
|
|
|
+ return Result.error("guideId不能为空");
|
|
|
+ }
|
|
|
+ // 认证闸门:规划师(基础类别)认证通过才可开始服务(家庭绑定)
|
|
|
+ Result<Void> denied = plannerCertificationGuard.assertCertified(guideId,
|
|
|
+ PlannerCertificationService.CATEGORY_PLANNER);
|
|
|
+ if (denied != null) {
|
|
|
+ return Result.error(denied.getCode(), denied.getMessage());
|
|
|
+ }
|
|
|
+ String inviteToken = firstNonBlank(
|
|
|
+ body.get("bindToken") != null ? body.get("bindToken").toString() : null,
|
|
|
+ body.get("inviteToken") != null ? body.get("inviteToken").toString() : null);
|
|
|
+ String serviceType = body.get("serviceType") != null ? body.get("serviceType").toString() : "consulting";
|
|
|
+ Long servicePrice = ParamUtils.getLong(body.get("servicePrice"));
|
|
|
+ boolean success = bindInviteService.confirmBind(inviteToken, guideId, familyId, serviceType,
|
|
|
+ servicePrice != null ? servicePrice.intValue() : 0);
|
|
|
+ return Result.success(success);
|
|
|
+ } catch (RuntimeException e) {
|
|
|
+ return Result.error(400, e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 取第一个非空白字符串(bindToken / inviteToken 兼容) */
|
|
|
+ private static String firstNonBlank(String... values) {
|
|
|
+ for (String value : values) {
|
|
|
+ if (value != null && !value.trim().isEmpty()) {
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|