micro-bundle/internal/dao/bundleExtend.go

457 lines
19 KiB
Go

package dao
import (
"errors"
"fmt"
"micro-bundle/internal/model"
"micro-bundle/pb/bundle"
"micro-bundle/pkg/app"
"micro-bundle/pkg/utils"
"strconv"
"time"
"dubbo.apache.org/dubbo-go/v3/common/logger"
"github.com/duke-git/lancet/v2/datetime"
"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.BundleOrderRecords{}
if err := tx.Model(&model.BundleOrderRecords{}).Where(&model.BundleOrderRecords{CustomerID: strconv.Itoa(data.UserId)}).Order("created_at desc").First(&record).Error; err != nil {
return err
}
var expireTime time.Time
if record.ExpirationTime != "" {
loc, _ := time.LoadLocation("Asia/Shanghai")
et, _ := time.ParseInLocation(time.DateTime, record.ExpirationTime, loc)
expireTime = et
} else {
t, _ := time.Parse("2006-01-02 15:04:05", record.PayTime)
expireTime = t
logger.Infof("过期时间为空,使用默认过期时间" + expireTime.Format(time.DateTime))
}
switch data.TimeUnit {
case 1:
expireTime = datetime.AddDay(expireTime, int64(data.AvailableDurationAdditional))
case 2:
expireTime = datetime.AddMonth(expireTime, int64(data.AvailableDurationAdditional))
case 3:
expireTime = datetime.AddYear(expireTime, int64(data.AvailableDurationAdditional))
default:
return errors.New("时间单位有误")
}
record.ExpirationTime = expireTime.Format(time.DateTime)
return tx.Model(&model.BundleOrderRecords{}).Where(&model.BundleOrderRecords{UUID: record.UUID}).Updates(&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").
Select(`bb.*, bor.expiration_time as expired_time, bor.bundle_name, bor.status,
bor.uuid as order_uuid, rn.name as user_name,
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").
Where("rn.name IS NOT NULL").
Where("u.deleted_at = 0").
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("bor.expiration_time <= ?", time.UnixMilli(req.ExpiredTimeEnd))
}
if req.ExpiredTimeStart != 0 {
session = session.Where("bor.expiration_time >= ?", 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) {
err = app.ModuleClients.BundleDB.Table("fiee_bundle.bundle_balance AS bb").
Select("bb.*,bor.uuid AS order_uuid, bor.bundle_name AS bundle_name, bor.status AS bundle_status, bor.pay_time AS pay_time, bor.expiration_time AS expired_time,bor.amount AS payment_amount,bor.amount_type AS payment_type").
Joins("LEFT JOIN bundle_order_records bor ON bor.uuid = bb.order_uuid").
Joins("LEFT JOIN `micro-account`.`user` u ON u.id = bb.user_id").
Where("bor.deleted_at IS NULL").
Where("bb.user_id = ?", req.UserId).
// Where("bor.expiration_time > ?", time.Now()).
Order("bb.created_at desc").
First(&data).Error
if err != nil {
return
}
var additionalInfo model.UserBundleBalancePo
err = app.ModuleClients.BundleDB.Model(&model.BundleExtensionRecords{}).
Select("SUM(account_additional) as account_additional, SUM(images_additional) as image_additional, SUM(video_additional) as video_additional, SUM(data_additional) as data_additional").
Where("type = 1"). // 手动扩展
Where("user_id = ?", req.UserId).
Where("created_at > ?", data.PayTime). // 判断扩展是否生效
First(&additionalInfo).Error
if err != nil {
return
}
data.AccountAdditional = additionalInfo.AccountAdditional
data.VideoAdditional = additionalInfo.VideoAdditional
data.ImageAdditional = additionalInfo.ImageAdditional
data.DataAnalysisAdditional = additionalInfo.DataAnalysisAdditional
return
}
func AddBundleBalanceByUserId(data model.BundleBalanceUsePo) 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("用户还没有套餐信息")
}
if data.AccountNumber > 0 { // 增加账号消耗数
for range data.AccountNumber {
if oldData.BundleAccountConsumptionNumber < oldData.BundleAccountNumber { // 消耗账号数优先套餐内
oldData.BundleAccountConsumptionNumber++
continue
}
if oldData.IncreaseAccountConsumptionNumber < oldData.IncreaseAccountNumber { // 其次消耗增值的
oldData.IncreaseAccountConsumptionNumber++
continue
}
return errors.New("账号数不足")
}
} else { // 减少账号消耗数,用于解绑账号
for range data.AccountNumber {
if oldData.IncreaseAccountConsumptionNumber > 0 {
oldData.IncreaseAccountConsumptionNumber--
continue
}
if oldData.BundleAccountConsumptionNumber > 0 {
oldData.BundleAccountConsumptionNumber--
continue
}
return errors.New("当前未绑定账号")
}
}
for range data.VideoNumber {
if oldData.MonthlyLimitVideoConsumptionNumber < oldData.MonthlyLimitVideoNumber { // 限制类型视频可用额度充足
if oldData.BundleLimitVideoExpiredConsumptionNumber < oldData.BundleLimitVideoExpiredNumber { // 套餐内会过期的限制类型视频充足
oldData.BundleLimitVideoExpiredConsumptionNumber++
oldData.MonthlyLimitVideoConsumptionNumber++
continue
}
if oldData.IncreaseLimitVideoExpiredConsumptionNumber < oldData.IncreaseLimitVideoExpiredNumber { // 增值服务会过期的限制类型视频充足
oldData.IncreaseLimitVideoExpiredConsumptionNumber++
oldData.MonthlyLimitVideoConsumptionNumber++
continue
}
if oldData.BundleLimitVideoConsumptionNumber < oldData.BundleLimitVideoNumber { // 套餐内不会过期的限制类型视频充足
oldData.BundleLimitVideoConsumptionNumber++
oldData.MonthlyLimitVideoConsumptionNumber++
continue
}
if oldData.IncreaseLimitVideoConsumptionNumber < oldData.IncreaseLimitVideoNumber { // 增值服务不会过期的限制类型视频充足
oldData.IncreaseLimitVideoConsumptionNumber++
oldData.MonthlyLimitVideoConsumptionNumber++
continue
}
}
if oldData.BundleLimitVideoNumber < oldData.BundleVideoNumber { //套餐内非限制类型的视频充足
oldData.BundleLimitVideoNumber++
continue
}
if oldData.IncreaseVideoConsumptionNumber < oldData.IncreaseVideoNumber { //增值服务非限制类型的视频充足
oldData.IncreaseVideoConsumptionNumber++
continue
}
if oldData.ManualVideoConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualVideoConsumptionNumber++
oldData.MonthlyManualVideoConsumptionNumber++ // 记录本月使用的手动扩展
continue
}
return errors.New("可用视频数不足")
}
for range data.ImageNumber {
if oldData.MonthlyLimitImageConsumptionNumber < oldData.MonthlyLimitImageNumber { // 限制类型图文可用额度充足
if oldData.BundleLimitImageExpiredConsumptionNumber < oldData.BundleLimitImageExpiredNumber { // 套餐内会过期的限制类型图文充足
oldData.BundleLimitImageExpiredConsumptionNumber++
oldData.MonthlyLimitImageConsumptionNumber++
continue
}
if oldData.IncreaseLimitImageExpiredConsumptionNumber < oldData.IncreaseLimitImageExpiredNumber { // 增值服务会过期的限制类型图文充足
oldData.IncreaseLimitImageExpiredConsumptionNumber++
oldData.MonthlyLimitImageConsumptionNumber++
continue
}
if oldData.BundleLimitImageConsumptionNumber < oldData.BundleLimitImageNumber { // 套餐内不会过期的限制类型图文充足
oldData.BundleLimitImageConsumptionNumber++
oldData.MonthlyLimitImageConsumptionNumber++
continue
}
if oldData.IncreaseLimitImageConsumptionNumber < oldData.IncreaseLimitImageNumber { // 增值服务不会过期的限制类型图文充足
oldData.IncreaseLimitImageConsumptionNumber++
oldData.MonthlyLimitImageConsumptionNumber++
continue
}
}
if oldData.BundleLimitImageNumber < oldData.BundleImageNumber { //套餐内非限制类型的图文充足
oldData.BundleLimitImageNumber++
continue
}
if oldData.IncreaseImageConsumptionNumber < oldData.IncreaseImageNumber { //增值服务非限制类型的图文充足
oldData.IncreaseImageConsumptionNumber++
continue
}
if oldData.ManualImageConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualImageConsumptionNumber++
oldData.MonthlyManualImageConsumptionNumber++ // 记录本月使用的手动扩展
continue
}
return errors.New("可用图文数不足")
}
for range data.DataAnalysisNumber {
if oldData.MonthlyLimitDataAnalysisConsumptionNumber < oldData.MonthlyLimitDataAnalysisNumber { // 限制类型数据分析可用额度充足
if oldData.BundleLimitDataAnalysisExpiredConsumptionNumber < oldData.BundleLimitDataAnalysisExpiredNumber { // 套餐内会过期的限制类型数据分析充足
oldData.BundleLimitDataAnalysisExpiredConsumptionNumber++
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
continue
}
if oldData.IncreaseLimitDataAnalysisExpiredConsumptionNumber < oldData.IncreaseLimitDataAnalysisExpiredNumber { // 增值服务会过期的限制类型数据分析充足
oldData.IncreaseLimitDataAnalysisExpiredConsumptionNumber++
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
continue
}
if oldData.BundleLimitDataAnalysisConsumptionNumber < oldData.BundleLimitDataAnalysisNumber { // 套餐内不会过期的限制类型数据分析充足
oldData.BundleLimitDataAnalysisConsumptionNumber++
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
continue
}
if oldData.IncreaseLimitDataAnalysisConsumptionNumber < oldData.IncreaseLimitDataAnalysisNumber { // 增值服务不会过期的限制类型数据分析充足
oldData.IncreaseLimitDataAnalysisConsumptionNumber++
oldData.MonthlyLimitDataAnalysisConsumptionNumber++
continue
}
}
if oldData.BundleLimitDataAnalysisNumber < oldData.BundleDataAnalysisNumber { //套餐内非限制类型的数据分析充足
oldData.BundleLimitDataAnalysisNumber++
continue
}
if oldData.IncreaseDataAnalysisConsumptionNumber < oldData.IncreaseDataAnalysisNumber { //增值服务非限制类型的数据分析充足
oldData.IncreaseDataAnalysisConsumptionNumber++
continue
}
if oldData.ManualDataAnalysisConsumptionNumber < oldData.ManualDataAnalysisNumber { // 手动扩展类型充足
oldData.ManualDataAnalysisConsumptionNumber++
oldData.MonthlyManualDataAnalysisConsumptionNumber++ // 记录本月使用的手动扩展
continue
}
return errors.New("可用数据分析数不足")
}
return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Save(&oldData).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 as ccl").Select("ccl.*,cwe.artist_confirmed_time").
Joins("left join cast_work_extra as cwe on cwe.work_uuid = ccl.work_uuid").
Where("ccl.deleted_at = 0")
if req.Title != "" {
session = session.Where("title = ?", req.Title)
}
if req.Platform != 0 {
session = session.Where(fmt.Sprintf("JSON_CONTAINS(platform_ids,'%d')", req.Platform))
}
if req.Account != "" {
session = session.Where(fmt.Sprintf(`JSON_CONTAINS(media_names,'"%s"')`, req.Account))
}
if req.SubmitTimeEnd != 0 {
session = session.Where("artist_confirmed_time <= ?", req.SubmitTimeEnd/1000) // 转换为秒级时间戳
}
if req.SubmitTimeStart != 0 {
session = session.Where("artist_confirmed_time >= ?", req.SubmitTimeStart/1000)
}
if req.User != "" {
if utils.IsPhoneNumber(req.User) {
session = session.Where("artist_phone = ?", req.User)
} else {
session = session.Where("artist_name like ?", "%"+req.User+"%")
}
}
if req.Operator != "" {
if utils.IsPhoneNumber(req.Operator) {
session = session.Where("operator_phone = ?", req.Operator)
} else {
session = session.Where("operator_name like ?", "%"+req.Operator+"%")
}
}
if req.Type != 0 {
session = session.Where("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 {
batch := []model.BundleActivate{}
for _, v := range ids {
batch = append(batch, model.BundleActivate{UserId: int(v), Activate: true})
}
return app.ModuleClients.BundleDB.Model(&model.BundleActivate{}).Where("user_id = ?").Save(batch).Error
}