123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- // Copyright 2019 getensh.com. All rights reserved.
- // Use of this source code is governed by getensh.com.
- package user
- import (
- "context"
- "encoding/json"
- "fmt"
- "github.com/go-pay/gopay/wechat"
- "gorm.io/gorm"
- "property-household/errors"
- dbmodel "property-household/model"
- "property-household/pb"
- pb_v1 "property-household/pb/v1"
- "property-household/utils"
- "strings"
- "time"
- "git.getensh.com/common/gopkgs/database"
- "git.getensh.com/common/gopkgs/logger"
- "go.uber.org/zap"
- "google.golang.org/grpc/status"
- )
- // 后端测试使用写死,后期改为微信小程序登录
- func loginForTesting(phone string) (reply *pb_v1.LoginReply, err error) {
- user := &dbmodel.TUser{}
- where := map[string]interface{}{
- "phone": phone,
- }
- err = user.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return nil, errors.DataBaseError
- }
- if user.ID == 0 {
- return nil, errors.UserNotExist
- }
- reply = &pb_v1.LoginReply{Phone: phone, Uid: user.ID}
- reply.List, err = getHouses(user.ID)
- if err != nil {
- return nil, err
- }
- return reply, nil
- }
- func getGardenInfos(ids []int64) (map[int64]pb_v1.GardenItem, error) {
- ret := map[int64]pb_v1.GardenItem{}
- if len(ids) == 0 {
- return ret, nil
- }
- mreq := pb_v1.GardenInfosRequest{
- Ids: ids,
- }
- mreply, err := pb.System.GardenInfos(context.Background(), &mreq)
- if err != nil {
- return nil, err
- }
- for _, v := range mreply.List {
- ret[v.Id] = *v
- }
- return ret, nil
- }
- func getHouses(uid int64) ([]*pb_v1.HouseholdHouseInfo, error) {
- p := dbmodel.THouseApproved{}
- where := map[string]interface{}{
- "uid": uid,
- }
- list, err := p.List(database.DB(), where, nil, -1, -1)
- if err != nil {
- return nil, errors.DataBaseError
- }
- gardenIdsM := map[int64]bool{}
- gardenIds := []int64{}
- for _, v := range list {
- if gardenIdsM[v.GardenId] {
- continue
- }
- gardenIdsM[v.GardenId] = true
- gardenIds = append(gardenIds, v.GardenId)
- }
- gardenInfosM, err := getGardenInfos(gardenIds)
- if err != nil {
- return nil, err
- }
- ret := make([]*pb_v1.HouseholdHouseInfo, len(list))
- for i, v := range list {
- ret[i] = &pb_v1.HouseholdHouseInfo{
- Id: v.ID,
- GardenName: gardenInfosM[v.GardenId].GardenName,
- GardenId: v.GardenId,
- HouseId: v.HouseId,
- UserType: v.UserType,
- HouseName: fmt.Sprintf("%v-%v-%v", v.BuildingNumber, v.UnitNumber, v.HouseNumber),
- }
- }
- return ret, nil
- }
- func userChange(uid int64, userInfo dbmodel.TUser) (err error) {
- db := database.DB().Begin()
- defer func() {
- if err != nil {
- db.Rollback()
- }
- }()
- p1 := dbmodel.THouseApproved{}
- p2 := dbmodel.THouse{}
- where := map[string]interface{}{
- "uid": uid,
- }
- uvalues := map[string]interface{}{"updated_at": time.Now()}
- p1values := map[string]interface{}{}
- p2values := map[string]interface{}{}
- if userInfo.Phone != "" {
- uvalues["phone"] = userInfo.Phone
- p1values["phone"] = userInfo.Phone
- p2values["phone"] = userInfo.Phone
- }
- if userInfo.PublicOpenId != "" {
- uvalues["public_open_id"] = userInfo.PublicOpenId
- p1values["public_open_id"] = userInfo.PublicOpenId
- }
- if userInfo.NickName != "" {
- uvalues["nick_name"] = userInfo.NickName
- }
- if userInfo.IdNumber != "" {
- uvalues["id_number"] = userInfo.IdNumber
- p2values["id_number"] = userInfo.IdNumber
- }
- if userInfo.IdType != 0 {
- uvalues["id_type"] = userInfo.IdType
- p2values["id_type"] = userInfo.IdType
- }
- if userInfo.RealName != "" {
- uvalues["real_name"] = userInfo.RealName
- p2values["name"] = userInfo.RealName
- }
- u := dbmodel.TUser{}
- uwhere := map[string]interface{}{
- "id": uid,
- }
- err = u.Update(db, uwhere, uvalues)
- if err != nil {
- return errors.DataBaseError
- }
- approvedList, err := p1.List(database.DB(), where, nil, -1, -1)
- if err != nil {
- return errors.DataBaseError
- }
- if len(p1values) > 0 {
- p1values["updated_at"] = time.Now()
- err = p1.Update(db, where, p1values)
- if err != nil {
- return errors.DataBaseError
- }
- }
- if len(p2values) > 0 {
- p2values["updated_at"] = time.Now()
- err = p2.Update(db, where, p2values)
- if err != nil {
- return errors.DataBaseError
- }
- }
- mreq := pb_v1.HouseholdChangeRequest{
- Phone: userInfo.Phone,
- PublicOpenId: userInfo.PublicOpenId,
- Uid: uid,
- NickName: userInfo.NickName,
- Name: userInfo.RealName,
- IdType: userInfo.IdType,
- IdNumber: userInfo.IdNumber,
- }
- m := map[int64]bool{}
- for _, v := range approvedList {
- if m[v.GardenId] {
- continue
- }
- m[v.GardenId] = true
- mreq.GardenIds = append(mreq.GardenIds, v.GardenId)
- }
- m = nil
- if len(mreq.GardenIds) > 0 {
- _, err = pb.Garden.HouseholdChange(context.Background(), &mreq)
- if err != nil {
- return err
- }
- }
- db.Commit()
- return nil
- }
- func getPublicOpenId(unionId string) (string, error) {
- if unionId == "" {
- return "", nil
- }
- p := dbmodel.TUserWxPublic{}
- where := map[string]interface{}{
- "union_id": unionId,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return "", errors.DataBaseError
- }
- return p.OpenId, nil
- }
- func openimRegister(userId int64, realName string, phone string, face string, gender int32) string {
- if realName == "" {
- realName = phone
- }
- openimId := fmt.Sprintf("household%d", userId)
- mreq := pb_v1.OpenImRegisterRequest{UserId: openimId, Platform: 5, NickName: realName, FaceUrl: face, Gender: gender}
- _, err := pb.Thirdparty.OpenImRegister(context.Background(), &mreq)
- if err != nil {
- return ""
- }
- user := dbmodel.TUser{}
- where := map[string]interface{}{
- "id": userId,
- }
- values := map[string]interface{}{
- "openim_id": openimId,
- }
- err = user.Update(database.DB(), where, values)
- if err != nil {
- return ""
- }
- return openimId
- }
- // 手机号登录
- func Login(ctx context.Context, req *pb_v1.LoginRequest) (reply *pb_v1.LoginReply, err error) {
- reply = &pb_v1.LoginReply{}
- // 捕获各个task中的异常并返回给调用者
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("%+v", r)
- e := &status.Status{}
- if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
- logger.Error("err",
- zap.String("system_err", err.Error()),
- zap.Stack("stacktrace"))
- }
- }
- }()
- if false {
- return loginForTesting(req.Code)
- }
- if req.Code == "" || req.PhoneEncrypt == "" || req.PhoneIv == "" ||
- req.UserEncrypt == "" || req.UserIv == "" {
- return nil, errors.ParamsError
- }
- mreq := &pb_v1.WxAppletLoginAuthRequest{Code: req.Code}
- mreply, err := pb.Thirdparty.WxAppletLoginAuth(ctx, mreq)
- if err != nil {
- return nil, err
- }
- fmt.Printf("xxxxxxxxxxx:%v,%v,%v\n", mreply.SessionKey, mreply.OpenId, mreply.UnionId)
- // 解密手机和用户信息
- phoneInfo := wechat.UserPhone{}
- userInfo := wechat.AppletUserInfo{}
- err = wechat.DecryptOpenDataToStruct(req.PhoneEncrypt, req.PhoneIv, mreply.SessionKey, &phoneInfo)
- if err != nil {
- logger.Error("func",
- zap.String("call", "wechat.DecryptOpenDataToStruct1"),
- zap.String("params", fmt.Sprintf("%s,%s,%s", req.PhoneEncrypt, phoneInfo, mreply.SessionKey)),
- zap.String("error", err.Error()))
- return nil, status.Error(10003, "信息获取失败")
- }
- err = wechat.DecryptOpenDataToStruct(req.UserEncrypt, req.UserIv, mreply.SessionKey, &userInfo)
- if err != nil {
- logger.Error("func",
- zap.String("call", "wechat.DecryptOpenDataToStruct2"),
- zap.String("params", fmt.Sprintf("%s,%s,%s", req.UserEncrypt, req.UserIv, mreply.SessionKey)),
- zap.String("error", err.Error()))
- return nil, status.Error(10003, "信息获取失败")
- }
- user := &dbmodel.TUser{}
- where := map[string]interface{}{
- "open_id": mreply.OpenId,
- }
- err = user.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return nil, errors.DataBaseError
- }
- // 已存在,登录成功
- if user.ID > 0 {
- needChange := false
- publicOpendId := user.PublicOpenId
- if publicOpendId == "" {
- publicOpendId, err = getPublicOpenId(user.UnionId)
- if err != nil {
- return nil, err
- }
- needChange = true
- }
- if user.Phone != phoneInfo.PhoneNumber {
- needChange = true
- }
- if needChange {
- uinfo := dbmodel.TUser{Phone: phoneInfo.PhoneNumber, PublicOpenId: publicOpendId}
- err = userChange(user.ID, uinfo)
- if err != nil {
- return nil, err
- }
- }
- reply.OpenId = user.OpenId
- reply.Phone = phoneInfo.PhoneNumber
- reply.NickName = user.NickName
- reply.Uid = user.ID
- reply.RealName = user.RealName
- reply.Avatar = user.Avatar
- reply.List, err = getHouses(user.ID)
- reply.OpenimId = user.OpenimId
- if reply.OpenimId == "" {
- reply.OpenimId = openimRegister(user.ID, user.RealName, user.Phone, user.Avatar, user.Gender)
- }
- idNumber := ""
- if user.IdNumber != "" {
- idNumber = utils.CertDecrypt(user.IdNumber)
- }
- reply.IdNumber = idNumber
- return reply, nil
- }
- // 不存在
- publicOpendId, err := getPublicOpenId(mreply.UnionId)
- if err != nil {
- return nil, err
- }
- user.NickName = userInfo.NickName
- user.Phone = phoneInfo.PhoneNumber
- user.OpenId = mreply.OpenId
- user.UnionId = mreply.UnionId
- user.Avatar = userInfo.AvatarUrl
- user.PublicOpenId = publicOpendId
- user.Gender = int32(userInfo.Gender)
- err = user.Insert(database.DB())
- if err != nil {
- msg := strings.ToLower(err.Error())
- if strings.Contains(msg, "duplicate") {
- return nil, errors.ErrDuplicate
- }
- return nil, errors.DataBaseError
- }
- reply.OpenId = user.OpenId
- reply.Phone = user.Phone
- reply.NickName = user.NickName
- reply.Uid = user.ID
- reply.Avatar = userInfo.AvatarUrl
- reply.OpenimId = openimRegister(user.ID, user.NickName, user.Phone, user.Avatar, user.Gender)
- reply.IdNumber = ""
- return reply, nil
- }
|