micro-account/pkg/service/account.go
2025-02-24 20:46:14 +08:00

1094 lines
32 KiB
Go

package service
import (
"context"
"database/sql"
"dubbo.apache.org/dubbo-go/v3/common/logger"
_ "dubbo.apache.org/dubbo-go/v3/imports"
"errors"
"fmt"
"github.com/fonchain_enterprise/micro-account/api/account"
"github.com/fonchain_enterprise/micro-account/pkg/application"
"github.com/fonchain_enterprise/micro-account/pkg/cache"
"github.com/fonchain_enterprise/micro-account/pkg/common/jwt"
"github.com/fonchain_enterprise/micro-account/pkg/common/page"
"github.com/fonchain_enterprise/micro-account/pkg/common/redis_key"
"github.com/fonchain_enterprise/micro-account/pkg/common/utils"
"github.com/fonchain_enterprise/micro-account/pkg/common/verifica"
"github.com/fonchain_enterprise/micro-account/pkg/domain"
"github.com/fonchain_enterprise/micro-account/pkg/m"
"github.com/fonchain_enterprise/micro-account/pkg/model"
"github.com/fonchain_enterprise/micro-account/pkg/serializer"
"github.com/fonchain_enterprise/utils/mobile"
"github.com/go-redis/redis"
uuid2 "github.com/google/uuid"
"gorm.io/gorm"
"image"
"log"
"math"
rand2 "math/rand"
"strconv"
"strings"
"time"
)
type AccountProvider struct {
account.UnimplementedAccountServer
}
// OffLine 踢出
func (a *AccountProvider) OffLine(ctx context.Context, in *account.CommonRequest) (*account.CommonResponse, error) {
response := &account.CommonResponse{}
err := application.OffByLogId(in.ID)
if err != nil {
return nil, err
}
return response, nil
}
// Logout 登出
func (a *AccountProvider) Logout(ctx context.Context, in *account.DecryptJwtRequest) (*account.CommonResponse, error) {
response := &account.CommonResponse{}
err := application.Logout(in, model.Status_Out)
if err != nil {
return nil, err
}
return response, nil
}
// OnlineLogById 获取某个id的在线数据
func (a *AccountProvider) OnlineLogById(ctx context.Context, in *account.OnlineLogByIdRequest) (*account.LoginLog, error) {
response := &account.LoginLog{}
response, err := application.OnlineLogById(in.ID)
if err != nil {
return response, nil
}
return response, nil
}
// OnlineLog 获取某个人的在线数据
func (a *AccountProvider) OnlineLog(ctx context.Context, in *account.LoginInfosByUserIdRequest) (*account.LoginLogsResponse, error) {
response := &account.LoginLogsResponse{}
response.Data = application.OnlineLogList(in)
return response, nil
}
func (a *AccountProvider) Login(ctx context.Context, in *account.LoginRequest) (*account.TokenInfo, error) {
timeNow := time.Now()
tokenInfo := &account.TokenInfo{IsSampleAddress: true}
//nowIpAddress := ""
var user *model.User
if err := model.DB.Preload("RealName").Where(&model.User{TelNum: in.TelNum, Domain: &in.Domain}).First(&user).Error; err != nil {
return nil, errors.New(m.AccountDoesNotExist)
}
if in.Code == "" && in.Password == "" {
return nil, errors.New(m.ERRORCODE)
}
fmt.Println("---------------add1---", time.Now().Sub(timeNow))
if in.Code != "" {
str := cache.RedisClient.Get(redis_key.GetAccountKey(in.Domain, in.TelAreaCode+in.TelNum)) // 登陆检测
code := str.Val()
if code != in.Code {
return nil, errors.New(m.ERRORCODE)
}
}
fmt.Println("---------------add2---", time.Now().Sub(timeNow))
if in.Password != "" {
if !user.CheckPassword(in.Password) { //200毫秒
return nil, errors.New(m.ERRORPWD)
}
}
fmt.Println("---------------add3---", time.Now().Sub(timeNow))
//生成token
tokenTime := m.TokenTime
token, refreshToken, err := jwt.GenerateTotalToken(user.ID, in.Domain, tokenTime, user.TelNum, m.JWTSecret)
if err != nil {
logger.Error(err)
return nil, err
}
fmt.Println("---------------add4---", time.Now().Sub(timeNow))
if err := application.AddRefreshToken(refreshToken); err != nil {
logger.Error(err)
return nil, err
}
tokenInfo.Token = token
tokenInfo.RefreshToken = refreshToken
tokenInfo.AccountInfo = serializer.BuildUser(user)
fmt.Println("---------------add4---", time.Now().Sub(timeNow))
//tokenInfo.AccountInfo.NowLogId = application.LoginAddLog(user, token, in.Ip, nowIpAddress)
fmt.Println("---------------结束", time.Now().Sub(timeNow))
return tokenInfo, nil
}
func (a *AccountProvider) RefreshToken(_ context.Context, in *account.RefreshTokenRequest) (*account.TokenInfo, error) {
response := &account.TokenInfo{}
oldRefreshToken := in.RefreshToken
//验证
claims, err := jwt.ParseRefreshToken(oldRefreshToken, m.JWTSecret)
if err != nil {
return nil, err
}
var user *model.User
if err := model.DB.Preload("RealName").Where(&model.User{ID: claims.ID, Domain: &in.Domain}).First(&user).Error; err != nil {
return nil, errors.New(m.Not_Found)
}
//生成token
token, refreshToken, err := jwt.GenerateTotalToken(user.ID, in.Domain, m.TokenTime, user.TelNum, m.JWTSecret)
if err != nil {
logger.Error(err)
return nil, err
}
//refresh 是否合法
if err := application.CheckRefreshToke(oldRefreshToken); err != nil {
logger.Error(err)
return nil, err
}
//refresh 是否合法
if err := application.AddRefreshToken(refreshToken); err != nil {
logger.Error(err)
return nil, err
}
//nowIpAddress := application.GetIpAddressByIp(in.Ip) //400毫秒
//_ = application.LoginAddLog(user, token, in.Ip, nowIpAddress)
response.Token = token
response.RefreshToken = refreshToken
response.AccountInfo = serializer.BuildUser(user)
return response, nil
}
func (a *AccountProvider) OnlySendMsg(_ context.Context, in *account.SendMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
//telTodayNum := redis_key.GetAccountKeyCountToday(in.Domain, in.TelNum, in.Scope)
//校验(1-是否已经发送 2-是否今日发送超过指定数量)
/*str := cache.RedisClient.Get(redis_key.GetOnlyAccountKey(in.Domain, in.TelNum))
if str.Val() != "" {
return nil, errors.New(m.Mobile_Sended)
}
*/
if err := domain.CheckMsgPre(in.Domain, in.TelNum, in.Scope); err != nil {
return response, err
}
//执行发送 并且记录code
//code, err := verifica.SendMsg(in.TelNum, in.Project)
//兼容老代码
sigNo := in.SignNo
if sigNo == 0 {
sigNo = verifica.SIG_NO
if in.Project == "seller" {
sigNo = verifica.SIG_NO_SELLER
}
}
if in.MId == 0 {
in.MId = mobile.TMP1
}
code, err := verifica.SendCustomCode(in.TelNum, uint(in.MId), uint(sigNo))
if err != nil {
return nil, err
}
err = domain.SetOnlyRecordTelMsgCode(in.Domain, in.TelNum, code, in.Scope)
if err != nil {
return response, err
}
return response, nil
}
func (a *AccountProvider) OnlyCheckMsg(_ context.Context, in *account.CheckMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
fmt.Println(in)
str := cache.RedisClient.Get(redis_key.GetOnlyAccountKey(in.Domain, in.TelNum))
code := str.Val()
if code == "" {
return nil, errors.New(m.Mobile_Not_Send)
}
if code != in.GetCode() {
return nil, errors.New(m.Mobile_Wrong_Code)
}
return response, nil
}
// SendMsg 发送验证码
func (a *AccountProvider) SendMsg(_ context.Context, in *account.SendMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
//var user *model.User
if domain.InBlockList(in.Domain, in.TelNum) {
return nil, errors.New(m.Black_Mobile_Sended)
}
//if err := model.DB.Where(&model.User{TelNum: in.TelNum, Domain: &in.Domain}).First(&user).Error; err != nil {
// return nil, errors.New(m.Not_Found)
//}
//此处不再校验验证码有效期
//校验(1-是否已经发送 2-是否今日发送超过指定数量)
/*
str := cache.RedisClient.Get(redis_key.GetAccountKey(in.Domain, in.TelNum)) // 发送验证码
if str.Val() != "" {
return nil, errors.New(m.Mobile_Sended)
}
*/
//是否存活 (1分钟冷却) (1-是否已经发送 2-是否今日发送超过指定数量) 55秒
if err := domain.CodeLive(in.Domain, in.TelNum); err != nil {
return nil, err
}
//今日是否达到上限
if err := domain.CheckMsg(redis_key.GetAccountKeyCountToday(in.Domain, in.TelNum)); err != nil {
return nil, err
}
//执行发送 并且记录code
code, err := verifica.SendMsgV2(in.TelNum, in.Project, uint(in.SignNo))
if err != nil {
return nil, err
}
err = domain.SetRecordTelMsgCode(in.Domain, in.TelNum, code)
if err != nil {
return response, err
}
return response, nil
}
func (a *AccountProvider) SendMsgRegister(_ context.Context, in *account.SendMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
telTodayNum := redis_key.GetAccountKeyCountToday(in.Domain, in.TelNum)
// 手机号是否存在
var count int64
model.DB.Model(&model.User{}).Where(&model.User{TelNum: in.TelNum, Domain: &in.Domain}).Count(&count)
if count > 0 {
return response, errors.New(m.ACCOUNT_EXIST)
}
//校验(1-是否已经发送 2-是否今日发送超过指定数量)
if err := domain.CodeLive(in.Domain, in.TelNum); err != nil {
return nil, err
}
if err := domain.CheckMsg(telTodayNum); err != nil {
return nil, err
}
//执行发送 并且记录code
code, err := verifica.SendMsgV2(in.TelNum, in.Project, uint(in.SignNo))
if err != nil {
return nil, err
}
err = domain.SetRecordTelMsgCode(in.Domain, in.TelNum, code)
if err != nil {
return response, err
}
return response, nil
}
func (a *AccountProvider) CheckMsg(_ context.Context, in *account.CheckMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
str := cache.RedisClient.Get(redis_key.GetAccountKey(in.Domain, in.TelNum)) //校验验证码
code := str.Val()
if code == "" {
return nil, errors.New(m.Mobile_Not_Send)
}
if code != in.GetCode() {
return nil, errors.New(m.Mobile_Wrong_Code)
}
return response, nil
}
func (a *AccountProvider) RealName(_ context.Context, in *account.RealNameRequest) (*account.RealNameResponse, error) {
// 检查用户是否存在
var existingUser model.User
if err := model.DB.First(&existingUser, "id = ?", in.Id).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
// 如果用户已经实名
if existingUser.Status == m.Pass {
return &account.RealNameResponse{Status: m.FAILED}, errors.New("已实名")
}
// 如果实名审核中
if existingUser.Status == m.UnderReview {
return &account.RealNameResponse{Status: m.FAILED}, errors.New("实名审核中,请勿重复提交")
}
// 检查用户是否已关联实名信息
if existingUser.RealNameID == nil {
// 如果没有找到实名信息,创建一个新的 RealName 记录
newRealName := model.RealName{
Name: in.Name,
Sex: int(in.Sex),
Nationality: in.Nationality,
DocumentType: int(in.DocumentType),
CertificatePicture: in.CertificatePicture,
Validity: in.Validity,
PlaceOfResidence: in.PlaceOfResidence,
GroupPhoto: in.GroupPhoto,
Attachment: in.Attachment,
}
// 创建实名信息
if err := model.DB.Create(&newRealName).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
// 更新用户的实名信息 ID
existingUser.RealNameID = &newRealName.ID
existingUser.Status = m.UnderReview // 审核中状态
if err := model.DB.Save(&existingUser).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
// 返回成功
return &account.RealNameResponse{Status: m.SUCCESS}, nil
}
// 如果已存在实名信息,更新该信息
updateData := map[string]interface{}{
//"status": m.UnderReview, // 审核中状态
"name": in.Name,
"sex": in.Sex,
"nationality": in.Nationality,
"document_type": in.DocumentType,
"certificate_picture": in.CertificatePicture,
"validity": in.Validity,
"place_of_residence": in.PlaceOfResidence,
"group_photo": in.GroupPhoto,
"attachment": in.Attachment,
}
// 更新 RealName 表中的数据
var existingRealName model.RealName
if err := model.DB.First(&existingRealName, "id = ?", existingUser.RealNameID).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
if err := model.DB.Model(&existingUser).Update("status", m.UnderReview).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
if err := model.DB.Model(&existingRealName).Updates(updateData).Error; err != nil {
return &account.RealNameResponse{Status: m.FAILED}, err
}
return &account.RealNameResponse{Status: m.SUCCESS}, nil
}
func (a *AccountProvider) CheckRealName(ctx context.Context, in *account.CheckRealNameRequest) (*account.CheckRealNameResponse, error) {
// 根据用户 ID 查询用户
var user model.User
if err := model.DB.First(&user, "id = ?", in.Id).Error; err != nil {
return &account.CheckRealNameResponse{Status: m.FAILED}, err
}
// 只有当用户处于“审核中”状态时才能进行审核更新
if user.Status != m.UnderReview {
return &account.CheckRealNameResponse{Status: m.FAILED}, errors.New("用户状态异常,无法进行审核")
}
// 根据传入的审核结果更新用户状态和备注
if in.Pass {
user.Status = m.Pass
} else {
user.Status = m.AuditFailure
user.NotPassRemarks = in.NotPassRemarks
}
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
log.Fatalf("加载时区失败: %v", err)
}
user.AuditTime = time.Now().In(loc).Format("2006-01-02 15:04:05")
// 保存更新
if err := model.DB.Save(&user).Error; err != nil {
return &account.CheckRealNameResponse{Status: m.FAILED}, err
}
return &account.CheckRealNameResponse{Status: m.SUCCESS}, nil
}
// Register 注册
func (a *AccountProvider) Register(_ context.Context, in *account.RegistRequest) (*account.RegisterResponse, error) {
var err error
// 验证验证码
if in.Code == "" {
return &account.RegisterResponse{Status: m.Unknown}, errors.New(m.Mobile_Wrong_Code)
}
if err := domain.CheckRegisterCode(in.Domain, in.TelAreaCode+in.TelNum, in.Code); err != nil {
return &account.RegisterResponse{Status: m.Unknown}, errors.New(m.Mobile_Code_Wrong)
}
// 手机号是否已注册
var tempUser *model.User
if err := model.DB.Model(&model.User{}).Where(&model.User{TelNum: in.TelNum, Domain: &in.Domain}).First(&tempUser).Error; err == nil {
// 用户已存在
return &account.RegisterResponse{ID: uint64(tempUser.ID), Status: uint64(tempUser.Status)}, nil
} else if err != gorm.ErrRecordNotFound {
// 查询错误
return &account.RegisterResponse{Status: m.Unknown}, err
}
var subNum sql.NullString
if err := model.DB.Model(&model.User{}).Select("MAX(SUBSTRING(sub_num, 3, 6))").Row().Scan(&subNum); err != nil {
return &account.RegisterResponse{Status: m.Unknown}, err
}
var newNum int
if !subNum.Valid || subNum.String == "" {
// 如果没有用户,起始编号为 FE00001
newNum = 1
} else {
// 递增现有编号
parsedNum, err := strconv.Atoi(subNum.String)
if err != nil {
return &account.RegisterResponse{Status: m.Unknown}, err
}
newNum = parsedNum + 1
}
subNum.String = fmt.Sprintf("FE%05d", newNum)
//数据库中创建该用户记录
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
log.Fatalf("加载时区失败: %v", err)
}
user := model.User{
Domain: &in.Domain,
TelNum: in.TelNum,
Status: m.Unnamed,
TelAreaCode: in.TelAreaCode,
RegistrationTime: time.Now().In(loc).Format("2006-01-02 15:04:05"),
SubNum: subNum.String,
RealNameID: nil,
}
if err = model.DB.Create(&user).Error; err != nil {
return &account.RegisterResponse{Status: 0}, err
}
return &account.RegisterResponse{Status: uint64(user.Status), ID: uint64(user.ID)}, nil
}
// CheckPwd 检测密码是否正确
func (a *AccountProvider) CheckPwd(_ context.Context, in *account.CheckPwdRequest) (*account.UpdateResponse, error) {
response := &account.UpdateResponse{}
claims, err := jwt.ParseToken(in.Token, m.JWTSecret)
if err != nil {
return nil, err
}
//获取该用户信息
var user model.User
if err := model.DB.First(&user, claims.ID).Error; err != nil {
return response, err
}
if in.Password != "" {
if !user.CheckPassword(in.Password) {
return nil, errors.New(m.ERRORPWD)
}
}
return response, nil
}
func (a *AccountProvider) Authentication(_ context.Context, in *account.AuthenticationRequest) (*account.RequestStatus, error) {
claims, err := jwt.ParseToken(in.Token, m.JWTSecret)
if err != nil {
return nil, err
}
//获取该用户信息
var user model.User
if err := model.DB.First(&user, claims.ID).Error; err != nil {
logger.Error(err)
return &account.RequestStatus{Status: m.FAILED}, err
}
var realName model.RealName
//if user.RealNameID != 0 {
// if err := model.DB.First(&realName, user.RealNameID).Error; err != nil {
// logger.Error(err)
// return &account.RequestStatus{Status: m.FAILED}, err
// }
//}
//EncryptedIDNum, errCrypt := encryption.AesEncrypt([]byte(in.IDNum), strconv.Itoa(int(user.ID)))
//if errCrypt != nil {
// return &account.RequestStatus{Status: m.FAILED}, err
//}
realName.Name = in.Name
//realName.IDNum = base64.StdEncoding.EncodeToString(EncryptedIDNum)
//保存实名信息
if err := model.DB.Save(&realName).Error; err != nil {
logger.Error(err)
return &account.RequestStatus{Status: m.FAILED}, err
}
return &account.RequestStatus{Status: m.SUCCESS}, nil
}
func (a *AccountProvider) Info(ctx context.Context, in *account.InfoRequest) (*account.UserInfoResponse, error) {
//获取该用户信息
var user *model.User
if err := model.DB.Where(&model.User{Domain: &in.Domain}).Preload("RealName").First(&user, in.ID).Error; err != nil {
logger.Error(err)
return nil, err
}
realName := user.RealName
if realName == nil {
realName = &model.RealName{
Name: "",
Sex: 0,
Nationality: "",
DocumentType: 0,
CertificatePicture: "",
Validity: "",
PlaceOfResidence: "",
GroupPhoto: "",
Attachment: "",
}
}
response := &account.UserInfoResponse{
Id: uint64(user.ID),
Status: int32(user.Status),
Name: realName.Name,
Sex: int32(realName.Sex),
Nationality: realName.Nationality,
DocumentType: int32(realName.DocumentType),
CertificatePicture: realName.CertificatePicture,
Validity: realName.Validity,
PlaceOfResidence: realName.PlaceOfResidence,
GroupPhoto: realName.GroupPhoto,
Attachment: realName.Attachment,
SubNum: user.SubNum,
NotPassRemarks: user.NotPassRemarks,
}
return response, nil
}
func (a *AccountProvider) UserList(ctx context.Context, in *account.UserListRequest) (*account.UserListResponse, error) {
var count int64
var users []*model.User
modelObj := model.DB.Model(&model.User{}).Joins("RealName")
if in.Domain != "" {
modelObj.Where("domain = ? ", in.Domain)
}
if in.SubNum != "" {
modelObj.Where("sub_num like ? ", "%"+in.SubNum+"%")
}
if in.RealNameOrNot == 2 {
modelObj.Where("status = 1 ") //未实名
} else if in.RealNameOrNot == 1 {
modelObj.Where("status != 1 ") //已实名
}
if in.Name != "" {
modelObj.Where("RealName.name like ? ", "%"+in.Name+"%")
}
if in.DocumentType != 0 {
modelObj.Where("RealName.document_type = ? ", in.DocumentType)
}
if in.AuditStatus != 0 {
modelObj.Where("status = ? ", in.AuditStatus)
}
if in.Sex != 0 {
modelObj.Where("RealName.sex = ?", in.Sex)
}
modelObj.Count(&count)
if in.Page > 0 && in.PageSize > 0 {
modelObj.Limit(int(in.PageSize)).Offset(page.GetOffset(in.Page, in.PageSize))
}
modelObj.Preload("RealName").Find(&users)
response := &account.UserListResponse{}
response.UserList = serializer.BuildUserList(users)
response.Page = in.Page
response.PageSize = in.PageSize
response.Count = uint64(count)
return response, nil
}
// 艺术商城,发送国际短信验证码
func (a *AccountProvider) SendNationMsg(_ context.Context, in *account.SendNationMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
// var user *model.User
if domain.InBlockList(in.Domain, in.TelNum) {
return nil, errors.New(m.Black_Mobile_Sended)
}
// if err := model.DB.Where(&model.User{TelNum: in.TelNum, Domain: &in.Domain}).First(&user).Error; err != nil {
// return nil, errors.New(m.Not_Found)
// }
//此处不再校验验证码有效期
//校验(1-是否已经发送 2-是否今日发送超过指定数量)
/*
str := cache.RedisClient.Get(redis_key.GetAccountKey(in.Domain, in.TelNum)) // 发送验证码
if str.Val() != "" {
return nil, errors.New(m.Mobile_Sended)
}
*/
code := mobile.RandCode()
//是否存活 (1分钟冷却) (1-是否已经发送 2-是否今日发送超过指定数量) 55秒
if err := domain.CodeLive(in.Domain, in.TelNum); err != nil {
return nil, err
}
//今日是否达到上限
if err := domain.CheckMsg(redis_key.GetAccountKeyCountToday(in.Domain, in.TelNum)); err != nil {
return nil, err
}
//执行发送 并且记录code
err := verifica.SendNationMsg(in.TelNum, fmt.Sprintf("FiEE||%s", code), 0)
if err != nil {
return nil, err
}
err = domain.SetRecordTelMsgCode(in.Domain, in.TelNum, code)
if err != nil {
return response, err
}
return response, nil
}
func (a *AccountProvider) GenerateSliderCaptcha(_ context.Context, in *account.GenerateSliderCaptchaRequest) (*account.GenerateSliderCaptchaResponse, error) {
captcha := &model.Captcha{
CanvasWidth: int(in.CanvasWidth),
CanvasHeight: int(in.CanvasHeight),
BlockWidth: int(in.BlockWidth),
BlockHeight: int(in.BlockHeight),
Place: int(in.Place),
}
err := model.CheckCaptcha(captcha)
if err != nil {
return nil, err
}
canvasWidth := captcha.CanvasWidth
canvasHeight := captcha.CanvasHeight
blockWidth := captcha.BlockWidth
blockHeight := captcha.BlockHeight
//blockRadius := captcha.BlockRadius
place := captcha.Place
img, _ := utils.GetBufferedImage(place)
canvasImage := utils.ImageResize(img, canvasWidth, canvasHeight).(*image.RGBA)
blockX := utils.GetNonceByRange(blockWidth, canvasWidth-blockWidth-10)
blockY := utils.GetNonceByRange(10, canvasHeight-blockHeight+1)
blockImage := image.NewRGBA(image.Rect(0, 0, blockWidth, blockHeight))
utils.CutByTemplate(canvasImage, blockImage, blockWidth, blockHeight, blockX, blockY)
fmt.Println("1---", 0)
fmt.Println("2---", blockY)
fmt.Println("2---", blockX)
// 生成UUID
nonceStr := fmt.Sprintf("%x", rand2.New(rand2.NewSource(time.Now().UnixNano())).Uint64())
// 保存X轴像素
cache.RedisClient.Set("imageCode:"+nonceStr, blockX, 15*time.Minute)
resp := &account.GenerateSliderCaptchaResponse{
NonceStr: nonceStr,
CanvasSrc: utils.ToBase64(canvasImage, "png"),
BlockSrc: utils.ToBase64(blockImage, "png"),
BlockY: uint64(blockY),
FaceY: 0,
//BlockX: uint64(blockX),
}
return resp, nil
}
func (a *AccountProvider) VerifySliderCaptcha(_ context.Context, in *account.VerifySliderCaptchaRequest) (*account.VerifySliderCaptchaResponse, error) {
resp := &account.VerifySliderCaptchaResponse{}
// 检查图像验证码
text, err := cache.RedisClient.Get("imageCode:" + in.NonceStr).Result()
if err == redis.Nil {
err = errors.New("验证码已失效")
return resp, err
} else if err != nil {
err = errors.New("服务器错误")
return resp, err
}
if utils.Abs(utils.ParseInt(text)-int(math.Round(float64(in.BlockX)))) > m.AllowDeviation {
err = errors.New("验证失败,请控制拼图对齐缺口")
return resp, err
}
err = cache.RedisClient.Set("SliderStatus:"+in.NonceStr, "unused", 15*time.Minute).Err()
if err != nil {
return resp, err
}
resp.NonceStr = in.NonceStr
return resp, nil
}
func (a *AccountProvider) DecryptJwt(_ context.Context, in *account.DecryptJwtRequest) (*account.DecryptJwtResponse, error) {
//默认在线
fmt.Println()
isOffline := false
claims, err := jwt.ParseToken(in.Token, m.JWTSecret)
if err != nil {
return nil, err
}
tokenKey := redis_key.GetTokenInfo(in.Domain, in.Token)
num, err := cache.RedisClient.Exists(tokenKey).Result()
if num <= 0 { //不存在则下线
isOffline = true
}
//获取该用户信息
response := &account.DecryptJwtResponse{
ID: uint64(claims.ID),
Account: claims.Account,
Domain: claims.Domain,
NickName: claims.NickName,
IsOffline: isOffline,
}
//更新下活跃时间
application.UpdateLastDate(in.Token)
return response, nil
}
func (a *AccountProvider) UserByTel(_ context.Context, in *account.UserByTelRequest) (*account.UserInfoResponse, error) {
response := &account.UserInfoResponse{}
var user *model.User
if err := model.DB.Model(&model.User{}).Preload("RealName").Where(&model.User{Domain: &in.Domain, TelNum: in.Tel}).First(&user).Error; err != nil {
if err.Error() == "record not found" { //不存在
return response, nil
}
return response, err
}
realName := user.RealName
if realName == nil {
realName = &model.RealName{
Name: "",
Sex: 0,
Nationality: "",
DocumentType: 0,
CertificatePicture: "",
Validity: "",
PlaceOfResidence: "",
GroupPhoto: "",
Attachment: "",
}
}
response = &account.UserInfoResponse{
Id: uint64(user.ID),
Status: int32(user.Status),
Name: realName.Name,
Sex: int32(realName.Sex),
Nationality: realName.Nationality,
DocumentType: int32(realName.DocumentType),
CertificatePicture: realName.CertificatePicture,
Validity: realName.Validity,
PlaceOfResidence: realName.PlaceOfResidence,
GroupPhoto: realName.GroupPhoto,
Attachment: realName.Attachment,
SubNum: user.SubNum,
NotPassRemarks: user.NotPassRemarks,
Domain: *user.Domain,
}
return response, nil
}
func (a *AccountProvider) UsersByTel(_ context.Context, in *account.UsersByTelRequest) (*account.ListResponse, error) {
response := &account.ListResponse{}
if len(in.Tels) == 0 {
return response, nil
}
var users []*model.User
model.DB.Model(&model.User{}).Where(&model.User{Domain: &in.Domain}).Where("tel_num in (?)", in.Tels).Find(&users)
response.Data = serializer.BuildUsers(users)
response.Count = uint64(len(users))
return response, nil
}
func (a *AccountProvider) ListByIDs(_ context.Context, in *account.ListByIDsRequest) (*account.ListResponse, error) {
var count int64
//获取该用户信息
//var user model.User
var users []*model.User
modelObj := model.DB.Model(&model.User{}).Preload("Clocks.Device")
if len(in.IDs) > 0 {
modelObj.Where("id in ? ", in.IDs)
}
if in.NickName != "" {
modelObj.Where("nickname like ?", "%"+in.NickName+"%")
}
if len(in.InvitationCode) > 0 {
modelObj.Where("invitation_code in (?)", in.InvitationCode)
}
modelObj.Count(&count)
if in.Page > 0 && in.PageSize > 0 {
modelObj.Limit(int(in.PageSize)).Offset(page.GetOffset(in.Page, in.PageSize))
}
if in.OrderType == 1 {
modelObj.Order("id desc")
} else if in.OrderType == 2 {
modelObj.Order("enter_date asc")
}
//modelObj.Find(&users, in.IDs)
modelObj.Find(&users)
response := &account.ListResponse{}
response.Data = serializer.BuildUsers(users)
response.Count = uint64(count)
return response, nil
}
func (a *AccountProvider) RandList(_ context.Context, in *account.ListRequest) (*account.ListResponse, error) {
//获取该用户信息
//var user model.User
users, count := model.RandList(in.Domain, int(in.PageSize))
response := &account.ListResponse{}
response.Data = serializer.BuildUsers(users)
response.Count = uint64(count)
response.AllCount = uint64(model.DomainCount(in.Domain))
return response, nil
}
func (a *AccountProvider) Remove(_ context.Context, in *account.RemoveRequest) (*account.RemoveResponse, error) {
response := &account.RemoveResponse{}
err := model.DB.Transaction(func(tx *gorm.DB) error {
var err error
//删除个人
if err = model.DB.Where(&model.User{Domain: &in.Domain}).Delete(&model.User{}, in.ID).Error; err != nil {
return err
}
return nil
})
return response, err
}
// SendNewTelNumMsg 给新手机号发送验证码
func (a *AccountProvider) SendNewTelNumMsg(_ context.Context, in *account.SendNewTelNumMsgRequest) (*account.SendMsgStatusResponse, error) {
var user *model.User
response := &account.SendMsgStatusResponse{}
if err := model.DB.First(&user, in.ID).Error; err != nil {
return response, errors.New(m.Not_Found)
}
if in.NewTelNum == "" { //新手机号是空,则去redis中查询上次的手机号
newTelNum, err := user.NowNewTelNum()
if err != nil {
return response, err
}
in.NewTelNum = newTelNum
}
err := user.SendNewTelMsg(in.NewTelNum, in.Project, uint(in.SignNo))
return response, err
}
// UpdateTelNum 更新新手机号
func (a *AccountProvider) UpdateTelNum(_ context.Context, in *account.SendNewTelNumMsgRequest) (*account.SendMsgStatusResponse, error) {
var user *model.User
response := &account.SendMsgStatusResponse{}
if err := model.DB.First(&user, in.ID).Error; err != nil {
return response, errors.New(m.Not_Found)
}
err := user.ChangeNewTel(in.Code)
return response, err
}
func (a *AccountProvider) SendCustomMsg(ctx context.Context, in *account.SendCustomMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
var user *model.User
uuid := uuid2.NewString()
logger.Info(uuid, ",发送自定义短信手机号", in.TelNum, "连接地址", in.Url)
if err := model.DB.Model(&model.User{}).First(&user, in.ID).Error; err != nil {
logger.Info(uuid, ",错误", err.Error())
return nil, errors.New(m.Not_Found)
}
//执行发送 并且记录code
fmt.Println("接收短信", in.Url, in)
in.Url = strings.Replace(in.Url, "|", "||", 1)
telNum := in.TelNum
if _, ok := model.SendPhoneNum[user.TelNum]; ok {
telNum = model.SendPhoneNum[user.TelNum]
}
if telNum == "" {
telNum = user.TelNum
}
err := verifica.SendCustomMsg(telNum, in.Url, uint(in.MId))
return response, err
}
func (a *AccountProvider) SendExCustomMsg(ctx context.Context, in *account.SendCustomMsgRequest) (*account.SendMsgStatusResponse, error) {
response := &account.SendMsgStatusResponse{}
fmt.Println("对外的发送短信参数:", in.TelNum, in.Url, in.MId)
err := verifica.SendCustomSignNoMsg(in.TelNum, in.Url, uint(in.MId), uint(in.SigNo))
return response, err
}
func (a *AccountProvider) MailAccountByNickName(_ context.Context, in *account.MailAccountByNickNameRequest) (*account.MaiAccountResponse, error) {
var err error
response := &account.MaiAccountResponse{}
//response.EnglishName, response.MailAccount, err = model.GetMailAndEnglishNameByNickName(in.NickName, in.Domain, in.ID)
return response, err
}
func (a *AccountProvider) QueryPersonnelWithTheSameName(_ context.Context, req *account.QueryPersonnelWithTheSameNameRequest) (*account.QueryPersonnelWithTheSameNameResponse, error) {
var duplicateNames []string
query := model.DB.Table("user").
Select("nickname").
Group("nickname").
Having("COUNT(nickname) >= ?", 2)
if len(req.Names) != 0 {
query.Where("nickname in (?)", req.Names)
}
if req.Domain != "" {
query.Where("domain = ?", req.Domain)
}
if req.Status != "" {
query.Where("status = ?", req.Status)
}
query.Where("deleted_at = 0")
if err := query.Pluck("nickname", &duplicateNames).Error; err != nil {
return nil, errors.New(m.Not_Found)
}
response := &account.QueryPersonnelWithTheSameNameResponse{
Names: duplicateNames,
Count: uint64(len(duplicateNames)),
}
return response, nil
}
func (a *AccountProvider) UsersByJobNum(_ context.Context, in *account.UsersByJobNumRequest) (*account.ListResponse, error) {
response := &account.ListResponse{}
if len(in.JobNum) == 0 {
return response, nil
}
var users []*model.User
model.DB.Model(&model.User{}).Where(&model.User{Domain: &in.Domain}).Where("job_num in (?)", in.JobNum).Find(&users)
response.Data = serializer.BuildUsers(users)
response.Count = uint64(len(users))
return response, nil
}