// Code scaffolded by goctl. Safe to edit. // goctl 1.10.1 package auth import ( "context" "encoding/json" "fmt" "io" "net/http" "net/url" "sundynix-micro-go/app/auth/api/internal/svc" "sundynix-micro-go/app/auth/api/internal/types" plantPb "sundynix-micro-go/app/plant/rpc/plant" sysPb "sundynix-micro-go/app/system/rpc/system" "github.com/zeromicro/go-zero/core/logx" ) type LoginByPhoneLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewLoginByPhoneLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginByPhoneLogic { return &LoginByPhoneLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *LoginByPhoneLogic) LoginByPhone(req *types.LoginByPhoneReq) (resp *types.LoginResp, err error) { // 1. 调用微信接口获取手机号 // TODO: 从配置中获取access_token accessToken := "" // 需要通过微信API获取 apiURL := "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken data := map[string]interface{}{"code": req.Code} jsonData, _ := json.Marshal(data) httpResp, err := http.Post(apiURL, "application/json", nil) if err != nil { l.Errorf("获取手机号失败: %v", err) return nil, fmt.Errorf("获取手机号失败") } defer httpResp.Body.Close() body, _ := io.ReadAll(httpResp.Body) var dataMap map[string]interface{} _ = json.Unmarshal(body, &dataMap) _ = jsonData _ = url.Values{} // 2. 通过 plant-rpc 和 system-rpc 获取用户 if l.svcCtx.PlantRpc == nil { return nil, fmt.Errorf("植物服务不可用") } profileResp, err := l.svcCtx.PlantRpc.FindOrCreateUserByOpenId(l.ctx, &plantPb.FindOrCreateUserByOpenIdReq{ OpenId: req.OpenId, ClientId: req.ClientId, }) if err != nil { return nil, fmt.Errorf("微信登录解析失败") } userResp, err := l.svcCtx.SystemRpc.GetUserById(l.ctx, &sysPb.GetUserByIdReq{ Id: profileResp.UserId, }) if err != nil { return nil, fmt.Errorf("用户不存在") } // 3. 如果需要更新手机号 phoneInfo, ok := dataMap["phone_info"].(map[string]interface{}) if ok { phoneNumber, _ := phoneInfo["phoneNumber"].(string) if phoneNumber != "" && userResp.User.Phone == "" { _, _ = l.svcCtx.SystemRpc.UpdateUser(l.ctx, &sysPb.UpdateUserReq{ Id: userResp.User.Id, Phone: phoneNumber, }) userResp.User.Phone = phoneNumber } } // 4. 生成Token(复用统一的 generateToken 函数) token, err := generateToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, userResp.User) if err != nil { return nil, fmt.Errorf("生成Token失败") } return &types.LoginResp{ Token: token, UserInfo: userResp.User, }, nil }