refactor: reorganize modules and add Linux build tooling

This commit is contained in:
2026-08-09 12:41:08 +08:00
parent 86024fa81d
commit 5cc5fd92ed
1461 changed files with 4054 additions and 4724 deletions

View File

@@ -0,0 +1,172 @@
package models
import (
"context"
"time"
"bsm/full/module/base/passport/internal/impl"
)
var (
// 默认缓存TTL
DefaultTTL = 30 * time.Minute
// 用户信息缓存TTL
UserCacheTTL = 1 * time.Hour
// Token缓存TTL
TokenCacheTTL = 24 * time.Hour
)
// GetAccountByCache 通过缓存获取账户信息
func GetAccountByCache(ctx context.Context, field, value string) (*PassportAccount, error) {
var account *PassportAccount
key := impl.RedisService.BuildKey("account", field, value)
// 尝试从缓存获取
err := impl.RedisService.Get(key, &account)
if err == nil && account != nil {
return account, nil
}
// 缓存未命中,从数据库获取
account, err = GetPassportAccountByField(field, value)
if err != nil {
return nil, err
}
// 存入缓存
err = impl.RedisService.Set(key, account, UserCacheTTL)
return account, err
}
// GetUserDataByCache 通过缓存获取用户扩展数据
func GetUserDataByCache(ctx context.Context, passportID uint) (*PassportData, error) {
var data *PassportData
key := impl.RedisService.BuildKey("userdata", passportID)
// 尝试从缓存获取
err := impl.RedisService.Get(key, &data)
if err == nil && data != nil {
return data, nil
}
// 缓存未命中,从数据库获取
err = impl.DBService.Where("passport_id = ?", passportID).First(&data).Error
if err != nil {
return nil, err
}
// 存入缓存
err = impl.RedisService.Set(key, data, UserCacheTTL)
return data, err
}
// GetUserTagsByCache 通过缓存获取用户标签
func GetUserTagsByCache(ctx context.Context, passportID uint) ([]*PassportTags, error) {
var tags []*PassportTags
key := impl.RedisService.BuildKey("usertags", passportID)
// 尝试从缓存获取
err := impl.RedisService.Get(key, &tags)
if err == nil && tags != nil {
return tags, nil
}
// 缓存未命中,从数据库获取
err = impl.DBService.Where("passport_id = ?", passportID).Find(&tags).Error
if err != nil {
return nil, err
}
// 存入缓存
err = impl.RedisService.Set(key, tags, DefaultTTL)
return tags, err
}
// InvalidateUserCache 清除用户相关缓存
func InvalidateUserCache(ctx context.Context, passportID uint, identity string) error {
keys := []string{
impl.RedisService.BuildKey("account", "id", passportID),
impl.RedisService.BuildKey("account", "identity", identity),
impl.RedisService.BuildKey("userdata", passportID),
impl.RedisService.BuildKey("usertags", passportID),
}
for _, key := range keys {
impl.RedisService.Client.Del(impl.RedisService.Ctx, key)
}
return nil
}
// SetTokenCache 设置Token缓存
func SetTokenCache(ctx context.Context, identity, token string) error {
key := impl.RedisService.BuildKey("token", identity)
return impl.RedisService.Set(key, token, TokenCacheTTL)
}
// GetTokenCache 获取Token缓存
func GetTokenCache(ctx context.Context, identity string) (string, error) {
var token string
key := impl.RedisService.BuildKey("token", identity)
err := impl.RedisService.Get(key, &token)
return token, err
}
// InvalidateTokenCache 清除Token缓存
func InvalidateTokenCache(ctx context.Context, identity string) error {
key := impl.RedisService.BuildKey("token", identity)
return impl.RedisService.Client.Del(impl.RedisService.Ctx, key).Err()
}
// SetVerificationCodeCache 设置验证码缓存
func SetVerificationCodeCache(ctx context.Context, phone, code string, ttl time.Duration) error {
key := impl.RedisService.BuildKey("verifycode", phone)
return impl.RedisService.Set(key, code, ttl)
}
// GetVerificationCodeCache 获取验证码缓存
func GetVerificationCodeCache(ctx context.Context, phone string) (string, error) {
var code string
key := impl.RedisService.BuildKey("verifycode", phone)
err := impl.RedisService.Get(key, &code)
return code, err
}
// InvalidateVerificationCodeCache 清除验证码缓存
func InvalidateVerificationCodeCache(ctx context.Context, phone string) error {
key := impl.RedisService.BuildKey("verifycode", phone)
return impl.RedisService.Client.Del(impl.RedisService.Ctx, key).Err()
}
// IncrementLoginAttempts 增加登录尝试次数
func IncrementLoginAttempts(ctx context.Context, account string) (int64, error) {
key := impl.RedisService.BuildKey("loginattempts", account)
result := impl.RedisService.Client.Incr(impl.RedisService.Ctx, key)
if result.Err() != nil {
return 0, result.Err()
}
// 设置过期时间15分钟
impl.RedisService.Client.Expire(impl.RedisService.Ctx, key, 15*time.Minute)
return result.Val(), nil
}
// GetLoginAttempts 获取登录尝试次数
func GetLoginAttempts(ctx context.Context, account string) (int64, error) {
key := impl.RedisService.BuildKey("loginattempts", account)
result := impl.RedisService.Client.Get(impl.RedisService.Ctx, key)
if result.Err() != nil {
return 0, nil // 如果key不存在返回0
}
return result.Int64()
}
// ClearLoginAttempts 清除登录尝试次数
func ClearLoginAttempts(ctx context.Context, account string) error {
key := impl.RedisService.BuildKey("loginattempts", account)
return impl.RedisService.Client.Del(impl.RedisService.Ctx, key).Err()
}

