refactor: 礼物功能,优化用户获取逻辑,优化排行榜逻辑,优化调用逻辑,优化结构。
parent
310a2dcb5c
commit
0e7b79a083
@ -0,0 +1,67 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var _ GiftModel = (*customGiftModel)(nil)
|
||||
|
||||
type (
|
||||
// GiftModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customGiftModel.
|
||||
GiftModel interface {
|
||||
giftModel
|
||||
// Transaction 开启事务,传入方法即可
|
||||
Transaction(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error
|
||||
// InsertTx 事务插入
|
||||
InsertTx(ctx context.Context, tx *gorm.DB, data *Gift) error
|
||||
// UpdateTx 事务更新
|
||||
UpdateTx(ctx context.Context, tx *gorm.DB, data *Gift) error
|
||||
FindByPlatformGift(ctx context.Context, platform string, giftId string) (*Gift, error)
|
||||
}
|
||||
|
||||
customGiftModel struct {
|
||||
*defaultGiftModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewGiftModel returns a model for the database table.
|
||||
func NewGiftModel(conn *gorm.DB) GiftModel {
|
||||
return &customGiftModel{
|
||||
defaultGiftModel: newGiftModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customGiftModel) Transaction(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error {
|
||||
return withTx(ctx, m.conn, tx).Transaction(func(tx *gorm.DB) error {
|
||||
return fn(tx)
|
||||
})
|
||||
}
|
||||
|
||||
func (m *customGiftModel) InsertTx(ctx context.Context, tx *gorm.DB, data *Gift) error {
|
||||
err := withTx(ctx, m.conn, tx).Create(&data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customGiftModel) UpdateTx(ctx context.Context, tx *gorm.DB, data *Gift) error {
|
||||
err := withTx(ctx, m.conn, tx).Save(data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customGiftModel) FindByPlatformGift(ctx context.Context, platform string, giftId string) (*Gift, error) {
|
||||
var resp Gift
|
||||
db := m.conn.WithContext(ctx)
|
||||
err := db.Model(&Gift{}).
|
||||
Where("platform = ? AND gift_id = ?", platform, giftId).
|
||||
Take(&resp).Error
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var _ UserGiftModel = (*customUserGiftModel)(nil)
|
||||
|
||||
type (
|
||||
// UserGiftModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customUserGiftModel.
|
||||
UserGiftModel interface {
|
||||
userGiftModel
|
||||
}
|
||||
|
||||
customUserGiftModel struct {
|
||||
*defaultUserGiftModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewUserGiftModel returns a model for the database table.
|
||||
func NewUserGiftModel(conn *gorm.DB) UserGiftModel {
|
||||
return &customUserGiftModel{
|
||||
defaultUserGiftModel: newUserGiftModel(conn),
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var _ UserIntegralModel = (*customUserIntegralModel)(nil)
|
||||
|
||||
type (
|
||||
// UserIntegralModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customUserIntegralModel.
|
||||
UserIntegralModel interface {
|
||||
userIntegralModel
|
||||
Transact(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error
|
||||
InsertTx(ctx context.Context, tx *gorm.DB, data *UserIntegral) error
|
||||
UpdateIntegralTx(ctx context.Context, tx *gorm.DB, userId, addon int64) error
|
||||
FindIntegral(ctx context.Context, tx *gorm.DB, userId int64) (int64, error)
|
||||
}
|
||||
|
||||
customUserIntegralModel struct {
|
||||
*defaultUserIntegralModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewUserIntegralModel returns a model for the database table.
|
||||
func NewUserIntegralModel(conn *gorm.DB) UserIntegralModel {
|
||||
return &customUserIntegralModel{
|
||||
defaultUserIntegralModel: newUserIntegralModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customUserIntegralModel) Transact(ctx context.Context, tx *gorm.DB, fn func(tx *gorm.DB) error) error {
|
||||
return withTx(ctx, m.conn, tx).Transaction(fn)
|
||||
}
|
||||
|
||||
func (m *customUserIntegralModel) InsertTx(ctx context.Context, tx *gorm.DB, data *UserIntegral) error {
|
||||
err := withTx(ctx, m.conn, tx).Create(&data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customUserIntegralModel) UpdateIntegralTx(ctx context.Context, tx *gorm.DB, userId, change int64) error {
|
||||
if change < 0 {
|
||||
return errors.New("无法将积分更新至负数")
|
||||
}
|
||||
db := withTx(ctx, m.conn, tx)
|
||||
|
||||
result := db.Table(m.table).
|
||||
Where("user_id = ?", userId).
|
||||
Update("integral", change)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return ErrRowsAffectedZero
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *customUserIntegralModel) FindIntegral(ctx context.Context, tx *gorm.DB, userId int64) (int64, error) {
|
||||
var resp int64
|
||||
err := withTx(ctx, m.conn, tx).Table(m.table).
|
||||
Select(fmt.Sprintf("%s.integral", m.table)).
|
||||
Where("user_id = ?", userId).Take(&resp).Error
|
||||
switch err {
|
||||
case nil:
|
||||
return resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return 0, ErrNotFound
|
||||
default:
|
||||
return 0, err
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var _ UserNobilityModel = (*customUserNobilityModel)(nil)
|
||||
|
||||
type (
|
||||
// UserNobilityModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customUserNobilityModel.
|
||||
UserNobilityModel interface {
|
||||
userNobilityModel
|
||||
}
|
||||
|
||||
customUserNobilityModel struct {
|
||||
*defaultUserNobilityModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewUserNobilityModel returns a model for the database table.
|
||||
func NewUserNobilityModel(conn *gorm.DB) UserNobilityModel {
|
||||
return &customUserNobilityModel{
|
||||
defaultUserNobilityModel: newUserNobilityModel(conn),
|
||||
}
|
||||
}
|
@ -1,9 +1,35 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var ErrNotFound = gorm.ErrRecordNotFound
|
||||
var ErrRowsAffectedZero = errors.New("RowsAffected zero")
|
||||
|
||||
// BitBool is an implementation of a bool for the MySQL type BIT(1).
|
||||
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
|
||||
type BitBool bool
|
||||
|
||||
// Value implements the driver.Valuer interface,
|
||||
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
|
||||
func (b BitBool) Value() (driver.Value, error) {
|
||||
if b {
|
||||
return []byte{1}, nil
|
||||
} else {
|
||||
return []byte{0}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface,
|
||||
// and turns the bitfield incoming from MySQL into a BitBool
|
||||
func (b *BitBool) Scan(src interface{}) error {
|
||||
v, ok := src.([]byte)
|
||||
if !ok {
|
||||
return errors.New("bad []byte type assertion")
|
||||
}
|
||||
*b = v[0] == 1
|
||||
return nil
|
||||
}
|
||||
|
@ -1,20 +1,47 @@
|
||||
Name: usercenter.rpc
|
||||
ListenOn: 127.0.0.1:30001
|
||||
Timeout: 5000
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 127.0.0.1:2379
|
||||
Key: usercenter.rpc.dev
|
||||
Timeout: 5000 # default is 2000
|
||||
NonBlock: true
|
||||
Log:
|
||||
Mode: console
|
||||
KeepDays: 7
|
||||
Level: info
|
||||
DB:
|
||||
#DataSource: root:root@tcp(192.168.1.100:3306)/dmgame?charset=utf8mb4&loc=Asia%2FShanghai&parseTime=true
|
||||
DataSource: root:root@tcp(127.0.0.1:3306)/dmgame?charset=utf8mb4&loc=Asia%2FShanghai&parseTime=true
|
||||
UserRetriever:
|
||||
Enabled: false
|
||||
UpdateDuration: 720 # 720 hours = 30 Day = 1 Month
|
||||
Cron:
|
||||
PlatformUser: "0 0/5 * * * ?" # 每隔5分钟执行一次
|
||||
Nobility: "0 0/10 * * * ?" # 每隔10分钟执行一次
|
||||
NobilityPlatforms: [ "bilibili" ] # 需要获取贵族的平台列表
|
||||
Bilibili:
|
||||
RoomId: 8722013
|
||||
Mid: 6704420
|
||||
RoomShortInfoApi: https://api.live.bilibili.com/room/v1/Room/room_init
|
||||
TopListApi: https://api.live.bilibili.com/guard/topList
|
||||
Rank:
|
||||
Enabled: false
|
||||
Cron:
|
||||
Update: "0/10 * * * * ?" # 10s一次
|
||||
Persistence: "0 0/10 * * * ?" # 10min一次
|
||||
GiftCollector:
|
||||
Enabled: true
|
||||
Log:
|
||||
Mode: console
|
||||
KeepDays: 7
|
||||
Level: info
|
||||
Platforms: [ "bilibili" ]
|
||||
Cron:
|
||||
CollectGift: "0 0 0/6 * * ?" # 每隔6小时执行一次
|
||||
Integral:
|
||||
# RMB到积分的转换
|
||||
RMBToIntegral: 1000
|
||||
# 平台礼物到RMB的转换
|
||||
GiftToRMB:
|
||||
bilibili: 0.001
|
||||
# 平台免费礼物到积分的转换
|
||||
FreeToIntegral:
|
||||
bilibili: 0.0001
|
@ -0,0 +1,32 @@
|
||||
package gift
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UserBuyNobilityLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewUserBuyNobilityLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserBuyNobilityLogic {
|
||||
return &UserBuyNobilityLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// UserBuyNobility 用户购买贵族
|
||||
// 1. 记录送礼
|
||||
// 2. 新增积分
|
||||
func (l *UserBuyNobilityLogic) UserBuyNobility(in *pb.UserBuyNobilityReq) (*pb.UserBuyNobilityResp, error) {
|
||||
// TODO 未完成
|
||||
return &pb.UserBuyNobilityResp{}, nil
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package gift
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/uuid"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/logic/gift_collect"
|
||||
"live-service/app/user_center/rpc/internal/logic/integral"
|
||||
"live-service/app/user_center/rpc/internal/logic/platform_user"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"strconv"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UserSendGiftLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewUserSendGiftLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserSendGiftLogic {
|
||||
return &UserSendGiftLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// UserSendGift 用户赠送礼物
|
||||
// 1. 记录用户赠送信息
|
||||
// 2. 新增用户积分
|
||||
func (l *UserSendGiftLogic) UserSendGift(in *pb.UserSendGiftReq) (*pb.UserSendGiftResp, error) {
|
||||
// 首先获取用户id
|
||||
var err error
|
||||
sysUser, err := platform_user.NewRetrievePlatformUserLogic(l.ctx, l.svcCtx).RetrievePlatformUser(&pb.PlatformUserReq{
|
||||
Platform: in.Platform,
|
||||
PUid: in.PUid,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := &pb.UserSendGiftResp{
|
||||
User: sysUser.User,
|
||||
}
|
||||
|
||||
// 记录送礼信息
|
||||
{
|
||||
dbUserGift := &model.UserGift{
|
||||
Id: uuid.NextId(),
|
||||
UserId: sysUser.User.Id,
|
||||
Platform: in.Platform,
|
||||
RoomId: in.RoomId,
|
||||
GiftId: strconv.FormatInt(in.GiftId, 10),
|
||||
GiftName: in.GiftName,
|
||||
Num: in.Num,
|
||||
}
|
||||
if in.IsPaid {
|
||||
dbUserGift.Price = in.Price
|
||||
} else {
|
||||
dbUserGift.FreePrice = in.Price
|
||||
}
|
||||
if err = l.svcCtx.UserGiftModel.Insert(l.ctx, dbUserGift); err != nil {
|
||||
l.Logger.Errorf("记录用户[%d]送礼信息 [%d:%s:%d] 失败,操作继续...", sysUser.User.Id, in.GiftId, in.GiftName, in.Num)
|
||||
}
|
||||
}
|
||||
|
||||
// 积分
|
||||
{
|
||||
// 待增加的积分
|
||||
addonIntegral := calcIntegral(l.svcCtx.Config, in.Platform, in.IsPaid, float64(in.Price), in.Num)
|
||||
if tmpMap, ok := gift_collect.Service.GetCacheByPlatform(in.Platform); ok {
|
||||
if tmpData, ok := tmpMap[in.GiftId]; ok {
|
||||
addonIntegral = calcIntegral(l.svcCtx.Config, in.Platform, tmpData.IsPaid, tmpData.Price, in.Num)
|
||||
}
|
||||
}
|
||||
|
||||
newIntegral, err := integral.NewChangeIntegralLogic(l.ctx, l.svcCtx).ChangeIntegral(&pb.ChangeIntegralReq{
|
||||
UserId: sysUser.User.Id,
|
||||
Change: addonIntegral,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Integral = newIntegral
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package gift
|
||||
|
||||
import (
|
||||
"github.com/shopspring/decimal"
|
||||
"live-service/app/user_center/rpc/internal/config"
|
||||
)
|
||||
|
||||
func calcIntegral(cfg config.Config, platform string, isPaid bool, price float64, num int64) int64 {
|
||||
giftToRMBRadio, _ := cfg.Integral.GiftToRMB[platform]
|
||||
freeToIntegralRadio, _ := cfg.Integral.FreeToIntegral[platform]
|
||||
rmbToIntegral := cfg.Integral.RMBToIntegral
|
||||
|
||||
var newPrice float64
|
||||
if isPaid {
|
||||
newPrice = price * giftToRMBRadio
|
||||
} else {
|
||||
newPrice = price * freeToIntegralRadio
|
||||
}
|
||||
|
||||
decimal.DivisionPrecision = 2
|
||||
return decimal.NewFromFloat(newPrice).
|
||||
Mul(decimal.NewFromInt(num)).
|
||||
Mul(decimal.NewFromFloat(rmbToIntegral)).
|
||||
Round(0).IntPart()
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package gift_collect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
pbMq "live-service/app/pb/mq"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
)
|
||||
|
||||
var Service *GiftCollector
|
||||
|
||||
type (
|
||||
GiftData struct {
|
||||
Id int64 // 礼物ID
|
||||
Name string // 礼物名称
|
||||
Price float64 // 礼物单价(rmb)
|
||||
IsPaid bool // 是否收费礼物
|
||||
}
|
||||
GiftCollector struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
cron *cron.Cron
|
||||
|
||||
collectorMapper map[string]CollectorFunc
|
||||
|
||||
// cacheGift 礼物缓存 platform:giftId:giftData
|
||||
cacheGift map[string]map[int64]GiftData
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
CollectorFunc func(ctx context.Context, svcCtx *svc.ServiceContext) (ret map[int64]GiftData, err error)
|
||||
)
|
||||
|
||||
func InitCollector(svcCtx *svc.ServiceContext) {
|
||||
ctx := context.Background()
|
||||
Service = &GiftCollector{
|
||||
ctx: context.Background(),
|
||||
svcCtx: svcCtx,
|
||||
cron: cron.New(cron.WithSeconds()),
|
||||
collectorMapper: map[string]CollectorFunc{
|
||||
pbMq.Platform_name[int32(pbMq.Platform_bilibili)]: GiftCollectorBilibili,
|
||||
},
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
|
||||
if !svcCtx.Config.GiftCollector.Enabled {
|
||||
return
|
||||
}
|
||||
Service.startJob()
|
||||
}
|
||||
|
||||
func (c *GiftCollector) startJob() {
|
||||
cfg := c.svcCtx.Config.GiftCollector
|
||||
// 先执行一次
|
||||
c.collectGift(cfg.Platforms...)
|
||||
|
||||
_, _ = c.cron.AddFunc(cfg.Cron.CollectGift, func() {
|
||||
c.collectGift(cfg.Platforms...)
|
||||
})
|
||||
c.cron.Start()
|
||||
}
|
||||
|
||||
func (c *GiftCollector) collectGift(platforms ...string) {
|
||||
for _, platform := range platforms {
|
||||
if handle, ok := c.collectorMapper[platform]; ok {
|
||||
ret, err := handle(c.ctx, c.svcCtx)
|
||||
if err != nil {
|
||||
// TODO 打印
|
||||
continue
|
||||
}
|
||||
// caching
|
||||
c.cacheGift[platform] = ret
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetCacheByPlatform 获取缓存中的礼物信息
|
||||
func (c *GiftCollector) GetCacheByPlatform(platform string) (map[int64]GiftData, bool) {
|
||||
data, ok := c.cacheGift[platform]
|
||||
return data, ok
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
package gift_collect
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"git.noahlan.cn/northlan/ntools-go/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"io/ioutil"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
CoinTypeGold = "gold"
|
||||
CoinTypeSilver = "silver"
|
||||
)
|
||||
|
||||
type (
|
||||
bilibiliGift struct {
|
||||
Id int64 `json:"id"` // 礼物ID
|
||||
Name string `json:"name"` // 礼物名称
|
||||
Price int64 `json:"price"` // 礼物单价
|
||||
CoinType string `json:"coin_type"` // 瓜子类型 gold金瓜子 silver银瓜子
|
||||
}
|
||||
)
|
||||
|
||||
func isPaidGift(coinType string) bool {
|
||||
if coinType == CoinTypeGold {
|
||||
return true
|
||||
}
|
||||
if coinType == CoinTypeSilver {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GiftCollectorBilibili(ctx context.Context, svcCtx *svc.ServiceContext) (ret map[int64]GiftData, err error) {
|
||||
const platform = "bilibili"
|
||||
radio, _ := svcCtx.Config.Integral.GiftToRMB[platform]
|
||||
|
||||
// 1. 读取API
|
||||
httpResp, err := http.Get("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/giftConfig?platform=app")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
resBody, err := ioutil.ReadAll(httpResp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var responseData struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
List []bilibiliGift `json:"list"`
|
||||
} `json:"data"`
|
||||
}
|
||||
err = json.Unmarshal(resBody, &responseData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 2. 事务分批入库 限定每次分批入库数量
|
||||
batchSize := 50
|
||||
dataLen := len(responseData.Data.List)
|
||||
batches := dataLen / batchSize
|
||||
if dataLen%batchSize != 0 {
|
||||
batches += 1
|
||||
}
|
||||
ret = make(map[int64]GiftData)
|
||||
for i := 0; i < batches; i++ {
|
||||
// TODO 错误处理
|
||||
_ = svcCtx.GiftModel.Transaction(ctx, nil, func(tx *gorm.DB) error {
|
||||
lenJ := (i + 1) * batchSize
|
||||
if lenJ > dataLen {
|
||||
lenJ = dataLen
|
||||
}
|
||||
for j := i * batchSize; j < lenJ; j++ {
|
||||
gift := responseData.Data.List[j]
|
||||
|
||||
dbGift := &model.Gift{
|
||||
Id: uuid.NextId(),
|
||||
GiftId: strconv.FormatInt(gift.Id, 10),
|
||||
GiftName: gift.Name,
|
||||
Platform: platform,
|
||||
}
|
||||
giftData := GiftData{
|
||||
Id: gift.Id,
|
||||
Name: gift.Name,
|
||||
}
|
||||
if isPaidGift(gift.CoinType) {
|
||||
dbGift.PPricePaid = gift.Price
|
||||
dbGift.Price = float64(gift.Price) * float64(radio)
|
||||
|
||||
giftData.IsPaid = true
|
||||
giftData.Price = dbGift.Price
|
||||
} else {
|
||||
dbGift.PPriceFree = gift.Price
|
||||
|
||||
giftData.IsPaid = false
|
||||
giftData.Price = float64(dbGift.PPriceFree)
|
||||
}
|
||||
ret[giftData.Id] = giftData
|
||||
|
||||
if err = svcCtx.GiftModel.UpdateTx(ctx, tx, dbGift); err != nil {
|
||||
if errors.Is(err, model.ErrRowsAffectedZero) {
|
||||
err = nil
|
||||
_ = svcCtx.GiftModel.InsertTx(ctx, tx, dbGift)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package gift_collect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestA(t *testing.T) {
|
||||
count := 10
|
||||
batchSize := 5
|
||||
batches := 0
|
||||
if count%batchSize == 0 {
|
||||
batches = count / batchSize
|
||||
} else {
|
||||
batches = count/batchSize + 1
|
||||
}
|
||||
for i := 0; i < batches; i++ {
|
||||
fmt.Println()
|
||||
fmt.Println(i)
|
||||
fmt.Println()
|
||||
lenJ := (i + 1) * batchSize
|
||||
if lenJ > count {
|
||||
lenJ = count
|
||||
}
|
||||
for j := i * batchSize; j < lenJ; j++ {
|
||||
fmt.Println(j)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("count: %d size: %d batches: %d\n", count, batchSize, batches)
|
||||
fmt.Printf("求余: %v", count%batchSize)
|
||||
|
||||
//data := make([]int, 0, 322)
|
||||
//for i := 0; i < 322; i++ {
|
||||
// data = append(data, i)
|
||||
//}
|
||||
//
|
||||
//batchSize := 50
|
||||
//tmpList := make([]int, 0, batchSize)
|
||||
//for i, gift := range data {
|
||||
// tmpList = append(tmpList, gift)
|
||||
// if (i+1)%batchSize == 0 || (i+1) == len(data) {
|
||||
// // 一次
|
||||
// fmt.Printf("%d 次 %+v\n", (i+1)%batchSize, tmpList)
|
||||
// tmpList = make([]int, 0, batchSize)
|
||||
// }
|
||||
//}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package integral
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ChangeIntegralLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewChangeIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChangeIntegralLogic {
|
||||
return &ChangeIntegralLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// ChangeIntegral 新增用户积分
|
||||
func (l *ChangeIntegralLogic) ChangeIntegral(in *pb.ChangeIntegralReq) (*pb.ChangeIntegralResp, error) {
|
||||
if err := l.svcCtx.UserIntegralModel.Transact(l.ctx, nil, func(tx *gorm.DB) error {
|
||||
integral, err := l.svcCtx.UserIntegralModel.FindIntegral(l.ctx, tx, in.UserId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
if in.Change < 0 {
|
||||
return errors.New("用户积分不足")
|
||||
}
|
||||
// 用户积分记录不存在,进行插入
|
||||
if err = l.svcCtx.UserIntegralModel.InsertTx(l.ctx, tx, &model.UserIntegral{
|
||||
UserId: in.UserId,
|
||||
Integral: in.Change,
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "插入用户积分失败")
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
return errors.Wrap(err, "获取当前用户积分失败")
|
||||
}
|
||||
}
|
||||
if integral+in.Change < 0 {
|
||||
return errors.New("用户积分不足")
|
||||
}
|
||||
|
||||
if err = l.svcCtx.UserIntegralModel.UpdateIntegralTx(l.ctx, tx, in.UserId, integral+in.Change); err != nil {
|
||||
return errors.Wrap(err, "更新用户积分失败")
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithErr(err), "记录积分-事务执行失败, err:%+v", err)
|
||||
}
|
||||
|
||||
// 查询当前用户积分
|
||||
integral, err := l.svcCtx.UserIntegralModel.FindIntegral(l.ctx, nil, in.UserId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithMsg("查询用户积分失败"), "查询用户积分失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.ChangeIntegralResp{
|
||||
UserId: in.UserId,
|
||||
Change: in.Change,
|
||||
Integral: integral,
|
||||
}, nil
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package integral
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserIntegralLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetUserIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserIntegralLogic {
|
||||
return &GetUserIntegralLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserIntegral 获取用户积分
|
||||
func (l *GetUserIntegralLogic) GetUserIntegral(in *pb.UserIdResp) (*pb.UserIntegralResp, error) {
|
||||
// 查询当前用户积分
|
||||
integral, err := l.svcCtx.UserIntegralModel.FindIntegral(l.ctx, nil, in.UserId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "查询用户积分失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.UserIntegralResp{
|
||||
UserId: in.UserId,
|
||||
Integral: integral,
|
||||
}, nil
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package platform_user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserIdByPUidLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetUserIdByPUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserIdByPUidLogic {
|
||||
return &GetUserIdByPUidLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserIdByPUid 通过平台用户id获取系统用户ID
|
||||
func (l *GetUserIdByPUidLogic) GetUserIdByPUid(in *pb.PlatformUserReq) (*pb.UserIdResp, error) {
|
||||
sysUserId, err := l.svcCtx.UserPlatformModel.FindUserIdByPlatform(l.ctx, in.Platform, in.PUid)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "获取系统用户ID失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.UserIdResp{
|
||||
UserId: sysUserId,
|
||||
}, nil
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type RetrievePlatformUserLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewRetrievePlatformUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RetrievePlatformUserLogic {
|
||||
return &RetrievePlatformUserLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// RetrievePlatformUser 查询或创建用户(此时不查询平台用户信息)
|
||||
func (l *RetrievePlatformUserLogic) RetrievePlatformUser(in *pb.PlatformUserReq) (*pb.PlatformUserResp, error) {
|
||||
var username string
|
||||
var dbPlatformUser *model.UserPlatform
|
||||
|
||||
err := l.svcCtx.UserPlatformModel.Transaction(l.ctx, nil, func(tx *gorm.DB) error {
|
||||
var err error
|
||||
if dbPlatformUser, err = l.svcCtx.UserPlatformModel.FindOneByPlatformAndPUid(l.ctx, tx, in.Platform, in.PUid); err != nil {
|
||||
if !errors.Is(err, model.ErrNotFound) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if dbPlatformUser != nil {
|
||||
if one, err := l.svcCtx.UserModel.FindOneTx(l.ctx, tx, dbPlatformUser.UserId); err != nil {
|
||||
username = one.Username
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// insert
|
||||
newId := uuid.NextId()
|
||||
if err := l.svcCtx.UserModel.InsertTx(l.ctx, tx, &model.User{Id: newId}); err != nil {
|
||||
return errors.Wrap(err, "插入用户数据失败")
|
||||
}
|
||||
dbPlatformUser = &model.UserPlatform{
|
||||
Id: uuid.NextId(),
|
||||
UserId: newId,
|
||||
Platform: in.Platform,
|
||||
PUid: in.PUid,
|
||||
PInfo: "{}",
|
||||
}
|
||||
if err := l.svcCtx.UserPlatformModel.InsertTx(l.ctx, tx, dbPlatformUser); err != nil {
|
||||
return errors.Wrap(err, "插入平台用户数据失败")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "查询或创建用户-事务执行失败, err:%+v", err)
|
||||
}
|
||||
return &pb.PlatformUserResp{
|
||||
User: l.buildPBUser(username, dbPlatformUser),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *RetrievePlatformUserLogic) buildPBUser(username string, dbPlatformUser *model.UserPlatform) *pb.User {
|
||||
return &pb.User{
|
||||
Id: dbPlatformUser.UserId,
|
||||
Username: username,
|
||||
Platform: dbPlatformUser.Platform,
|
||||
PUid: dbPlatformUser.PUid,
|
||||
PUname: dbPlatformUser.PUname,
|
||||
PAvatar: dbPlatformUser.PAvatar,
|
||||
PInfo: dbPlatformUser.PInfo,
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error {
|
||||
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, {{.lowerStartCamelPrimaryKey}})
|
||||
if err!=nil{
|
||||
return err
|
||||
}
|
||||
|
||||
{{end}} {{.keys}}
|
||||
err {{if .containsIndexCache}}={{else}}:={{end}} m.ExecCtx(ctx, func(conn *gorm.DB) *gorm.DB {
|
||||
return conn.Delete(&{{.upperStartCamelObject}}{}, {{.lowerStartCamelPrimaryKey}})
|
||||
}, {{.keyValues}}){{else}} err:= m.conn.WithContext(ctx).Delete(&{{.upperStartCamelObject}}{}, {{.lowerStartCamelPrimaryKey}}).Error
|
||||
{{end}}
|
||||
return err
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package {{.pkg}}
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var ErrNotFound = gorm.ErrRecordNotFound
|
@ -0,0 +1 @@
|
||||
{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}
|
@ -0,0 +1,8 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary interface{}) string {
|
||||
return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary)
|
||||
}
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) queryPrimary(conn *gorm.DB, v, primary interface{}) error {
|
||||
return conn.Model(&{{.upperStartCamelObject}}{}).Where("{{.originalPrimaryField}} = ?", primary).Take(v).Error
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) {
|
||||
{{if .withCache}}{{.cacheKey}}
|
||||
var resp {{.upperStartCamelObject}}
|
||||
err := m.QueryRowIndexCtx(ctx, &resp, {{.cacheKeyVariable}}, m.formatPrimary, func(conn *gorm.DB, v interface{}) (interface{}, error) {
|
||||
if err := conn.Model(&{{.upperStartCamelObject}}{}).Where("{{.originalField}}", {{.lowerStartCamelField}}).Take(&resp).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.{{.upperStartCamelPrimaryKey}}, nil
|
||||
}, m.queryPrimary)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}{{else}}var resp {{.upperStartCamelObject}}
|
||||
err := m.conn.WithContext(ctx).Model(&{{.upperStartCamelObject}}{}).Where("{{.originalField}}", {{.lowerStartCamelField}}).Take(&resp).Error
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}{{end}}
|
@ -0,0 +1,25 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) {
|
||||
{{if .withCache}}{{.cacheKey}}
|
||||
var resp {{.upperStartCamelObject}}
|
||||
err := m.QueryRowCtx(ctx, &resp, {{.cacheKeyVariable}}, func(conn *gorm.DB) *gorm.DB {
|
||||
return conn.Where("id = ?", {{.lowerStartCamelPrimaryKey}})
|
||||
})
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}{{else}}var resp {{.upperStartCamelObject}}
|
||||
err := m.conn.WithContext(ctx).Model(&{{.upperStartCamelObject}}{}).Where("{{.originalPrimaryKey}} = ?", {{.lowerStartCamelPrimaryKey}}).Take(&resp).Error
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case gormc.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}{{end}}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
||||
"strings"
|
||||
{{if .time}}"time"{{end}}
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"gorm.io/gorm"
|
||||
)
|
@ -0,0 +1,12 @@
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
{{if .time}}"time"{{end}}
|
||||
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormc"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"gorm.io/gorm"
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context, data *{{.upperStartCamelObject}}) error {
|
||||
{{if .withCache}}{{.keys}}
|
||||
err := m.ExecCtx(ctx, func(conn *gorm.DB) *gorm.DB {
|
||||
return conn.Create(&data)
|
||||
}, {{.keyValues}}){{else}}err:=m.conn.WithContext(ctx).Create(&data).Error{{end}}
|
||||
return err
|
||||
}
|
@ -0,0 +1 @@
|
||||
Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error
|
@ -0,0 +1 @@
|
||||
FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error)
|
@ -0,0 +1 @@
|
||||
FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error)
|
@ -0,0 +1 @@
|
||||
Insert(ctx context.Context, data *{{.upperStartCamelObject}}) error
|
@ -0,0 +1 @@
|
||||
Update(ctx context.Context, data *{{.upperStartCamelObject}}) error
|
@ -0,0 +1,13 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package {{.pkg}}
|
||||
{{.imports}}
|
||||
{{.vars}}
|
||||
{{.types}}
|
||||
{{.new}}
|
||||
{{.insert}}
|
||||
{{.find}}
|
||||
{{.update}}
|
||||
{{.delete}}
|
||||
{{.extraMethod}}
|
||||
{{.tableName}}
|
@ -0,0 +1,7 @@
|
||||
|
||||
func new{{.upperStartCamelObject}}Model(conn *gorm.DB{{if .withCache}}, c cache.CacheConf{{end}}) *default{{.upperStartCamelObject}}Model {
|
||||
return &default{{.upperStartCamelObject}}Model{
|
||||
{{if .withCache}}CachedConn: gormc.NewConn(conn, c){{else}}conn:conn{{end}},
|
||||
table: {{.table}},
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package {{.pkg}}
|
||||
{{if .withCache}}
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
{{else}}
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
{{end}}
|
||||
var _ {{.upperStartCamelObject}}Model = (*custom{{.upperStartCamelObject}}Model)(nil)
|
||||
|
||||
type (
|
||||
// {{.upperStartCamelObject}}Model is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in custom{{.upperStartCamelObject}}Model.
|
||||
{{.upperStartCamelObject}}Model interface {
|
||||
{{.lowerStartCamelObject}}Model
|
||||
}
|
||||
|
||||
custom{{.upperStartCamelObject}}Model struct {
|
||||
*default{{.upperStartCamelObject}}Model
|
||||
}
|
||||
)
|
||||
|
||||
// New{{.upperStartCamelObject}}Model returns a model for the database table.
|
||||
func New{{.upperStartCamelObject}}Model(conn *gorm.DB{{if .withCache}}, c cache.CacheConf{{end}}) {{.upperStartCamelObject}}Model {
|
||||
return &custom{{.upperStartCamelObject}}Model{
|
||||
default{{.upperStartCamelObject}}Model: new{{.upperStartCamelObject}}Model(conn{{if .withCache}}, c{{end}}),
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
|
||||
func ({{.upperStartCamelObject}}) TableName() string {
|
||||
model := new{{.upperStartCamelObject}}Model(nil)
|
||||
return model.tableName()
|
||||
}
|
@ -0,0 +1 @@
|
||||
`gorm:"column:{{.field}}"`
|
@ -0,0 +1,15 @@
|
||||
|
||||
type (
|
||||
{{.lowerStartCamelObject}}Model interface{
|
||||
{{.method}}
|
||||
}
|
||||
|
||||
default{{.upperStartCamelObject}}Model struct {
|
||||
{{if .withCache}}gormc.CachedConn{{else}}conn *gorm.DB{{end}}
|
||||
table string
|
||||
}
|
||||
|
||||
{{.upperStartCamelObject}} struct {
|
||||
{{.fields}}
|
||||
}
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
|
||||
func (m *default{{.upperStartCamelObject}}Model) Update(ctx context.Context, data *{{.upperStartCamelObject}}) error {
|
||||
{{if .withCache}}{{.keys}}
|
||||
err := m.ExecCtx(ctx, func(conn *gorm.DB) *gorm.DB {
|
||||
return conn.Save(data)
|
||||
}, {{.keyValues}}){{else}}err:=m.conn.WithContext(ctx).Save(data).Error{{end}}
|
||||
return err
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
var (
|
||||
{{.lowerStartCamelObject}}FieldNames = builder.RawFieldNames(&{{.upperStartCamelObject}}{}{{if .postgreSql}},true{{end}})
|
||||
{{.lowerStartCamelObject}}Rows = strings.Join({{.lowerStartCamelObject}}FieldNames, ",")
|
||||
{{.lowerStartCamelObject}}RowsExpectAutoSet = {{if .postgreSql}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "create_time", "update_time"), ","){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "`create_time`", "`update_time`"), ","){{end}}
|
||||
{{.lowerStartCamelObject}}RowsWithPlaceHolder = {{if .postgreSql}}builder.PostgreSqlJoin(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "create_time", "update_time")){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "`create_time`", "`update_time`"), "=?,") + "=?"{{end}}
|
||||
|
||||
{{if .withCache}}{{.cacheKeys}}{{end}}
|
||||
)
|
Loading…
Reference in New Issue