1.财务统计页增加excel导出功能;

This commit is contained in:
chenlin 2024-08-12 16:05:56 +08:00
parent c7216aa035
commit 39589bfe0f
5 changed files with 573 additions and 17 deletions

View File

@ -249,6 +249,14 @@ func ExpressNoList(c *gin.Context) {
//app.OK(c, nil, "") //app.OK(c, nil, "")
} }
// FundRecordList 查询财务统计列表
// @Summary 查询财务统计列表
// @Tags 财务管理
// @Produce json
// @Accept json
// @Param request body models.FundRecordListReq true "查询财务统计列表模型"
// @Success 200 {object} models.FundRecordListResp
// @Router /api/v1/order/fund_record/list [post]
func FundRecordList(c *gin.Context) { func FundRecordList(c *gin.Context) {
req := &models.FundRecordListReq{} req := &models.FundRecordListReq{}
if c.ShouldBindJSON(req) != nil { if c.ShouldBindJSON(req) != nil {
@ -257,18 +265,19 @@ func FundRecordList(c *gin.Context) {
return return
} }
list, count, err := req.List() list, count, exportUrl, err := req.List()
if err != nil { if err != nil {
logger.Errorf("err:", logger.Field("err", err)) logger.Errorf("err:", logger.Field("err", err))
app.Error(c, http.StatusInternalServerError, err, "查询失败") app.Error(c, http.StatusInternalServerError, err, "查询失败")
return return
} }
ret := map[string]interface{}{ ret := models.FundRecordListResp{
"total": count, Total: count,
"list": list, List: list,
"pageIndex": req.Page, PageIndex: req.Page,
"pageSize": req.PageSize, PageSize: req.PageSize,
ExportUrl: exportUrl,
} }
app.OK(c, ret, "") app.OK(c, ret, "")
} }

View File

@ -18,6 +18,7 @@ import (
"go-admin/tools" "go-admin/tools"
"go-admin/tools/config" "go-admin/tools/config"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"strconv"
"time" "time"
) )
@ -1553,9 +1554,10 @@ func (m *ExpressNoInfo) SetStore() {
} }
} }
// FundRecordListReq 财务统计入参
type FundRecordListReq struct { type FundRecordListReq struct {
Uid uint64 `json:"uid" ` Uid uint64 `json:"uid" `
FundType string `json:"fund_type"` // -member_gold -member_platinum -member_black_gold FundType string `json:"fund_type"`
TransactionId string `json:"transaction_id"` // 支付单号 TransactionId string `json:"transaction_id"` // 支付单号
OutTradeNo string `json:"out_trade_no"` OutTradeNo string `json:"out_trade_no"`
RefundId string `json:"refund_id"` RefundId string `json:"refund_id"`
@ -1564,9 +1566,18 @@ type FundRecordListReq struct {
EndTime time.Time `json:"end_time"` // 结束时间 EndTime time.Time `json:"end_time"` // 结束时间
Page int `json:"pageIndex"` Page int `json:"pageIndex"`
PageSize int `json:"pageSize"` PageSize int `json:"pageSize"`
IsExport uint32 `json:"is_export"` // 1-导出
} }
func (m *FundRecordListReq) List() ([]FundRecord, int64, error) { type FundRecordListResp struct {
List []FundRecord `json:"list"`
Total int64 `json:"total"` // 总条数
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 每页展示条数
ExportUrl string `json:"export_url"`
}
func (m *FundRecordListReq) List() ([]FundRecord, int64, string, error) {
var fundRecords []FundRecord var fundRecords []FundRecord
qs := orm.Eloquent.Table("fund_record") qs := orm.Eloquent.Table("fund_record")
@ -1602,7 +1613,7 @@ func (m *FundRecordListReq) List() ([]FundRecord, int64, error) {
err := qs.Count(&count).Error err := qs.Count(&count).Error
if err != nil { if err != nil {
logger.Errorf("err:", logger.Field("err", err)) logger.Errorf("err:", logger.Field("err", err))
return fundRecords, 0, err return fundRecords, 0, "", err
} }
if m.PageSize == 0 { if m.PageSize == 0 {
m.PageSize = 10 m.PageSize = 10
@ -1613,13 +1624,146 @@ func (m *FundRecordListReq) List() ([]FundRecord, int64, error) {
if page < 0 { if page < 0 {
page = 0 page = 0
} }
err = qs.Order("created_at DESC").Offset(page * pageSize).Limit(pageSize).Find(&fundRecords).Error
if err != nil { if m.IsExport == 1 { // 导出excel
logger.Errorf("err:", logger.Field("err", err)) err = qs.Order("created_at DESC").Find(&fundRecords).Error
return fundRecords, 0, err if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return fundRecords, 0, "", err
}
exportUrl, err := fundRecordListExport(fundRecords)
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return fundRecords, 0, "", err
}
return nil, 0, exportUrl, nil
} else {
err = qs.Order("created_at DESC").Offset(page * pageSize).Limit(pageSize).Find(&fundRecords).Error
if err != nil {
logger.Errorf("err:", logger.Field("err", err))
return fundRecords, 0, "", err
}
} }
return fundRecords, count, nil return fundRecords, count, "", nil
}
// TranslateFundType 将fund_type转换为对应的字符
func TranslateFundType(fundType string) string {
fundTypeMap := map[string]string{
"member_fee": "会员费",
"buy_goods_refund": "商品退货",
"buy_goods": "商品购买",
"buy_goods_cancel": "商品取消",
"recycle_card": "回收卡带",
"postage_package_fee": "购买运费包",
"member_deposit": "押金",
"upgrade_member": "升级会员",
"member_expire_delay": "滞纳金",
"express_fee": "邮费",
"deposit_refund": "退押金",
"express_fee_refund": "退邮费",
"downgrade_renewal": "降级续费",
}
if val, ok := fundTypeMap[fundType]; ok {
return val
}
return "未知类型"
}
// ConvertAmount 将Amount转换为格式化字符串
func ConvertAmount(amount int64) string {
// 转换为以分为单位的小数,保留两位小数
convertedAmount := float64(amount) / 100.0
sign := "+"
if convertedAmount < 0 {
sign = "-"
convertedAmount = -convertedAmount
}
return sign + strconv.FormatFloat(convertedAmount, 'f', 2, 64)
}
// fundRecordListExport 导出财务统计数据
func fundRecordListExport(list []FundRecord) (string, error) {
file := excelize.NewFile()
fSheet := "Sheet1"
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "财务统计" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title := []interface{}{"用户ID", "类型", "金额", "商户单号", "交易单号", "退款单号", "付款单号", "创建时间", "备注"}
for i, _ := range title {
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
err := file.SetCellValue(fSheet, cell, title[i])
if err != nil {
logger.Errorf("file set value err:", err)
}
}
var row []interface{}
nExcelStartRow := 0
for rowId := 0; rowId < len(list); rowId++ {
formattedTime := list[rowId].CreatedAt.Format(QueryTimeFormat)
row = []interface{}{
list[rowId].Uid,
TranslateFundType(list[rowId].FundType),
ConvertAmount(list[rowId].Amount),
list[rowId].OutTradeNo,
list[rowId].TransactionId,
list[rowId].RefundId,
list[rowId].PaymentNo,
formattedTime,
list[rowId].Remark,
}
for j, _ := range row {
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
err := file.SetCellValue(fSheet, cell, row[j])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
nExcelStartRow++
}
// 设置所有单元格的样式: 居中、加边框
style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
"border":[{"type":"left","color":"000000","style":1},
{"type":"top","color":"000000","style":1},
{"type":"right","color":"000000","style":1},
{"type":"bottom","color":"000000","style":1}]}`)
//设置单元格高度
file.SetRowHeight("Sheet1", 1, 20)
// 设置单元格大小
file.SetColWidth("Sheet1", "A", "A", 10)
file.SetColWidth("Sheet1", "B", "B", 13)
file.SetColWidth("Sheet1", "C", "C", 10)
file.SetColWidth("Sheet1", "D", "D", 16)
file.SetColWidth("Sheet1", "E", "E", 30)
file.SetColWidth("Sheet1", "F", "F", 30)
file.SetColWidth("Sheet1", "G", "G", 30)
file.SetColWidth("Sheet1", "H", "H", 25)
file.SetColWidth("Sheet1", "I", "I", 13)
var endRow string
endRow = fmt.Sprintf("I"+"%d", nExcelStartRow+1)
// 应用样式到整个表格
_ = file.SetCellStyle("Sheet1", "A1", endRow, style)
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
fmt.Println(err)
}
return url + fileName, nil
} }
type CooperativeOrderReq struct { type CooperativeOrderReq struct {

View File

@ -4589,6 +4589,39 @@ const docTemplate = `{
} }
} }
}, },
"/api/v1/order/fund_record/list": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"财务管理"
],
"summary": "查询财务统计列表",
"parameters": [
{
"description": "查询财务统计列表模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.FundRecordListReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.FundRecordListResp"
}
}
}
}
},
"/api/v1/order/list": { "/api/v1/order/list": {
"post": { "post": {
"consumes": [ "consumes": [
@ -10751,7 +10784,7 @@ const docTemplate = `{
"description": "入/出库,开始时间", "description": "入/出库,开始时间",
"type": "string" "type": "string"
}, },
"store_list": { "store_id": {
"description": "门店复选", "description": "门店复选",
"type": "array", "type": "array",
"items": { "items": {
@ -11389,6 +11422,123 @@ const docTemplate = `{
} }
} }
}, },
"models.FundRecord": {
"type": "object",
"properties": {
"amount": {
"type": "integer"
},
"createdAt": {
"description": "创建时间",
"type": "string"
},
"fund_type": {
"description": "-member_gold -member_platinum -member_black_gold",
"type": "string"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
},
"out_trade_no": {
"type": "string"
},
"payment_no": {
"description": "付款单号",
"type": "string"
},
"refund_id": {
"type": "string"
},
"remark": {
"description": "备注",
"type": "string"
},
"status": {
"description": "1-待支付 2-已支付 3-已退款",
"type": "integer"
},
"transaction_id": {
"description": "支付单号",
"type": "string"
},
"uid": {
"type": "integer"
},
"updatedAt": {
"description": "更新时间",
"type": "string"
}
}
},
"models.FundRecordListReq": {
"type": "object",
"properties": {
"end_time": {
"description": "结束时间",
"type": "string"
},
"fund_type": {
"type": "string"
},
"is_export": {
"description": "1-导出",
"type": "integer"
},
"out_trade_no": {
"type": "string"
},
"pageIndex": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"payment_no": {
"type": "string"
},
"refund_id": {
"type": "string"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"transaction_id": {
"description": "支付单号",
"type": "string"
},
"uid": {
"type": "integer"
}
}
},
"models.FundRecordListResp": {
"type": "object",
"properties": {
"export_url": {
"type": "string"
},
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/models.FundRecord"
}
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "每页展示条数",
"type": "integer"
},
"total": {
"description": "总条数",
"type": "integer"
}
}
},
"models.GameCard": { "models.GameCard": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -4578,6 +4578,39 @@
} }
} }
}, },
"/api/v1/order/fund_record/list": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"财务管理"
],
"summary": "查询财务统计列表",
"parameters": [
{
"description": "查询财务统计列表模型",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.FundRecordListReq"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/models.FundRecordListResp"
}
}
}
}
},
"/api/v1/order/list": { "/api/v1/order/list": {
"post": { "post": {
"consumes": [ "consumes": [
@ -10740,7 +10773,7 @@
"description": "入/出库,开始时间", "description": "入/出库,开始时间",
"type": "string" "type": "string"
}, },
"store_list": { "store_id": {
"description": "门店复选", "description": "门店复选",
"type": "array", "type": "array",
"items": { "items": {
@ -11378,6 +11411,123 @@
} }
} }
}, },
"models.FundRecord": {
"type": "object",
"properties": {
"amount": {
"type": "integer"
},
"createdAt": {
"description": "创建时间",
"type": "string"
},
"fund_type": {
"description": "-member_gold -member_platinum -member_black_gold",
"type": "string"
},
"id": {
"description": "数据库记录编号",
"type": "integer"
},
"out_trade_no": {
"type": "string"
},
"payment_no": {
"description": "付款单号",
"type": "string"
},
"refund_id": {
"type": "string"
},
"remark": {
"description": "备注",
"type": "string"
},
"status": {
"description": "1-待支付 2-已支付 3-已退款",
"type": "integer"
},
"transaction_id": {
"description": "支付单号",
"type": "string"
},
"uid": {
"type": "integer"
},
"updatedAt": {
"description": "更新时间",
"type": "string"
}
}
},
"models.FundRecordListReq": {
"type": "object",
"properties": {
"end_time": {
"description": "结束时间",
"type": "string"
},
"fund_type": {
"type": "string"
},
"is_export": {
"description": "1-导出",
"type": "integer"
},
"out_trade_no": {
"type": "string"
},
"pageIndex": {
"type": "integer"
},
"pageSize": {
"type": "integer"
},
"payment_no": {
"type": "string"
},
"refund_id": {
"type": "string"
},
"start_time": {
"description": "开始时间",
"type": "string"
},
"transaction_id": {
"description": "支付单号",
"type": "string"
},
"uid": {
"type": "integer"
}
}
},
"models.FundRecordListResp": {
"type": "object",
"properties": {
"export_url": {
"type": "string"
},
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/models.FundRecord"
}
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "每页展示条数",
"type": "integer"
},
"total": {
"description": "总条数",
"type": "integer"
}
}
},
"models.GameCard": { "models.GameCard": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -3357,7 +3357,7 @@ definitions:
start_time: start_time:
description: 入/出库,开始时间 description: 入/出库,开始时间
type: string type: string
store_list: store_id:
description: 门店复选 description: 门店复选
items: items:
type: integer type: integer
@ -3822,6 +3822,88 @@ definitions:
required: required:
- erp_commodity_id - erp_commodity_id
type: object type: object
models.FundRecord:
properties:
amount:
type: integer
createdAt:
description: 创建时间
type: string
fund_type:
description: -member_gold -member_platinum -member_black_gold
type: string
id:
description: 数据库记录编号
type: integer
out_trade_no:
type: string
payment_no:
description: 付款单号
type: string
refund_id:
type: string
remark:
description: 备注
type: string
status:
description: 1-待支付 2-已支付 3-已退款
type: integer
transaction_id:
description: 支付单号
type: string
uid:
type: integer
updatedAt:
description: 更新时间
type: string
type: object
models.FundRecordListReq:
properties:
end_time:
description: 结束时间
type: string
fund_type:
type: string
is_export:
description: 1-导出
type: integer
out_trade_no:
type: string
pageIndex:
type: integer
pageSize:
type: integer
payment_no:
type: string
refund_id:
type: string
start_time:
description: 开始时间
type: string
transaction_id:
description: 支付单号
type: string
uid:
type: integer
type: object
models.FundRecordListResp:
properties:
export_url:
type: string
list:
items:
$ref: '#/definitions/models.FundRecord'
type: array
pageIndex:
description: 页码
type: integer
pageSize:
description: 每页展示条数
type: integer
total:
description: 总条数
type: integer
type: object
models.GameCard: models.GameCard:
properties: properties:
coverImg: coverImg:
@ -10865,6 +10947,27 @@ paths:
summary: 操作日志列表update summary: 操作日志列表update
tags: tags:
- system/日志 - system/日志
/api/v1/order/fund_record/list:
post:
consumes:
- application/json
parameters:
- description: 查询财务统计列表模型
in: body
name: request
required: true
schema:
$ref: '#/definitions/models.FundRecordListReq'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/models.FundRecordListResp'
summary: 查询财务统计列表
tags:
- 财务管理
/api/v1/order/list: /api/v1/order/list:
post: post:
consumes: consumes: