You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
4.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package biz
import (
"context"
"database/sql"
"github.com/go-kratos/kratos/v2/errors"
"github.com/golang-jwt/jwt/v4"
"gorm.io/gorm"
"regexp"
"strings"
"time"
)
const SecretKey = "driver secret key"
// 司机业务逻辑
type DriverBiz struct {
DI DriverInterface
}
// 司机表模型
type Driver struct {
// 基础模型
gorm.Model
// 业务模型
DriverWork
// 关联部分
}
// 司机的业务模型
type DriverWork struct {
Telephone string `gorm:"type:varchar(16);uniqueIndex;" json:"telephone"`
Token sql.NullString `gorm:"type:varchar(2047);" json:"token"`
Status sql.NullString `gorm:"type:enum('out', 'in', 'listen', 'stop');" json:"status"`
Name sql.NullString `gorm:"type:varchar(255);index;" json:"name"`
IdNumber sql.NullString `gorm:"type:char(18);uniqueIndex;" json:"id_number"`
IdImageA sql.NullString `gorm:"type:varchar(255);" json:"id_image_a"`
LicenseImageA sql.NullString `gorm:"type:varchar(255);" json:"license_image_a"`
LicenseImageB sql.NullString `gorm:"type:varchar(255);" json:"license_image_b"`
DistinctCode sql.NullString `gorm:"type:varchar(16);index;" json:"distinct_code"`
TelephoneBak sql.NullString `gorm:"type:varchar(16);index;" json:"telephone_bak"`
AuditAt sql.NullTime `gorm:"index;" json:"audit_at"`
}
// 司机状态常量
const DriverStatusOut = "out"
const DriverStatusIn = "in"
const DriverStatusListen = "listen"
const DriverStatusStop = "stop"
const DriverTokenLife = 1 * 30 * 24 * 3600
// 司机相关的资源操作接口
type DriverInterface interface {
GetVerifyCode(context.Context, string) (string, error)
FetchVerifyCode(context.Context, string) (string, error)
FetchInfoByTel(context.Context, string) (*Driver, error)
InitDriverInfo(context.Context, string) (*Driver, error)
GetSavedVerifyCode(context.Context, string) (string, error)
SaveToken(context.Context, string, string) error
GetToken(context.Context, string) (string, error)
}
// DriverBiz 构造器
func NewDriverBiz(di DriverInterface) *DriverBiz {
return &DriverBiz{
DI: di,
}
}
// 验证登录信息方法
func (db *DriverBiz) CheckLogin(ctx context.Context, tel, verifyCode string) (string, error) {
// 验证验证码是否正确
code, err := db.DI.GetSavedVerifyCode(ctx, tel)
if err != nil {
return "", err
}
if verifyCode != code {
return "", errors.New(1, "verify code error", "'")
}
// 生成token
token, err := generateJWT(tel)
if err != nil {
return "", err
}
// 存储到driver表中
if err := db.DI.SaveToken(ctx, tel, token); err != nil {
return "", err
}
// 返回token
return token, nil
}
// 生成JWT
func generateJWT(tel string) (string, error) {
// 构建token类型
claims := jwt.RegisteredClaims{
Issuer: "LaomaDJ",
Subject: "driver authentication",
Audience: []string{"driver"},
ExpiresAt: jwt.NewNumericDate(time.Now().Add(DriverTokenLife * time.Second)),
NotBefore: nil,
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: tel,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 签名
// 生成token字符串
tokenString, err := token.SignedString([]byte(SecretKey))
if err != nil {
return "", err
}
return tokenString, nil
}
// 比对验证码是否一致
// 将司机信息入库
func (db *DriverBiz) InitDriverInfo(ctx context.Context, tel string) (*Driver, error) {
// 校验验证码(略)
// 司机是否已经注册的校验(略)?
// 司机是否在黑名单中校验(略)?
//
if tel == "" {
return nil, errors.New(1, "telephone is empty", "")
}
return db.DI.InitDriverInfo(ctx, tel)
}
// 实现获取验证码的业务逻辑
func (db *DriverBiz) GetVerifyCode(ctx context.Context, tel string) (string, error) {
// 一,校验手机号
pattern := `^(13\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\d|19[0-35-9])\d{8}$`
regexpPattern := regexp.MustCompile(pattern)
if !regexpPattern.MatchString(tel) {
return "", errors.New(200, "DRIVER", "driver telephone error")
}
// 二调用data/获取验证码
return db.DI.GetVerifyCode(ctx, tel)
}
func (db *DriverBiz) CheckVerifyCode(ctx context.Context, tel, code string) bool {
// 一,校验手机号
pattern := `^(13\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\d|19[0-35-9])\d{8}$`
regexpPattern := regexp.MustCompile(pattern)
if !regexpPattern.MatchString(tel) {
return false
}
code = strings.TrimSpace(code)
if len(code) == 0 {
return false
}
verifyCode, err := db.DI.FetchVerifyCode(ctx, tel)
if err != nil {
return false
}
if verifyCode == code {
return true
}
return false
}
func (db *DriverBiz) GetInfoByTel(ctx context.Context, tel string) (*Driver, error) {
driver, err := db.DI.FetchInfoByTel(ctx, tel)
if err != nil {
return nil, err
}
return driver, nil
}