1.新增店员绩效导出excel功能;

2.新增租卡会员统计导出excel功能;
This commit is contained in:
chenlin 2024-02-01 15:36:24 +08:00
parent be82112908
commit 013a52f66b
6 changed files with 328 additions and 27 deletions

View File

@ -239,19 +239,13 @@ func CooperativeMemberPromotionStatisticList(c *gin.Context) {
return
}
list, count, err := req.List()
ret, err := req.List()
if err != nil {
logger.Errorf("err:", err)
app.Error(c, http.StatusInternalServerError, err, "查询失败")
return
}
ret := models.CooperativeMemberPromotionStatisticListResp{
Count: count,
PageIndex: req.Page,
List: list,
}
app.OK(c, ret, "")
return
}

View File

@ -3,7 +3,9 @@ package models
import (
"fmt"
"github.com/codinl/go-logger"
"github.com/xuri/excelize/v2"
orm "go-admin/common/global"
"go-admin/tools/config"
"gorm.io/gorm"
"regexp"
"strings"
@ -701,7 +703,7 @@ type CooperativeMemberPromotionStatistic struct {
RenewalGoldCount uint32 `json:"renewal_gold_count"` // 续费黄金会员数量
RenewalPlatinumCount uint32 `json:"renewal_platinum_count"` // 续费白金会员数量
RenewalBlackGoldCount uint32 `json:"renewal_black_gold_count"` // 续费黑金会员数量
Date string `json:"date" gorm:"index"` //
Date string `json:"date" gorm:"index"` // 日期
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
UpgradeGoldToPlatinumCount uint32 `json:"upgrade_gold_to_platinum_count" gorm:"default:0"` // 升级:黄金->白金数量
@ -724,12 +726,18 @@ type CooperativeMemberPromotionStatisticReq struct {
}
type CooperativeMemberPromotionStatisticListResp struct {
Count int64 `json:"count"`
PageIndex int `json:"pageIndex"`
List []CooperativeMemberPromotionStatistic `json:"list"`
Total int64 `json:"total"` // 总条数
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 每页展示条数
ExportUrl string `json:"export_url"` // 导出excel地址
}
func (m *CooperativeMemberPromotionStatisticReq) List() ([]CooperativeMemberPromotionStatistic, int64, error) {
func (m *CooperativeMemberPromotionStatisticReq) List() (*CooperativeMemberPromotionStatisticListResp, error) {
resp := &CooperativeMemberPromotionStatisticListResp{
PageIndex: m.Page,
PageSize: m.PageSize,
}
list := make([]CooperativeMemberPromotionStatistic, 0)
page := m.Page - 1
@ -778,8 +786,11 @@ func (m *CooperativeMemberPromotionStatisticReq) List() ([]CooperativeMemberProm
if !endTime.IsZero() {
qs = qs.Where("created_at<?", endTime)
}
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberDayStorePromotions).Error
if m.IsExport == 1 {
err = qs.Order("id DESC").Find(&memberDayStorePromotions).Error
} else {
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberDayStorePromotions).Error
}
list = CooperativeMemberPromotionStoreDayToStatistic(memberDayStorePromotions)
} else {
var memberDayPromotions []CooperativeMemberPromotionDay
@ -790,10 +801,13 @@ func (m *CooperativeMemberPromotionStatisticReq) List() ([]CooperativeMemberProm
if !endTime.IsZero() {
qs = qs.Where("created_at<?", endTime)
}
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberDayPromotions).Error
if m.IsExport == 1 {
err = qs.Order("id DESC").Find(&memberDayPromotions).Error
} else {
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberDayPromotions).Error
}
list = CooperativeMemberPromotionDayListToStatistic(memberDayPromotions)
}
case 2:
if m.StoreId != 0 {
var memberStorePromotions []CooperativeMemberPromotionStore
@ -810,7 +824,11 @@ func (m *CooperativeMemberPromotionStatisticReq) List() ([]CooperativeMemberProm
if !endTime.IsZero() {
qs = qs.Where("created_at<?", endTime)
}
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberStorePromotions).Error
if m.IsExport == 1 {
err = qs.Order("id DESC").Find(&memberStorePromotions).Error
} else {
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberStorePromotions).Error
}
list = CooperativeMemberPromotionStoreToStatistic(memberStorePromotions)
} else {
var memberPromotions []CooperativeMemberPromotion
@ -824,23 +842,171 @@ func (m *CooperativeMemberPromotionStatisticReq) List() ([]CooperativeMemberProm
if !endTime.IsZero() {
qs = qs.Where("created_at<?", endTime)
}
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberPromotions).Error
if m.IsExport == 1 {
err = qs.Order("id DESC").Find(&memberPromotions).Error
} else {
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&memberPromotions).Error
}
list = CooperativeMemberPromotionToStatistic(memberPromotions)
}
}
if err != nil && err != RecordNotFound {
logger.Error("count err:", err)
return list, count, err
return nil, err
}
// 添加门店信息
err = cooperativeMemberPromotionAddStoreInfo(list)
if err != nil {
logger.Error("cooperativeMemberPromotionAddStoreInfo err:", err)
return nil, err
}
err = qs.Count(&count).Error
if err != nil {
logger.Error("count err:", err)
return list, 0, err
return nil, err
}
return list, count, nil
if m.IsExport == 1 {
fileName, err := promotionStatisticListExport(list)
if err != nil {
logger.Error("count err:", err)
return nil, err
}
resp.ExportUrl = fileName
} else {
resp.List = list
resp.Total = count
}
return resp, nil
}
// 添加门店信息
func cooperativeMemberPromotionAddStoreInfo(list []CooperativeMemberPromotionStatistic) error {
// 查询门店信息
var storeList []Store
err := orm.Eloquent.Table("store").Find(&storeList).Error
if err != nil {
logger.Errorf("err:", err)
return err
}
storeMap := make(map[uint32]Store, 0)
for i, _ := range storeList {
storeMap[storeList[i].ID] = storeList[i]
}
for i, _ := range list {
store := storeMap[list[i].StoreId]
list[i].Store = &store
}
return nil
}
// 导出租卡会员统计excel
func promotionStatisticListExport(list []CooperativeMemberPromotionStatistic) (string, error) {
file := excelize.NewFile()
fSheet := "Sheet1"
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "租卡会员统计" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title1 := []interface{}{"合作商", "门店", "开通会员", "开通会员", "开通会员", "续费会员", "续费会员", "续费会员",
"升级会员数", "升级会员数", "升级会员数", "日期"}
title2 := []interface{}{"合作商", "门店", "黄金会员_数量", "白金会员_数量", "黑金会员_数量", "黄金会员_数量", "白金会员_数量",
"黑金会员_数量", "黄金->白金", "黄金->黑金", "白金->黑金", "日期"}
for i, _ := range title1 {
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
err := file.SetCellValue(fSheet, cell, title1[i])
if err != nil {
logger.Error("file set value err:", err)
}
}
for i, _ := range title2 {
cell, _ := excelize.CoordinatesToCellName(1+i, 2)
err := file.SetCellValue(fSheet, cell, title2[i])
if err != nil {
logger.Error("file set value err:", err)
}
}
var row []interface{}
nExcelStartRow := 0
for i := 0; i < len(list); i++ {
row = []interface{}{
list[i].CooperativeName, // 合作商
list[i].Store.Name, // 门店名称
list[i].GoldCount, // 开通会员:黄金会员数量
list[i].PlatinumCount, // 开通会员:白金会员数量
list[i].BlackGoldCount, // 开通会员:黑金会员数量
list[i].RenewalGoldCount, // 续费会员:黄金会员数量
list[i].RenewalPlatinumCount, // 续费会员:白金会员数量
list[i].RenewalBlackGoldCount, // 续费会员:黑金会员数量
list[i].UpgradeGoldToPlatinumCount, // 升级:黄金->白金数量
list[i].UpgradeGoldToBlackCount, // 升级:黄金->黑金数量
list[i].UpgradePlatinumToBlackCount, // 升级:白金->黑金数量
list[i].Date,
}
for j, _ := range row {
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3)
err := file.SetCellValue(fSheet, cell, row[j])
if err != nil {
logger.Error("file set value 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}]}`)
// 设置单元格的样式: 居中、加边框、自动换行
style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true},
"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}]}`)
endRow := fmt.Sprintf("L%d", nExcelStartRow+2)
// 合并单元格
_ = file.MergeCell(fSheet, "A1", "A2")
_ = file.MergeCell(fSheet, "B1", "B2")
_ = file.MergeCell(fSheet, "C1", "E1")
_ = file.MergeCell(fSheet, "F1", "H1")
_ = file.MergeCell(fSheet, "I1", "K1")
_ = file.MergeCell(fSheet, "L1", "L2")
//设置单元格高度
file.SetRowHeight("Sheet1", 1, 18)
file.SetRowHeight("Sheet1", 2, 18)
// 设置单元格大小
file.SetColWidth("Sheet1", "A", "A", 15)
file.SetColWidth("Sheet1", "B", "B", 20)
// 从列 C 到列 K逐一设置宽度为 20
for col := 'C'; col <= 'K'; col++ {
colName := string(col)
file.SetColWidth("Sheet1", colName, colName, 12)
}
// 应用样式到整个表格
_ = file.SetCellStyle("Sheet1", "A1", "L1", style1)
_ = file.SetCellStyle("Sheet1", "A2", 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
}
func CooperativeMemberPromotionDayListToStatistic(list []CooperativeMemberPromotionDay) []CooperativeMemberPromotionStatistic {

View File

@ -2648,6 +2648,116 @@ func (m *AssistantInviteMemberReportReq) List() ([]InviteMemberReport, int64, er
return memberReport, count, nil
}
// 店员绩效导出excel
func inviteMemberReport(list []InviteMemberReport) (string, error) {
file := excelize.NewFile()
fSheet := "Sheet1"
url := ExportUrl
fileName := time.Now().Format(TimeFormat) + "店员绩效" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title1 := []interface{}{"昵称", "小程序ID", "合作商", "门店",
"开通会员数", "开通会员数", "开通会员数", "开通会员数", "开通会员数",
"续费会员数(干预)", "续费会员数(干预)", "续费会员数(干预)",
"升级会员数(干预)", "升级会员数(干预)", "升级会员数(干预)",
"续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)",
"升级会员数(自动)", "升级会员数(自动)", "升级会员数(自动)"}
title2 := []interface{}{"昵称", "小程序ID", "合作商", "门店",
"年费黄金会员_数量", "半年黄金", "季度黄金", "年费白金会员_数量", "年费黑金会员_数量",
"年费黄金", "年费白金", "年费黑金",
"黄金->白金", "黄金->黑金", "白金->黑金",
"续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)", "续费会员数(自动)",
"升级会员数(自动)", "升级会员数(自动)", "升级会员数(自动)"}
for i, _ := range title1 {
cell, _ := excelize.CoordinatesToCellName(1+i, 1)
err := file.SetCellValue(fSheet, cell, title1[i])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
for i, _ := range title2 {
cell, _ := excelize.CoordinatesToCellName(1+i, 2)
err := file.SetCellValue(fSheet, cell, title2[i])
if err != nil {
logger.Error("file set value err:", logger.Field("err", err))
}
}
var row []interface{}
nExcelStartRow := 0
for i := 0; i < len(list); i++ {
row = []interface{}{
list[i].CooperativeName, // 合作商
list[i].Store.Name, // 门店名称
list[i].GoldCount, // 开通会员:黄金会员数量
list[i].PlatinumCount, // 开通会员:白金会员数量
list[i].BlackGoldCount, // 开通会员:黑金会员数量
list[i].RenewalGoldCount, // 续费会员:黄金会员数量
list[i].RenewalPlatinumCount, // 续费会员:白金会员数量
list[i].RenewalBlackGoldCount, // 续费会员:黑金会员数量
list[i].UpgradeGoldToPlatinumCount, // 升级:黄金->白金数量
list[i].UpgradeGoldToBlackCount, // 升级:黄金->黑金数量
list[i].UpgradePlatinumToBlackCount, // 升级:白金->黑金数量
list[i].Date,
}
for j, _ := range row {
cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+3)
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}]}`)
// 设置单元格的样式: 居中、加边框、自动换行
style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true},
"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}]}`)
endRow := fmt.Sprintf("L%d", nExcelStartRow+2)
// 合并单元格
_ = file.MergeCell(fSheet, "A1", "A2")
_ = file.MergeCell(fSheet, "B1", "B2")
_ = file.MergeCell(fSheet, "C1", "E1")
_ = file.MergeCell(fSheet, "F1", "H1")
_ = file.MergeCell(fSheet, "I1", "K1")
_ = file.MergeCell(fSheet, "L1", "L2")
//设置单元格高度
file.SetRowHeight("Sheet1", 1, 18)
file.SetRowHeight("Sheet1", 2, 18)
// 设置单元格大小
file.SetColWidth("Sheet1", "A", "A", 15)
file.SetColWidth("Sheet1", "B", "B", 20)
// 从列 C 到列 K逐一设置宽度为 20
for col := 'C'; col <= 'K'; col++ {
colName := string(col)
file.SetColWidth("Sheet1", colName, colName, 12)
}
// 应用样式到整个表格
_ = file.SetCellStyle("Sheet1", "A1", "L1", style1)
_ = file.SetCellStyle("Sheet1", "A2", 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
}
func InviteMemberReportListSetUser(list []InviteMemberReport) []InviteMemberReport {
ids := make([]uint32, 0, len(list))
for i, _ := range list {

View File

@ -5368,6 +5368,7 @@ const docTemplate = `{
"type": "string"
},
"date": {
"description": "日期",
"type": "string"
},
"day_time": {
@ -5421,8 +5422,9 @@ const docTemplate = `{
"models.CooperativeMemberPromotionStatisticListResp": {
"type": "object",
"properties": {
"count": {
"type": "integer"
"export_url": {
"description": "导出excel地址",
"type": "string"
},
"list": {
"type": "array",
@ -5431,6 +5433,15 @@ const docTemplate = `{
}
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "每页展示条数",
"type": "integer"
},
"total": {
"description": "总条数",
"type": "integer"
}
}

View File

@ -5357,6 +5357,7 @@
"type": "string"
},
"date": {
"description": "日期",
"type": "string"
},
"day_time": {
@ -5410,8 +5411,9 @@
"models.CooperativeMemberPromotionStatisticListResp": {
"type": "object",
"properties": {
"count": {
"type": "integer"
"export_url": {
"description": "导出excel地址",
"type": "string"
},
"list": {
"type": "array",
@ -5420,6 +5422,15 @@
}
},
"pageIndex": {
"description": "页码",
"type": "integer"
},
"pageSize": {
"description": "每页展示条数",
"type": "integer"
},
"total": {
"description": "总条数",
"type": "integer"
}
}

View File

@ -757,6 +757,7 @@ definitions:
description: 创建时间
type: string
date:
description: 日期
type: string
day_time:
type: string
@ -795,13 +796,21 @@ definitions:
type: object
models.CooperativeMemberPromotionStatisticListResp:
properties:
count:
type: integer
export_url:
description: 导出excel地址
type: string
list:
items:
$ref: '#/definitions/models.CooperativeMemberPromotionStatistic'
type: array
pageIndex:
description: 页码
type: integer
pageSize:
description: 每页展示条数
type: integer
total:
description: 总条数
type: integer
type: object
models.CooperativeMemberPromotionStatisticReq: