// Package gen
// @Link https://github.com/xiujiecn/xiu-admin
// @Copyright Copyright (c) 2026 LiXiujie
// @Author Lxj
// @License https://github.com/xiujiecn/xiu-admin/blob/master/LICENSE
// @AutoGenerate Version
package common
import (
"context"
"database/sql"
"fmt"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/hook"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/convert"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/excel"
"strconv"
"time"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
type sCommonProfitAccountMonthBill struct{}
func NewCommonProfitAccountMonthBill() *sCommonProfitAccountMonthBill {
return &sCommonProfitAccountMonthBill{}
}
func init() {
service.RegisterCommonProfitAccountMonthBill(NewCommonProfitAccountMonthBill())
}
// Model 盈利账户月账单表ORM模型
func (s *sCommonProfitAccountMonthBill) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
if len(option) == 0 {
option = append(option, &handler.Option{
FilterTenant: true,
FilterAuth: true,
})
}
return handler.Model(dao.TProfitAccountMonthBill.Ctx(ctx), option...)
}
// List 获取盈利账户月账单表列表
func (s *sCommonProfitAccountMonthBill) List(ctx context.Context, in *model.TProfitAccountMonthBillListParam) (list []*model.TProfitAccountMonthBillListModel, totalCount int, err error) {
mod := s.Model(ctx)
// 字段过滤
mod = mod.Fields(model.TProfitAccountMonthBillListModel{})
// 查询账单ID
if in.Id > 0 {
mod = mod.Where(dao.TProfitAccountMonthBill.Columns().Id, in.Id)
}
// 查询账单状态:1正常,2已调整,3已作废
if in.BillStatus > 0 {
mod = mod.Where(dao.TProfitAccountMonthBill.Columns().BillStatus, in.BillStatus)
}
// 查询创建时间
if len(in.CreatedAt) == 2 {
in.CreatedAt[1] = in.CreatedAt[1].EndOfDay()
}
if len(in.CreatedAt) == 2 {
mod = mod.WhereBetween(dao.TProfitAccountMonthBill.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1])
}
// 分页
mod = mod.Page(in.Page, in.PageSize)
// 排序
mod = mod.OrderDesc(dao.TProfitAccountMonthBill.Columns().Id)
// 操作人摘要信息
mod = mod.Hook(hook.MemberSummary)
// 查询数据
if err = mod.ScanAndCount(&list, &totalCount, false); err != nil {
err = gerror.Wrap(err, "获取盈利账户月账单表列表失败,请稍后重试!")
return
}
return
}
// Export 导出盈利账户月账单表
func (s *sCommonProfitAccountMonthBill) Export(ctx context.Context, in *model.TProfitAccountMonthBillListParam) (err error) {
list, totalCount, err := s.List(ctx, in)
if err != nil {
return
}
// 字段的排序是依据tags的字段顺序,如果你不想使用默认的排序方式,可以直接定义 tags = []string{"字段名称", "字段名称2", ...}
tags, err := convert.GetEntityDescTags(model.TProfitAccountMonthBillExportModel{})
if err != nil {
return
}
var (
fileName = "导出盈利账户月账单表-" + gctx.CtxId(ctx)
sheetName = fmt.Sprintf("索引条件共%v行,共%v页,当前导出是第%v页,本页共%v行", totalCount, (totalCount+in.PageSize-1)/in.PageSize, in.Page, len(list))
exports []model.TProfitAccountMonthBillExportModel
)
if err = gconv.Scan(list, &exports); err != nil {
return
}
err = excel.ExportByStructs(ctx, tags, exports, fileName, sheetName)
return
}
// Edit 修改/新增盈利账户月账单表
func (s *sCommonProfitAccountMonthBill) Edit(ctx context.Context, in *model.TProfitAccountMonthBillEditParam) (err error) {
return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
// 修改
if in.Id > 0 {
updatedBy := contexts.GetUserId(ctx)
in.UpdatedBy = &updatedBy
in.UpdatedAt = gtime.Now()
if _, err = s.Model(ctx).
Fields(model.TProfitAccountMonthBillUpdateFields{}).
WherePri(in.Id).Data(in).Update(); err != nil {
err = gerror.Wrap(err, "修改盈利账户月账单表失败,请稍后重试!")
}
return
}
// 新增
tenantId := contexts.GetTenantId(ctx)
in.TenantId = &tenantId
createdDept := contexts.GetDeptId(ctx)
in.CreatedDept = &createdDept
createdBy := contexts.GetUserId(ctx)
in.CreatedBy = &createdBy
in.CreatedAt = gtime.Now()
if _, err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Fields(model.TProfitAccountMonthBillInsertFields{}).
Data(in).Insert(); err != nil {
err = gerror.Wrap(err, "新增盈利账户月账单表失败,请稍后重试!")
}
return
})
}
// Delete 删除盈利账户月账单表
func (s *sCommonProfitAccountMonthBill) Delete(ctx context.Context, in *model.TProfitAccountMonthBillDeleteParam) (err error) {
if _, err = s.Model(ctx).WherePri(in.Id).Unscoped().Delete(); err != nil {
err = gerror.Wrap(err, "删除盈利账户月账单表失败,请稍后重试!")
return
}
return
}
// View 获取盈利账户月账单表指定信息
func (s *sCommonProfitAccountMonthBill) View(ctx context.Context, in *model.TProfitAccountMonthBillViewParam) (res *model.TProfitAccountMonthBillViewModel, err error) {
if err = s.Model(ctx).WherePri(in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil {
err = gerror.Wrap(err, "获取盈利账户月账单表信息,请稍后重试!")
return
}
return
}
// SettleProfitAccountMonthBill 按可提现变动明细统计并写入盈利账户月账单。
func (s *sCommonProfitAccountMonthBill) SettleProfitAccountMonthBill(ctx context.Context, in *model.TProfitAccountMonthBillSettleParam) (res *model.TProfitAccountMonthBillSettleResult, err error) {
if in == nil {
in = &model.TProfitAccountMonthBillSettleParam{}
}
if err = in.Filter(ctx); err != nil {
return nil, gerror.Wrap(err, "账期格式错误,请使用YYYY-MM")
}
_, err = time.Parse("2006-01", in.AccountPeriod)
if err != nil {
return nil, gerror.Wrap(err, "账期格式错误,请使用YYYY-MM")
}
now := gtime.Now()
userId := contexts.GetUserId(ctx)
tenantId := contexts.GetTenantId(ctx)
changeColumns := dao.TFinWithdrawableChange.Columns()
billColumns := dao.TProfitAccountMonthBill.Columns()
type changeRow struct {
Id int64 `orm:"id"`
DeptId int64 `orm:"dept_id"`
TenantId string `orm:"tenant_id"`
CreatedDept int64 `orm:"created_dept"`
ChangeType int `orm:"change_type"`
IncomeExpenseType int `orm:"income_expense_type"`
ChangeAmount float64 `orm:"change_amount"`
BeforeBalance float64 `orm:"before_balance"`
CreatedAt *gtime.Time `orm:"created_at"`
}
var rows []*changeRow
mod := handler.Model(dao.TFinWithdrawableChange.Ctx(ctx), &handler.Option{
FilterTenant: false,
FilterAuth: false,
}).
Fields(
changeColumns.Id,
changeColumns.DeptId,
changeColumns.TenantId,
changeColumns.CreatedDept,
changeColumns.ChangeType,
changeColumns.IncomeExpenseType,
changeColumns.ChangeAmount,
changeColumns.BeforeBalance,
changeColumns.CreatedAt,
).
Where(changeColumns.AccountPeriod, in.AccountPeriod)
if tenantId != "" {
mod = mod.Where(changeColumns.TenantId, tenantId)
}
if err = mod.OrderAsc(changeColumns.TenantId).OrderAsc(changeColumns.DeptId).OrderAsc(changeColumns.CreatedAt).OrderAsc(changeColumns.Id).Scan(&rows); err != nil {
return nil, gerror.Wrap(err, "查询可提现变动明细失败,请稍后重试!")
}
type billGroup struct {
DeptId int64
TenantId string
CreatedDept int64
AccountPeriod string
OpeningBalance float64
CommissionIncome float64
BalanceTransferInIncome float64
WithdrawalExpense float64
WithdrawableTransferOutExpense float64
ProfitCreditRepayExpense float64
TotalIncome float64
TotalExpense float64
IncomeCount int
ExpenseCount int
DetailCount int
}
groups := make(map[string]*billGroup)
keys := make([]string, 0, 16)
for _, row := range rows {
if row == nil || row.DeptId <= 0 {
continue
}
switch row.ChangeType {
case 0, 1, 2, 3, 4:
default:
continue
}
key := fmt.Sprintf("%s:%d", row.TenantId, row.DeptId)
group := groups[key]
if group == nil {
group = &billGroup{
DeptId: row.DeptId,
TenantId: row.TenantId,
CreatedDept: row.CreatedDept,
AccountPeriod: in.AccountPeriod,
OpeningBalance: row.BeforeBalance,
}
groups[key] = group
keys = append(keys, key)
}
group.DetailCount++
switch row.ChangeType {
case 0:
group.CommissionIncome += row.ChangeAmount
case 1:
group.WithdrawalExpense += row.ChangeAmount
case 2:
group.WithdrawableTransferOutExpense += row.ChangeAmount
case 3:
group.BalanceTransferInIncome += row.ChangeAmount
case 4:
group.ProfitCreditRepayExpense += row.ChangeAmount
}
if row.IncomeExpenseType == 0 {
group.TotalIncome += row.ChangeAmount
group.IncomeCount++
} else if row.IncomeExpenseType == 1 {
group.TotalExpense += row.ChangeAmount
group.ExpenseCount++
}
}
res = &model.TProfitAccountMonthBillSettleResult{
AccountPeriod: in.AccountPeriod,
}
if len(groups) == 0 {
return res, nil
}
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
for _, key := range keys {
group := groups[key]
if group == nil {
continue
}
totalIncome := group.TotalIncome
totalExpense := group.TotalExpense
closingBalance := group.OpeningBalance + totalIncome - totalExpense
group.TotalIncome = totalIncome
group.TotalExpense = totalExpense
lookup := tx.Ctx(ctx).Model(dao.TProfitAccountMonthBill.Table()).
Fields(billColumns.Id).
Where(billColumns.DeptId, group.DeptId).
Where(billColumns.AccountPeriod, group.AccountPeriod)
if group.TenantId != "" {
lookup = lookup.Where(billColumns.TenantId, group.TenantId)
}
var existing struct {
Id int64 `orm:"id"`
}
if err := lookup.LockUpdate().Scan(&existing); err != nil && err != sql.ErrNoRows {
return gerror.Wrap(err, "查询盈利账户月账单失败,请稍后重试!")
}
tenantValue := group.TenantId
if tenantValue == "" {
tenantValue = tenantId
}
if tenantValue == "" {
return gerror.New("租户ID不能为空")
}
createdDeptValue := group.CreatedDept
if createdDeptValue == 0 {
createdDeptValue = contexts.GetDeptId(ctx)
}
if createdDeptValue == 0 {
return gerror.New("创建部门不能为空")
}
data := g.Map{
billColumns.DeptId: group.DeptId,
billColumns.AccountPeriod: group.AccountPeriod,
billColumns.OpeningBalance: group.OpeningBalance,
billColumns.CommissionIncome: group.CommissionIncome,
billColumns.BalanceTransferInIncome: group.BalanceTransferInIncome,
billColumns.WithdrawalExpense: group.WithdrawalExpense,
billColumns.WithdrawableTransferOutExpense: group.WithdrawableTransferOutExpense,
billColumns.ProfitCreditRepayExpense: group.ProfitCreditRepayExpense,
billColumns.TotalIncome: totalIncome,
billColumns.TotalExpense: totalExpense,
billColumns.ClosingBalance: closingBalance,
billColumns.IncomeCount: group.IncomeCount,
billColumns.ExpenseCount: group.ExpenseCount,
billColumns.BillStatus: 1,
billColumns.SettleTime: now,
billColumns.SettleBy: userId,
billColumns.Remark: "根据可提现变动明细统计生成",
billColumns.TenantId: tenantValue,
billColumns.UpdatedBy: userId,
billColumns.UpdatedAt: now,
}
if existing.Id > 0 {
if _, err := tx.Ctx(ctx).Model(dao.TProfitAccountMonthBill.Table()).
WherePri(existing.Id).
Data(data).
Update(); err != nil {
return gerror.Wrap(err, "更新盈利账户月账单失败,请稍后重试!")
}
res.UpdateCount++
} else {
data[billColumns.CreatedDept] = createdDeptValue
data[billColumns.CreatedBy] = userId
data[billColumns.CreatedAt] = now
if _, err := tx.Ctx(ctx).Model(dao.TProfitAccountMonthBill.Table()).
Data(data).
Insert(); err != nil {
return gerror.Wrap(err, "新增盈利账户月账单失败,请稍后重试!")
}
res.InsertCount++
}
res.DeptCount++
res.DetailCount += group.DetailCount
res.TotalIncome += totalIncome
res.TotalExpense += totalExpense
}
return nil
})
if err != nil {
return nil, err
}
return res, nil
}
// 获取月账单盈利账户汇总信息
func (s *sCommonProfitAccountMonthBill) GetProfitBillSummary(ctx context.Context, month string) (res *model.TProfitBillModel, err error) {
// 计算上月账期(基于当前时间)
// now := time.Now()
// lastMonthTime := now.AddDate(0, -1, 0)
// lastMonthPeriod := lastMonthTime.Format("2006-01")
var bill *model.TProfitAccountMonthBillViewModel
if err = dao.TProfitAccountMonthBill.Ctx(ctx).
Where(dao.TProfitAccountMonthBill.Columns().AccountPeriod, month).
Where(dao.TProfitAccountMonthBill.Columns().DeptId, contexts.GetDeptId(ctx)).
Scan(&bill); err != nil {
err = gerror.Wrap(err, "查询上月账单失败,请稍后重试!")
return
}
if bill == nil {
return
}
res = &model.TProfitBillModel{}
res.TotalIncome = bill.TotalIncome
res.TotalExpense = bill.TotalExpense
return
}
// GetCoreFinancialData 获取核心财务指标
func (s *sCommonProfitAccountMonthBill) GetCoreFinancialData(ctx context.Context, in *model.TCommissionOverviewParam) (res *model.TCoreFinancialDataModel, err error) {
res = &model.TCoreFinancialDataModel{}
deptId := contexts.GetDeptId(ctx)
// 解析账期参数
var startPeriod, endPeriod string
if in.Type == 1 { // 年
startPeriod = in.Year + "-01"
endPeriod = in.Year + "-12"
} else if in.Type == 2 { // 月
startPeriod = in.Month
endPeriod = in.Month
}
// 1. 获取总收入:统计 t_profit_account_month_bill 的 total_income
type totalIncomeRow struct {
TotalIncome float64 `orm:"total_income"`
}
var totalIncomeResult *totalIncomeRow
if err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Where(dao.TProfitAccountMonthBill.Columns().DeptId, deptId).
WhereGTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, startPeriod).
WhereLTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, endPeriod).
Fields("SUM(" + dao.TProfitAccountMonthBill.Columns().TotalIncome + ") as total_income").
Scan(&totalIncomeResult); err != nil {
err = gerror.Wrap(err, "查询总收入失败,请稍后重试!")
return
}
if totalIncomeResult != nil {
res.TotalIncome = totalIncomeResult.TotalIncome
}
// 2. 获取顶级利润:查询 t_fin_commission_detail 中顶级部门的 commission_income
// 顶级部门ID通常为1或当前部门的顶级父部门
type topProfitRow struct {
CommissionIncome float64 `orm:"commission_income"`
}
var topProfitResult *topProfitRow
if err = handler.Model(dao.TFinCommissionDetail.Ctx(ctx)).
Where(dao.TFinCommissionDetail.Columns().BenefitDeptId, deptId).
WhereGTE(dao.TFinCommissionDetail.Columns().AccountPeriod, startPeriod).
WhereLTE(dao.TFinCommissionDetail.Columns().AccountPeriod, endPeriod).
Fields("SUM(" + dao.TFinCommissionDetail.Columns().CommissionAmount + ") as commission_income").
Scan(&topProfitResult); err != nil {
err = gerror.Wrap(err, "查询顶级利润失败,请稍后重试!")
return
}
if topProfitResult != nil {
res.TopLevelProfit = topProfitResult.CommissionIncome
}
// 3. 获取待审核提现:从 t_profit_account_month_bill 查询 withdrawable_transfer_out_expense
type pendingWithdrawRow struct {
WithdrawableTransferOutExpense float64 `orm:"withdrawable_transfer_out_expense"`
}
var pendingWithdrawResult *pendingWithdrawRow
if err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Where(dao.TProfitAccountMonthBill.Columns().DeptId, deptId).
WhereGTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, startPeriod).
WhereLTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, endPeriod).
Fields("SUM(" + dao.TProfitAccountMonthBill.Columns().WithdrawableTransferOutExpense + ") as withdrawable_transfer_out_expense").
Scan(&pendingWithdrawResult); err != nil {
err = gerror.Wrap(err, "查询待审核提现失败,请稍后重试!")
return
}
if pendingWithdrawResult != nil {
res.PendingWithdrawAmount = pendingWithdrawResult.WithdrawableTransferOutExpense
}
// 4. 获取已提现金额:统计 t_profit_account_month_bill 的 balance_transfer_in_income
type withdrawedRow struct {
WithdrawalExpense float64 `orm:"withdrawal_expense"`
}
var withdrawedResult *withdrawedRow
if err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Where(dao.TProfitAccountMonthBill.Columns().DeptId, deptId).
WhereGTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, startPeriod).
WhereLTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, endPeriod).
Fields("SUM(" + dao.TProfitAccountMonthBill.Columns().WithdrawalExpense + ") as withdrawal_expense").
Scan(&withdrawedResult); err != nil {
err = gerror.Wrap(err, "查询已提现金额失败,请稍后重试!")
return
}
if withdrawedResult != nil {
res.WithdrawedAmount = withdrawedResult.WithdrawalExpense
}
return
}
// GetFinancialTrend 获取财务趋势折线图
// 指标类型:1总收入,2顶级利润,3待审核提现,4已提现金额
// 月份视图:按天查询 t_fin_withdrawable_change
// 年份视图:按月查询 t_profit_account_month_bill
func (s *sCommonProfitAccountMonthBill) GetFinancialTrend(ctx context.Context, in *model.TFinancialTrendParam) (res *model.TFinancialTrendModel, err error) {
res = &model.TFinancialTrendModel{}
// 默认查询所有指标
indicators := in.Indicators
if len(indicators) == 0 {
indicators = []int{1, 2, 3, 4}
}
// 指标名称映射
indicatorNames := map[int]string{
1: "总收入",
2: "顶级利润",
3: "待审核提现",
4: "已提现金额",
}
if in.Type == 1 {
// 年视图:按月查询 t_profit_account_month_bill
year := in.Year
months := []string{"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"}
res.Labels = make([]string, 0, 12)
for _, m := range months {
res.Labels = append(res.Labels, year+"-"+m)
}
type monthBillRow struct {
AccountPeriod string `orm:"account_period"`
TotalIncome float64 `orm:"total_income"`
CommissionIncome float64 `orm:"commission_income"`
BalanceTransferInIncome float64 `orm:"balance_transfer_in_income"`
WithdrawalExpense float64 `orm:"withdrawal_expense"`
}
var bills []*monthBillRow
if err = s.Model(ctx, &handler.Option{FilterAuth: false}).
Where(dao.TProfitAccountMonthBill.Columns().DeptId, contexts.GetDeptId(ctx)).
WhereGTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, year+"-01").
WhereLTE(dao.TProfitAccountMonthBill.Columns().AccountPeriod, year+"-12").
Fields(
dao.TProfitAccountMonthBill.Columns().AccountPeriod,
dao.TProfitAccountMonthBill.Columns().TotalIncome,
dao.TProfitAccountMonthBill.Columns().CommissionIncome,
dao.TProfitAccountMonthBill.Columns().BalanceTransferInIncome,
dao.TProfitAccountMonthBill.Columns().WithdrawalExpense,
).
Scan(&bills); err != nil {
return nil, gerror.Wrap(err, "查询财务趋势数据失败,请稍后重试!")
}
// 构建月份映射
billMap := make(map[string]*monthBillRow)
for _, bill := range bills {
billMap[bill.AccountPeriod] = bill
}
// 构建每个指标的数据数组
res.Series = make([]model.TFinancialTrendSeries, 0, len(indicators))
for _, ind := range indicators {
series := model.TFinancialTrendSeries{
Name: indicatorNames[ind],
Type: ind,
Values: make([]float64, 0, 12),
}
for _, period := range res.Labels {
var val float64
if bill, ok := billMap[period]; ok {
switch ind {
case 1:
val = bill.TotalIncome
case 2:
val = bill.CommissionIncome
case 3:
val = bill.BalanceTransferInIncome
case 4:
val = bill.WithdrawalExpense
}
}
series.Values = append(series.Values, val)
}
res.Series = append(res.Series, series)
}
} else if in.Type == 2 {
// 月视图:按天查询 t_fin_withdrawable_change
month := in.Month
t := gtime.NewFromStr(month + "-01")
daysInMonth := t.EndOfMonth().Day()
res.Labels = make([]string, 0, daysInMonth)
for day := 1; day <= daysInMonth; day++ {
res.Labels = append(res.Labels, month+"-"+strconv.Itoa(day))
}
// 解析月份获取开始和结束日期
startDate := month + "-01"
endDate := month + "-" + strconv.Itoa(daysInMonth)
type dailyRow struct {
Date string `orm:"date"`
IncomeAmt float64 `orm:"income_amt"`
Expense1Amt float64 `orm:"expense1_amt"`
Expense3Amt float64 `orm:"expense3_amt"`
}
var dailyResults []*dailyRow
if err = handler.Model(dao.TFinWithdrawableChange.Ctx(ctx)).
Where(dao.TFinWithdrawableChange.Columns().DeptId, contexts.GetDeptId(ctx)).
WhereGTE(dao.TFinWithdrawableChange.Columns().CreatedAt, startDate).
WhereLTE(dao.TFinWithdrawableChange.Columns().CreatedAt, endDate).
Fields(`
DATE_FORMAT(` + dao.TFinWithdrawableChange.Columns().CreatedAt + `, '%Y-%m-%d') as date,
SUM(CASE WHEN ` + dao.TFinWithdrawableChange.Columns().IncomeExpenseType + `=0 THEN ` + dao.TFinWithdrawableChange.Columns().ChangeAmount + ` ELSE 0 END) as income_amt,
SUM(CASE WHEN ` + dao.TFinWithdrawableChange.Columns().IncomeExpenseType + `=1 THEN ` + dao.TFinWithdrawableChange.Columns().ChangeAmount + ` ELSE 0 END) as expense1_amt,
SUM(CASE WHEN ` + dao.TFinWithdrawableChange.Columns().IncomeExpenseType + `=3 THEN ` + dao.TFinWithdrawableChange.Columns().ChangeAmount + ` ELSE 0 END) as expense3_amt
`).
Group("DATE_FORMAT(" + dao.TFinWithdrawableChange.Columns().CreatedAt + ", '%Y-%m-%d')").
Order("date ASC").
Scan(&dailyResults); err != nil {
return nil, gerror.Wrap(err, "查询日趋势数据失败,请稍后重试!")
}
// 构建日期映射
dailyMap := make(map[string]*dailyRow)
for _, row := range dailyResults {
dailyMap[row.Date] = row
}
// 查询顶级利润(从分润表)
type commissionRow struct {
CommissionAmount float64 `orm:"commission_amount"`
}
var commissionResult *commissionRow
if err = handler.Model(dao.TFinCommissionDetail.Ctx(ctx)).
Where(dao.TFinCommissionDetail.Columns().BenefitDeptId, contexts.GetDeptId(ctx)).
WhereGTE(dao.TFinCommissionDetail.Columns().AccountPeriod, month).
WhereLTE(dao.TFinCommissionDetail.Columns().AccountPeriod, month).
Fields("SUM(" + dao.TFinCommissionDetail.Columns().CommissionAmount + ") as commission_amount").
Scan(&commissionResult); err != nil {
return nil, gerror.Wrap(err, "查询顶级利润失败,请稍后重试!")
}
topProfit := 0.0
if commissionResult != nil {
topProfit = commissionResult.CommissionAmount
}
// 构建每个指标的数据数组
res.Series = make([]model.TFinancialTrendSeries, 0, len(indicators))
for _, ind := range indicators {
series := model.TFinancialTrendSeries{
Name: indicatorNames[ind],
Type: ind,
Values: make([]float64, 0, daysInMonth),
}
for _, date := range res.Labels {
var val float64
switch ind {
case 1: // 总收入
if row, ok := dailyMap[date]; ok {
val = row.IncomeAmt
}
case 2: // 顶级利润
val = topProfit
case 3: // 待审核提现
if row, ok := dailyMap[date]; ok {
val = row.Expense3Amt
}
case 4: // 已提现金额
if row, ok := dailyMap[date]; ok {
val = row.Expense1Amt
}
}
series.Values = append(series.Values, val)
}
res.Series = append(res.Series, series)
}
}
return
}