统一导出模式,使用sql语句的方式进行导出
This commit is contained in:
parent
485e8cc944
commit
fabed6916c
|
|
@ -1,32 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type baseExportBiz struct {
|
||||
fileSize int
|
||||
opts *ExportOpts
|
||||
fileName string
|
||||
}
|
||||
|
||||
func (e *baseExportBiz) FileSize() int {
|
||||
return e.fileSize
|
||||
}
|
||||
|
||||
func (e *baseExportBiz) FileName() string {
|
||||
return e.fileName
|
||||
}
|
||||
|
||||
func (e *baseExportBiz) FileNames() []string {
|
||||
name := make([]string, e.fileSize+1)
|
||||
for i := 0; i <= e.fileSize; i++ {
|
||||
name[i] = fmt.Sprintf(e.fileName, i)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (e *baseExportBiz) setFileArg(begin time.Time) {
|
||||
e.fileName = getFielName(e.opts.Path, e.opts.Tag, begin)
|
||||
}
|
||||
153
biz/batch.go
153
biz/batch.go
|
|
@ -1,153 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"excel_export/data"
|
||||
"excel_export/export"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewBatchBiz(repo *data.DirectRepo, historyRepo *data.HistoryDirectRepo, opts *ExportOpts) *BatchBiz {
|
||||
biz := &BatchBiz{
|
||||
repo: repo,
|
||||
historyRepo: historyRepo,
|
||||
}
|
||||
biz.opts = DefaultOpts
|
||||
if opts != nil {
|
||||
biz.opts = opts
|
||||
}
|
||||
biz.opts.Tag = "batch"
|
||||
return biz
|
||||
}
|
||||
|
||||
type BatchBiz struct {
|
||||
repo *data.DirectRepo
|
||||
historyRepo *data.HistoryDirectRepo
|
||||
baseExportBiz
|
||||
}
|
||||
|
||||
func (e *BatchBiz) Export(begin, end time.Time) error {
|
||||
e.setFileArg(begin)
|
||||
file := export.NewExport(e.fileName, e.opts.ExcelMaxRow)
|
||||
|
||||
if err := file.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.Title(export.Batchs{}.Title()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出历史订单数据
|
||||
if err := e.exportHistoryData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出最近7天数据
|
||||
if err := e.exportData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.fileSize = file.Index()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *BatchBiz) exportHistoryData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.historyRepo.BatchList(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.HistoryTransforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].SerialNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *BatchBiz) exportData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.repo.BatchList(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.Transforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].SerialNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e BatchBiz) Transforms(data []data.Direct) export.Batchs {
|
||||
result := make(export.Batchs, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.Transform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e BatchBiz) Transform(data data.Direct) *export.Batch {
|
||||
return &export.Batch{
|
||||
ResellerId: data.Batch.ResellerId,
|
||||
ResellerName: data.Batch.Reseller.Name,
|
||||
OursProductId: data.OursProductId,
|
||||
OursProductTitle: data.OrderItem.OursProductTitle,
|
||||
PlatformName: data.PlatformProduct.Platform.Name,
|
||||
PlatformProductCode: data.PlatformProduct.Code,
|
||||
PlatformProductName: data.PlatformProduct.Name,
|
||||
Status: data.Status,
|
||||
OrderOrderNumber: data.OrderOrderNumber,
|
||||
SerialNumber: data.SerialNumber,
|
||||
TerminalAccount: data.TerminalAccount,
|
||||
TradePrice: data.TradePrice,
|
||||
PlatformPrice: data.PlatformPrice,
|
||||
CreateTime: data.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
ExecuteTime: data.ExecuteTime.Format("2006-01-02 15:04:05"),
|
||||
Remark: data.Batch.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
func (e BatchBiz) HistoryTransforms(data []data.HistoryDirect) export.Batchs {
|
||||
result := make(export.Batchs, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.HistoryTransform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e BatchBiz) HistoryTransform(data data.HistoryDirect) *export.Batch {
|
||||
return &export.Batch{
|
||||
ResellerId: data.Batch.ResellerId,
|
||||
ResellerName: data.Batch.Reseller.Name,
|
||||
OursProductId: data.OursProductId,
|
||||
OursProductTitle: data.OrderItem.OursProductTitle,
|
||||
PlatformName: data.PlatformProduct.Platform.Name,
|
||||
PlatformProductCode: data.PlatformProduct.Code,
|
||||
PlatformProductName: data.PlatformProduct.Name,
|
||||
Status: data.Status,
|
||||
OrderOrderNumber: data.OrderOrderNumber,
|
||||
SerialNumber: data.SerialNumber,
|
||||
TerminalAccount: data.TerminalAccount,
|
||||
TradePrice: data.TradePrice,
|
||||
PlatformPrice: data.PlatformPrice,
|
||||
CreateTime: data.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
ExecuteTime: data.ExecuteTime.Format("2006-01-02 15:04:05"),
|
||||
Remark: data.Batch.Remark,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func batchBiz() *BatchBiz {
|
||||
db := data.Conn()
|
||||
repo := data.NewDirectRepo(db)
|
||||
historyRepo := data.NewHistoryDirectRepo(db)
|
||||
|
||||
return NewBatchBiz(repo, historyRepo, nil)
|
||||
}
|
||||
|
||||
func TestBatchBiz_Export(t *testing.T) {
|
||||
biz := batchBiz()
|
||||
begin := time.Date(2021, 10, 1, 0, 0, 0, 0, time.Local)
|
||||
end := time.Date(2022, 12, 1, 0, 0, 0, 0, time.Local)
|
||||
|
||||
err := biz.Export(begin, end)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for i := 0; i <= biz.FileSize(); i++ {
|
||||
fileName := fmt.Sprintf(biz.FileName(), i)
|
||||
assert.FileExists(t, fileName)
|
||||
|
||||
//清理文件
|
||||
os.Remove(fileName)
|
||||
}
|
||||
|
||||
}
|
||||
90
biz/card.go
90
biz/card.go
|
|
@ -1,90 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"excel_export/data"
|
||||
"excel_export/export"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewCardBiz(repo *data.CardRepo, opts *ExportOpts) *CardBiz {
|
||||
biz := &CardBiz{
|
||||
repo: repo,
|
||||
}
|
||||
|
||||
if opts == nil {
|
||||
opts = DefaultOpts
|
||||
}
|
||||
opts.Tag = "card"
|
||||
biz.opts = opts
|
||||
return biz
|
||||
}
|
||||
|
||||
type CardBiz struct {
|
||||
repo *data.CardRepo
|
||||
baseExportBiz
|
||||
}
|
||||
|
||||
func (e *CardBiz) Export(begin, end time.Time) error {
|
||||
e.setFileArg(begin)
|
||||
file := export.NewExport(e.fileName, e.opts.ExcelMaxRow)
|
||||
|
||||
if err := file.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.Title(export.Cards{}.Title()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := e.exportData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.fileSize = file.Index()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *CardBiz) exportData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.repo.List(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.Transforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].OrderNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e CardBiz) Transforms(data []data.Card) export.Cards {
|
||||
result := make(export.Cards, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.Transform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e CardBiz) Transform(data data.Card) *export.Card {
|
||||
return &export.Card{
|
||||
OrderNumber: data.OrderNumber,
|
||||
ResellerOrderNumber: data.ResellerOrderNumber,
|
||||
Amount: data.Amount,
|
||||
Quantity: data.Quantity,
|
||||
Status: data.Status,
|
||||
ResellerId: data.ResellerId,
|
||||
ResellerName: data.Reseller.Name,
|
||||
OursProductId: data.OursProductId,
|
||||
OursProductTitle: data.OurProduct.Name,
|
||||
CreateTime: time.Unix(data.CreateTime, 0).Format("2006-01-02 15:04:05"),
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func cardBiz() *CardBiz {
|
||||
db := data.Conn()
|
||||
repo := data.NewCardRepo(db)
|
||||
|
||||
return NewCardBiz(repo, nil)
|
||||
}
|
||||
|
||||
func TestCardBiz_Export(t *testing.T) {
|
||||
biz := cardBiz()
|
||||
begin := time.Date(2012, 10, 1, 0, 0, 0, 0, time.Local)
|
||||
end := time.Date(2022, 12, 1, 0, 0, 0, 0, time.Local)
|
||||
|
||||
err := biz.Export(begin, end)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for i := 0; i <= biz.FileSize(); i++ {
|
||||
fileName := fmt.Sprintf(biz.FileName(), i)
|
||||
assert.FileExists(t, fileName)
|
||||
|
||||
//清理文件
|
||||
os.Remove(fileName)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
QueryLImit = 10
|
||||
ExcelMaxRow = 10
|
||||
)
|
||||
|
||||
func getFielName(path, filename string, time time.Time) string {
|
||||
if path == "" {
|
||||
path, _ = os.Getwd()
|
||||
}
|
||||
date := time.Format("20060102")
|
||||
return fmt.Sprintf("%s/%s_%s_%%d.xlsx", path, filename, date)
|
||||
}
|
||||
|
||||
type ExportOpts struct {
|
||||
QueryLimit int
|
||||
ExcelMaxRow int
|
||||
Path string
|
||||
Tag string
|
||||
}
|
||||
|
||||
var DefaultOpts *ExportOpts = &ExportOpts{
|
||||
QueryLimit: QueryLImit,
|
||||
ExcelMaxRow: ExcelMaxRow,
|
||||
Tag: "export",
|
||||
}
|
||||
|
||||
func NewExportOpts(query, limit int, path string) *ExportOpts {
|
||||
return &ExportOpts{
|
||||
QueryLimit: query,
|
||||
ExcelMaxRow: limit,
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
Config struct {
|
||||
Systems []System
|
||||
}
|
||||
System struct {
|
||||
Name string
|
||||
Db string
|
||||
Jobs []Job
|
||||
}
|
||||
|
||||
Job struct {
|
||||
Name string
|
||||
Tasks []Task
|
||||
File string
|
||||
}
|
||||
|
||||
Task struct {
|
||||
PK string
|
||||
Sql string
|
||||
Timestamp bool
|
||||
Elt string
|
||||
Order string
|
||||
}
|
||||
)
|
||||
|
||||
func (c Config) GetSystem(system string) (System, error) {
|
||||
for _, s := range c.Systems {
|
||||
if s.Name == system {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return System{}, errors.New("没有找到相关配置:" + system)
|
||||
}
|
||||
|
||||
func (s System) GetJob(job string) (Job, error) {
|
||||
for _, j := range s.Jobs {
|
||||
if j.Name == job {
|
||||
return j, nil
|
||||
}
|
||||
}
|
||||
return Job{}, errors.New("没有找到相关配置:" + job)
|
||||
}
|
||||
|
||||
func (t Task) GetSql(params map[string]interface{}) string {
|
||||
sql := t.Sql
|
||||
|
||||
m := regexp.MustCompile("({[a-zA-Z0-9]+})")
|
||||
if strings.Trim(t.Elt, " ") != "" {
|
||||
wehre := m.ReplaceAllFunc([]byte(t.Elt), func(b []byte) []byte {
|
||||
field := string(b[1 : len(b)-1])
|
||||
|
||||
if val, ok := params[field]; ok {
|
||||
return []byte(t.getParam(val))
|
||||
}
|
||||
return b
|
||||
})
|
||||
|
||||
sql = sql + " where " + string(wehre)
|
||||
}
|
||||
|
||||
if strings.Trim(t.Order, " ") != "" {
|
||||
sql = sql + " order by " + t.Order
|
||||
}
|
||||
|
||||
return sql
|
||||
}
|
||||
|
||||
func (t Task) getParam(parm interface{}) string {
|
||||
switch p := parm.(type) {
|
||||
case time.Time:
|
||||
if t.Timestamp {
|
||||
return strconv.FormatInt(p.Unix(), 10)
|
||||
} else {
|
||||
return p.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
case string:
|
||||
return p
|
||||
case int:
|
||||
return strconv.Itoa(p)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(p), 10)
|
||||
default:
|
||||
return fmt.Sprint(p)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTask_GetSql(t *testing.T) {
|
||||
task := Task{
|
||||
Sql: "select * from order",
|
||||
Elt: "create_time between {begin} and {end} and o.order_number > {last}",
|
||||
Timestamp: true,
|
||||
Order: " ",
|
||||
}
|
||||
begin, _ := time.Parse("2006-01-02 15:04:05", "2023-01-01 00:00:00")
|
||||
end := begin.Add(time.Hour * 24)
|
||||
sql := task.GetSql(map[string]interface{}{"begin": begin, "end": end, "last": 0})
|
||||
|
||||
assert.Equal(t, fmt.Sprintf("select * from order where create_time between %d and %d and o.order_number > 0", begin.Unix(), end.Unix()), sql)
|
||||
}
|
||||
|
||||
func TestTask_GetSql_OrderBy(t *testing.T) {
|
||||
task := Task{
|
||||
Sql: "select * from order",
|
||||
Elt: "create_time between '{begin}' and '{end}'",
|
||||
Timestamp: false,
|
||||
Order: "create_time",
|
||||
}
|
||||
begin, _ := time.Parse("2006-01-02 15:04:05", "2023-01-01 00:00:00")
|
||||
end := begin.Add(time.Hour * 24)
|
||||
sql := task.GetSql(map[string]interface{}{"begin": begin, "end": end})
|
||||
assert.Equal(t, fmt.Sprintf("select * from order where create_time between '%s' and '%s' order by create_time", begin.Format("2006-01-02 15:04:05"), end.Format("2006-01-02 15:04:05")), sql)
|
||||
}
|
||||
159
biz/direct.go
159
biz/direct.go
|
|
@ -1,159 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"excel_export/data"
|
||||
"excel_export/export"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewDirectBiz(repo *data.DirectRepo, historyRepo *data.HistoryDirectRepo, opts *ExportOpts) *DirectBiz {
|
||||
biz := &DirectBiz{
|
||||
repo: repo,
|
||||
historyRepo: historyRepo,
|
||||
}
|
||||
if opts == nil {
|
||||
opts = DefaultOpts
|
||||
}
|
||||
opts.Tag = "direct"
|
||||
biz.opts = opts
|
||||
return biz
|
||||
}
|
||||
|
||||
type DirectBiz struct {
|
||||
repo *data.DirectRepo
|
||||
historyRepo *data.HistoryDirectRepo
|
||||
baseExportBiz
|
||||
}
|
||||
|
||||
func (e *DirectBiz) FileSize() int {
|
||||
return e.fileSize
|
||||
}
|
||||
|
||||
func (e *DirectBiz) Export(begin, end time.Time) error {
|
||||
e.setFileArg(begin)
|
||||
file := export.NewExport(e.fileName, e.opts.ExcelMaxRow)
|
||||
|
||||
if err := file.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.Title(export.Directs{}.Title()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出历史订单数据
|
||||
if err := e.exportHistoryData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出最近7天数据
|
||||
if err := e.exportData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.fileSize = file.Index()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *DirectBiz) exportHistoryData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.historyRepo.List(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.HistoryTransforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].SerialNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *DirectBiz) exportData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.repo.List(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.Transforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].SerialNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e DirectBiz) Transforms(data []data.Direct) export.Directs {
|
||||
result := make(export.Directs, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.Transform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e DirectBiz) Transform(data data.Direct) *export.Direct {
|
||||
return &export.Direct{
|
||||
ResellerId: data.Order.ResellerId,
|
||||
ResellerName: data.Order.Reseller.Name,
|
||||
ResellerOrderNumber: data.Order.ResellerOrderNumber,
|
||||
OursProductId: data.OursProductId,
|
||||
OursProductTitle: data.OrderItem.OursProductTitle,
|
||||
PlatformName: data.PlatformProduct.Platform.Name,
|
||||
PlatformProductCode: data.PlatformProduct.Code,
|
||||
PlatformProductName: data.PlatformProduct.Name,
|
||||
Status: data.Status,
|
||||
OrderOrderNumber: data.OrderOrderNumber,
|
||||
SerialNumber: data.SerialNumber,
|
||||
TerminalAccount: data.TerminalAccount,
|
||||
TradePrice: data.TradePrice,
|
||||
PlatformPrice: data.PlatformPrice,
|
||||
CreateTime: data.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
ExecuteTime: data.ExecuteTime.Format("2006-01-02 15:04:05"),
|
||||
Remark: data.Order.Remark.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
func (e DirectBiz) HistoryTransforms(data []data.HistoryDirect) export.Directs {
|
||||
result := make(export.Directs, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.HistoryTransform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e DirectBiz) HistoryTransform(data data.HistoryDirect) *export.Direct {
|
||||
return &export.Direct{
|
||||
ResellerId: data.Order.ResellerId,
|
||||
ResellerName: data.Order.Reseller.Name,
|
||||
ResellerOrderNumber: data.Order.ResellerOrderNumber,
|
||||
OursProductId: data.OursProductId,
|
||||
OursProductTitle: data.OrderItem.OursProductTitle,
|
||||
PlatformName: data.PlatformProduct.Platform.Name,
|
||||
PlatformProductCode: data.PlatformProduct.Code,
|
||||
PlatformProductName: data.PlatformProduct.Name,
|
||||
Status: data.Status,
|
||||
OrderOrderNumber: data.OrderOrderNumber,
|
||||
SerialNumber: data.SerialNumber,
|
||||
TerminalAccount: data.TerminalAccount,
|
||||
TradePrice: data.TradePrice,
|
||||
PlatformPrice: data.PlatformPrice,
|
||||
CreateTime: data.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
ExecuteTime: data.ExecuteTime.Format("2006-01-02 15:04:05"),
|
||||
Remark: data.Order.Remark.Remark,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func directBiz() *DirectBiz {
|
||||
db := data.Conn()
|
||||
repo := data.NewDirectRepo(db)
|
||||
historyRepo := data.NewHistoryDirectRepo(db)
|
||||
|
||||
return NewDirectBiz(repo, historyRepo, nil)
|
||||
}
|
||||
|
||||
func TestDirectBiz_Export(t *testing.T) {
|
||||
biz := directBiz()
|
||||
begin := time.Date(2022, 10, 1, 0, 0, 0, 0, time.Local)
|
||||
end := time.Date(2022, 12, 1, 0, 0, 0, 0, time.Local)
|
||||
|
||||
err := biz.Export(begin, end)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for i := 0; i <= biz.FileSize(); i++ {
|
||||
fileName := fmt.Sprintf(biz.FileName(), i)
|
||||
assert.FileExists(t, fileName)
|
||||
|
||||
//清理文件
|
||||
os.Remove(fileName)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/tealeg/xlsx/v3"
|
||||
)
|
||||
|
||||
const Sheet_Name = "sheet_1"
|
||||
|
||||
type Excel struct {
|
||||
f *File
|
||||
count int //总数
|
||||
isNew bool
|
||||
titles []string
|
||||
file *xlsx.File
|
||||
sheet *xlsx.Sheet
|
||||
}
|
||||
|
||||
func NewExcel(fileName string, limit int, param map[string]string) *Excel {
|
||||
return &Excel{
|
||||
f: NewFile(fileName, limit, param),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Excel) slice() {
|
||||
if e.f.slice() {
|
||||
e.reset()
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Excel) reset() {
|
||||
e.save()
|
||||
e.f.NextFile()
|
||||
e.Open()
|
||||
e.WriteTitle(nil)
|
||||
e.slice()
|
||||
}
|
||||
|
||||
func (e *Excel) Open() error {
|
||||
var err error
|
||||
if e.f.IsFileExist() {
|
||||
e.file, err = xlsx.OpenFile(e.f.FileName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
e.isNew = true
|
||||
e.file = xlsx.NewFile()
|
||||
}
|
||||
|
||||
var ok bool
|
||||
e.sheet, ok = e.file.Sheet[Sheet_Name]
|
||||
if !ok {
|
||||
e.sheet, err = e.file.AddSheet(Sheet_Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
//需要处理偏移数据
|
||||
e.f.SetRow(e.sheet.MaxRow - 1)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Excel) save() error {
|
||||
return e.file.Save(e.f.FileName())
|
||||
}
|
||||
|
||||
func (e *Excel) WriteTitle(titles []string) error {
|
||||
if e.file == nil || e.sheet == nil {
|
||||
return errors.New("没有执行open方法")
|
||||
}
|
||||
|
||||
if titles != nil {
|
||||
e.titles = titles
|
||||
}
|
||||
|
||||
if e.titles != nil && e.isNew {
|
||||
e.Write(e.titles)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Excel) Write(data interface{}) error {
|
||||
if e.f.slice() {
|
||||
e.reset()
|
||||
}
|
||||
row := e.sheet.AddRow()
|
||||
row.WriteSlice(data, -1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Excel) Close() error {
|
||||
return e.save()
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package export
|
||||
|
||||
type ExcelExporter struct {
|
||||
mFetcher DataFetcher
|
||||
file FileAdapter
|
||||
}
|
||||
|
||||
func NewExcelExporter(fetcher DataFetcher, file FileAdapter) DataExporter {
|
||||
return &ExcelExporter{
|
||||
mFetcher: fetcher,
|
||||
file: file,
|
||||
}
|
||||
}
|
||||
|
||||
func (ee *ExcelExporter) Fetcher(fetcher DataFetcher) {
|
||||
ee.mFetcher = fetcher
|
||||
}
|
||||
|
||||
func (ee *ExcelExporter) File(file FileAdapter) {
|
||||
ee.file = file
|
||||
}
|
||||
|
||||
func (ee *ExcelExporter) Export(sql string) error {
|
||||
rows := ee.mFetcher.Fetch(sql)
|
||||
//fmt.Printf("Excel Exporter.Excel, got %v rows\n", len(rows))
|
||||
ee.file.Open()
|
||||
ee.file.WriteTitle([]string{"字段1", "字段2", "字段3", "字段4", "字段5"})
|
||||
for _, v := range rows {
|
||||
// fmt.Printf(" 行号: %d 值: %s\n", i+1, v)
|
||||
ee.file.Write(v)
|
||||
}
|
||||
ee.file.Close()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExcelExporter_Export(t *testing.T) {
|
||||
data := NewMysqlDataFetcher("aaa")
|
||||
pwd, _ := os.Getwd()
|
||||
file := NewExcel(pwd+"/aa-{begin}.xlsx", 5, map[string]string{"begin": "202301"})
|
||||
e := NewExcelExporter(data, file)
|
||||
err := e.Export("aa")
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.FileExists(t, pwd+"/aa-202301_0.xlsx")
|
||||
assert.FileExists(t, pwd+"/aa-202301_1.xlsx")
|
||||
assert.NoFileExists(t, pwd+"/aa-202301_2.xlsx")
|
||||
|
||||
_ = os.Remove(pwd + "/aa-202301_0.xlsx")
|
||||
_ = os.Remove(pwd + "/aa-202301_1.xlsx")
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExcel_Write(t *testing.T) {
|
||||
pwd, _ := os.Getwd()
|
||||
e := NewExcel(pwd+"/aa-{begin}.xlsx", 5, map[string]string{"begin": "202301"})
|
||||
|
||||
e.Open()
|
||||
|
||||
e.WriteTitle([]string{"姓名", "年龄"})
|
||||
data := make([]interface{}, 2)
|
||||
data[0] = "张三"
|
||||
for i := 0; i < 9; i++ {
|
||||
data[1] = 10 + i
|
||||
e.Write(data)
|
||||
}
|
||||
e.Close()
|
||||
|
||||
assert.FileExists(t, pwd+"/aa-202301_0.xlsx")
|
||||
assert.FileExists(t, pwd+"/aa-202301_1.xlsx")
|
||||
assert.NoFileExists(t, pwd+"/aa-202301_2.xlsx")
|
||||
|
||||
_ = os.Remove(pwd + "/aa-202301_0.xlsx")
|
||||
_ = os.Remove(pwd + "/aa-202301_1.xlsx")
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package export
|
||||
|
||||
type (
|
||||
DataExporter interface {
|
||||
Fetcher(fetcher DataFetcher)
|
||||
File(file FileAdapter)
|
||||
Export(sql string) error
|
||||
}
|
||||
DataFetcher interface {
|
||||
Fetch(sql string) []interface{}
|
||||
}
|
||||
|
||||
FileAdapter interface {
|
||||
Open() error
|
||||
WriteTitle([]string) error
|
||||
Write(interface{}) error
|
||||
Close() error
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type FileOpts struct {
|
||||
fileName string
|
||||
limit int
|
||||
row int
|
||||
}
|
||||
|
||||
func (f *FileOpts) slice() bool {
|
||||
f.row++
|
||||
if f.row > f.limit+1 { // +1 排除标题行
|
||||
f.row = 0
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type File struct {
|
||||
FileOpts
|
||||
|
||||
param map[string]string
|
||||
index int
|
||||
}
|
||||
|
||||
func NewFile(name string, limit int, param map[string]string) *File {
|
||||
return &File{
|
||||
FileOpts: FileOpts{
|
||||
fileName: name,
|
||||
limit: limit,
|
||||
},
|
||||
param: param,
|
||||
}
|
||||
}
|
||||
func (f *File) SetIndex(index int) *File {
|
||||
f.index = index
|
||||
return f
|
||||
}
|
||||
func (f *File) SetRow(row int) *File {
|
||||
f.row = row
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *File) NextFile() *File {
|
||||
f.index++
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *File) FileName() string {
|
||||
m := regexp.MustCompile("({[a-zA-Z0-9]+})")
|
||||
name := m.ReplaceAllFunc([]byte(f.fileName), func(b []byte) []byte {
|
||||
field := string(b[1 : len(b)-1])
|
||||
|
||||
if val, ok := f.param[field]; ok {
|
||||
return []byte(val)
|
||||
}
|
||||
return b
|
||||
})
|
||||
|
||||
ex := regexp.MustCompile("(\\..*)")
|
||||
name = ex.ReplaceAllFunc(name, func(b []byte) []byte {
|
||||
i := []byte("_" + strconv.Itoa(f.index))
|
||||
ret := make([]byte, len(b)+len(i))
|
||||
copy(ret, i)
|
||||
copy(ret[len(i):], b)
|
||||
return ret
|
||||
})
|
||||
|
||||
return string(name)
|
||||
}
|
||||
|
||||
func (f *File) IsFileExist() bool {
|
||||
_, err := os.Stat(f.FileName())
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFile_FileName(t *testing.T) {
|
||||
f := NewFile("/usr/file-{begin}-{end}.xlsx", 10, map[string]string{
|
||||
"begin": "20230404",
|
||||
"end": "20230404",
|
||||
})
|
||||
assert.Equal(t, "/usr/file-20230404-20230404_0.xlsx", f.FileName())
|
||||
|
||||
f.NextFile()
|
||||
assert.Equal(t, "/usr/file-20230404-20230404_1.xlsx", f.FileName())
|
||||
}
|
||||
|
||||
func TestFile_IsFileExist(t *testing.T) {
|
||||
gwd, _ := os.Getwd()
|
||||
|
||||
f := NewFile(gwd+"/file-{begin}-{end}.xlsx", 10, map[string]string{
|
||||
"begin": "20230404",
|
||||
"end": "20230404",
|
||||
})
|
||||
|
||||
assert.False(t, f.IsFileExist())
|
||||
|
||||
path := gwd + "/file-20230404-20230404_0.xlsx"
|
||||
_, err := os.Create(path)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.FileExists(t, path)
|
||||
assert.True(t, f.IsFileExist())
|
||||
|
||||
err = os.Remove(path)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type MysqlDataFetcher struct {
|
||||
Config string
|
||||
}
|
||||
|
||||
func (mf *MysqlDataFetcher) Fetch(sql string) []interface{} {
|
||||
rows := make([]interface{}, 0, 6)
|
||||
// 插入6个随机数组成的切片,模拟查询要返回的数据集
|
||||
rows = append(rows, rand.Perm(5), rand.Perm(5), rand.Perm(5), rand.Perm(5), rand.Perm(5), rand.Perm(5))
|
||||
return rows
|
||||
}
|
||||
|
||||
func NewMysqlDataFetcher(configStr string) DataFetcher {
|
||||
return &MysqlDataFetcher{
|
||||
Config: configStr,
|
||||
}
|
||||
}
|
||||
150
biz/order.go
150
biz/order.go
|
|
@ -1,150 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"excel_export/data"
|
||||
"excel_export/export"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewOrderBiz(repo *data.OrderRepo, historyRepo *data.HistoryOrderRepo, opts *ExportOpts) *OrderBiz {
|
||||
biz := &OrderBiz{
|
||||
repo: repo,
|
||||
historyRepo: historyRepo,
|
||||
}
|
||||
|
||||
biz.opts = DefaultOpts
|
||||
if opts != nil {
|
||||
biz.opts = opts
|
||||
}
|
||||
return biz
|
||||
}
|
||||
|
||||
type OrderBiz struct {
|
||||
repo *data.OrderRepo
|
||||
historyRepo *data.HistoryOrderRepo
|
||||
baseExportBiz
|
||||
}
|
||||
|
||||
func (e *OrderBiz) Export(begin, end time.Time) error {
|
||||
e.setFileArg(begin)
|
||||
file := export.NewExport(e.fileName, e.opts.ExcelMaxRow)
|
||||
|
||||
if err := file.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := file.Title(export.Orders{}.Title()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出历史订单数据
|
||||
if err := e.exportHistoryData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//导出最近7天数据
|
||||
if err := e.exportData(file, begin, end); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.fileSize = file.Index()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OrderBiz) exportHistoryData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.historyRepo.List(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.HistoryTransforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].OrderNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *OrderBiz) exportData(export *export.Export, begin, end time.Time) error {
|
||||
var last string
|
||||
for true {
|
||||
//导出最近7天数据
|
||||
data, err := e.repo.List(context.Background(), begin, end, e.opts.QueryLimit, last)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取导出数据错误:%w", err)
|
||||
}
|
||||
|
||||
if err := export.Export(e.Transforms(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(data) < e.opts.QueryLimit {
|
||||
return nil
|
||||
}
|
||||
last = data[len(data)-1].OrderNumber
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e OrderBiz) Transforms(data []data.Order) export.Orders {
|
||||
result := make(export.Orders, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.Transform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e OrderBiz) Transform(order data.Order) *export.Order {
|
||||
return &export.Order{
|
||||
OrderNumber: order.OrderNumber,
|
||||
ResellerId: order.ResellerId,
|
||||
ResellerName: order.Reseller.Name,
|
||||
ResellerOrderNumber: order.ResellerOrderNumber,
|
||||
Amount: order.Amount,
|
||||
Account: order.Account,
|
||||
Quantity: order.Quantity,
|
||||
Status: order.Status,
|
||||
PayStatus: order.PayStatus,
|
||||
CreateTime: time.Unix(order.CreateTime, 0).Format("2006-01-02 15:04:05"),
|
||||
FinishTime: time.Unix(order.FinishTime, 0).Format("2006-01-02 15:04:05"),
|
||||
OursProductId: order.Item.OursProductId,
|
||||
OursProductTitle: order.Item.OursProductTitle,
|
||||
Remark: order.Remark.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
func (e OrderBiz) HistoryTransforms(data []data.HistoryOrder) export.Orders {
|
||||
result := make(export.Orders, len(data))
|
||||
for i, val := range data {
|
||||
result[i] = e.HistoryTransform(val)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (e OrderBiz) HistoryTransform(order data.HistoryOrder) *export.Order {
|
||||
return &export.Order{
|
||||
OrderNumber: order.OrderNumber,
|
||||
ResellerId: order.ResellerId,
|
||||
ResellerName: order.Reseller.Name,
|
||||
ResellerOrderNumber: order.ResellerOrderNumber,
|
||||
Amount: order.Amount,
|
||||
Account: order.Account,
|
||||
Quantity: order.Quantity,
|
||||
Status: order.Status,
|
||||
PayStatus: order.PayStatus,
|
||||
CreateTime: order.CreateTime.Format("2006-01-02 15:04:05"),
|
||||
FinishTime: order.FinishTime.Format("2006-01-02 15:04:05"),
|
||||
OursProductId: order.Item.OursProductId,
|
||||
OursProductTitle: order.Item.OursProductTitle,
|
||||
Remark: order.Remark.Remark,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package biz
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func orderBiz() *OrderBiz {
|
||||
db := data.Conn()
|
||||
repo := data.NewOrderRepo(db)
|
||||
historyRepo := data.NewHistoryOrderRepo(db)
|
||||
|
||||
return NewOrderBiz(repo, historyRepo, nil)
|
||||
}
|
||||
|
||||
func TestOrderBiz_Export(t *testing.T) {
|
||||
biz := orderBiz()
|
||||
begin := time.Date(2022, 8, 1, 0, 0, 0, 0, time.UTC)
|
||||
end := time.Date(2022, 8, 2, 10, 0, 0, 0, time.UTC)
|
||||
|
||||
err := biz.Export(begin, end)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for i := 0; i <= biz.FileSize(); i++ {
|
||||
fileName := fmt.Sprintf(biz.FileName(), i)
|
||||
assert.FileExists(t, fileName)
|
||||
|
||||
//清理文件
|
||||
os.Remove(fileName)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
system:
|
||||
- name: "直连天下"
|
||||
db: ""
|
||||
jobs:
|
||||
- name: "卡密订单"
|
||||
tasks:
|
||||
- sql: >-
|
||||
SELECT
|
||||
order_number AS `订单号` ,
|
||||
reseller_order_number AS `分销商订单号`,
|
||||
order_card.price AS `扣款价格`,
|
||||
order_card.`quantity` as `数量`,
|
||||
case order_card.`status`
|
||||
WHEN 0 THEN '充值中'
|
||||
WHEN 1 THEN '充值成功'
|
||||
WHEN -2 THEN '充值失败'
|
||||
ELSE order_card.`status`
|
||||
END
|
||||
AS 充值状态,
|
||||
r.`name` AS `分销商名称` ,
|
||||
o.`name` AS `订单商品名称`,
|
||||
FROM_UNIXTIME(order_card.`create_time`) AS `创建时间`
|
||||
FROM
|
||||
order_card
|
||||
LEFT JOIN reseller r ON order_card.reseller_id = r.id
|
||||
LEFT JOIN ours_product o ON o.id = order_card.ours_product_id
|
||||
timestamp: true
|
||||
elt: "order_card.create_time BETWEEN {begin} AND {end} and order_card.order_number > {last}"
|
||||
order: "order_card.create_time,order_card.order_number"
|
||||
file: "直连天下-卡密订单-${month}.xlsx"
|
||||
- name: "上游订单"
|
||||
tasks:
|
||||
- sql: >-
|
||||
SELECT
|
||||
o.reseller_id as `分销商id`,
|
||||
r.`name` as `分销商名称`,
|
||||
o.reseller_order_number as `商户订单号`,
|
||||
od.ours_product_id as `我们的商品id`,
|
||||
oi.ours_product_title as `订单商品名称`,
|
||||
oi.ours_product_title as `商品名称`,
|
||||
p.name as `接口平台`,
|
||||
CASE od.`status`
|
||||
WHEN -10 THEN '取消充值(失败)'
|
||||
WHEN -6 THEN '手动失败'
|
||||
WHEN -5 THEN '手动重试'
|
||||
WHEN -3 THEN '卡单'
|
||||
WHEN -2 THEN '失败重试'
|
||||
WHEN -1 THEN '充值失败'
|
||||
WHEN 0 THEN '待充值'
|
||||
WHEN 1 THEN '充值成功'
|
||||
WHEN 2 THEN '充值中'
|
||||
else od.`status`
|
||||
END
|
||||
AS 充值状态,
|
||||
pp.`code` as `接口平台产品编码`,
|
||||
pp.`name` as `接口平台产品名称`,
|
||||
od.order_order_number as `系统订单号`,
|
||||
od.serial_number as `流水号`,
|
||||
od.terminal_account as `充值账号`,
|
||||
od.trade_price as `成交价格`,
|
||||
od.platform_price as `接口平台价格`,
|
||||
od.create_time as `创建时间`,
|
||||
od.execute_time as `执行时间`,
|
||||
re.remark as `备注`
|
||||
FROM
|
||||
history_order_direct od
|
||||
right join `history_order` o on o.order_number = od.order_order_number
|
||||
left join history_order_item oi on o.order_number = oi.order_order_number
|
||||
left join platform_product pp on pp.id = od.platform_product_id
|
||||
left join platform p on pp.platform_id = p.id
|
||||
left join reseller r on r.id = o.reseller_id
|
||||
left join history_order_remark re on o.order_number = re.order_number
|
||||
timestamp: false
|
||||
elt: "od.create_time BETWEEN '{begin}' and '{end}' and od.serial_number > {last}"
|
||||
order: "od.create_time,od.serial_number"
|
||||
- sql: >-
|
||||
SELECT
|
||||
o.reseller_id as `分销商id`,
|
||||
r.`name` as `分销商名称`,
|
||||
o.reseller_order_number as `商户订单号`,
|
||||
od.ours_product_id as `我们的商品id`,
|
||||
oi.ours_product_title as `订单商品名称`,
|
||||
op.NAME as `商品名称`,
|
||||
p.name as `接口平台`,
|
||||
CASE od.`status`
|
||||
WHEN -10 THEN '取掉充值(失败)'
|
||||
WHEN -6 THEN '手动失败'
|
||||
WHEN -5 THEN '手动重试'
|
||||
WHEN -3 THEN '卡单'
|
||||
WHEN -2 THEN '失败重试'
|
||||
WHEN -1 THEN '充值失败'
|
||||
WHEN 0 THEN '待充值'
|
||||
WHEN 1 THEN '充值成功'
|
||||
WHEN 2 THEN '充值中'
|
||||
else od.`status`
|
||||
END
|
||||
AS 充值状态,
|
||||
pp.`code` as `接口平台产品编码`,
|
||||
pp.`name` as `接口平台产品名称`,
|
||||
od.order_order_number as `系统订单号`,
|
||||
od.serial_number as `流水号`,
|
||||
od.terminal_account as `充值账号`,
|
||||
od.trade_price as `成交价格`,
|
||||
od.platform_price as `接口平台价格`,
|
||||
od.create_time as `创建时间`,
|
||||
od.execute_time as `执行时间`,
|
||||
re.remark as `备注`
|
||||
|
||||
FROM
|
||||
order_direct od
|
||||
right join `order` o on o.order_number = od.order_order_number
|
||||
left join order_item oi on o.order_number = oi.order_order_number
|
||||
left JOIN ours_product op ON od.ours_product_id = op.id
|
||||
left join platform_product pp on pp.id = od.platform_product_id
|
||||
left join platform p on pp.platform_id = p.id
|
||||
left join reseller r on r.id = o.reseller_id
|
||||
left join order_remark re on o.order_number = re.order_number
|
||||
timestamp: false
|
||||
elt: "od.create_time BETWEEN '{begin}' and '{end}' and od.serial_number > {last}"
|
||||
order: "od.create_time,od.serial_number"
|
||||
file: "直连天下-上游订单-${month}.xlsx"
|
||||
- name: "下游订单"
|
||||
tasks:
|
||||
- sql: >-
|
||||
SELECT
|
||||
o.order_number as `订单号`,
|
||||
o.reseller_id as `分销商id`,
|
||||
r.`name` as `分销商名称`,
|
||||
o.reseller_order_number as `商户订单号`,
|
||||
o.amount as `扣款金额`,
|
||||
oi.ours_product_id as `我们的商品id`,
|
||||
oi.ours_product_title as `订单商品名称`,
|
||||
oi.ours_product_title as `商品名称`,
|
||||
o.account as `充值账号`,
|
||||
o.quantity as `数量`,
|
||||
CASE o.`status`
|
||||
|
||||
WHEN -2 THEN '全部失败'
|
||||
WHEN -1 THEN '关闭订单'
|
||||
WHEN 0 THEN '待充值'
|
||||
WHEN 1 THEN '订单完成'
|
||||
WHEN 2 THEN '部分成功'
|
||||
END
|
||||
AS 充值状态,
|
||||
CASE o.pay_status
|
||||
|
||||
WHEN -2 THEN '退款失败'
|
||||
WHEN -1 THEN '支付失败'
|
||||
WHEN 0 THEN '未支付'
|
||||
WHEN 1 THEN '支付中'
|
||||
WHEN 2 THEN '支付成功'
|
||||
WHEN 3 THEN '退款中'
|
||||
WHEN 4 THEN '全部退款'
|
||||
WHEN 5 THEN '部分退款'
|
||||
END
|
||||
AS 支付状态,
|
||||
o.create_time as `创建时间`,
|
||||
o.finish_time as `完成时间`,
|
||||
re.remark as `备注`
|
||||
|
||||
FROM
|
||||
`history_order` o
|
||||
left join history_order_item oi on oi.order_order_number = o.order_number
|
||||
left join reseller r on r.id = o.reseller_id
|
||||
left join history_order_remark re on o.order_number = re.order_number
|
||||
elt: "o.`create_time` >= '{begin}' and o.create_time < '{end}' and o.order_number > {last}"
|
||||
timestamp: false
|
||||
order: "o.create_time,o.order_number"
|
||||
- sql: >-
|
||||
SELECT
|
||||
o.order_number as `订单号`,
|
||||
o.reseller_id as `分销商id`,
|
||||
r.`name` as `分销商名称`,
|
||||
o.reseller_order_number as `商户订单号`,
|
||||
o.amount as `扣款金额`,
|
||||
op.id as `我们的商品id`,
|
||||
oi.ours_product_title as `订单商品名称`,
|
||||
op.NAME as `商品名称`,
|
||||
o.account as `充值账号`,
|
||||
o.quantity as `数量`,
|
||||
CASE o.`status`
|
||||
|
||||
WHEN -2 THEN '全部失败'
|
||||
WHEN -1 THEN '关闭订单'
|
||||
WHEN 0 THEN '待充值'
|
||||
WHEN 1 THEN '订单完成'
|
||||
WHEN 2 THEN '部分成功'
|
||||
END
|
||||
AS 充值状态,
|
||||
CASE o.pay_status
|
||||
|
||||
WHEN -2 THEN '退款失败'
|
||||
WHEN -1 THEN '支付失败'
|
||||
WHEN 0 THEN '未支付'
|
||||
WHEN 1 THEN '支付中'
|
||||
WHEN 2 THEN '支付成功'
|
||||
WHEN 3 THEN '退款中'
|
||||
WHEN 4 THEN '全部退款'
|
||||
WHEN 5 THEN '部分退款'
|
||||
END
|
||||
AS 支付状态,
|
||||
from_unixtime(o.create_time) as `创建时间`,
|
||||
from_unixtime(o.finish_time) as `完成时间`,
|
||||
re.remark as `备注`
|
||||
|
||||
FROM
|
||||
`order` o
|
||||
left join order_item oi on oi.order_order_number = o.order_number
|
||||
left JOIN ours_product op ON oi.ours_product_id = op.id
|
||||
left join reseller r on r.id = o.reseller_id
|
||||
left join order_remark re on o.order_number = re.order_number
|
||||
elt: "o.`create_time` >= {begin} and o.create_time < {end} and o.order_number > {last}"
|
||||
timestamp: true
|
||||
order: "o.create_time,o.order_number"
|
||||
file: "直连天下-下游订单-${month}.xlsx"
|
||||
|
||||
- name: "营销系统"
|
||||
db: ""
|
||||
jobs:
|
||||
- name: "订单信息"
|
||||
tasks:
|
||||
- sql: ""
|
||||
elt: ""
|
||||
file: "营销系统-订单信息-${month}.xlsx"
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package export
|
||||
|
||||
type Batch struct {
|
||||
ResellerId int
|
||||
ResellerName string
|
||||
OursProductId int
|
||||
OursProductTitle string
|
||||
PlatformName string
|
||||
PlatformProductCode string
|
||||
PlatformProductName string
|
||||
Status int
|
||||
OrderOrderNumber string
|
||||
SerialNumber string
|
||||
TerminalAccount string
|
||||
TradePrice float32
|
||||
PlatformPrice float32
|
||||
CreateTime string
|
||||
ExecuteTime string
|
||||
DingTalkSn string
|
||||
Remark string
|
||||
}
|
||||
|
||||
type Batchs []*Batch
|
||||
|
||||
func (o Batchs) Title() []string {
|
||||
return []string{
|
||||
"分销商id",
|
||||
"分销商名称",
|
||||
"我们的商品id",
|
||||
"订单商品名称",
|
||||
"接口平台",
|
||||
"接口平台产品编码",
|
||||
"接口平台产品名称",
|
||||
"充值状态",
|
||||
"系统订单号",
|
||||
"流水号",
|
||||
"充值账号",
|
||||
"成交价格",
|
||||
"接口平台价格",
|
||||
"创建时间",
|
||||
"执行时间",
|
||||
"钉钉审批序号",
|
||||
"批量备注",
|
||||
}
|
||||
}
|
||||
|
||||
func (o Batchs) Size() int {
|
||||
return len(o)
|
||||
}
|
||||
|
||||
func (o Batchs) Data() []interface{} {
|
||||
d := make([]interface{}, o.Size())
|
||||
for i, v := range o {
|
||||
d[i] = v
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
package export
|
||||
|
||||
type Card struct {
|
||||
OrderNumber string
|
||||
ResellerOrderNumber string
|
||||
Amount float32
|
||||
Quantity int
|
||||
Status int
|
||||
ResellerId int
|
||||
ResellerName string
|
||||
OursProductId int
|
||||
OursProductTitle string
|
||||
CreateTime string
|
||||
}
|
||||
|
||||
type Cards []*Card
|
||||
|
||||
func (o Cards) Title() []string {
|
||||
return []string{
|
||||
"订单号",
|
||||
"分销商订单号",
|
||||
"扣款价格",
|
||||
"数量",
|
||||
"充值状态",
|
||||
"分销商编号",
|
||||
"分销商名称",
|
||||
"订单商品编号",
|
||||
"订单商品名称",
|
||||
"创建时间",
|
||||
}
|
||||
}
|
||||
|
||||
func (o Cards) Size() int {
|
||||
return len(o)
|
||||
}
|
||||
|
||||
func (o Cards) Data() []interface{} {
|
||||
d := make([]interface{}, o.Size())
|
||||
for i, v := range o {
|
||||
d[i] = v
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package export
|
||||
|
||||
type Direct struct {
|
||||
ResellerId int64
|
||||
ResellerName string
|
||||
ResellerOrderNumber string
|
||||
OursProductId int
|
||||
OursProductTitle string
|
||||
PlatformName string
|
||||
PlatformProductCode string
|
||||
PlatformProductName string
|
||||
Status int
|
||||
OrderOrderNumber string
|
||||
SerialNumber string
|
||||
TerminalAccount string
|
||||
TradePrice float32
|
||||
PlatformPrice float32
|
||||
CreateTime string
|
||||
ExecuteTime string
|
||||
Remark string
|
||||
}
|
||||
|
||||
type Directs []*Direct
|
||||
|
||||
func (o Directs) Title() []string {
|
||||
return []string{
|
||||
"分销商id",
|
||||
"分销商名称",
|
||||
"商户订单号",
|
||||
"我们的商品id",
|
||||
"订单商品名称",
|
||||
"接口平台",
|
||||
"接口平台产品编码",
|
||||
"接口平台产品名称",
|
||||
"充值状态",
|
||||
"系统订单号",
|
||||
"流水号",
|
||||
"充值账号",
|
||||
"成交价格",
|
||||
"接口平台价格",
|
||||
"创建时间",
|
||||
"执行时间",
|
||||
"备注",
|
||||
}
|
||||
}
|
||||
|
||||
func (o Directs) Size() int {
|
||||
return len(o)
|
||||
}
|
||||
|
||||
func (o Directs) Data() []interface{} {
|
||||
d := make([]interface{}, o.Size())
|
||||
for i, v := range o {
|
||||
d[i] = v
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
package export
|
||||
|
||||
type Entity interface {
|
||||
Title() []string
|
||||
Size() int
|
||||
Data() []interface{}
|
||||
}
|
||||
133
export/excel.go
133
export/excel.go
|
|
@ -1,133 +0,0 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/tealeg/xlsx/v3"
|
||||
"os"
|
||||
)
|
||||
|
||||
const sheet_name = "sheet_1"
|
||||
|
||||
type Export struct {
|
||||
index int
|
||||
count int //总数
|
||||
row int //当前执行的数据行
|
||||
limit int //导出限制
|
||||
path string
|
||||
isNew bool
|
||||
titles []string
|
||||
file *xlsx.File
|
||||
sheet *xlsx.Sheet
|
||||
}
|
||||
|
||||
func NewExport(path string, limit int) *Export {
|
||||
return &Export{
|
||||
path: path,
|
||||
limit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Export) Title(titles []string) error {
|
||||
if e.file == nil || e.sheet == nil {
|
||||
return errors.New("没有执行open方法")
|
||||
}
|
||||
|
||||
if titles != nil {
|
||||
e.titles = titles
|
||||
}
|
||||
|
||||
if e.titles != nil && e.isNew {
|
||||
row := e.sheet.AddRow()
|
||||
row.WriteSlice(e.titles, -1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Export) fileName() string {
|
||||
return fmt.Sprintf(e.path, e.index)
|
||||
}
|
||||
|
||||
func (e *Export) slice() {
|
||||
e.row++
|
||||
if e.row > e.limit {
|
||||
e.row = 0
|
||||
e.reset()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (e *Export) reset() {
|
||||
e.save()
|
||||
e.index++
|
||||
e.Open()
|
||||
e.Title(nil)
|
||||
e.slice()
|
||||
}
|
||||
|
||||
func (e Export) Index() int {
|
||||
return e.index
|
||||
}
|
||||
|
||||
func (e *Export) Export(data Entity) error {
|
||||
if e.file == nil || e.sheet == nil {
|
||||
return errors.New("没有执行open方法")
|
||||
}
|
||||
|
||||
e.count = e.count + data.Size()
|
||||
for _, order := range data.Data() {
|
||||
e.slice()
|
||||
row := e.sheet.AddRow()
|
||||
row.WriteStruct(order, -1)
|
||||
}
|
||||
return e.save()
|
||||
}
|
||||
|
||||
func (e *Export) Open() error {
|
||||
path := e.fileName()
|
||||
exist, err := e.isFielExist(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if exist {
|
||||
e.isNew = false
|
||||
if e.file, err = xlsx.OpenFile(path); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
e.isNew = true
|
||||
e.file = xlsx.NewFile()
|
||||
}
|
||||
|
||||
var ok bool
|
||||
e.sheet, ok = e.file.Sheet[sheet_name]
|
||||
if !ok {
|
||||
e.sheet, err = e.file.AddSheet(sheet_name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
//需要处理偏移数据
|
||||
e.row = e.sheet.MaxRow - 1
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Export) isFielExist(file string) (bool, error) {
|
||||
_, err := os.Stat(file)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (e *Export) save() error {
|
||||
return e.file.Save(e.fileName())
|
||||
}
|
||||
|
|
@ -1,231 +0,0 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"fmt"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExport_Export(t *testing.T) {
|
||||
dir, _ := os.Getwd()
|
||||
path := dir + "/aa_%d.xlsx"
|
||||
e := NewExport(path, 4)
|
||||
err := e.Open()
|
||||
assert.Nil(t, err)
|
||||
|
||||
data := NewOrder([]data.Order{
|
||||
{
|
||||
OrderNumber: "123451",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123452",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123453",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123454",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123455",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123456",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123457",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123458",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
{
|
||||
OrderNumber: "123459",
|
||||
Reseller: data.Reseller{
|
||||
Id: 23456,
|
||||
Name: "分销商名称",
|
||||
},
|
||||
ResellerOrderNumber: "123456448",
|
||||
Amount: 12.22,
|
||||
Account: "13512345678",
|
||||
Quantity: 1,
|
||||
Status: 1,
|
||||
PayStatus: 1,
|
||||
CreateTime: 1672744984,
|
||||
FinishTime: 1672744984,
|
||||
Item: data.OrderItem{
|
||||
OursProductId: 101,
|
||||
OursProductTitle: "商品名称",
|
||||
},
|
||||
Remark: data.OrderRemark{
|
||||
Remark: "备注信息",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
err = e.Title(data.Title())
|
||||
assert.Nil(t, err)
|
||||
|
||||
err = e.Export(data)
|
||||
assert.Nil(t, err)
|
||||
|
||||
for i := 0; i <= e.Index(); i++ {
|
||||
file := fmt.Sprintf(path, i)
|
||||
assert.FileExists(t, file)
|
||||
os.Remove(file)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
package export
|
||||
|
||||
import (
|
||||
"excel_export/data"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Order struct {
|
||||
OrderNumber string
|
||||
ResellerId int64
|
||||
ResellerName string
|
||||
ResellerOrderNumber string
|
||||
Amount float32
|
||||
Account string
|
||||
Quantity int
|
||||
Status int
|
||||
PayStatus int
|
||||
OursProductId int
|
||||
OursProductTitle string
|
||||
Remark string
|
||||
CreateTime string
|
||||
FinishTime string
|
||||
}
|
||||
|
||||
func TransformOrder(order data.Order) *Order {
|
||||
return &Order{
|
||||
OrderNumber: order.OrderNumber,
|
||||
ResellerId: order.ResellerId,
|
||||
ResellerName: order.Reseller.Name,
|
||||
ResellerOrderNumber: order.ResellerOrderNumber,
|
||||
Amount: order.Amount,
|
||||
Account: order.Account,
|
||||
Quantity: order.Quantity,
|
||||
Status: order.Status,
|
||||
PayStatus: order.PayStatus,
|
||||
CreateTime: time.Unix(order.CreateTime, 0).Format("2006-01-02 15:04:05"),
|
||||
FinishTime: time.Unix(order.FinishTime, 0).Format("2006-01-02 15:04:05"),
|
||||
OursProductId: order.Item.OursProductId,
|
||||
OursProductTitle: order.Item.OursProductTitle,
|
||||
Remark: order.Remark.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
func NewOrder(data []data.Order) Orders {
|
||||
o := make([]*Order, len(data))
|
||||
for i, v := range data {
|
||||
o[i] = TransformOrder(v)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
type Orders []*Order
|
||||
|
||||
func (o Orders) Title() []string {
|
||||
return []string{
|
||||
"订单号",
|
||||
"分销商ID",
|
||||
"分销商名称",
|
||||
"分销商订单号",
|
||||
"总价",
|
||||
"充值账号",
|
||||
"数量",
|
||||
"状态",
|
||||
"支付状态",
|
||||
"商品编号",
|
||||
"商品名称",
|
||||
"备注",
|
||||
"创建时间",
|
||||
"完成时间",
|
||||
}
|
||||
}
|
||||
|
||||
func (o Orders) Size() int {
|
||||
return len(o)
|
||||
}
|
||||
|
||||
func (o Orders) Data() []interface{} {
|
||||
d := make([]interface{}, o.Size())
|
||||
for i, v := range o {
|
||||
d[i] = v
|
||||
}
|
||||
return d
|
||||
}
|
||||
14
go.mod
14
go.mod
|
|
@ -3,13 +3,18 @@ module excel_export
|
|||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/spf13/cobra v1.6.1 // direct
|
||||
github.com/tealeg/xlsx/v3 v3.2.4 // direct
|
||||
gorm.io/driver/mysql v1.4.5 // direct
|
||||
gorm.io/gorm v1.24.3 // direct
|
||||
github.com/spf13/cobra v1.6.1 // direct
|
||||
)
|
||||
|
||||
require github.com/stretchr/testify v1.8.1
|
||||
require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.8.1
|
||||
)
|
||||
|
||||
require github.com/smartystreets/goconvey v1.7.2
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
|
|
@ -17,17 +22,18 @@ require (
|
|||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/go-cmp v0.5.2 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
github.com/kr/text v0.1.0 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/fastuuid v1.2.0 // indirect
|
||||
github.com/shabbyrobe/xmlwriter v0.0.0-20200208144257-9fca06d00ffa // indirect
|
||||
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/smartystreets/assertions v1.2.0 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
|
|||
Loading…
Reference in New Issue