View File

@@ -0,0 +1,65 @@
/**
* @Author: ZhaoYadong
* @Date: 2024-02-27 21:09:45
* @LastEditors: ZhaoYadong
* @LastEditTime: 2024-02-28 09:13:35
* @FilePath: /server/Users/edy/go/src/passport/internal/models/passport_account.go
*/
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"errors"
"bsm/full/module/base/passport/internal/impl"
"bsm/full/module/base/passport/internal/vars"
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/types"
"gorm.io/gorm"
)
/*
* PassportAccount
* Comment: 通行证帐号表
* Version: 10
* Created: 2022-04-12 10:44:51 , Updated:0001-01-01 00:00:00
*/
type PassportAccount struct {
types.Std_IICUDS
Account string `gorm:"column:account;type:varchar(255);default:'';" json:"account"` // 帐号
Phone string `gorm:"column:phone;type:varchar(20);default:'';" json:"phone"` // 手机号
Email string `gorm:"column:email;type:varchar(255);default:'';" json:"email"` // Email
Password string `gorm:"column:password;type:varchar(255);not null;" json:"password"` // 密码
Salt string `gorm:"column:salt;type:varchar(255);not null;" json:"salt"` // 密码盐
}
func init() {
database.AppendMigrate(&PassportAccount{})
}
// TableName .
func (table *PassportAccount) TableName() string {
return "passport_account" //对应数据库表名
}
// GetPassportAccountByField 根据特定字段值获取PassportAccount对象
func GetPassportAccountByField(field string, value any) (*PassportAccount, error) {
var (
data PassportAccount
condition = map[string]any{field: value}
)
err := impl.DBService.Where(condition).First(&data).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errcode.ErrNotFound(404, "Account not found")
}
return nil, errcode.ErrDB
}
if data.Status == vars.Status_Disable {
return nil, errcode.ErrPermissionDenied
}
return &data, nil
}

View File

