Compare commits

...

16 Commits

Author SHA1 Message Date
c8c2202538 同步proto 2026-01-30 20:00:50 +08:00
e57dd03269 Update work.go 2026-01-30 19:53:05 +08:00
6f1277ec9b Update work.go 2026-01-30 19:49:44 +08:00
f6c5f53002 merge main 2026-01-30 19:44:34 +08:00
dee2b9d50c Update work.go 2026-01-30 19:40:52 +08:00
cjy
248d8f50ef fix:修改状态映射 2026-01-30 18:31:28 +08:00
cjy
8e7a3643d2 Merge branch 'feat-cjy-report' 2026-01-30 18:20:52 +08:00
cjy
df8fbfbc43 fix:修复批量导入的时候,始终固定报告名 2026-01-30 17:31:00 +08:00
JNG
a5ffa3e8b5 Merge branch 'jng' 2026-01-30 14:07:46 +08:00
jiaji.H
e4e2e303ea 美化文件名称 2026-01-30 13:43:40 +08:00
jiaji.H
973c95c76d Updata:文件名增加时间戳 2026-01-30 13:40:15 +08:00
jiaji.H
b05a300aa9 Updata:更新接口 2026-01-30 13:22:43 +08:00
jiaji.H
0e79282724 Updata:修正路由 2026-01-30 13:02:10 +08:00
jiaji.H
bc27434bed Updaya:增加导出接口 2026-01-30 12:42:47 +08:00
jiaji.H
c0d8c07a90 Updata:增加临时数据信息导出 2026-01-30 12:35:19 +08:00
cjy
254d85ced3 Merge branch 'feat-cjy-report'
# Conflicts:
#	api/cast/cast.pb.go
#	api/cast/cast.pb.validate.go
#	api/cast/cast_triple.pb.go
#	pkg/service/cast/work.go
2026-01-30 12:01:23 +08:00
8 changed files with 9608 additions and 7083 deletions

File diff suppressed because it is too large Load Diff

View File

@ -17,9 +17,6 @@ var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
func (this *GetInEffectOrderRecordRequest) Validate() error {
return nil
}
func (this *QueryTheOrderSnapshotInformationReq) Validate() error {
return nil
}
@ -368,12 +365,6 @@ func (this *BatchGetValueAddServiceLangResponse) Validate() error {
}
return nil
}
func (this *UpdateBundleBalanceReq) Validate() error {
return nil
}
func (this *UpdateBundleBalanceResp) Validate() error {
return nil
}
func (this *BundleExtendRequest) Validate() error {
return nil
}
@ -821,131 +812,19 @@ func (this *MetricsVideoSubmitExportItem) Validate() error {
func (this *MetricsBalanceDetailExportReq) Validate() error {
return nil
}
func (this *CustomerListRequest) Validate() error {
func (this *WorkCastInfo) Validate() error {
return nil
}
func (this *CustomerListResponse) Validate() error {
for _, item := range this.List {
func (this *ExportWorkCastInfoReq) Validate() error {
return nil
}
func (this *ExportWorkCastInfoResp) Validate() error {
for _, item := range this.Data {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
return github_com_mwitkow_go_proto_validators.FieldError("Data", err)
}
}
}
return nil
}
func (this *CustomerDetailRequest) Validate() error {
return nil
}
func (this *CustomerDetailResponse) Validate() error {
if this.Customer != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Customer); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Customer", err)
}
}
return nil
}
func (this *CustomerUpdateRequest) Validate() error {
if this.Customer != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Customer); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Customer", err)
}
}
return nil
}
func (this *CustomerInfo) Validate() error {
return nil
}
func (this *Customer) Validate() error {
return nil
}
func (this *ReferralPersonListRequest) Validate() error {
return nil
}
func (this *ReferralPersonListResponse) Validate() error {
return nil
}
func (this *ContractUpdateRequest) Validate() error {
if this.Contract != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Contract); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Contract", err)
}
}
return nil
}
func (this *ContractListRequest) Validate() error {
return nil
}
func (this *ContractListResponse) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *ContractDetailRequest) Validate() error {
return nil
}
func (this *ContractDetailResponse) Validate() error {
if this.Contract != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Contract); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("Contract", err)
}
}
return nil
}
func (this *GetDevelopmentCyclesByContractUUIDRequest) Validate() error {
return nil
}
func (this *GetDevelopmentCyclesByContractUUIDResponse) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *GetPaymentCyclesByContractUUIDRequest) Validate() error {
return nil
}
func (this *GetPaymentCyclesByContractUUIDResponse) Validate() error {
for _, item := range this.List {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("List", err)
}
}
}
return nil
}
func (this *ContractInfo) Validate() error {
return nil
}
func (this *Contract) Validate() error {
for _, item := range this.PaymentCycles {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("PaymentCycles", err)
}
}
}
for _, item := range this.DevelopmentCycles {
if item != nil {
if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(item); err != nil {
return github_com_mwitkow_go_proto_validators.FieldError("DevelopmentCycles", err)
}
}
}
return nil
}
func (this *ContractPaymentCycle) Validate() error {
return nil
}
func (this *DevelopmentCycle) Validate() error {
return nil
}

