Преглед изворни кода

更新收入记录控制器和服务,新增用户ID查询参数,优化统计数据获取逻辑,确保统计结果的准确性和完整性。

wuyi пре 2 месеци
родитељ
комит
2375c34402

+ 19 - 20
src/controllers/income-records.controller.ts

@@ -8,29 +8,23 @@ import {
 } from '../dto/income-records.dto'
 import { UserRole } from '../entities/user.entity'
 import { TeamService } from '../services/team.service'
+import { UserService } from '../services/user.service'
 
 export class IncomeRecordsController {
   private incomeRecordsService: IncomeRecordsService
   private teamService: TeamService
+  private userService: UserService
 
   constructor(app: FastifyInstance) {
     this.incomeRecordsService = new IncomeRecordsService(app)
     this.teamService = new TeamService(app)
+    this.userService = new UserService(app)
   }
 
   async create(request: FastifyRequest<{ Body: CreateIncomeRecordBody }>, reply: FastifyReply) {
     try {
-      const {
-        agentId,
-        userId,
-        incomeAmount,
-        incomeType,
-        orderType,
-        orderPrice,
-        orderNo,
-        payChannel,
-        payNo
-      } = request.body
+      const { agentId, userId, incomeAmount, incomeType, orderType, orderPrice, orderNo, payChannel, payNo } =
+        request.body
 
       // 验证必填字段
       if (
@@ -152,24 +146,29 @@ export class IncomeRecordsController {
   }
 
   async getStatistics(
-    request: FastifyRequest<{ Querystring: { startDate?: string; endDate?: string } }>,
+    request: FastifyRequest<{ Querystring: { startDate?: string; endDate?: string; userId?: number } }>,
     reply: FastifyReply
   ) {
     try {
-      const { startDate, endDate } = request.query
+      const { startDate, endDate, userId } = request.query
       const user = request.user
       if (!user) {
         return reply.code(403).send({ message: '用户未登录' })
       }
-      let userId: number | undefined
-      let agentId: number | undefined
-      if (user.role === UserRole.TEAM) {
-        const team = await this.teamService.findByUserId(user.id)
-        agentId = team.id
+
+      let finalUserId: number | undefined
+      if (user.role === UserRole.ADMIN) {
+        if (userId) {
+          finalUserId = userId
+        }
+      } else if (user.role === UserRole.TEAM) {
+        finalUserId = user.id
       } else if (user.role === UserRole.PROMOTER) {
-        userId = user.id
+        const promoter = await this.userService.findById(user.id)
+        finalUserId = promoter.parentId
       }
-      const statistics = await this.incomeRecordsService.getStatistics(startDate, endDate, agentId, userId)
+
+      const statistics = await this.incomeRecordsService.getStatistics(startDate, endDate, finalUserId)
       return reply.send(statistics)
     } catch (error) {
       return reply.code(500).send({ message: '获取统计数据失败' })

+ 1 - 1
src/routes/income-records.routes.ts

@@ -55,7 +55,7 @@ export default async function incomeRecordsRoutes(fastify: FastifyInstance) {
   )
 
   // 获取统计数据
-  fastify.get<{ Querystring: { startDate?: string; endDate?: string } }>(
+  fastify.get<{ Querystring: { startDate?: string; endDate?: string; userId?: number } }>(
     '/statistics/summary',
     { onRequest: [authenticate, hasAnyRole(UserRole.ADMIN, UserRole.TEAM, UserRole.PROMOTER)] },
     incomeRecordsController.getStatistics.bind(incomeRecordsController)

+ 14 - 13
src/services/income-records.service.ts

@@ -174,8 +174,7 @@ export class IncomeRecordsService {
   async getStatistics(
     startDate?: string,
     endDate?: string,
-    agentId?: number,
-    userId?: number
+    agentId?: number
   ): Promise<{
     dates: string[]
     agents: Array<{
@@ -194,12 +193,14 @@ export class IncomeRecordsService {
 
     // 验证日期格式
     const start = new Date(startDate)
+    start.setHours(0, 0, 0, 0)
     const end = new Date(endDate)
-    
+    end.setHours(23, 59, 59, 999)
+
     if (isNaN(start.getTime()) || isNaN(end.getTime())) {
       throw new Error('日期格式不正确')
     }
-    
+
     if (start > end) {
       throw new Error('开始时间不能晚于结束时间')
     }
@@ -208,7 +209,11 @@ export class IncomeRecordsService {
     const dates: string[] = []
     const currentDate = new Date(start)
     while (currentDate <= end) {
-      dates.push(currentDate.toISOString().split('T')[0])
+      // 使用本地时区格式化日期
+      const year = currentDate.getFullYear()
+      const month = String(currentDate.getMonth() + 1).padStart(2, '0')
+      const day = String(currentDate.getDate()).padStart(2, '0')
+      dates.push(`${year}-${month}-${day}`)
       currentDate.setDate(currentDate.getDate() + 1)
     }
 
@@ -217,9 +222,9 @@ export class IncomeRecordsService {
       .createQueryBuilder('record')
       .select([
         'record.agentId as agentId',
-        'DATE(record.createdAt) as date',
-        'SUM(CASE WHEN record.incomeType = :tipType THEN record.incomeAmount ELSE 0 END) as tipAmount',
-        'SUM(CASE WHEN record.incomeType = :commissionType THEN record.incomeAmount ELSE 0 END) as commissionAmount',
+        'DATE_FORMAT(record.createdAt, "%Y-%m-%d") as date',
+        'SUM(IF(record.incomeType = :tipType, record.incomeAmount, 0)) as tipAmount',
+        'SUM(IF(record.incomeType = :commissionType, record.incomeAmount, 0)) as commissionAmount',
         'SUM(record.incomeAmount) as totalAmount'
       ])
       .where('record.createdAt >= :start', { start })
@@ -229,7 +234,7 @@ export class IncomeRecordsService {
       .setParameter('tipType', IncomeType.TIP)
       .setParameter('commissionType', IncomeType.COMMISSION)
       .groupBy('record.agentId')
-      .addGroupBy('DATE(record.createdAt)')
+      .addGroupBy('DATE_FORMAT(record.createdAt, "%Y-%m-%d")')
       .orderBy('record.agentId', 'ASC')
       .addOrderBy('date', 'ASC')
 
@@ -238,10 +243,6 @@ export class IncomeRecordsService {
       queryBuilder = queryBuilder.andWhere('record.agentId = :agentId', { agentId })
     }
 
-    if (userId) {
-      queryBuilder = queryBuilder.andWhere('record.userId = :userId', { userId })
-    }
-
     // 执行聚合查询
     const agentStats = await queryBuilder.getRawMany()
 

+ 72 - 12
src/services/team.service.ts

@@ -1,6 +1,7 @@
 import { Repository, Like } from 'typeorm'
 import { FastifyInstance } from 'fastify'
 import { Team } from '../entities/team.entity'
+import { IncomeRecords, IncomeType } from '../entities/income-records.entity'
 import { PaginationResponse } from '../dto/common.dto'
 import { CreateTeamBody, UpdateTeamBody, ListTeamQuery } from '../dto/team.dto'
 import { UserService } from './user.service'
@@ -10,11 +11,13 @@ import * as randomstring from 'randomstring'
 
 export class TeamService {
   private teamRepository: Repository<Team>
+  private incomeRecordsRepository: Repository<IncomeRecords>
   private userService: UserService
   private sysConfigService: SysConfigService
 
   constructor(app: FastifyInstance) {
     this.teamRepository = app.dataSource.getRepository(Team)
+    this.incomeRecordsRepository = app.dataSource.getRepository(IncomeRecords)
     this.userService = new UserService(app)
     this.sysConfigService = new SysConfigService(app)
   }
@@ -122,10 +125,61 @@ export class TeamService {
     averageCommissionRate: number
     allTeams: Array<{ id: number; name: string; totalRevenue: number; todayRevenue: number }>
   }> {
+    // 获取所有团队信息
     const teams = await this.teamRepository.find({
-      select: ['id', 'name', 'totalRevenue', 'todayRevenue', 'commissionRate']
+      select: ['id', 'name', 'userId', 'commissionRate']
     })
 
+    // 获取今天的开始时间
+    const today = new Date()
+    today.setHours(0, 0, 0, 0)
+    const todayEnd = new Date()
+    todayEnd.setHours(23, 59, 59, 999)
+
+    // 获取所有团队的 userId 列表
+    const teamUserIds = teams.map(team => team.userId)
+
+    // 查询所有团队的总收入统计(通过 userId 关联)
+    const totalRevenueStats = teamUserIds.length > 0 ? await this.incomeRecordsRepository
+      .createQueryBuilder('record')
+      .select([
+        'record.agentId as userId',
+        'SUM(record.incomeAmount) as totalRevenue'
+      ])
+      .where('record.delFlag = :delFlag', { delFlag: false })
+      .andWhere('record.status = :status', { status: true })
+      .andWhere('record.agentId IN (:...teamUserIds)', { teamUserIds })
+      .groupBy('record.agentId')
+      .getRawMany() : []
+
+    // 查询所有团队的今日收入统计(通过 userId 关联)
+    const todayRevenueStats = teamUserIds.length > 0 ? await this.incomeRecordsRepository
+      .createQueryBuilder('record')
+      .select([
+        'record.agentId as userId',
+        'SUM(record.incomeAmount) as todayRevenue'
+      ])
+      .where('record.delFlag = :delFlag', { delFlag: false })
+      .andWhere('record.status = :status', { status: true })
+      .andWhere('record.createdAt >= :today', { today })
+      .andWhere('record.createdAt <= :todayEnd', { todayEnd })
+      .andWhere('record.agentId IN (:...teamUserIds)', { teamUserIds })
+      .groupBy('record.agentId')
+      .getRawMany() : []
+
+    // 构建统计数据映射(使用 userId 作为键)
+    const totalRevenueMap = new Map<number, number>()
+    const todayRevenueMap = new Map<number, number>()
+
+    totalRevenueStats.forEach(stat => {
+      totalRevenueMap.set(stat.userId, Number(stat.totalRevenue) || 0)
+    })
+
+    todayRevenueStats.forEach(stat => {
+      todayRevenueMap.set(stat.userId, Number(stat.todayRevenue) || 0)
+    })
+
+    // 计算统计数据
     const statistics = {
       totalTeams: teams.length,
       totalRevenue: 0,
@@ -136,22 +190,28 @@ export class TeamService {
 
     let totalCommissionRate = 0
 
+    // 构建团队列表并计算总计(使用 team.userId 进行映射)
     teams.forEach(team => {
-      statistics.totalRevenue += Number(team.totalRevenue)
-      statistics.todayRevenue += Number(team.todayRevenue)
-      totalCommissionRate += Number(team.commissionRate)
-    })
+      const teamTotalRevenue = totalRevenueMap.get(team.userId) || 0
+      const teamTodayRevenue = todayRevenueMap.get(team.userId) || 0
 
-    statistics.averageCommissionRate = teams.length > 0 ? totalCommissionRate / teams.length : 0
 
-    statistics.allTeams = teams
-      .sort((a, b) => Number(b.totalRevenue) - Number(a.totalRevenue))
-      .map(team => ({
+      statistics.totalRevenue += teamTotalRevenue
+      statistics.todayRevenue += teamTodayRevenue
+      totalCommissionRate += Number(team.commissionRate)
+
+      statistics.allTeams.push({
         id: team.id,
         name: team.name,
-        totalRevenue: Number(team.totalRevenue),
-        todayRevenue: Number(team.todayRevenue)
-      }))
+        totalRevenue: Number(teamTotalRevenue.toFixed(5)),
+        todayRevenue: Number(teamTodayRevenue.toFixed(5))
+      })
+    })
+
+    statistics.averageCommissionRate = teams.length > 0 ? Number((totalCommissionRate / teams.length).toFixed(2)) : 0
+
+    // 按总收入排序
+    statistics.allTeams.sort((a, b) => b.totalRevenue - a.totalRevenue)
 
     return statistics
   }