micro-bundle/internal/dao/bundleExtend.go
2025-10-16 09:37:48 +08:00

589 lines
25 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 dao
import (
"errors"
"fmt"
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
"micro-bundle/pkg/app"
"micro-bundle/pkg/utils"
"time"
"gorm.io/gorm"
)
func AddBundleExtendRecord(data model.BundleExtensionRecords) error {
return app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&data).Error; err != nil {
return err
}
if data.AvailableDurationAdditional != 0 && data.TimeUnit != 0 {
record := model.BundleBalance{}
if err := tx.Model(&model.BundleBalance{}).Where(&model.BundleBalance{UserId: data.UserId}).Order("month desc").First(&record).Error; err != nil {
return err
}
record.ExpiredAt = record.ExpiredAt.Add(time.Hour * 24 * time.Duration(data.AvailableDurationAdditional))
return tx.Save(record).Error
}
return nil
})
}
func GetBundleExtendRecordList(req *bundle.BundleExtendRecordsListRequest) (data []model.BundleExtendRecordItemPo, total int64, err error) {
session := app.ModuleClients.BundleDB.Table("fiee_bundle.bundle_extension_records AS ber").
Select(`
ber.*,
rn.name as user_name,
u.tel_num as user_phone_number
`).Joins("LEFT JOIN `micro-account`.`user` u on u.id = user_id").
Joins("LEFT JOIN `micro-account`.`real_name` rn on u.real_name_id = rn.id").
Order("created_at desc")
if req.User != "" {
if utils.IsPhoneNumber(req.User) {
session = session.Where("u.tel_num = ?", req.User)
} else {
session = session.Where("rn.name like ?", "%"+req.User+"%")
}
}
if req.Operator != "" {
if utils.IsPhoneNumber(req.Operator) {
session = session.Where("ber.operator_phone_number = ?", req.Operator)
} else {
session = session.Where("ber.operator_name like ?", "%"+req.Operator+"%")
}
}
if req.Type != 0 {
session = session.Where("ber.`type` = ?", req.Type)
}
if req.StartTime != 0 {
session = session.Where("ber.created_at >= ?", time.UnixMilli(int64(req.StartTime)))
}
if req.EndTime != 0 {
session = session.Where("ber.created_at <= ?", time.UnixMilli(int64(req.EndTime)))
}
if req.AssociatedOrderNumber != "" {
session = session.Where("ber.associated_order_number like ?", "%"+req.AssociatedOrderNumber+"%")
}
if err = session.Count(&total).Error; err != nil {
return
}
if req.Page != 0 && req.PageSize != 0 {
session = session.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
}
err = session.Find(&data).Error
return
}
func GetBundleBalanceList(req *bundle.GetBundleBalanceListReq) (data []model.BundleBalancePo, total int64, err error) {
subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1").
Select("bor1.*").
Joins(`INNER JOIN (
SELECT customer_id, MAX(created_at) AS max_created_time
FROM bundle_order_records
GROUP BY customer_id
) bor2 ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time`)
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").Unscoped().
Select(`bb.*, bor.bundle_name, bor.status,
bor.uuid as order_uuid, rn.name as user_name,bc.activate,
u.tel_num as user_phone_number, u.id as user_id`).
Joins("LEFT JOIN `micro-account`.real_name rn ON u.real_name_id = rn.id").
Joins("LEFT JOIN (?) as bor ON bor.customer_id = u.id", subQuery).
Joins("LEFT JOIN fiee_bundle.bundle_balance bb ON u.id = bb.user_id AND bb.order_uuid = bor.uuid").
Joins("LEFT JOIN bundle_activate bc on bc.user_id = u.id").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
Where("bb.month = ?", req.Month).
Order("bor.expiration_time desc")
if req.UserName != "" {
if utils.IsPhoneNumber(req.UserName) {
session = session.Where("u.tel_num = ?", req.UserName)
} else {
session = session.Where("rn.name like ?", "%"+req.UserName+"%")
}
}
if req.Status != 0 {
session = session.Where("bor.status = ?", req.Status)
}
if req.BundleName != "" {
session = session.Where("bor.bundle_name like ?", "%"+req.BundleName+"%")
}
if req.ExpiredTimeEnd != 0 {
session = session.Where("bb.expired_at <= ?", time.UnixMilli(req.ExpiredTimeEnd))
}
if req.ExpiredTimeStart != 0 {
session = session.Where("bb.expired_at >= ?", time.UnixMilli(req.ExpiredTimeStart))
}
if req.Bought == 2 {
session = session.Where("bor.uuid IS NOT NULL")
}
if req.Bought == 1 {
session = session.Where("bor.uuid IS NULL")
}
err = session.Count(&total).Error
if err != nil {
return
}
if req.Page != 0 && req.PageSize != 0 {
session = session.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
}
err = session.Find(&data).Error
return
}
func GetBundleBalanceByUserId(req *bundle.GetBundleBalanceByUserIdReq) (data model.UserBundleBalancePo, err error) {
subQuery := app.ModuleClients.BundleDB.Table("bundle_order_records as bor1").
Select("bor1.*").
Joins(`INNER JOIN (
SELECT customer_id, MAX(created_at) AS max_created_time
FROM bundle_order_records
GROUP BY customer_id
) bor2 ON bor1.customer_id = bor2.customer_id AND bor1.created_at = bor2.max_created_time`)
session := app.ModuleClients.BundleDB.Table("`micro-account`.`user` AS u").Unscoped().
Select(`bb.*, bor.bundle_name, bor.status,bor.amount AS payment_amount,bor.amount_type AS payment_type,
bor.uuid as order_uuid, rn.name as user_name,bc.activate,
u.tel_num as user_phone_number, u.id as user_id`).
Joins("LEFT JOIN `micro-account`.real_name rn ON u.real_name_id = rn.id").
Joins("LEFT JOIN (?) as bor ON bor.customer_id = u.id", subQuery).
Joins("LEFT JOIN fiee_bundle.bundle_balance bb ON u.id = bb.user_id AND bb.order_uuid = bor.uuid").
Joins("LEFT JOIN bundle_activate bc on bc.user_id = u.id").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
Where("u.id = ?", req.UserId).
Where("bb.month = ?", time.Now().Format("2006-01")).
Order("bor.expiration_time desc")
err = session.First(&data).Error
return
}
func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) (usedType int, err error) {
err = app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) (err error) {
ba := model.BundleActivate{}
if err := tx.Model(&model.BundleActivate{}).Where("user_id = ?", data.UserId).First(&ba).Error; err != nil || ba.Activate != 2 {
return errors.New("套餐未激活")
}
oldData := model.BundleBalance{}
if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", data.UserId).Where("month = ?", time.Now().Format("2006-01")).Order("created_at desc").First(&oldData).Error; err != nil {
return errors.New("用户还没有套餐信息")
}
if data.AccountNumber > 0 { // 增加账号消耗数
if oldData.BundleAccountConsumptionNumber < oldData.BundleAccountNumber { // 消耗账号数优先套餐内
oldData.BundleAccountConsumptionNumber++
usedType = 1
goto Over
}
if oldData.IncreaseAccountConsumptionNumber < oldData.IncreaseAccountNumber { // 其次消耗增值的
oldData.IncreaseAccountConsumptionNumber++
usedType = 2
goto Over
}
if oldData.ManualAccountConsumptionNumber < oldData.ManualAccountNumber { // 最后消耗手动扩展的
oldData.ManualAccountConsumptionNumber++
oldData.MonthlyManualAccountConsumptionNumber++
usedType = 3
goto Over
}
return errors.New("账号数不足")
} else if data.AccountNumber < 0 { // 减少账号消耗数,用于解绑账号
if oldData.ManualAccountConsumptionNumber > 0 { // 最后消耗手动扩展的
oldData.ManualAccountConsumptionNumber--
oldData.MonthlyManualAccountConsumptionNumber--
usedType = 3
goto Over
}
if oldData.IncreaseAccountConsumptionNumber > 0 {
oldData.IncreaseAccountConsumptionNumber--
usedType = 2
goto Over
}
if oldData.BundleAccountConsumptionNumber > 0 {
oldData.BundleAccountConsumptionNumber--
usedType = 1
goto Over
}
return errors.New("当前未绑定账号")
}
if data.VideoNumber > 0 {
if oldData.MonthlyLimitVideoExpireNumber > oldData.MonthlyLimitVideoExpireConsumptionNumber { // 当月可使用的会过期的限制类型充足
if oldData.BundleLimitVideoExpiredConsumptionNumber < oldData.BundleLimitVideoExpiredNumber { // 套餐内会过期的限制类型视频充足
oldData.MonthlyLimitVideoExpireConsumptionNumber++
oldData.BundleLimitVideoExpiredConsumptionNumber++
oldData.MonthlyBundleVideoConsumptionNumber++
usedType = 1
goto Over
}
if oldData.IncreaseLimitVideoExpiredConsumptionNumber < oldData.IncreaseLimitVideoExpiredNumber { // 增值服务会过期的限制类型视频充足
oldData.MonthlyLimitVideoExpireConsumptionNumber++
oldData.IncreaseLimitVideoExpiredConsumptionNumber++
oldData.MonthlyIncreaseVideoConsumptionNumber++
usedType = 2
goto Over
}
}
if oldData.MonthlyLimitVideoNumber > oldData.MonthlyLimitVideoConsumptionNumber { // 当月可使用的不过期的限制类型充足
if oldData.BundleLimitVideoConsumptionNumber < oldData.BundleLimitVideoNumber { // 套餐内不过期的限制类型视频充足
oldData.MonthlyLimitVideoConsumptionNumber++
oldData.BundleLimitVideoConsumptionNumber++
oldData.MonthlyBundleVideoConsumptionNumber++
usedType = 1
goto Over
}
if oldData.IncreaseLimitVideoConsumptionNumber < oldData.IncreaseLimitVideoNumber { // 增值服务不过期的限制类型视频充足
oldData.MonthlyLimitVideoConsumptionNumber++
oldData.IncreaseLimitVideoConsumptionNumber++
oldData.MonthlyIncreaseVideoConsumptionNumber++
usedType = 2
goto Over
}
}
if oldData.BundleVideoConsumptionNumber < oldData.BundleVideoNumber { //套餐内非限制类型的视频充足
oldData.BundleVideoConsumptionNumber++
oldData.MonthlyBundleVideoConsumptionNumber++
usedType = 1
goto Over
}
if oldData.IncreaseVideoConsumptionNumber < oldData.IncreaseVideoNumber { //增值服务非限制类型的视频充足
oldData.IncreaseVideoConsumptionNumber++
oldData.MonthlyIncreaseVideoConsumptionNumber++
usedType = 2
goto Over
}
if oldData.ManualVideoConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualVideoConsumptionNumber++
oldData.MonthlyManualVideoConsumptionNumber++ // 记录本月使用的手动扩展
usedType = 3
goto Over
}
return errors.New("可用视频数不足")
}
if data.ImageNumber > 0 {
if oldData.MonthlyLimitImageExpireNumber > oldData.MonthlyLimitImageExpireConsumptionNumber { // 当月可使用的会过期的限制类型充足
if oldData.BundleLimitImageExpiredConsumptionNumber < oldData.BundleLimitImageExpiredNumber { // 套餐内会过期的限制类型图文充足
oldData.MonthlyLimitImageExpireConsumptionNumber++
oldData.BundleLimitImageExpiredConsumptionNumber++
oldData.MonthlyBundleImageConsumptionNumber++
goto Over
}
if oldData.IncreaseLimitImageExpiredConsumptionNumber < oldData.IncreaseLimitImageExpiredNumber { // 增值服务会过期的限制类型图文充足
oldData.MonthlyLimitImageExpireConsumptionNumber++
oldData.IncreaseLimitImageExpiredConsumptionNumber++
oldData.MonthlyIncreaseImageConsumptionNumber++
goto Over
}
}
if oldData.MonthlyLimitImageNumber > oldData.MonthlyLimitImageConsumptionNumber { // 当月可使用的不过期的限制类型充足
if oldData.BundleLimitImageConsumptionNumber < oldData.BundleLimitImageNumber { // 套餐内不过期的限制类型图文充足
oldData.MonthlyLimitImageConsumptionNumber++
oldData.BundleLimitImageConsumptionNumber++
oldData.MonthlyBundleImageConsumptionNumber++
goto Over
}
if oldData.IncreaseLimitImageConsumptionNumber < oldData.IncreaseLimitImageNumber { // 增值服务不过期的限制类型图文充足
oldData.MonthlyLimitImageConsumptionNumber++
oldData.IncreaseLimitImageConsumptionNumber++
oldData.MonthlyIncreaseImageConsumptionNumber++
goto Over
}
}
if oldData.BundleImageConsumptionNumber < oldData.BundleImageNumber { //套餐内非限制类型的图文充足
oldData.BundleImageConsumptionNumber++
oldData.MonthlyBundleImageConsumptionNumber++
goto Over
}
if oldData.IncreaseImageConsumptionNumber < oldData.IncreaseImageNumber { //增值服务非限制类型的图文充足
oldData.IncreaseImageConsumptionNumber++
oldData.MonthlyIncreaseImageConsumptionNumber++
goto Over
}
if oldData.ManualImageConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualImageConsumptionNumber++
oldData.MonthlyManualImageConsumptionNumber++ // 记录本月使用的手动扩展
goto Over
}
return errors.New("可用图文数不足")
}
if data.DataAnalysisNumber > 0 {
if oldData.MonthlyLimitDataAnalysisExpireNumber > oldData.MonthlyLimitDataAnalysisExpireConsumptionNumber { // 当月可使用的会过期的限制类型充足
if oldData.BundleLimitDataAnalysisExpiredConsumptionNumber < oldData.BundleLimitDataAnalysisExpiredNumber { // 套餐内会过期的限制类型数据分析充足
oldData.MonthlyLimitDataAnalysisExpireConsumptionNumber++
oldData.BundleLimitDataAnalysisExpiredConsumptionNumber++
oldData.MonthlyBundleDataAnalysisConsumptionNumber++
goto Over
}
if oldData.IncreaseLimitDataAnalysisExpiredConsumptionNumber < oldData.IncreaseLimitDataAnalysisExpiredNumber { // 增值服务会过期的限制类型数据分析充足
oldData.MonthlyLimitDataAnalysisExpireConsumptionNumber++
oldData.IncreaseLimitDataAnalysisExpiredConsumptionNumber++
oldData.MonthlyIncreaseDataAnalysisConsumptionNumber++
goto Over
}
}
if oldData.MonthlyLimitDataAnalysisNumber > oldData.MonthlyLimitDataAnalysisConsumptionNumber { // 当月可使用的不过期的限制类型充足
if oldData.BundleLimitDataAnalysisConsumptionNumber < oldData.BundleLimitDataAnalysisNumber { // 套餐内不过期的限制类型数据分析充足
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
oldData.BundleLimitDataAnalysisConsumptionNumber++
oldData.MonthlyBundleDataAnalysisConsumptionNumber++
goto Over
}
if oldData.IncreaseLimitDataAnalysisConsumptionNumber < oldData.IncreaseLimitDataAnalysisNumber { // 增值服务不过期的限制类型数据分析充足
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
oldData.IncreaseLimitDataAnalysisConsumptionNumber++
oldData.MonthlyIncreaseDataAnalysisConsumptionNumber++
goto Over
}
}
if oldData.BundleLimitDataAnalysisNumber < oldData.BundleDataAnalysisNumber { //套餐内非限制类型的数据分析充足
oldData.BundleLimitDataAnalysisNumber++
oldData.MonthlyBundleDataAnalysisConsumptionNumber++
goto Over
}
if oldData.IncreaseDataAnalysisConsumptionNumber < oldData.IncreaseDataAnalysisNumber { //增值服务非限制类型的数据分析充足
oldData.IncreaseDataAnalysisConsumptionNumber++
oldData.MonthlyIncreaseDataAnalysisConsumptionNumber++
goto Over
}
if oldData.ManualDataAnalysisConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualDataAnalysisConsumptionNumber++
oldData.MonthlyManualDataAnalysisConsumptionNumber++ // 记录本月使用的手动扩展
goto Over
}
return errors.New("可用数据分析数不足")
}
Over:
return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Save(&oldData).Error
})
return
}
func CreateUsedRecord(tx *gorm.DB, data model.BundleUsedRecord) error {
return tx.Create(&data).Error
}
func ExtendBundleBalanceByUserId(data model.BundleBalanceExtendPo) error {
return app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
oldData := model.BundleBalance{}
if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", data.UserId).Order("created_at desc").First(&oldData).Error; err != nil {
return errors.New("用户还没有套餐信息")
}
oldData.ManualImageNumber += data.ImageNumber
oldData.ManualDataAnalysisNumber += data.DataAnalysisNumber
oldData.ManualVideoNumber += data.VideoNumber
oldData.MonthlyNewDurationNumber += data.DurationNumber // 记录本月新增手动扩展时长
oldData.ExpiredAt.Add(time.Hour * 24 * time.Duration(data.DurationNumber))
return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Save(&oldData).Error
})
}
func CreateBundleBalance(data model.BundleBalance) error {
return app.ModuleClients.BundleDB.Create(&data).Error
}
func GetUsedRecord(req *bundle.GetUsedRecordListReq) (data []model.CostLogPo, total int64, err error) {
session := app.ModuleClients.BundleDB.
Table("cast_cost_log ccl").
Select("ccl.*,cwl.cost_type").
Joins("left join cast_work_log cwl on cwl.work_uuid = ccl.work_uuid").
Where("cwl.work_status = 1 and cwl.deleted_at = 0 and ccl.deleted_at = 0")
if req.WorkTitle != "" {
session = session.Where("ccl.work_title like ?", "%"+req.WorkTitle+"%")
}
if req.Platform != 0 {
session = session.Where(fmt.Sprintf("JSON_CONTAINS(ccl.platform_ids,'%d')", req.Platform))
}
if req.Account != "" {
session = session.Where(fmt.Sprintf(`JSON_CONTAINS(ccl.media_names,'"%s"')`, req.Account))
}
if req.SubmitTimeEnd != 0 {
session = session.Where("ccl.submit_time <= ?", time.UnixMilli(req.SubmitTimeEnd))
}
if req.SubmitTimeStart != 0 {
session = session.Where("ccl.submit_time >= ?", time.UnixMilli(req.SubmitTimeStart))
}
if req.CostType != 0 {
session = session.Where("cwl.cost_type = ?", req.CostType)
}
if req.User != "" {
if utils.IsPhoneNumber(req.User) {
session = session.Where("ccl.artist_phone = ?", req.User)
} else {
session = session.Where("ccl.artist_name like ?", "%"+req.User+"%")
}
}
if req.Operator != "" {
if utils.IsPhoneNumber(req.Operator) {
session = session.Where("ccl.operator_phone = ?", req.Operator)
} else {
session = session.Where("ccl.operator_name like ?", "%"+req.Operator+"%")
}
}
if req.Type != 0 {
session = session.Where("ccl.work_category = ?", req.Type)
}
if err = session.Count(&total).Error; err != nil {
return
}
if req.Page != 0 && req.PageSize != 0 {
session = session.Offset(int(req.Page-1) * int(req.PageSize)).Limit(int(req.PageSize))
}
err = session.Order("ccl.updated_at desc").Find(&data).Error
return
}
func GetImageWorkDetail(req *bundle.GetImageWorkDetailReq) (data model.CastWorkImage, err error) {
err = app.ModuleClients.BundleDB.Where(&model.CastWorkImage{WorkUuid: req.WorkId}).First(&data).Error
return
}
func GetVedioWorkDetail(req *bundle.GetVedioWorkDetailReq) (data model.CastWorkVideo, err error) {
err = app.ModuleClients.BundleDB.Where(&model.CastWorkVideo{WorkUuid: req.WorkId}).First(&data).Error
return
}
func ToBeComfirmedWorks(req *bundle.ToBeComfirmedWorksReq) (data []model.CastWorkLog, total int64, unconfirmed int64, err error) {
unConfirmSubQuery := app.ModuleClients.BundleDB.
Table("cast_work_log").
Select("work_uuid, MAX(update_time) AS max_update_time").
Group("work_uuid").Where("work_status = ?", 4)
err = app.ModuleClients.BundleDB.
Table("cast_work_log AS cwl").
Joins("INNER JOIN (?) AS t ON cwl.work_uuid = t.work_uuid AND cwl.update_time = t.max_update_time", unConfirmSubQuery).
Where("artist_uuid = ?", req.ArtistUuid).Where("confirmed_at = ?", 0).Count(&unconfirmed).Error
if err != nil {
return
}
subQuery := app.ModuleClients.BundleDB.
Table("cast_work_log").
Select("work_uuid, MAX(update_time) AS max_update_time").
Group("work_uuid").Where("work_status in ?", []int{4, 5, 6, 7})
session := app.ModuleClients.BundleDB.
Table("cast_work_log AS cwl").
Joins("INNER JOIN (?) AS t ON cwl.work_uuid = t.work_uuid AND cwl.update_time = t.max_update_time", subQuery).
Where("artist_uuid = ?", req.ArtistUuid)
err = session.Count(&total).Error
if err != nil {
return
}
if req.Page != 0 && req.PageSize != 0 {
session.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
}
err = session.Order("created_at desc").Find(&data).Error
return
}
func ConfirmWork(req *bundle.ConfirmWorkReq) error {
return app.ModuleClients.BundleDB.Model(&model.CastWorkLog{}).Where(&model.CastWorkLog{WorkUuid: req.WorkUuid}).Update("confirmed_at", time.Now().Unix()).Error
}
func BundleActivate(ids []uint32) error {
for _, v := range ids {
app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
activate := model.BundleActivate{}
if err := tx.Model(&model.BundleActivate{}).Where("user_id = ?", v).First(&activate).Error; err != nil {
balance := model.BundleBalance{}
if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", v).First(&balance).Error; err != nil {
return err
}
balance.ExpiredAt = balance.ExpiredAt.Add(time.Since(balance.StartAt))
balance.StartAt = time.Now()
if err := tx.Model(&model.BundleBalance{}).Save(balance).Error; err != nil {
return err
}
return tx.Model(&model.BundleActivate{}).Where("user_id = ?", v).Create(&model.BundleActivate{UserId: int(v), Activate: 2}).Error
}
return nil
})
}
return nil
}
func GetValueAddByOrderUUID(orderUUID string) (data []model.BundleOrderValueAdd, err error) {
err = app.ModuleClients.BundleDB.Model(&model.BundleOrderValueAdd{}).Where("order_uuid = ?", orderUUID).Find(&data).Error
return
}
func UpdateBundleBalance() error {
bl := []model.BundleBalance{}
if err := app.ModuleClients.BundleDB.Raw(`select
*
from
bundle_balance bb
inner join (
select
max(bb.month) as month ,
user_id
from
bundle_balance bb
group by
bb.user_id
) newest on
newest.month = bb.month
and bb.user_id = newest.user_id
and bb.expired_at > now()`).Find(&bl).Error; err != nil {
return err
}
now := time.Now()
month := time.Now().Format("2006-01")
for _, v := range bl {
if v.Month == month {
continue
}
cal := func(total, limit int) int { // 计算本月发放的限制类型数量
var released int // 已释放的次数
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() {
} else if v.StartAt.Day() >= 16 { //第一个月释放的
released += limit/2 + 1
} else {
released += limit
}
interval := now.Year()*12 + int(now.Month()) - (v.StartAt.Year()*12 + int(v.StartAt.Month())) // 后续月份释放的
released += interval * limit
remaining := max(total-released, 0) // 还剩余多少次没有发放
if v.StartAt.Month() == now.Month() && v.StartAt.Year() == now.Year() && v.StartAt.Day() >= 16 { // 本月为第一个月并且16号后购买只给一半向上取整
return min(limit/2+1, remaining)
}
if v.ExpiredAt.Month() == now.Month() && v.ExpiredAt.Year() == now.Year() && v.ExpiredAt.Day() < 16 { // 本月为最后一个月并且16号前到期只给一半向下取整
return min(limit/2, remaining)
}
return min(limit, remaining)
}
v.MonthlyInvalidBundleVideoNumber = v.MonthlyLimitVideoExpireNumber - v.MonthlyLimitVideoExpireConsumptionNumber // 当月过期的视频数
v.InvalidBundleVideoNumber += v.MonthlyInvalidBundleVideoNumber
v.MonthlyInvalidBundleImageNumber = v.MonthlyLimitImageExpireNumber - v.MonthlyLimitImageExpireConsumptionNumber
v.InvalidBundleImageNumber += v.MonthlyInvalidBundleImageNumber
v.MonthlyInvalidBundleDataAnalysisNumber = v.MonthlyLimitDataAnalysisExpireNumber - v.MonthlyLimitDataAnalysisExpireConsumptionNumber
v.InvalidBundleDataAnalysisNumber += v.MonthlyInvalidBundleDataAnalysisNumber
// 当月可用的限制类型数等于本月方法的套餐和增值两种类型的总和
v.MonthlyLimitVideoExpireNumber = cal(v.BundleLimitVideoExpiredNumber, v.MonthlyLimitVideoQuotaNumber) + cal(v.IncreaseLimitVideoExpiredNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyLimitVideoNumber = v.MonthlyLimitVideoNumber - v.MonthlyLimitVideoConsumptionNumber + cal(v.BundleLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber) + cal(v.IncreaseLimitVideoNumber, v.MonthlyLimitVideoQuotaNumber)
v.MonthlyLimitImageExpireNumber = cal(v.BundleLimitImageExpiredNumber, v.MonthlyLimitImageQuotaNumber) + cal(v.IncreaseLimitImageExpiredNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyLimitImageNumber = v.MonthlyLimitImageNumber - v.MonthlyLimitImageConsumptionNumber + cal(v.BundleLimitImageNumber, v.MonthlyLimitImageQuotaNumber) + cal(v.IncreaseLimitImageNumber, v.MonthlyLimitImageQuotaNumber)
v.MonthlyLimitDataAnalysisExpireNumber = cal(v.BundleLimitDataAnalysisExpiredNumber, v.MonthlyLimitDataAnalysisQuotaNumber) + cal(v.IncreaseLimitDataAnalysisExpiredNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
v.MonthlyLimitDataAnalysisNumber = v.MonthlyLimitDataAnalysisNumber - v.MonthlyLimitDataAnalysisConsumptionNumber + cal(v.BundleLimitDataAnalysisNumber, v.MonthlyLimitDataAnalysisQuotaNumber) + cal(v.IncreaseLimitDataAnalysisNumber, v.MonthlyLimitDataAnalysisQuotaNumber)
v.MonthlyLimitVideoConsumptionNumber = 0 // 重置单月消耗数量
v.MonthlyLimitVideoExpireConsumptionNumber = 0
v.MonthlyManualVideoConsumptionNumber = 0
v.MonthlyLimitImageConsumptionNumber = 0
v.MonthlyLimitImageExpireConsumptionNumber = 0
v.MonthlyManualImageConsumptionNumber = 0
v.MonthlyLimitDataAnalysisConsumptionNumber = 0
v.MonthlyLimitDataAnalysisExpireConsumptionNumber = 0
v.MonthlyManualDataAnalysisConsumptionNumber = 0
v.MonthlyBundleVideoConsumptionNumber = 0
v.MonthlyBundleImageConsumptionNumber = 0
v.MonthlyBundleDataAnalysisConsumptionNumber = 0
v.MonthlyIncreaseVideoConsumptionNumber = 0
v.MonthlyIncreaseImageConsumptionNumber = 0
v.MonthlyIncreaseDataAnalysisConsumptionNumber = 0
v.Month = month
v.ID = 0
app.ModuleClients.BundleDB.Create(&v)
}
return nil
}