File diff suppressed because it is too large Load Diff

View File

@ -14,8 +14,13 @@ func BundleRouter(r *gin.RouterGroup) {
bundleAppRoute := r.Group("bundle")
bundleAppNoAuthRoute := r.Group("bundle")
bundleAppRoute.Use(middleware.CheckLogin(service.AccountFieeProvider))
bundleClientNoAuthRoute := r.Group("bundle/no-auth")
// 套餐
{
{
bundleClientNoAuthRoute.POST("export/work-cast-info", bundle.ExportWorkCastInfo)
bundleClientNoAuthRoute.POST("export/bundle-price-info", bundle.ExportBundlePriceInfo)
}
bundleClientRoute := bundleRoute.Group("system")
{
bundleClientRoute.POST("create", bundle.CreateBundle)
@ -50,6 +55,7 @@ func BundleRouter(r *gin.RouterGroup) {
metrics.POST("export/balance-detail", bundle.MetricsBalanceDetailExport)
metrics.POST("export/balance-metrics", bundle.BalanceMetricsExport)
}
}
bundleClientRouteV2 := bundleRoute.Group("system/v2")
{

View File

@ -18,9 +18,10 @@ func BundleOrderRouter(r *gin.RouterGroup) {
bundleOrderWebRoute := r.Group("bundle-order")
bundleOrderWebRoute.POST("password-free/bundle-order-list-download", bundle.OrderRecordsListPasswordFreeDownload)
bundleOrderWebRoute.Use(middleware.CheckWebLogin(service.AccountProvider))
bundleOrderNoAuthRoute := r.Group("bundle-order")
// 套餐
{
bundleOrderNoAuthRoute.POST("common/web/no-auth/reconciliation-list-download", bundle.GetReconciliationListDownload)
bundleOrderClientWebRoute := bundleOrderWebRoute.Group("common/web")
{
bundleOrderClientWebRoute.POST("bundle-order-list", bundle.OrderRecordsList)

View File

@ -658,3 +658,136 @@ func GetAccountBundleBalance(c *gin.Context) {
})
service.Success(c, result)
}
func writeToExcelCast(filename string, items []*bundle.WorkCastInfo) error {
f := excelize.NewFile()
sheet := "Sheet1"
// 手动表头(顺序与写入字段顺序必须一致)
headers := []string{
"用户名称", "用户编号", "套餐名称", "下单时间",
"作品标题", "消费类型", "作品类型",
"作品上传时间", "艺人待确认时间", "艺人验收确认时间",
}
// 写表头
for i, h := range headers {
col, _ := excelize.ColumnNumberToName(i + 1)
cell := col + "1"
if err := f.SetCellValue(sheet, cell, h); err != nil {
return err
}
}
// 从第2行开始写数据
for r, it := range items {
row := r + 2
// 逐列写入(注意顺序必须和 headers 一致)
write := func(colIdx int, v interface{}) error {
col, _ := excelize.ColumnNumberToName(colIdx)
cell := fmt.Sprintf("%s%d", col, row)
return f.SetCellValue(sheet, cell, v)
}
costType := ""
if it.CostType == 1 {
costType = "套餐"
} else if it.CostType == 2 {
costType = "增值"
}
workCategory := ""
if it.WorkCategory == 1 {
workCategory = "图文"
} else if it.WorkCategory == 2 {
workCategory = "视频"
}
_ = write(1, it.CustomerName)
_ = write(2, it.CustomerNum)
_ = write(3, it.BundleName)
_ = write(4, it.SignedTime)
_ = write(5, it.Title)
_ = write(6, costType)
_ = write(7, workCategory)
_ = write(8, it.SubmitTime)
_ = write(9, it.WaitingTime)
_ = write(10, it.ConfirmTime)
}
// 可选:设置列宽,使表格更美观
_ = f.SetColWidth(sheet, "A", "AZ", 15)
// 保存文件
if err := f.SaveAs(filename); err != nil {
return err
}
return nil
}
func writeToExcelPriceInfo(filename string, items []*bundle.BundleBalanceExportItem) error {
f := excelize.NewFile()
sheet := "Sheet1"
// 手动表头(顺序与写入字段顺序必须一致)
headers := []string{
"所属月份", "用户编号", "姓名", "手机号", "手续费",
"套餐视频总数", "增值服务视频总数", "套餐视频单价", "增值视频单价",
"当月使用套餐视频数", "当月使用增值视频数",
"当月消耗套餐金额($)", "当月消耗增值金额($)",
}
// 写表头
for i, h := range headers {
col, _ := excelize.ColumnNumberToName(i + 1)
cell := col + "1"
if err := f.SetCellValue(sheet, cell, h); err != nil {
return err
}
}
// 从第2行开始写数据
for r, it := range items {
row := r + 2
// 逐列写入(注意顺序必须和 headers 一致)
write := func(colIdx int, v interface{}) error {
col, _ := excelize.ColumnNumberToName(colIdx)
cell := fmt.Sprintf("%s%d", col, row)
return f.SetCellValue(sheet, cell, v)
}
_ = write(1, it.Month)
_ = write(2, it.CustomerNum)
_ = write(3, it.UserName)
_ = write(4, it.UserPhoneNumber)
_ = write(5, it.Fee)
// 套餐视频数量及单价
_ = write(6, int(it.BundleVideoNumber))
_ = write(7, int(it.IncreaseVideoNumber))
_ = write(8, fmt.Sprintf("%.2f", it.BundleVideoUnitPrice))
_ = write(9, fmt.Sprintf("%.2f", it.IncreaseVideoUnitPrice))
// 视频类
_ = write(10, int(it.MonthlyBundleVideoConsumptionNumber))
_ = write(11, int(it.MonthlyIncreaseVideoConsumptionNumber))
// 当月视频消耗金额($)
monthlyBundleVideoConsumptionPrice, err := strconv.ParseFloat(it.MonthlyBundleVideoConsumptionPrice, 64)
if err != nil {
return err
}
monthlyIncreaseVideoConsumptionPrice, err := strconv.ParseFloat(it.MonthlyIncreaseVideoConsumptionPrice, 64)
if err != nil {
return err
}
_ = write(12, fmt.Sprintf("%.2f", monthlyBundleVideoConsumptionPrice))
_ = write(13, fmt.Sprintf("%.2f", monthlyIncreaseVideoConsumptionPrice))
}
// 可选:设置列宽,使表格更美观
_ = f.SetColWidth(sheet, "A", "AZ", 15)
// 保存文件
if err := f.SaveAs(filename); err != nil {
return err
}
return nil
}

View File

@ -676,3 +676,61 @@ func tsToStr(ts int64, layout string) string {
t := time.Unix(ts, 0).In(time.Local)
return t.Format(layout)
}
func ExportWorkCastInfo(ctx *gin.Context) {
var req bundle.ExportWorkCastInfoReq
req.StartTime = "2025-01-01 00:00:00"
req.EndTime = "2025-12-31 23:59:59"
resp, err := service.BundleProvider.ExportWorkCastInfo(ctx, &req)
if err != nil {
service.Error(ctx, err)
return
}
exportFileName := "作品上传数据_2025-12-31_" + time.Now().Format("20060102150405") + ".xlsx"
filePath := fmt.Sprintf("./runtime/%d/%s", 9999, exportFileName)
utils.CheckDirPath("./runtime/"+fmt.Sprint(9999), true)
if err := writeToExcelCast(filePath, resp.Data); err != nil {
service.Error(ctx, err)
return
}
var scheme string
if ctx.GetHeader("X-Forwarded-Proto") == "https" {
scheme = "https"
} else {
scheme = "http"
}
var exportUrl string = fmt.Sprintf("%s://%s/api/fiee/static/%s", scheme, ctx.Request.Host, strings.Replace(filePath, "./runtime/", "", 1))
service.Success(ctx, gin.H{
"url": exportUrl,
})
}
func ExportBundlePriceInfo(ctx *gin.Context) {
var req bundle.BundleBalanceExportReq
exportFileName := "业务收入大表2025.1.1-2025.12.31_" + time.Now().Format("20060102150405") + ".xlsx"
filePath := fmt.Sprintf("./runtime/%d/%s", 9999, exportFileName)
utils.CheckDirPath("./runtime/"+fmt.Sprint(9999), true)
req.Month = []string{"2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08", "2025-09", "2025-10", "2025-11", "2025-12"}
res, err := service.BundleProvider.BundleBalanceExport(context.Background(), &req)
if err != nil {
service.Error(ctx, errors.New(common.BalanceMetricsExportFailed))
return
}
if err := writeToExcelPriceInfo(filePath, res.Data); err != nil {
service.Error(ctx, errors.New(common.BalanceMetricsExportFailed))
return
}
var scheme string
if ctx.GetHeader("X-Forwarded-Proto") == "https" {
scheme = "https"
} else {
scheme = "http"
}
var exportUrl string = fmt.Sprintf("%s://%s/api/fiee/static/%s", scheme, ctx.Request.Host, strings.Replace(filePath, "./runtime/", "", 1))
service.Success(ctx, gin.H{
"url": exportUrl,
})
}

View File

@ -26,6 +26,7 @@ import (
"image"
"image/jpeg"
"io"
"net/http"
"net/url"
"os"
"path/filepath"
@ -1270,7 +1271,16 @@ func WorkListExport(ctx *gin.Context) {
req.PageSize = originalPageSize
zap.L().Info("数据获取完成开始生成Excel", zap.Int("总数据量", len(allData)))
if len(allData) == 0 {
service.Error(ctx, errors.New("没有可导出的数据"))
zap.L().Warn("没有可导出的数据")
// 明确设置 Content-Type 为 JSON避免被误认为是 Excel 文件
ctx.Header("Content-Type", "application/json; charset=utf-8")
ctx.JSON(http.StatusOK, gin.H{
"status": 1,
"code": 1,
"msg": "没有可导出的数据",
"data": struct{}{},
})
ctx.Abort()
return
}
@ -1278,7 +1288,15 @@ func WorkListExport(ctx *gin.Context) {
excelFile, err := logicCastWork.ExportExcelWorkList(allData)
if err != nil {
zap.L().Error("生成Excel失败", zap.Error(err))
service.Error(ctx, err)
// 明确设置 Content-Type 为 JSON避免被误认为是 Excel 文件
ctx.Header("Content-Type", "application/json; charset=utf-8")
ctx.JSON(http.StatusOK, gin.H{
"status": 1,
"code": 1,
"msg": err.Error(),
"data": struct{}{},
})
ctx.Abort()
return
}