electricity_bill_calc_service/service/charge.go

116 lines
3.5 KiB
Go

package service
import (
"electricity_bill_calc/global"
"electricity_bill_calc/logger"
"electricity_bill_calc/repository"
"electricity_bill_calc/types"
"fmt"
"go.uber.org/zap"
)
type _ChargeService struct {
log *zap.Logger
}
var ChargeService = &_ChargeService{
log: logger.Named("Service", "Charge"),
}
// 创建一条新的用户充值记录,同时更新用户的服务期限
func (cs _ChargeService) RecordUserCharge(uid string, fee, discount, amount *float64, chargeTo types.Date, extendExpriationIgnoringSettle bool) (bool, error) {
cs.log.Info(
"创建一条新的用户充值记录。",
zap.String("uid", uid),
zap.Float64p("fee", fee),
zap.Float64p("discount", discount),
zap.Float64p("amount", amount),
logger.DateField("chargeTo", chargeTo),
zap.Bool("extendExpriationIgnoringSettle", extendExpriationIgnoringSettle),
)
ctx, cancel := global.TimeoutContext()
defer cancel()
tx, err := global.DB.Begin(ctx)
if err != nil {
cs.log.Error("开启数据库事务失败。", zap.Error(err))
return false, err
}
ok, err := repository.ChargeRepository.CreateChargeRecord(tx, ctx, uid, fee, discount, amount, chargeTo)
switch {
case err == nil && !ok:
cs.log.Error("未能成功创建用户充值记录", zap.Error(err))
tx.Rollback(ctx)
return false, fmt.Errorf("未能成功创建用户充值记录")
case err != nil:
cs.log.Error("创建用户充值记录失败。", zap.Error(err))
tx.Rollback(ctx)
return false, err
}
if extendExpriationIgnoringSettle {
ok, err = repository.UserRepository.UpdateServiceExpiration(tx, ctx, uid, chargeTo.Time)
switch {
case err != nil:
cs.log.Error("更新用户服务期限失败。", zap.Error(err))
tx.Rollback(ctx)
return false, err
case !ok:
cs.log.Error("未能成功更新用户服务期限", zap.Error(err))
tx.Rollback(ctx)
return false, fmt.Errorf("未能成功更新用户服务期限")
}
}
err = tx.Commit(ctx)
if err != nil {
cs.log.Error("提交数据库事务失败。", zap.Error(err))
return false, err
}
return true, nil
}
// 撤销用户的某一条充值记录,同时重新设置用户的服务期限
func (cs _ChargeService) CancelUserCharge(uid string, seq int64) (bool, error) {
cs.log.Info("撤销用户的充值记录。", zap.String("uid", uid), zap.Int64("seq", seq))
ctx, cancel := global.TimeoutContext()
defer cancel()
tx, err := global.DB.Begin(ctx)
if err != nil {
cs.log.Error("开启数据库事务失败。", zap.Error(err))
return false, err
}
ok, err := repository.ChargeRepository.CancelCharge(tx, ctx, uid, seq)
switch {
case err == nil && !ok:
cs.log.Error("未能成功撤销用户充值记录", zap.Error(err))
tx.Rollback(ctx)
return false, fmt.Errorf("未能成功撤销用户充值记录")
case err != nil:
cs.log.Error("撤销用户充值记录失败。", zap.Error(err))
tx.Rollback(ctx)
return false, err
}
if ok {
lastValidCharge, err := repository.ChargeRepository.LatestValidChargeTo(tx, ctx, uid)
if err != nil {
cs.log.Error("查询用户最近一次有效的充值记录失败。", zap.Error(err))
tx.Rollback(ctx)
return false, err
}
ok, err = repository.UserRepository.UpdateServiceExpiration(tx, ctx, uid, lastValidCharge.Time)
if err != nil || !ok {
cs.log.Error("更新用户服务期限失败。", zap.Error(err))
tx.Rollback(ctx)
return false, err
}
}
err = tx.Commit(ctx)
if err != nil {
cs.log.Error("提交数据库事务失败。", zap.Error(err))
return false, err
}
return true, nil
}