@@ -0,0 +1,75 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"errors"
"time"
"bsm/full/module/base/passport/internal/impl"
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
"gorm.io/gorm"
)
/*
* PassportExtend
* Comment: 通行证帐号扩展表
* Version: 10
* Created: 2022-04-12 10:50:54 , Updated:0001-01-01 00:00:00
*/
type PassportData struct {
types.Std_ID
types.Std_Passport
Nickname string `gorm:"column:nickname;type:varchar(64);default:'';" json:"nickname"` // 昵称
Avatar string `gorm:"column:avatar;type:varchar(255);default:'';" json:"avatar"` // 头像
Birthday time.Time `gorm:"column:birthday;" json:"birthday"` // 生日
Sex int8 `gorm:"column:sex;default:0;" json:"sex"` // 性别1为女性2为男性
Country string `gorm:"column:country;default:'';" json:"country"` // 国家
Province string `gorm:"column:province;default:'';" json:"province"` // 省
City string `gorm:"column:city;default:'';" json:"city"` // 市
Area string `gorm:"column:area;default:'';" json:"area"` // 区
Sign string `gorm:"column:sign;type:varchar(500);default:'';" json:"sign"` // 签名
Cover string `gorm:"column:cover;type:varchar(255);default:'';" json:"cover"` // 背景&封面
Score int32 `gorm:"column:score;default:0;" json:"score"` // 积分
Level int32 `gorm:"column:level;default:0;" json:"level"` // 等级
Rights string `gorm:"column:rights;type:varchar(255);default:'';" json:"rights"` // 权限
AgencyId uint `gorm:"column:agency_id;default:0;" json:"agency_id"` // 分销代理id
StaffId uint `gorm:"column:staff_id;default:0;" json:"staff_id"` // 工作人员id
OwnerId uint `gorm:"column:owner_id;default:0;" json:"owner_id"` // 所属唯一id
OwnerIdentity string `gorm:"column:owner_identity;type:varchar(64);default:'';" json:"owner_identity"` // 所属唯一码
EmailVerify int32 `gorm:"default:0"` // 邮件验证状态:0 未验证 1 验证中2 验证成功,-1 验证失败
PhoneVerify int32 `gorm:"default:0"` // 手机验证状态:0 未验证 1 验证中2 验证成功,-1 验证失败
FaceVerify int32 `gorm:"default:0"` // 人脸或照片验证状态:0 未验证 1 验证中2 验证成功,-1 验证失败
DocumentVerify int32 `gorm:"default:0"` // 证件验证状态:0 未验证 1 验证中2 验证成功,-1 验证失败
KycVerify int32 `gorm:"default:0"` // KYC验证状态:0 未验证 1 验证中2 验证成功,-1 验证失败
UpdatedAt time.Time // 最后更新时间
}
func init() {
database.AppendMigrate(&PassportData{})
}
// TableName .
func (table *PassportData) TableName() string {
return "passport_data" //对应数据库表名
}
func CheckPassportData(id uint, identity string) (*PassportData, error) {
var data PassportData
err := impl.DBService.Where("passport_id=? AND passport_identity=?", id, identity).First(&data).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
data = PassportData{
Std_Passport: types.Std_Passport{
PassportID: id,
PassportIdentity: identity,
},
}
impl.DBService.Create(&data)
return &data, nil
}
return nil, err
}
return &data, nil
}

View File

@@ -0,0 +1,31 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportNotify
* Comment: 会员消息通知表
* Version: 10
* Created: 2022-04-12 10:37:50 , Updated:0001-01-01 00:00:00
*/
type PassportNotify struct {
types.Std_IICUDS
types.Std_Passport
Type int8 `gorm:"column:type;default:0;" json:"type"` // 类型
Body string `gorm:"column:body;type:text;default:'';" json:"body"` // 正文
Title string `gorm:"column:title;type:varchar(255);default:'';" json:"title"` // 标题
From string `gorm:"column:from;type:varchar(36);default:'';" json:"from"` // 发信人
}
func init() {
database.AppendMigrate(&PassportNotify{})
}
// TableName .
func (table *PassportNotify) TableName() string {
return "passport_notify" //对应数据库表名
}

View File

@@ -0,0 +1,26 @@
package models
import (
"time"
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
"gorm.io/gorm"
)
// 第三方登录配置表
type PassportProvider struct {
gorm.Model
types.Std_Passport
ID uint `gorm:"primaryKey" json:"id"`
Provider string `gorm:"type:varchar(20);index;not null" json:"provider"` // google, twitter, facebook, wechat, apple, custom
ProviderID string `gorm:"type:varchar(255);index;not null" json:"provider_id"` // 第三方平台的用户ID
Email string `gorm:"type:varchar(100)" json:"email"`
AccessToken string `gorm:"type:text" json:"-"`
RefreshToken string `gorm:"type:text" json:"-"`
ExpiresAt time.Time `json:"expires_at"`
}
func init() {
database.AppendMigrate(&PassportProvider{})
}

View File

@@ -0,0 +1,34 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"time"
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportRightsExpiry
* Comment: 通行证特权有效期记录表
* Version: 10
* Created: 2022-04-11 17:33:50 , Updated:0001-01-01 00:00:00
*/
type PassportRightsExpiry struct {
types.Std_IICUDS
types.Std_Passport
Rights string `gorm:"default:'';" json:"rights"` // 特权名称
StartDate time.Time `json:"start_date"` // 生效日期
EndDate time.Time `json:"end_date"` // 结束日期
Remark string `gorm:"default:'';" json:"remark"` // 备注
}
func init() {
database.AppendMigrate(&PassportRightsExpiry{})
}
// TableName .
func (table *PassportRightsExpiry) TableName() string {
return "passport_rights_expiry" //对应数据库表名
}

View File

@@ -0,0 +1,31 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportScore
* Comment: 会员积分记录表
* Version: 10
* Created: 2022-04-12 10:38:56 , Updated:0001-01-01 00:00:00
*/
type PassportScore struct {
types.Std_IICUDS
types.Std_Passport
Score int64 `gorm:"default:0;" json:"score"` // 积分
Action string `gorm:"default:'';" json:"action"` // 动作
Remark string `gorm:"default:'';" json:"remark"` // 描述
}
func init() {
database.AppendMigrate(&PassportScore{})
}
// TableName .
func (table *PassportScore) TableName() string {
return "passport_score" //对应数据库表名
}

