micro-bundle/internal/logic/bundleExtendLogic.go
2025-10-13 14:15:37 +08:00

326 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logic
import (
"errors"
"micro-bundle/internal/dao"
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/common/logger"
"github.com/jinzhu/copier"
"github.com/samber/lo"
)
func BundleExtend(req *bundle.BundleExtendRequest) (*bundle.BundleExtendResponse, error) {
data := model.BundleExtensionRecords{}
if err := copier.CopyWithOption(&data, req, copier.Option{DeepCopy: true}); err != nil {
return nil, err
}
if err := dao.ExtendBundleBalanceByUserId(model.BundleBalanceExtendPo{
UserId: int(req.UserId),
VideoNumber: int(req.VideoAdditional),
ImageNumber: int(req.ImagesAdditional),
DataAnalysisNumber: int(req.DataAdditional),
AccountNumber: int(req.AccountAdditional),
DurationNumber: int(req.DataAdditional),
}); err != nil {
return nil, errors.New("用户没有余量信息")
}
err := dao.AddBundleExtendRecord(data)
if err != nil {
logger.Error(err)
return nil, errors.New("创建扩展记录失败")
}
return nil, nil
}
func BundleExtendRecordsList(req *bundle.BundleExtendRecordsListRequest) (*bundle.BundleExtendRecordsListResponse, error) {
data, total, err := dao.GetBundleExtendRecordList(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
resp := &bundle.BundleExtendRecordsListResponse{}
resp.Total = total
resp.Data = lo.Map(data, func(m model.BundleExtendRecordItemPo, _ int) *bundle.BundleExtendRecordItem {
result := &bundle.BundleExtendRecordItem{}
copier.Copy(result, &m)
result.CreatedAt = uint64(m.CreatedAt.UnixMilli())
return result
})
return resp, nil
}
func GetBundleBalanceList(req *bundle.GetBundleBalanceListReq) (*bundle.GetBundleBalanceListResp, error) {
data, total, err := dao.GetBundleBalanceList(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
resp := &bundle.GetBundleBalanceListResp{}
resp.Total = total
resp.Data = lo.Map(data, func(m model.BundleBalancePo, _ int) *bundle.BundleBalanceItem {
result := &bundle.BundleBalanceItem{}
copier.Copy(result, &m)
loc, _ := time.LoadLocation("Asia/Shanghai")
t, _ := time.ParseInLocation(time.DateTime, m.ExpirationTime, loc)
if m.OrderUUID != "" {
result.Bought = 2
} else {
result.Bought = 1
}
result.ExpiredTime = t.UnixMilli()
return result
})
return resp, nil
}
func GetBundleBalanceByUserId(req *bundle.GetBundleBalanceByUserIdReq) (*bundle.GetBundleBalanceByUserIdResp, error) {
data, err := dao.GetBundleBalanceByUserId(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
result := &bundle.GetBundleBalanceByUserIdResp{}
copier.Copy(result, &data)
loc, _ := time.LoadLocation("Asia/Shanghai")
t, _ := time.ParseInLocation(time.DateTime, data.ExpiredTime, loc)
result.ExpiredTime = t.UnixMilli()
t, _ = time.ParseInLocation(time.DateTime, data.PayTime, loc)
result.PayTime = t.UnixMilli()
return result, nil
}
func AddBundleBalance(req *bundle.AddBundleBalanceReq) (*bundle.AddBundleBalanceResp, error) {
data := model.BundleBalanceUsePo{
UserId: int(req.UserId),
AccountNumber: int(req.AccountConsumptionNumber),
ImageNumber: int(req.ImageConsumptionNumber),
VideoNumber: int(req.VideoConsumptionNumber),
DataAnalysisNumber: int(req.DataAnalysisConsumptionNumber),
}
uesdType, err := dao.AddBundleBalanceByUserId(data)
return &bundle.AddBundleBalanceResp{
UsedType: uint32(uesdType),
}, err
}
func CreateBundleBalance(req *bundle.CreateBundleBalanceReq) (*bundle.CreateBundleBalanceResp, error) {
var data model.BundleBalance
addValues, err := dao.GetValueAddByOrderUUID(req.OrderUUID)
if err != nil || len(addValues) == 0 {
return nil, errors.New("获取增值服务失败")
}
data.StartAt = time.Now()
data.ExpiredAt = time.Now()
userId, err := strconv.Atoi(addValues[0].CustomerID)
if err != nil {
return nil, err
}
data.Month = time.Now().Format("2006-01")
data.UserId = userId
data.OrderUUID = req.OrderUUID
for _, v := range addValues {
switch v.ServiceType {
case 1: // 视频类型
if v.EquityType == 1 { // 套餐权益
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitVideoQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.BundleLimitVideoExpiredNumber += int(v.Num)
} else {
data.BundleLimitVideoNumber += int(v.Num)
}
} else {
data.BundleVideoNumber += int(v.Num)
}
} else {
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitVideoQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.IncreaseLimitVideoExpiredNumber += int(v.Num)
} else {
data.IncreaseLimitVideoNumber += int(v.Num)
}
} else {
data.IncreaseVideoNumber += int(v.Num)
}
}
case 2: // 图文类型
if v.EquityType == 1 { // 套餐权益
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitImageQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.BundleLimitImageExpiredNumber += int(v.Num)
} else {
data.BundleLimitImageNumber += int(v.Num)
}
} else {
data.BundleImageNumber += int(v.Num)
}
} else {
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitImageQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.IncreaseLimitImageExpiredNumber += int(v.Num)
} else {
data.IncreaseLimitImageNumber += int(v.Num)
}
} else {
data.IncreaseImageNumber += int(v.Num)
}
}
case 3: // 数据分析
if v.EquityType == 1 { // 套餐权益
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitDataAnalysisQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.BundleLimitDataAnalysisExpiredNumber += int(v.Num)
} else {
data.BundleLimitDataAnalysisNumber += int(v.Num)
}
} else {
data.BundleDataAnalysisNumber += int(v.Num)
}
} else {
if v.QuotaType == 2 { // 限制额度
data.MonthlyLimitDataAnalysisQuotaNumber = int(v.QuotaValue)
if v.IsExpired { // 会过期的限制类型
data.IncreaseLimitDataAnalysisExpiredNumber += int(v.Num)
} else {
data.IncreaseLimitDataAnalysisNumber += int(v.Num)
}
} else {
data.IncreaseDataAnalysisNumber += int(v.Num)
}
}
case 4: // 账号数
if v.EquityType == 1 { // 套餐权益
data.BundleAccountNumber += int(v.Num)
} else {
data.IncreaseAccountNumber += int(v.Num)
}
case 5: // 可用时长
switch v.Unit {
case "天":
data.ExpiredAt = data.ExpiredAt.Add(time.Hour * 24 * time.Duration(v.Num))
case "月":
data.ExpiredAt = data.ExpiredAt.Add(time.Hour * 24 * 30 * time.Duration(v.Num))
case "年":
data.ExpiredAt = data.ExpiredAt.Add(time.Hour * 24 * 365 * time.Duration(v.Num))
}
}
}
now := time.Now()
cal := func(total, limit int) int { // 计算本月发放的限制类型数量
var released int // 已释放的次数
if data.StartAt.Month() == now.Month() && data.StartAt.Year() == now.Year() {
} else if data.StartAt.Day() >= 16 { //第一个月释放的
released += limit/2 + 1
} else {
released += limit
}
interval := now.Year()*12 + int(now.Month()) - (data.StartAt.Year()*12 + int(data.StartAt.Month())) // 后续月份释放的
released += interval * limit
remaining := max(total-released, 0) // 还剩余多少次没有发放
if data.StartAt.Month() == now.Month() && data.StartAt.Year() == now.Year() && data.StartAt.Day() >= 16 { // 本月为第一个月并且16号后购买只给一半向上取整
return min(limit/2+1, remaining)
}
if data.ExpiredAt.Month() == now.Month() && data.ExpiredAt.Year() == now.Year() && data.ExpiredAt.Day() < 16 { // 本月为最后一个月并且16号前到期只给一半向下取整
return min(limit/2, remaining)
}
return min(limit, remaining)
}
// 当月可用的限制类型数等于本月方法的套餐和增值两种类型的总和
data.MonthlyLimitVideoExpireNumber = cal(data.BundleLimitVideoExpiredNumber, data.MonthlyLimitVideoQuotaNumber) + cal(data.IncreaseLimitVideoExpiredNumber, data.MonthlyLimitVideoQuotaNumber)
data.MonthlyLimitVideoNumber = cal(data.BundleLimitVideoNumber, data.MonthlyLimitVideoQuotaNumber) + cal(data.IncreaseLimitVideoNumber, data.MonthlyLimitVideoQuotaNumber)
data.MonthlyLimitImageExpireNumber = cal(data.BundleLimitImageExpiredNumber, data.MonthlyLimitImageQuotaNumber) + cal(data.IncreaseLimitImageExpiredNumber, data.MonthlyLimitImageQuotaNumber)
data.MonthlyLimitImageNumber = cal(data.BundleLimitImageNumber, data.MonthlyLimitImageQuotaNumber) + cal(data.IncreaseLimitImageNumber, data.MonthlyLimitImageQuotaNumber)
data.MonthlyLimitDataAnalysisExpireNumber = cal(data.BundleLimitDataAnalysisExpiredNumber, data.MonthlyLimitDataAnalysisQuotaNumber) + cal(data.IncreaseLimitDataAnalysisExpiredNumber, data.MonthlyLimitDataAnalysisQuotaNumber)
data.MonthlyLimitDataAnalysisNumber = cal(data.BundleLimitDataAnalysisNumber, data.MonthlyLimitDataAnalysisQuotaNumber) + cal(data.IncreaseLimitDataAnalysisNumber, data.MonthlyLimitDataAnalysisQuotaNumber)
err = dao.CreateBundleBalance(data)
if err != nil {
logger.Error(err)
return nil, errors.New("创建余量信息失败")
}
return nil, nil
}
func GetUsedRecord(req *bundle.GetUsedRecordListReq) (*bundle.GetUsedRecordListResp, error) {
data, total, err := dao.GetUsedRecord(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
resp := &bundle.GetUsedRecordListResp{}
resp.Total = total
resp.Data = lo.Map(data, func(m model.CostLogPo, _ int) *bundle.WorkCastItem {
result := &bundle.WorkCastItem{}
copier.Copy(result, &m)
loc, _ := time.LoadLocation("Asia/Shanghai")
t := time.Unix(m.ArtistConfirmedTime, 0).In(loc)
result.ArtistConfirmedTime = t.Format(time.DateTime)
return result
})
return resp, nil
}
func GetImageWorkDetail(req *bundle.GetImageWorkDetailReq) (*bundle.GetImageWorkDetailResp, error) {
data, err := dao.GetImageWorkDetail(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
result := &bundle.GetImageWorkDetailResp{}
err = copier.Copy(result, &data)
return result, err
}
func GetVedioWorkDetail(req *bundle.GetVedioWorkDetailReq) (*bundle.GetVedioeWorkDetailResp, error) {
data, err := dao.GetVedioWorkDetail(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
result := &bundle.GetVedioeWorkDetailResp{}
err = copier.Copy(result, &data)
return result, err
}
func ToBeComfirmedWorks(req *bundle.ToBeComfirmedWorksReq) (*bundle.ToBeComfirmedWorksResp, error) {
data, total, unconfirmed, err := dao.ToBeComfirmedWorks(req)
if err != nil {
logger.Error(err)
return nil, errors.New("查询失败")
}
result := &bundle.ToBeComfirmedWorksResp{
Total: total,
Unconfirmed: unconfirmed,
}
result.Data = lo.Map(data, func(m model.CastWorkLog, _ int) *bundle.WorkItem {
result := &bundle.WorkItem{}
copier.Copy(result, &m)
return result
})
return result, nil
}
func ConfirmWork(req *bundle.ConfirmWorkReq) (*bundle.ConfirmWorkResp, error) {
return nil, dao.ConfirmWork(req)
}
func BundleActivate(req *bundle.BundleActivateReq) error {
return dao.BundleActivate(req.Ids)
}
func UpdateBundleBalance() {
dao.UpdateBundleBalance()
}