@@ -0,0 +1,558 @@
|
||||
package exportctrl
|
||||
|
||||
import (
|
||||
"91porn-server/common/timeutil"
|
||||
"91porn-server/models/v/export_task_mod"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/log"
|
||||
"91porn-server/common/stderr"
|
||||
"91porn-server/common/timeutil/timerange"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/l/playlgmod"
|
||||
"91porn-server/models/s/statordermod"
|
||||
"91porn-server/models/s/statvidmod"
|
||||
"91porn-server/models/v/exchcodemod"
|
||||
"91porn-server/models/v/rchgordmod"
|
||||
"91porn-server/models/v/txnmod"
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
"91porn-server/models/v/wdordmod"
|
||||
"91porn-server/web/service/exchcodeser"
|
||||
"91porn-server/web/service/exportser"
|
||||
"91porn-server/web/service/withdrawser"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type userListReq struct {
|
||||
usermod.UserListSelector
|
||||
common.StandQuery
|
||||
IsPretendAcc *int `form:"isPretendAcc" json:"isPretendAcc"` //是否马甲账号
|
||||
}
|
||||
|
||||
// Export doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/:fileType [get]
|
||||
func Export(c *gin.Context) {
|
||||
typeFile := c.Param("fileType")
|
||||
t, err := strconv.ParseInt(typeFile, 10, 64)
|
||||
if typeFile == "" || err != nil {
|
||||
common.ServeJSON(c, stderr.ErrParamError, err.Error())
|
||||
return
|
||||
}
|
||||
fpath, err := exportser.Export(t)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(c, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
c.Writer.WriteHeader(http.StatusOK)
|
||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
c.Header("Content-Type", "application/octet-stream")
|
||||
c.File(fpath)
|
||||
}
|
||||
|
||||
func getMuchUser(arg userListReq) []*usermod.User {
|
||||
uInfo := []*usermod.User{}
|
||||
cond, opt := common.StandQueryMap(arg.StandQuery, arg.UserListSelector)
|
||||
//马甲账户
|
||||
if arg.IsPretendAcc != nil && *arg.IsPretendAcc == 1 {
|
||||
cond["devID"] = bson.M{"$regex": usermod.SystemDevIDPrex, "$options": "i"}
|
||||
}
|
||||
//total, err := usermod.GetTotalCnt(cond, opt)
|
||||
//if err != nil {
|
||||
// return uInfo
|
||||
//}
|
||||
|
||||
// 每次最多导出1000条
|
||||
uInfo, _ = usermod.FindMany(cond, opt, int64(arg.PageNumber), int64(1000))
|
||||
return uInfo
|
||||
|
||||
//if total < 1000 {
|
||||
// uInfo, err = usermod.FindMany(cond, opt, int64(0), int64(1000))
|
||||
// return uInfo
|
||||
//}
|
||||
////创建多个协程去拉取
|
||||
//const goRoutineCnt int = 60
|
||||
//var wg sync.WaitGroup
|
||||
//size := total / int64(goRoutineCnt)
|
||||
//wg.Add(goRoutineCnt)
|
||||
//var mData [goRoutineCnt][]*usermod.User
|
||||
//for i := 0; i < goRoutineCnt-1; i++ {
|
||||
// common.GoParam(i, func(i int) {
|
||||
// defer wg.Done()
|
||||
// skip := int64(i) * size
|
||||
// mData[i], err = usermod.FindMany(cond, opt, int64(skip), int64(size))
|
||||
// })
|
||||
//}
|
||||
//common.Go(func() {
|
||||
// defer wg.Done()
|
||||
// skip := int64(goRoutineCnt-1) * size
|
||||
// mData[goRoutineCnt-1], err = usermod.FindMany(cond, opt, int64(skip), int64(size+size))
|
||||
//})
|
||||
//wg.Wait()
|
||||
//for i := 0; i < goRoutineCnt; i++ {
|
||||
// uInfo = append(uInfo, mData[i]...)
|
||||
//}
|
||||
//return uInfo
|
||||
}
|
||||
|
||||
func setArray2Map(datas []playlgmod.UIDCount) map[uint64]int {
|
||||
m := make(map[uint64]int)
|
||||
for _, d := range datas {
|
||||
m[d.UID] = d.Count
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func calWatchedVideoCnt(uids []uint64) []playlgmod.UIDCount {
|
||||
le := len(uids)
|
||||
if le < 1000 {
|
||||
datas, _ := playlgmod.HasWatchedVideoCnt(uids)
|
||||
return datas
|
||||
}
|
||||
//创建多个协程去拉取
|
||||
const goRoutineCnt = 10
|
||||
var wg sync.WaitGroup
|
||||
var mData [goRoutineCnt][]playlgmod.UIDCount
|
||||
size := le / goRoutineCnt
|
||||
wg.Add(goRoutineCnt)
|
||||
for i := 0; i < goRoutineCnt-1; i++ {
|
||||
common.GoParam(i, func(i int) {
|
||||
defer wg.Done()
|
||||
begin := i * size
|
||||
end := begin + size - 1
|
||||
mData[i], _ = playlgmod.HasWatchedVideoCnt(uids[begin:end])
|
||||
})
|
||||
}
|
||||
common.Go(func() {
|
||||
defer wg.Done()
|
||||
begin := (goRoutineCnt - 1) * size
|
||||
end := le - 1
|
||||
mData[goRoutineCnt-1], _ = playlgmod.HasWatchedVideoCnt(uids[begin:end])
|
||||
})
|
||||
wg.Wait()
|
||||
datas := []playlgmod.UIDCount{}
|
||||
for i := 0; i < goRoutineCnt; i++ {
|
||||
datas = append(datas, mData[i]...)
|
||||
}
|
||||
return datas
|
||||
}
|
||||
|
||||
//
|
||||
//func encodeUsers(users []*usermod.User, videoCntMap map[uint64]int, unDealVideoCntMap map[uint64]int) []usermod.ExportUser {
|
||||
// usersLen := len(users)
|
||||
// uids := make([]uint64, 0, usersLen)
|
||||
// uInfos := make([]usermod.ExportUser, 0, usersLen)
|
||||
// for _, u := range users {
|
||||
// if u != nil {
|
||||
// user := usermod.ExportUser{
|
||||
// UID: u.UID,
|
||||
// DevID: u.DevID,
|
||||
// DevType: u.DevType,
|
||||
// RegisterIP: u.RegisterIP,
|
||||
// Mobile: u.Mobile,
|
||||
// Gender: u.Gender,
|
||||
// Channel: u.DistrictCode,
|
||||
// Name: u.Name,
|
||||
// PromotionCode: u.PromCode,
|
||||
// Summary: u.Summary,
|
||||
// Region: u.Region,
|
||||
// Birthday: u.Birthday,
|
||||
// VipLevel: u.VipLevel,
|
||||
// VipExpireDate: u.VipExpireDate,
|
||||
// CreatedAt: u.CreatedAt,
|
||||
// MobileBindAt: u.MobileBindAt,
|
||||
// HasLocked: u.HasLocked,
|
||||
// HasBanned: u.HasBanned,
|
||||
// TotalVideoCnt: videoCntMap[u.UID],
|
||||
// UndealVideoCnt: unDealVideoCntMap[u.UID],
|
||||
// LastVisitAt: u.LastVisitAt,
|
||||
// }
|
||||
// uInfos = append(uInfos, user)
|
||||
// uids = append(uids, u.UID)
|
||||
// }
|
||||
// }
|
||||
// wCnt := setArray2Map(calWatchedVideoCnt(uids))
|
||||
// for i, u := range uInfos {
|
||||
// uInfos[i].WatchCount = wCnt[u.UID]
|
||||
// }
|
||||
// return uInfos
|
||||
//}
|
||||
|
||||
func getUIDs(users []*usermod.User) []uint64 {
|
||||
uids := make([]uint64, 0, len(users))
|
||||
for _, v := range users {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
uids = append(uids, v.UID)
|
||||
}
|
||||
return uids
|
||||
}
|
||||
|
||||
// Export doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/:fileType [get]
|
||||
func UserList(c *gin.Context) {
|
||||
manager, err := common.GetAdminAct(c)
|
||||
if err != nil {
|
||||
common.ServeJSON(c, stderr.AdminIDErr, err.Error())
|
||||
return
|
||||
}
|
||||
var arg userListReq
|
||||
if err := c.ShouldBind(&arg); err != nil {
|
||||
common.ServeJSON(c, stderr.ErrParamError, "user List arg error "+err.Error())
|
||||
return
|
||||
}
|
||||
if code := IsWithinWeek(arg.StartTime, arg.EndTime); code != stderr.Success {
|
||||
common.ServeJSON(c, code, code)
|
||||
return
|
||||
}
|
||||
err = export_task_mod.CreateTask(export_task_mod.ExportUserTask, manager, arg)
|
||||
if err != nil {
|
||||
common.ServeJSON(c, stderr.ErrExportFileFail, "")
|
||||
return
|
||||
}
|
||||
common.ServeJSON(c, stderr.Success, "成功")
|
||||
}
|
||||
|
||||
// IsWithinWeek 判断是否是一周内
|
||||
func IsWithinWeek(start *string, end *string) (code stderr.Code) {
|
||||
if start == nil || end == nil {
|
||||
return stderr.ErrTimeIsEmpty
|
||||
}
|
||||
startTime := timeutil.StrTimeToTime(*start)
|
||||
endTime := timeutil.StrTimeToTime(*end)
|
||||
hours := endTime.Sub(startTime).Hours()
|
||||
if hours > 24*7 {
|
||||
return stderr.ErrTimeWithinWeek
|
||||
}
|
||||
return stderr.Success
|
||||
}
|
||||
|
||||
// RechargeOrder doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/rechargeOrder [get]
|
||||
func RechargeOrder(ctx *gin.Context) {
|
||||
var arg struct {
|
||||
common.StandQuery
|
||||
rchgordmod.RchgQueryReq
|
||||
}
|
||||
if err := ctx.ShouldBind(&arg); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, err)
|
||||
return
|
||||
}
|
||||
//导出条数写死
|
||||
arg.StandQuery.PageNumber = 1
|
||||
arg.StandQuery.PageSize = 100000
|
||||
_, data, err := rchgordmod.FindRechargesOrders(common.StandQueryMap(arg.StandQuery, arg.RchgQueryReq))
|
||||
if err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrDbQueryError, "")
|
||||
return
|
||||
}
|
||||
exptData := make([]*rchgordmod.RchargeOrderExport, len(data))
|
||||
_100 := decimal.NewFromInt(100)
|
||||
for i, v := range data {
|
||||
exptData[i] = &rchgordmod.RchargeOrderExport{
|
||||
ID: v.ID,
|
||||
UID: v.UID,
|
||||
DevID: v.DevID,
|
||||
OID: v.OID,
|
||||
UserIP: v.UserIP,
|
||||
Name: v.Name,
|
||||
Tel: v.Tel,
|
||||
PayAct: v.PayAct,
|
||||
DevType: v.DevType,
|
||||
Amount: decimal.NewFromInt(v.Amount).Div(_100).StringFixed(4),
|
||||
Money: decimal.NewFromInt(v.Money).Div(_100).StringFixed(4),
|
||||
PayMoney: decimal.NewFromInt(v.PayMoney).Div(_100).StringFixed(4),
|
||||
RechargeType: v.RechargeType,
|
||||
ProductID: v.ProductID,
|
||||
VipID: v.VipID,
|
||||
Channel: v.Channel,
|
||||
Status: v.Status,
|
||||
StatusDesc: v.StatusDesc,
|
||||
ProgressAt: v.ProgressAt,
|
||||
FailureAt: v.FailureAt,
|
||||
SuccessAt: v.SuccessAt,
|
||||
PaymentAt: v.PaymentAt,
|
||||
CreatedAt: v.CreatedAt,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
SourcePage: v.SourcePage,
|
||||
SourceRef: v.SourceRef,
|
||||
VideoID: v.VideoID,
|
||||
ActivityID: v.ActivityID,
|
||||
ExperimentID: v.ExperimentID,
|
||||
ExperimentVariant: v.ExperimentVariant,
|
||||
SessionID: v.SessionID,
|
||||
}
|
||||
}
|
||||
fpath, err := exportser.RechargeOrderExport(exptData)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
|
||||
// WithdrawOrder doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/withdrawOrder [get]
|
||||
func WithdrawOrder(ctx *gin.Context) {
|
||||
var arg struct {
|
||||
common.StandQuery
|
||||
wdordmod.WithdrawWebQueryReq
|
||||
}
|
||||
if err := ctx.ShouldBind(&arg); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, err)
|
||||
return
|
||||
}
|
||||
//导出条数写死
|
||||
arg.StandQuery.PageNumber = 1
|
||||
arg.StandQuery.PageSize = 100000
|
||||
_, data, err := withdrawser.GetAllOrders(common.StandQueryMap(arg.StandQuery, arg.WithdrawWebQueryReq))
|
||||
if err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrDbQueryError, "")
|
||||
return
|
||||
}
|
||||
fpath, err := exportser.WithdrawOrderExport(data)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
|
||||
// GoldTurnover doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/withdrawOrder [get]
|
||||
func GoldTurnover(ctx *gin.Context) {
|
||||
req := txnmod.CoinLogReq{}
|
||||
if err := ctx.ShouldBind(&req); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, nil)
|
||||
return
|
||||
}
|
||||
m := make(map[string]interface{})
|
||||
if req.UID > 0 {
|
||||
m["uid"] = req.UID
|
||||
}
|
||||
if req.Balance == 1 {
|
||||
i := make(map[string]interface{})
|
||||
i["$gt"] = 0
|
||||
m["amount"] = i
|
||||
}
|
||||
if req.Balance == 2 {
|
||||
i := make(map[string]interface{})
|
||||
i["$lt"] = 0
|
||||
m["amount"] = i
|
||||
}
|
||||
if !req.End.IsZero() {
|
||||
i := make(map[string]interface{})
|
||||
i["$gte"] = req.Start
|
||||
i["$lt"] = req.End
|
||||
m["createdAt"] = i
|
||||
}
|
||||
if len(req.TranType) != 0 {
|
||||
m["tranType"] = req.TranType
|
||||
}
|
||||
infos, _, _, _ := txnmod.GetCoinLogs(1, 100000, m)
|
||||
fpath, err := exportser.GoldTurnoverExport(infos)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
|
||||
// VideoIncome doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/withdrawOrder [get]
|
||||
func VideoIncome(ctx *gin.Context) {
|
||||
type Query struct {
|
||||
StartTime *time.Time `form:"startTime" json:"startTime" binding:""` //开始时间
|
||||
EndTime *time.Time `form:"endTime" json:"endTime" binding:""` //结束时间
|
||||
UID *uint64 `form:"uid" json:"uid" binding:""` //uid
|
||||
Vid *string `form:"vid" json:"vid" binding:""` //vid
|
||||
}
|
||||
var arg struct {
|
||||
commod.Page
|
||||
Query
|
||||
}
|
||||
if err := ctx.ShouldBind(&arg); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, "stat VideoEarnStats arg error "+err.Error())
|
||||
return
|
||||
}
|
||||
endTime := time.Now()
|
||||
if arg.EndTime != nil {
|
||||
endTime = timerange.LocDayRange(*arg.EndTime).Head
|
||||
}
|
||||
startTime := time.Time{}
|
||||
if arg.StartTime != nil {
|
||||
startTime = timerange.LocDayRange(*arg.StartTime).Head
|
||||
}
|
||||
var vid *primitive.ObjectID
|
||||
if arg.Vid != nil {
|
||||
id, _ := primitive.ObjectIDFromHex(*arg.Vid)
|
||||
vid = &id
|
||||
}
|
||||
var vids []primitive.ObjectID
|
||||
if arg.UID != nil {
|
||||
list, _ := vidmod.FindMany((&vidmod.PublisherIDMatch{PublisherID: arg.UID}).New())
|
||||
vids = list.IDs()
|
||||
}
|
||||
limit := int64(100000)
|
||||
skip := int64(0)
|
||||
page, _ := statvidmod.VideoStatPages(skip, limit,
|
||||
statvidmod.SumDateGTEAndLTMatch{GTE: &startTime, LT: &endTime},
|
||||
statvidmod.VidMatch{Vid: vid},
|
||||
statvidmod.VidInMatch{Vids: vids},
|
||||
)
|
||||
fpath, err := exportser.VideoIncomeExport(page.List)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
|
||||
// OrderStat doc
|
||||
// @Summary 导出文件
|
||||
// @Description 导出excel文件
|
||||
// @Tags Web-Export
|
||||
// @Accept mpfd,json
|
||||
// @Produce json,html
|
||||
// @Param fileType query integer true "导出文件的类型"
|
||||
// @Success 200 {string} json "{"msg": "操作成功", "data":[]}"
|
||||
// @Failure 400 {string} json "{"msg": "操作失败"}"
|
||||
// @Router /web/export/withdrawOrder [get]
|
||||
func OrderStat(ctx *gin.Context) {
|
||||
var args struct {
|
||||
Type *int `form:"type" json:"type"` //订单类型
|
||||
Channel *string `form:"channel" json:"channel"`
|
||||
Start *time.Time `form:"start" json:"start"`
|
||||
End *time.Time `form:"end" json:"end"`
|
||||
}
|
||||
if err := ctx.ShouldBind(&args); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, nil)
|
||||
return
|
||||
}
|
||||
endTime := time.Now()
|
||||
if args.End != nil {
|
||||
endTime = *args.End
|
||||
}
|
||||
var startTime time.Time
|
||||
if args.Start != nil {
|
||||
startTime = *args.Start
|
||||
}
|
||||
skip := int64(0)
|
||||
limit := int64(100000)
|
||||
mats := []statordermod.Matcher{
|
||||
(&statordermod.ChannelMatch{}).New(),
|
||||
(&statordermod.TypeMatch{}).New(),
|
||||
(&statordermod.SumDateGTEAndLTMatch{GTE: &startTime, LT: &endTime}).New(),
|
||||
}
|
||||
list, err := statordermod.List(nil, &skip, &limit, mats...)
|
||||
if err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrDbQueryError, "")
|
||||
return
|
||||
}
|
||||
fpath, err := exportser.OrderStatExport(list)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
|
||||
// CodeList 导出兑换码
|
||||
func CodeList(ctx *gin.Context) {
|
||||
var param = exchcodemod.ListReqParam{}
|
||||
if err := ctx.ShouldBind(¶m); err != nil {
|
||||
common.ServeJSON(ctx, stderr.ErrParamError, err)
|
||||
return
|
||||
}
|
||||
data := exchcodeser.ExchangeCodes(param)
|
||||
fpath, err := exportser.ExchangeCodeExport(data)
|
||||
if err != nil {
|
||||
log.Warn("request multipart wrong ", log.E(err))
|
||||
common.ServeJSON(ctx, stderr.ErrExportFileFail, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Writer.WriteHeader(http.StatusOK)
|
||||
ctx.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(fpath)))
|
||||
ctx.Header("Content-Type", "application/octet-stream")
|
||||
ctx.File(fpath)
|
||||
}
|
||||
Reference in New Issue
Block a user