View File

@@ -0,0 +1,29 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportStatistics
* Comment:
* Version: 10
* Created: 2022-04-12 10:41:13 , Updated:0001-01-01 00:00:00
*/
type PassportStatistics struct {
types.Std_IICUDS
types.Std_Passport
Item string `gorm:"column:item;type:varchar(255);default:'';" json:"item"` // 统计项KEY
Value int64 `gorm:"default:0;" json:"value"` // 统计项数
}
func init() {
database.AppendMigrate(&PassportStatistics{})
}
// TableName .
func (table *PassportStatistics) TableName() string {
return "passport_statistics" //对应数据库表名
}

View File

@@ -0,0 +1,29 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportTags
* Comment:
* Version: 10
* Created: 2022-04-12 10:39:29 , Updated:0001-01-01 00:00:00
*/
type PassportTags struct {
types.Std_IICUDS
types.Std_Passport
Name string `gorm:"column:name;type:varchar(255);not null;" json:"name"` // 标签标题
Icon string `gorm:"column:icon;type:varchar(255);" json:"icon"` // 标签ICON
}
func init() {
database.AppendMigrate(&PassportTags{})
}
// TableName .
func (table *PassportTags) TableName() string {
return "passport_tags" //对应数据库表名
}

View File

@@ -0,0 +1,54 @@
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
package models
import (
"time"
"git.apinb.com/bsm-sdk/core/database"
"git.apinb.com/bsm-sdk/core/types"
)
/*
* PassportExtend
* Comment: 通行证帐号认证表
* Version: 10
* Created: 2022-04-12 10:50:54 , Updated:0001-01-01 00:00:00
*/
type PassportVerify struct {
types.Std_ID
types.Std_Passport
// 验证时间戳
EmailVerifyAt *time.Time
PhoneVerifyAt *time.Time
FaceVerifyAt *time.Time
DocumentVerifyAt *time.Time
KycVerifyAt *time.Time
// 验证相关 token/代码
EmailVerifyToken string `gorm:"type:varchar(100)"`
PhoneVerifyCode string `gorm:"type:varchar(10)"`
FaceVerifyReject string `gorm:"type:text"`
PhoneVerifyExpiresAt *time.Time
// 证件相关字段
DocumentType string `gorm:"type:varchar(50)"` // 如: 'id_card', 'passport'
DocumentName string `gorm:"type:varchar(100)"`
DocumentNumber string `gorm:"type:varchar(100)"`
DocumentFront string `gorm:"type:varchar(255)"` // 证件正面
DocumentBack string `gorm:"type:varchar(255)"` // 证件反面
// KYC 相关字段
KycDocumentBack string `gorm:"type:varchar(255)"`
KycStatus string `gorm:"type:varchar(20);default:'pending'"` // pending, approved, rejected
KycRejectReason string `gorm:"type:text"`
}
func init() {
database.AppendMigrate(&PassportVerify{})
}
// TableName .
func (pv *PassportVerify) TableName() string {
return "passport_verify" //对应数据库表名
}

View File

@@ -0,0 +1,65 @@
package models
import (
"bsm/full/module/base/passport/internal/impl"
"bsm/full/module/base/passport/internal/vars"
"git.apinb.com/bsm-sdk/core/types"
"git.apinb.com/bsm-sdk/core/utils"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
func InitData() error {
var cnt int64
var err error
err = impl.DBService.Model(&PassportAccount{}).Where("account=?", "demo").Count(&cnt).Error
if err != nil {
return err
}
if cnt == 0 {
salt := utils.ULID()
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("welcome"+salt), bcrypt.MinCost)
pa := PassportAccount{
Std_IICUDS: types.Std_IICUDS{
Identity: utils.UUID(),
Status: vars.Status_Normal,
},
Account: "demo",
Phone: "",
Password: string(hashedPassword),
Salt: salt,
}
err = impl.DBService.Create(&pa).Error
if err != nil {
return err
}
}
return nil
}
func PassportAccountExists(key, val string) bool {
var count int64
err := impl.DBService.Model(&PassportAccount{}).Where(key+" = ?", val).Count(&count).Error
if err != nil {
return false
}
return count > 0
}
func CreateAccount(pa *PassportAccount, nickname string) (err error) {
return impl.DBService.Transaction(func(tx *gorm.DB) error {
// 插入扩展表
pe := new(PassportData)
pe.PassportID = pa.ID
pe.PassportIdentity = pa.Identity
pe.Nickname = nickname
if err := tx.Create(pe).Error; err != nil {
return err
}
return nil
})
}