login.go 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // Copyright 2019 getensh.com. All rights reserved.
  2. // Use of this source code is governed by getensh.com.
  3. package user
  4. import (
  5. "context"
  6. "encoding/json"
  7. "fmt"
  8. "github.com/go-pay/gopay/wechat"
  9. "gorm.io/gorm"
  10. "property-household/errors"
  11. dbmodel "property-household/model"
  12. "property-household/pb"
  13. pb_v1 "property-household/pb/v1"
  14. "property-household/utils"
  15. "strings"
  16. "time"
  17. "git.getensh.com/common/gopkgs/database"
  18. "git.getensh.com/common/gopkgs/logger"
  19. "go.uber.org/zap"
  20. "google.golang.org/grpc/status"
  21. )
  22. // 后端测试使用写死,后期改为微信小程序登录
  23. func loginForTesting(phone string) (reply *pb_v1.LoginReply, err error) {
  24. user := &dbmodel.TUser{}
  25. where := map[string]interface{}{
  26. "phone": phone,
  27. }
  28. err = user.Find(database.DB(), where)
  29. if err != nil && err != gorm.ErrRecordNotFound {
  30. return nil, errors.DataBaseError
  31. }
  32. if user.ID == 0 {
  33. return nil, errors.UserNotExist
  34. }
  35. reply = &pb_v1.LoginReply{Phone: phone, Uid: user.ID}
  36. reply.List, err = getHouses(user.ID)
  37. if err != nil {
  38. return nil, err
  39. }
  40. return reply, nil
  41. }
  42. func getGardenInfos(ids []int64) (map[int64]pb_v1.GardenItem, error) {
  43. ret := map[int64]pb_v1.GardenItem{}
  44. if len(ids) == 0 {
  45. return ret, nil
  46. }
  47. mreq := pb_v1.GardenInfosRequest{
  48. Ids: ids,
  49. }
  50. mreply, err := pb.System.GardenInfos(context.Background(), &mreq)
  51. if err != nil {
  52. return nil, err
  53. }
  54. for _, v := range mreply.List {
  55. ret[v.Id] = *v
  56. }
  57. return ret, nil
  58. }
  59. func getHouses(uid int64) ([]*pb_v1.HouseholdHouseInfo, error) {
  60. p := dbmodel.THouseApproved{}
  61. where := map[string]interface{}{
  62. "uid": uid,
  63. }
  64. list, err := p.List(database.DB(), where, nil, -1, -1)
  65. if err != nil {
  66. return nil, errors.DataBaseError
  67. }
  68. gardenIdsM := map[int64]bool{}
  69. gardenIds := []int64{}
  70. for _, v := range list {
  71. if gardenIdsM[v.GardenId] {
  72. continue
  73. }
  74. gardenIdsM[v.GardenId] = true
  75. gardenIds = append(gardenIds, v.GardenId)
  76. }
  77. gardenInfosM, err := getGardenInfos(gardenIds)
  78. if err != nil {
  79. return nil, err
  80. }
  81. ret := make([]*pb_v1.HouseholdHouseInfo, len(list))
  82. for i, v := range list {
  83. ret[i] = &pb_v1.HouseholdHouseInfo{
  84. Id: v.ID,
  85. GardenName: gardenInfosM[v.GardenId].GardenName,
  86. GardenId: v.GardenId,
  87. HouseId: v.HouseId,
  88. UserType: v.UserType,
  89. HouseName: fmt.Sprintf("%v-%v-%v", v.BuildingNumber, v.UnitNumber, v.HouseNumber),
  90. }
  91. }
  92. return ret, nil
  93. }
  94. func userChange(uid int64, userInfo dbmodel.TUser) (err error) {
  95. db := database.DB().Begin()
  96. defer func() {
  97. if err != nil {
  98. db.Rollback()
  99. }
  100. }()
  101. p1 := dbmodel.THouseApproved{}
  102. p2 := dbmodel.THouse{}
  103. where := map[string]interface{}{
  104. "uid": uid,
  105. }
  106. uvalues := map[string]interface{}{"updated_at": time.Now()}
  107. p1values := map[string]interface{}{}
  108. p2values := map[string]interface{}{}
  109. if userInfo.Phone != "" {
  110. uvalues["phone"] = userInfo.Phone
  111. p1values["phone"] = userInfo.Phone
  112. p2values["phone"] = userInfo.Phone
  113. }
  114. if userInfo.PublicOpenId != "" {
  115. uvalues["public_open_id"] = userInfo.PublicOpenId
  116. p1values["public_open_id"] = userInfo.PublicOpenId
  117. }
  118. if userInfo.NickName != "" {
  119. uvalues["nick_name"] = userInfo.NickName
  120. }
  121. if userInfo.IdNumber != "" {
  122. uvalues["id_number"] = userInfo.IdNumber
  123. p2values["id_number"] = userInfo.IdNumber
  124. }
  125. if userInfo.IdType != 0 {
  126. uvalues["id_type"] = userInfo.IdType
  127. p2values["id_type"] = userInfo.IdType
  128. }
  129. if userInfo.RealName != "" {
  130. uvalues["real_name"] = userInfo.RealName
  131. p2values["name"] = userInfo.RealName
  132. }
  133. u := dbmodel.TUser{}
  134. uwhere := map[string]interface{}{
  135. "id": uid,
  136. }
  137. err = u.Update(db, uwhere, uvalues)
  138. if err != nil {
  139. return errors.DataBaseError
  140. }
  141. approvedList, err := p1.List(database.DB(), where, nil, -1, -1)
  142. if err != nil {
  143. return errors.DataBaseError
  144. }
  145. if len(p1values) > 0 {
  146. p1values["updated_at"] = time.Now()
  147. err = p1.Update(db, where, p1values)
  148. if err != nil {
  149. return errors.DataBaseError
  150. }
  151. }
  152. if len(p2values) > 0 {
  153. p2values["updated_at"] = time.Now()
  154. err = p2.Update(db, where, p2values)
  155. if err != nil {
  156. return errors.DataBaseError
  157. }
  158. }
  159. mreq := pb_v1.HouseholdChangeRequest{
  160. Phone: userInfo.Phone,
  161. PublicOpenId: userInfo.PublicOpenId,
  162. Uid: uid,
  163. NickName: userInfo.NickName,
  164. Name: userInfo.RealName,
  165. IdType: userInfo.IdType,
  166. IdNumber: userInfo.IdNumber,
  167. }
  168. m := map[int64]bool{}
  169. for _, v := range approvedList {
  170. if m[v.GardenId] {
  171. continue
  172. }
  173. m[v.GardenId] = true
  174. mreq.GardenIds = append(mreq.GardenIds, v.GardenId)
  175. }
  176. m = nil
  177. if len(mreq.GardenIds) > 0 {
  178. _, err = pb.Garden.HouseholdChange(context.Background(), &mreq)
  179. if err != nil {
  180. return err
  181. }
  182. }
  183. db.Commit()
  184. return nil
  185. }
  186. func getPublicOpenId(unionId string) (string, error) {
  187. if unionId == "" {
  188. return "", nil
  189. }
  190. p := dbmodel.TUserWxPublic{}
  191. where := map[string]interface{}{
  192. "union_id": unionId,
  193. }
  194. err := p.Find(database.DB(), where)
  195. if err != nil && err != gorm.ErrRecordNotFound {
  196. return "", errors.DataBaseError
  197. }
  198. return p.OpenId, nil
  199. }
  200. func openimRegister(userId int64, realName string, phone string, face string, gender int32) string {
  201. if realName == "" {
  202. realName = phone
  203. }
  204. openimId := fmt.Sprintf("household%d", userId)
  205. mreq := pb_v1.OpenImRegisterRequest{UserId: openimId, Platform: 5, NickName: realName, FaceUrl: face, Gender: gender}
  206. _, err := pb.Thirdparty.OpenImRegister(context.Background(), &mreq)
  207. if err != nil {
  208. return ""
  209. }
  210. user := dbmodel.TUser{}
  211. where := map[string]interface{}{
  212. "id": userId,
  213. }
  214. values := map[string]interface{}{
  215. "openim_id": openimId,
  216. }
  217. err = user.Update(database.DB(), where, values)
  218. if err != nil {
  219. return ""
  220. }
  221. return openimId
  222. }
  223. // 手机号登录
  224. func Login(ctx context.Context, req *pb_v1.LoginRequest) (reply *pb_v1.LoginReply, err error) {
  225. reply = &pb_v1.LoginReply{}
  226. // 捕获各个task中的异常并返回给调用者
  227. defer func() {
  228. if r := recover(); r != nil {
  229. err = fmt.Errorf("%+v", r)
  230. e := &status.Status{}
  231. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  232. logger.Error("err",
  233. zap.String("system_err", err.Error()),
  234. zap.Stack("stacktrace"))
  235. }
  236. }
  237. }()
  238. if false {
  239. return loginForTesting(req.Code)
  240. }
  241. if req.Code == "" || req.PhoneEncrypt == "" || req.PhoneIv == "" ||
  242. req.UserEncrypt == "" || req.UserIv == "" {
  243. return nil, errors.ParamsError
  244. }
  245. mreq := &pb_v1.WxAppletLoginAuthRequest{Code: req.Code}
  246. mreply, err := pb.Thirdparty.WxAppletLoginAuth(ctx, mreq)
  247. if err != nil {
  248. return nil, err
  249. }
  250. fmt.Printf("xxxxxxxxxxx:%v,%v,%v\n", mreply.SessionKey, mreply.OpenId, mreply.UnionId)
  251. // 解密手机和用户信息
  252. phoneInfo := wechat.UserPhone{}
  253. userInfo := wechat.AppletUserInfo{}
  254. err = wechat.DecryptOpenDataToStruct(req.PhoneEncrypt, req.PhoneIv, mreply.SessionKey, &phoneInfo)
  255. if err != nil {
  256. logger.Error("func",
  257. zap.String("call", "wechat.DecryptOpenDataToStruct1"),
  258. zap.String("params", fmt.Sprintf("%s,%s,%s", req.PhoneEncrypt, phoneInfo, mreply.SessionKey)),
  259. zap.String("error", err.Error()))
  260. return nil, status.Error(10003, "信息获取失败")
  261. }
  262. err = wechat.DecryptOpenDataToStruct(req.UserEncrypt, req.UserIv, mreply.SessionKey, &userInfo)
  263. if err != nil {
  264. logger.Error("func",
  265. zap.String("call", "wechat.DecryptOpenDataToStruct2"),
  266. zap.String("params", fmt.Sprintf("%s,%s,%s", req.UserEncrypt, req.UserIv, mreply.SessionKey)),
  267. zap.String("error", err.Error()))
  268. return nil, status.Error(10003, "信息获取失败")
  269. }
  270. user := &dbmodel.TUser{}
  271. where := map[string]interface{}{
  272. "open_id": mreply.OpenId,
  273. }
  274. err = user.Find(database.DB(), where)
  275. if err != nil && err != gorm.ErrRecordNotFound {
  276. return nil, errors.DataBaseError
  277. }
  278. // 已存在,登录成功
  279. if user.ID > 0 {
  280. needChange := false
  281. publicOpendId := user.PublicOpenId
  282. if publicOpendId == "" {
  283. publicOpendId, err = getPublicOpenId(user.UnionId)
  284. if err != nil {
  285. return nil, err
  286. }
  287. needChange = true
  288. }
  289. if user.Phone != phoneInfo.PhoneNumber {
  290. needChange = true
  291. }
  292. if needChange {
  293. uinfo := dbmodel.TUser{Phone: phoneInfo.PhoneNumber, PublicOpenId: publicOpendId}
  294. err = userChange(user.ID, uinfo)
  295. if err != nil {
  296. return nil, err
  297. }
  298. }
  299. reply.OpenId = user.OpenId
  300. reply.Phone = phoneInfo.PhoneNumber
  301. reply.NickName = user.NickName
  302. reply.Uid = user.ID
  303. reply.RealName = user.RealName
  304. reply.Avatar = user.Avatar
  305. reply.List, err = getHouses(user.ID)
  306. reply.OpenimId = user.OpenimId
  307. if reply.OpenimId == "" {
  308. reply.OpenimId = openimRegister(user.ID, user.RealName, user.Phone, user.Avatar, user.Gender)
  309. }
  310. idNumber := ""
  311. if user.IdNumber != "" {
  312. idNumber = utils.CertDecrypt(user.IdNumber)
  313. }
  314. reply.IdNumber = idNumber
  315. return reply, nil
  316. }
  317. // 不存在
  318. publicOpendId, err := getPublicOpenId(mreply.UnionId)
  319. if err != nil {
  320. return nil, err
  321. }
  322. user.NickName = userInfo.NickName
  323. user.Phone = phoneInfo.PhoneNumber
  324. user.OpenId = mreply.OpenId
  325. user.UnionId = mreply.UnionId
  326. user.Avatar = userInfo.AvatarUrl
  327. user.PublicOpenId = publicOpendId
  328. user.Gender = int32(userInfo.Gender)
  329. err = user.Insert(database.DB())
  330. if err != nil {
  331. msg := strings.ToLower(err.Error())
  332. if strings.Contains(msg, "duplicate") {
  333. return nil, errors.ErrDuplicate
  334. }
  335. return nil, errors.DataBaseError
  336. }
  337. reply.OpenId = user.OpenId
  338. reply.Phone = user.Phone
  339. reply.NickName = user.NickName
  340. reply.Uid = user.ID
  341. reply.Avatar = userInfo.AvatarUrl
  342. reply.OpenimId = openimRegister(user.ID, user.NickName, user.Phone, user.Avatar, user.Gender)
  343. reply.IdNumber = ""
  344. return reply, nil
  345. }