Files
kra-new/internal/service/business/ledger_excel.go
T

102 lines
3.9 KiB
Go

package business
import (
"context"
"strconv"
"github.com/xuri/excelize/v2"
"kra/internal/service/dto"
)
type ledgerCell struct {
value string
numeric bool
}
func textCell(value string) ledgerCell { return ledgerCell{value: value} }
func numericCell(value string) ledgerCell { return ledgerCell{value: value, numeric: true} }
func optionalNumber[T ~int | ~int64](value *T) ledgerCell {
if value == nil {
return textCell("")
}
return numericCell(strconv.FormatInt(int64(*value), 10))
}
func optionalMoney(value *string) ledgerCell {
if value == nil {
return textCell("")
}
return numericCell(*value)
}
func ledgerWorkbook(sheet string, headers []string, rows [][]ledgerCell) ([]byte, error) {
file := excelize.NewFile()
defer file.Close()
if err := file.SetSheetName(file.GetSheetName(0), sheet); err != nil {
return nil, err
}
for i, label := range headers {
cell, _ := excelize.CoordinatesToCellName(i+1, 1)
if err := file.SetCellStr(sheet, cell, label); err != nil {
return nil, err
}
}
for i, row := range rows {
for j, value := range row {
cell, _ := excelize.CoordinatesToCellName(j+1, i+2)
var err error
// 金额直接写入数值 XML,避免先转 float64;文本始终作为文本,保留订单号前导零。
if value.numeric {
err = file.SetCellDefault(sheet, cell, value.value)
} else {
err = file.SetCellStr(sheet, cell, value.value)
}
if err != nil {
return nil, err
}
}
}
last, _ := excelize.ColumnNumberToName(len(headers))
if err := file.SetColWidth(sheet, "A", last, 20); err != nil {
return nil, err
}
if err := file.SetPanes(sheet, &excelize.Panes{Freeze: true, YSplit: 1, TopLeftCell: "A2", ActivePane: "bottomLeft"}); err != nil {
return nil, err
}
buffer, err := file.WriteToBuffer()
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (s *LedgerService) ExportRegistrations(ctx context.Context, req *dto.LedgerQuery) ([]byte, error) {
f, _, err := ledgerRequest(req, false)
if err != nil {
return nil, err
}
items, err := s.uc.ExportRegistrations(ctx, f)
if err != nil {
return nil, err
}
rows := make([][]ledgerCell, 0, len(items))
for _, item := range items {
r := registrationResponse(item)
rows = append(rows, []ledgerCell{textCell(r.SourceDB), textCell(r.SourceDBLabel), numericCell(strconv.FormatUint(r.ID, 10)), numericCell(strconv.FormatUint(r.UserID, 10)), optionalNumber(r.RegisterTime), optionalNumber(r.FirstGameID), textCell(r.FirstGameName), optionalMoney(r.TotalPayAmount), textCell(r.RegisterIP), textCell(r.DeviceName), textCell(r.PromoteAccount), optionalNumber(r.PromoteID), textCell(r.BusierName)})
}
return ledgerWorkbook("注册明细", []string{"sourceDb", "所属平台", "ID", "玩家ID", "注册时间", "fgameId", "游戏", "累计充值", "注册IP", "机型", "渠道", "promoteId", "所属商务"}, rows)
}
func (s *LedgerService) ExportSpends(ctx context.Context, req *dto.LedgerQuery) ([]byte, error) {
f, _, err := ledgerRequest(req, true)
if err != nil {
return nil, err
}
items, err := s.uc.ExportSpends(ctx, f)
if err != nil {
return nil, err
}
rows := make([][]ledgerCell, 0, len(items))
for _, item := range items {
r := spendResponse(item)
rows = append(rows, []ledgerCell{textCell(r.SourceDB), textCell(r.SourceDBLabel), numericCell(strconv.FormatUint(r.ID, 10)), optionalNumber(r.UserID), textCell(r.OrderNumber), optionalNumber(r.GameID), textCell(r.GameName), textCell(r.ServerID), textCell(r.ServerName), textCell(r.PlayerName), optionalMoney(r.PayAmount), optionalNumber(r.PayTime), optionalNumber(r.PayWay), optionalNumber(r.PayStatus), textCell(r.IP), textCell(r.PromoteAccount), optionalNumber(r.PromoteID), textCell(r.BusierName)})
}
return ledgerWorkbook("充值明细", []string{"sourceDb", "所属平台", "ID", "玩家ID", "订单号", "gameId", "游戏", "serverId", "区服", "角色", "实付金额", "完成时间", "方式", "状态", "IP", "渠道", "promoteId", "所属商务"}, rows)
}