185 lines
4.4 KiB
Go
185 lines
4.4 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
"github.com/gogf/gf/v2/errors/gerror"
|
||
"github.com/gogf/gf/v2/util/gconv"
|
||
|
||
"cid/dao"
|
||
"cid/model/dto"
|
||
"cid/model/entity"
|
||
)
|
||
|
||
var Advertiser = new(advertiser)
|
||
|
||
type advertiser struct{}
|
||
|
||
// Add 添加广告主
|
||
func (s *advertiser) Add(ctx context.Context, req *dto.AddAdvertiserReq) (res *dto.AddAdvertiserRes, err error) {
|
||
advertiser := &entity.Advertiser{}
|
||
if err = gconv.Struct(req, advertiser); err != nil {
|
||
return
|
||
}
|
||
|
||
// 设置基础字段
|
||
now := time.Now()
|
||
advertiser.CreatedAt = now
|
||
advertiser.UpdatedAt = now
|
||
advertiser.IsDeleted = false
|
||
|
||
// 设置初始状态
|
||
advertiser.Status = "待审核"
|
||
|
||
if err = dao.Advertiser.Insert(ctx, advertiser); err != nil {
|
||
return
|
||
}
|
||
|
||
res = &dto.AddAdvertiserRes{Id: advertiser.Id.Hex()}
|
||
return
|
||
}
|
||
|
||
// Update 更新广告主
|
||
func (s *advertiser) Update(ctx context.Context, req *dto.UpdateAdvertiserReq) (err error) {
|
||
// 更新修改时间(不需要设置,DAO层会处理)
|
||
return dao.Advertiser.Update(ctx, req)
|
||
}
|
||
|
||
// UpdateStatus 更新广告主状态
|
||
func (s *advertiser) UpdateStatus(ctx context.Context, req *dto.UpdateAdvertiserStatusReq) (err error) {
|
||
return dao.Advertiser.UpdateStatus(ctx, req.Id, req.Status)
|
||
}
|
||
|
||
// Audit 审核广告主
|
||
func (s *advertiser) Audit(ctx context.Context, req *dto.AuditAdvertiserReq) (err error) {
|
||
return dao.Advertiser.Audit(ctx, req.Id, req.AuditStatus, req.AuditReason)
|
||
}
|
||
|
||
// Recharge 充值
|
||
func (s *advertiser) Recharge(ctx context.Context, req *dto.RechargeAdvertiserReq) (err error) {
|
||
// 验证金额
|
||
if req.Amount <= 0 {
|
||
return gerror.New("充值金额必须大于0")
|
||
}
|
||
|
||
// 执行充值
|
||
err = dao.Advertiser.Recharge(ctx, req.Id, req.Amount, req.Remark)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 记录充值流水(实际项目中可能需要创建充值记录表)
|
||
// 这里简化处理
|
||
|
||
return
|
||
}
|
||
|
||
// UpdateCreditLimit 更新授信额度
|
||
func (s *advertiser) UpdateCreditLimit(ctx context.Context, req *dto.UpdateCreditLimitReq) (err error) {
|
||
// 验证授信额度
|
||
if req.CreditLimit < 0 {
|
||
return gerror.New("授信额度不能为负数")
|
||
}
|
||
|
||
// 更新授信额度
|
||
err = dao.Advertiser.UpdateCreditLimit(ctx, req.Id, req.CreditLimit)
|
||
return
|
||
}
|
||
|
||
// GetOne 获取广告主详情
|
||
func (s *advertiser) GetOne(ctx context.Context, req *dto.GetAdvertiserReq) (res *dto.GetAdvertiserRes, err error) {
|
||
advertiser, err := dao.Advertiser.GetOne(ctx, req.Id)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
res = &dto.GetAdvertiserRes{
|
||
Advertiser: advertiser,
|
||
}
|
||
return
|
||
}
|
||
|
||
// List 获取广告主列表
|
||
func (s *advertiser) List(ctx context.Context, req *dto.ListAdvertiserReq) (res *dto.ListAdvertiserRes, err error) {
|
||
list, total, err := dao.Advertiser.List(ctx, req)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
res = &dto.ListAdvertiserRes{
|
||
List: list,
|
||
Total: int(total),
|
||
}
|
||
return
|
||
}
|
||
|
||
// GetBalance 获取广告主余额
|
||
func (s *advertiser) GetBalance(ctx context.Context, id string) (balance, creditLimit int64, err error) {
|
||
advertiser, err := dao.Advertiser.GetOne(ctx, id)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
balance = advertiser.AccountBalance
|
||
creditLimit = advertiser.CreditLimit
|
||
return
|
||
}
|
||
|
||
// CheckBudget 检查广告主预算
|
||
func (s *advertiser) CheckBudget(ctx context.Context, id string, cost int64) (hasEnoughBudget bool, err error) {
|
||
advertiser, err := dao.Advertiser.GetOne(ctx, id)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 可用金额 = 账户余额 + 授信额度 - 已消耗
|
||
availableAmount := advertiser.AccountBalance + advertiser.CreditLimit
|
||
|
||
// 检查预算是否充足
|
||
hasEnoughBudget = availableAmount >= cost
|
||
|
||
return
|
||
}
|
||
|
||
// DeductBudget 扣除预算
|
||
func (s *advertiser) DeductBudget(ctx context.Context, id string, cost int64) (err error) {
|
||
// 检查预算是否充足
|
||
hasEnoughBudget, err := s.CheckBudget(ctx, id, cost)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
if !hasEnoughBudget {
|
||
return gerror.New("预算不足")
|
||
}
|
||
|
||
// 获取广告主信息
|
||
advertiser, err := dao.Advertiser.GetOne(ctx, id)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 计算新余额
|
||
newBalance := advertiser.AccountBalance - cost
|
||
|
||
// 如果账户余额为负,从授信额度中扣除
|
||
if newBalance < 0 {
|
||
newCreditLimit := advertiser.CreditLimit + newBalance
|
||
newBalance = 0
|
||
|
||
// 更新授信额度
|
||
err = dao.Advertiser.UpdateCreditLimit(ctx, id, newCreditLimit)
|
||
if err != nil {
|
||
return
|
||
}
|
||
}
|
||
|
||
// 更新账户余额
|
||
err = dao.Advertiser.Update(ctx, &dto.UpdateAdvertiserReq{
|
||
Id: id,
|
||
AccountBalance: &newBalance,
|
||
})
|
||
return
|
||
}
|