diff --git a/pkg/e/msg.go b/pkg/e/msg.go index 7de2193..fec957e 100644 --- a/pkg/e/msg.go +++ b/pkg/e/msg.go @@ -155,6 +155,11 @@ const ( ErrorBalanceInsufficient = "余额不足" ) +const ( + BundlePurchaseExport = 1 + BundleDetailExport = 2 +) + // GetMsg 获取状态码对应信息 func GetMsg(code int) string { msg, ok := MsgFlags[code] diff --git a/pkg/service/bundle/bundleMetrics.go b/pkg/service/bundle/bundleMetrics.go index e49f632..8b7f8af 100644 --- a/pkg/service/bundle/bundleMetrics.go +++ b/pkg/service/bundle/bundleMetrics.go @@ -6,6 +6,7 @@ import ( "fmt" "fonchain-fiee/api/bundle" "fonchain-fiee/api/cast" + "fonchain-fiee/pkg/e" logicCast "fonchain-fiee/pkg/logic/cast" "fonchain-fiee/pkg/model/login" "fonchain-fiee/pkg/service" @@ -133,8 +134,8 @@ func MetricsBundlePurchaseExport(ctx *gin.Context) { } if err := exportStructToExcel(resp.Data, []string{ - "订单编号", "套餐", "用户编号", "客户姓名", "手机号", "支付时间", "增值视频数", "套餐金额", "增值金额", "支付金额", "结算金额", "手续费", "汇率(%)", - }, filePath, statistic); err != nil { + "订单编号", "套餐", "用户编号", "客户姓名", "手机号", "支付时间", "套餐视频数", "增值视频数", "套餐金额", "增值金额", "支付金额", "结算金额", "手续费", "汇率(%)", + }, filePath, e.BundlePurchaseExport, req.EndTime, statistic); err != nil { service.Error(ctx, errors.New(common.MetricsBundlePurchaseExportFailed)) return } @@ -441,7 +442,7 @@ func MetricsBalanceDetailExport(ctx *gin.Context) { "所属月份", "用户编号", "姓名", "手机号", "购买套餐时间", "套餐金额", "增值金额", "支付金额", "币种", "手续费", "套餐视频总数", "增值视频总数", "套餐视频单价", "增值视频单价", "当前需要上传套餐视频数", "当前需要上传增值视频数", "当前已上传套餐视频数", "当前已上传增值视频数", "当前套餐视频已消费总金额", "当前增值视频已消费总金额", - }, filePath, yelloStyle, statistic); err != nil { + }, filePath, e.BundleDetailExport, "", statistic); err != nil { service.Error(ctx, errors.New(common.MetricsBalanceDetailExportFailed)) return } @@ -518,11 +519,28 @@ func BalanceMetricsExport(ctx *gin.Context) { }) } -func exportStructToExcel[T any](data []T, headers []string, filename string, fns ...func(data []T, headers []string, f *excelize.File)) error { +func exportStructToExcel[T any](data []T, headers []string, filename string, exportType int, endTime string, fns ...func(data []T, headers []string, f *excelize.File)) error { f := excelize.NewFile() sheet := f.GetSheetName(f.GetActiveSheetIndex()) + // 创建黄色背景样式(用于截止行) + yellowStyle, err := f.NewStyle(&excelize.Style{ + Fill: excelize.Fill{ + Type: "pattern", + Color: []string{"#FFFF00"}, // 黄色 + Pattern: 1, // 实心填充 + }, + Alignment: &excelize.Alignment{ + Horizontal: "center", + Vertical: "center", + }, + }) + if err != nil { + // 如果创建样式失败,继续执行但不应用样式 + yellowStyle = 0 + } + // 写入表头 for i, h := range headers { cell, _ := excelize.CoordinatesToCellName(i+1, 1) @@ -546,12 +564,50 @@ func exportStructToExcel[T any](data []T, headers []string, filename string, fns } // 写入数据 - for rowIdx, item := range data { + actualRowIdx := 0 + for _, item := range data { val := reflect.ValueOf(item) if val.Kind() == reflect.Ptr { val = val.Elem() } + if exportType == e.BundlePurchaseExport { + if endTime != "" { + // 通过反射获取 PayTime 字段 + payTimeField := val.FieldByName("PayTime") + if payTimeField.IsValid() && payTimeField.Kind() == reflect.String { + payTimeStr := payTimeField.String() + if payTimeStr != "" { + // 解析时间 + endTimeParsed, err1 := time.Parse(time.DateTime, endTime) + payTimeParsed, err2 := time.Parse(time.DateTime, payTimeStr) + + if err1 == nil && err2 == nil { + // 如果 endTime <= PayTime,需要插入截止行 + if !endTimeParsed.After(payTimeParsed) { + // 格式化截止时间显示 + endTimeFormatted := endTimeParsed.Format("2006年01月02日15点") + // 在当前行写入"截止xxxx年xx月xx点" + cell, _ := excelize.CoordinatesToCellName(1, actualRowIdx+2) + f.SetCellValue(sheet, cell, fmt.Sprintf("截止%s", endTimeFormatted)) + // 应用黄色背景样式 + if yellowStyle > 0 { + // 合并整行的单元格以显示截止信息 + lastCol, _ := excelize.ColumnNumberToName(len(headers)) + startCell := cell + endCell := fmt.Sprintf("%s%d", lastCol, actualRowIdx+2) + f.MergeCell(sheet, startCell, endCell) + f.SetCellStyle(sheet, startCell, endCell, yellowStyle) + } + // 移动到下一行 + actualRowIdx++ + } + } + } + } + } + } + for colIdx, fieldIdx := range exportedFields { field := val.Field(fieldIdx) @@ -563,9 +619,10 @@ func exportStructToExcel[T any](data []T, headers []string, filename string, fns cellValue = field.Interface() } - cell, _ := excelize.CoordinatesToCellName(colIdx+1, rowIdx+2) + cell, _ := excelize.CoordinatesToCellName(colIdx+1, actualRowIdx+2) f.SetCellValue(sheet, cell, cellValue) } + actualRowIdx++ } }