web
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"dianshang/internal/model"
|
||||
"time"
|
||||
|
||||
@@ -121,3 +122,286 @@ func (r *CouponRepository) RestoreCoupon(userCouponID uint) error {
|
||||
"used_time": nil, // 清除使用时间
|
||||
}).Error
|
||||
}
|
||||
|
||||
// ==================== 管理端方法 ====================
|
||||
|
||||
// GetCouponListForAdmin 获取优惠券列表(管理端)
|
||||
func (r *CouponRepository) GetCouponListForAdmin(page, pageSize int, status, couponType, keyword string) ([]model.Coupon, int64, error) {
|
||||
var coupons []model.Coupon
|
||||
var total int64
|
||||
|
||||
query := r.db.Model(&model.Coupon{})
|
||||
|
||||
// 状态筛选
|
||||
if status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
|
||||
// 类型筛选
|
||||
if couponType != "" {
|
||||
query = query.Where("type = ?", couponType)
|
||||
}
|
||||
|
||||
// 关键词搜索
|
||||
if keyword != "" {
|
||||
query = query.Where("name LIKE ? OR description LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
err := query.Order("created_at DESC").
|
||||
Limit(pageSize).
|
||||
Offset(offset).
|
||||
Find(&coupons).Error
|
||||
|
||||
return coupons, total, err
|
||||
}
|
||||
|
||||
// GetCouponUsageStats 获取优惠券使用统计
|
||||
func (r *CouponRepository) GetCouponUsageStats(couponID uint) (int, int, error) {
|
||||
// 获取领取数
|
||||
var receivedCount int64
|
||||
err := r.db.Model(&model.UserCoupon{}).Where("coupon_id = ?", couponID).Count(&receivedCount).Error
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
// 获取使用数
|
||||
var usedCount int64
|
||||
err = r.db.Model(&model.UserCoupon{}).Where("coupon_id = ? AND status = ?", couponID, 1).Count(&usedCount).Error
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return int(receivedCount), int(usedCount), nil
|
||||
}
|
||||
|
||||
// Create 创建优惠券
|
||||
func (r *CouponRepository) Create(coupon *model.Coupon) error {
|
||||
return r.db.Create(coupon).Error
|
||||
}
|
||||
|
||||
// Update 更新优惠券
|
||||
func (r *CouponRepository) Update(couponID uint, updates map[string]interface{}) error {
|
||||
return r.db.Model(&model.Coupon{}).Where("id = ?", couponID).Updates(updates).Error
|
||||
}
|
||||
|
||||
// Delete 删除优惠券
|
||||
func (r *CouponRepository) Delete(couponID uint) error {
|
||||
return r.db.Delete(&model.Coupon{}, couponID).Error
|
||||
}
|
||||
|
||||
// CheckCouponHasUsers 检查优惠券是否有用户领取
|
||||
func (r *CouponRepository) CheckCouponHasUsers(couponID uint) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.Model(&model.UserCoupon{}).Where("coupon_id = ?", couponID).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
// BatchDelete 批量删除优惠券
|
||||
func (r *CouponRepository) BatchDelete(couponIDs []uint) error {
|
||||
return r.db.Delete(&model.Coupon{}, couponIDs).Error
|
||||
}
|
||||
|
||||
// CountTotalCoupons 统计总优惠券数
|
||||
func (r *CouponRepository) CountTotalCoupons(ctx context.Context) (int64, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&model.Coupon{}).Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// CountActiveCoupons 统计启用的优惠券数
|
||||
func (r *CouponRepository) CountActiveCoupons(ctx context.Context) (int64, error) {
|
||||
var count int64
|
||||
now := time.Now()
|
||||
err := r.db.WithContext(ctx).Model(&model.Coupon{}).
|
||||
Where("status = ? AND start_time <= ? AND end_time >= ?", 1, now, now).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// CountTotalReceived 统计总领取数
|
||||
func (r *CouponRepository) CountTotalReceived(ctx context.Context, startTime, endTime time.Time) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&model.UserCoupon{})
|
||||
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
query = query.Where("created_at BETWEEN ? AND ?", startTime, endTime)
|
||||
}
|
||||
|
||||
err := query.Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// CountTotalUsed 统计总使用数
|
||||
func (r *CouponRepository) CountTotalUsed(ctx context.Context, startTime, endTime time.Time) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&model.UserCoupon{}).Where("status = ?", 1)
|
||||
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
query = query.Where("used_time BETWEEN ? AND ?", startTime, endTime)
|
||||
}
|
||||
|
||||
err := query.Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// GetCouponTypeStats 获取各类型优惠券统计
|
||||
func (r *CouponRepository) GetCouponTypeStats(ctx context.Context) ([]map[string]interface{}, error) {
|
||||
var results []map[string]interface{}
|
||||
|
||||
rows, err := r.db.WithContext(ctx).Model(&model.Coupon{}).
|
||||
Select("type, COUNT(*) as count").
|
||||
Group("type").
|
||||
Rows()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var couponType, count int
|
||||
if err := rows.Scan(&couponType, &count); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
typeName := ""
|
||||
switch couponType {
|
||||
case 1:
|
||||
typeName = "满减券"
|
||||
case 2:
|
||||
typeName = "折扣券"
|
||||
case 3:
|
||||
typeName = "免邮券"
|
||||
}
|
||||
|
||||
results = append(results, map[string]interface{}{
|
||||
"type": couponType,
|
||||
"type_name": typeName,
|
||||
"count": count,
|
||||
})
|
||||
}
|
||||
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// GetTopCoupons 获取热门优惠券
|
||||
func (r *CouponRepository) GetTopCoupons(ctx context.Context, limit int) ([]map[string]interface{}, error) {
|
||||
var results []map[string]interface{}
|
||||
|
||||
err := r.db.WithContext(ctx).Model(&model.Coupon{}).
|
||||
Select("id, name, type, received_count, used_count").
|
||||
Order("received_count DESC").
|
||||
Limit(limit).
|
||||
Scan(&results).Error
|
||||
|
||||
return results, err
|
||||
}
|
||||
|
||||
// GetUserCouponListForAdmin 获取用户优惠券列表(管理端)
|
||||
func (r *CouponRepository) GetUserCouponListForAdmin(userID uint, page, pageSize int) ([]model.UserCoupon, int64, error) {
|
||||
var userCoupons []model.UserCoupon
|
||||
var total int64
|
||||
|
||||
query := r.db.Model(&model.UserCoupon{}).Where("user_id = ?", userID)
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
err := query.Preload("Coupon").
|
||||
Order("created_at DESC").
|
||||
Limit(pageSize).
|
||||
Offset(offset).
|
||||
Find(&userCoupons).Error
|
||||
|
||||
return userCoupons, total, err
|
||||
}
|
||||
|
||||
// GetDistributeHistory 获取优惠券发放历史
|
||||
func (r *CouponRepository) GetDistributeHistory(page, pageSize int) ([]map[string]interface{}, int64, error) {
|
||||
var history []map[string]interface{}
|
||||
var total int64
|
||||
|
||||
// 先获取总数
|
||||
type CountResult struct {
|
||||
Count int64
|
||||
}
|
||||
var countResult CountResult
|
||||
err := r.db.Model(&model.UserCoupon{}).
|
||||
Select("COUNT(DISTINCT DATE(created_at), coupon_id) as count").
|
||||
Scan(&countResult).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
total = countResult.Count
|
||||
|
||||
// 分页查询分组数据
|
||||
type DistributeRecord struct {
|
||||
DistributeDate string `gorm:"column:distribute_date"`
|
||||
CouponID uint `gorm:"column:coupon_id"`
|
||||
TotalCount int `gorm:"column:total_count"`
|
||||
UnusedCount int `gorm:"column:unused_count"`
|
||||
UsedCount int `gorm:"column:used_count"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
}
|
||||
|
||||
var records []DistributeRecord
|
||||
offset := (page - 1) * pageSize
|
||||
err = r.db.Model(&model.UserCoupon{}).
|
||||
Select(`
|
||||
DATE(created_at) as distribute_date,
|
||||
coupon_id,
|
||||
COUNT(*) as total_count,
|
||||
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as unused_count,
|
||||
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
|
||||
MIN(created_at) as created_at
|
||||
`).
|
||||
Group("DATE(created_at), coupon_id").
|
||||
Order("created_at DESC").
|
||||
Limit(pageSize).
|
||||
Offset(offset).
|
||||
Scan(&records).Error
|
||||
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 处理结果
|
||||
for i, record := range records {
|
||||
// 获取优惠券信息
|
||||
var coupon model.Coupon
|
||||
r.db.First(&coupon, record.CouponID)
|
||||
|
||||
// 判断发放类型
|
||||
distributeType := "batch"
|
||||
if record.TotalCount == 1 {
|
||||
distributeType = "single"
|
||||
}
|
||||
|
||||
history = append(history, map[string]interface{}{
|
||||
"id": i + 1 + offset,
|
||||
"coupon_id": record.CouponID,
|
||||
"coupon_name": coupon.Name,
|
||||
"distribute_type": distributeType,
|
||||
"distribute_date": record.DistributeDate,
|
||||
"total_count": record.TotalCount,
|
||||
"success_count": record.TotalCount,
|
||||
"fail_count": 0,
|
||||
"used_count": record.UsedCount,
|
||||
"unused_count": record.UnusedCount,
|
||||
"admin_name": "系统",
|
||||
"created_at": record.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return history, total, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user