瀏覽代碼

增加域名绑定队员获取分润功能

wilhelm wong 2 月之前
父節點
當前提交
9575c8c87a

+ 97 - 3
src/controllers/team-members.controller.ts

@@ -5,7 +5,9 @@ import {
   UpdateTeamMembersBody,
   ListTeamMembersQuery,
   TeamMembersParams,
-  UpdateRevenueBody
+  UpdateRevenueBody,
+  TeamMemberStatsQuery,
+  TeamMemberStatsResponse
 } from '../dto/team-members.dto'
 import { UserRole } from '../entities/user.entity'
 import { TeamService } from '../services/team.service'
@@ -33,7 +35,24 @@ export class TeamMembersController {
       const teamMember = await this.teamMembersService.create(request.body, request.user.id)
       return reply.code(201).send(teamMember)
     } catch (error) {
-      return reply.code(500).send({ message: '创建团队成员失败' })
+      console.error('创建团队成员失败:', error)
+      const errorMessage = error instanceof Error ? error.message : '未知错误'
+      // 检查是否是验证错误
+      if (errorMessage && (
+        errorMessage.includes('个人分成比例') || 
+        errorMessage.includes('团队分成比例') ||
+        errorMessage.includes('团队不存在') ||
+        errorMessage.includes('已有成员设置了')
+      )) {
+        return reply.code(400).send({ 
+          message: errorMessage,
+          error: 'VALIDATION_ERROR'
+        })
+      }
+      return reply.code(500).send({ 
+        message: '创建团队成员失败',
+        error: errorMessage
+      })
     }
   }
 
@@ -72,16 +91,44 @@ export class TeamMembersController {
       const { id } = request.params
       const updateData = { ...request.body, id }
 
+      // 验证团队成员是否存在
       try {
         await this.teamMembersService.findById(id)
       } catch (error) {
         return reply.code(404).send({ message: '团队成员不存在' })
       }
 
+      // 权限检查:团队管理员只能更新自己团队的成员
+      const user = request.user
+      if (user && user.role === UserRole.TEAM) {
+        const teamMember = await this.teamMembersService.findById(id)
+        const team = await this.teamService.findByUserId(user.id)
+        if (teamMember.teamId !== team.id) {
+          return reply.code(403).send({ message: '无权限更新其他团队的成员' })
+        }
+      }
+
       const updatedMember = await this.teamMembersService.update(updateData)
       return reply.send(updatedMember)
     } catch (error) {
-      return reply.code(500).send({ message: '更新团队成员失败' })
+      console.error('更新团队成员失败:', error)
+      const errorMessage = error instanceof Error ? error.message : '未知错误'
+      // 检查是否是验证错误
+      if (errorMessage && (
+        errorMessage.includes('个人分成比例') || 
+        errorMessage.includes('团队分成比例') ||
+        errorMessage.includes('团队不存在') ||
+        errorMessage.includes('已有成员设置了')
+      )) {
+        return reply.code(400).send({ 
+          message: errorMessage,
+          error: 'VALIDATION_ERROR'
+        })
+      }
+      return reply.code(500).send({ 
+        message: '更新团队成员失败', 
+        error: errorMessage
+      })
     }
   }
 
@@ -136,4 +183,51 @@ export class TeamMembersController {
       return reply.code(500).send({ message: '获取统计数据失败' })
     }
   }
+
+  /**
+   * 获取团队成员统计信息(根据域名绑定情况)
+   */
+  async getTeamMemberStats(request: FastifyRequest<{ Querystring: TeamMemberStatsQuery }>, reply: FastifyReply) {
+    try {
+      const user = request.user
+      if (!user) {
+        return reply.code(403).send({ message: '用户未登录' })
+      }
+
+      const { teamMemberId, startDate, endDate, domain } = request.query
+
+      if (!teamMemberId) {
+        return reply.code(400).send({ message: '团队成员ID不能为空' })
+      }
+
+      // 权限检查:只有团队成员本人、团队管理员或系统管理员可以查看统计
+      if (user.role === UserRole.PROMOTER) {
+        // 推广员只能查看自己的统计
+        const teamMember = await this.teamMembersService.findByUserId(user.id)
+        if (teamMember.id !== teamMemberId) {
+          return reply.code(403).send({ message: '无权限查看其他团队成员的统计信息' })
+        }
+      } else if (user.role === UserRole.TEAM) {
+        // 团队管理员可以查看自己团队成员的统计
+        const teamMember = await this.teamMembersService.findById(teamMemberId)
+        const team = await this.teamService.findByUserId(user.id)
+        if (teamMember.teamId !== team.id) {
+          return reply.code(403).send({ message: '无权限查看其他团队的成员统计信息' })
+        }
+      } else if (user.role !== UserRole.ADMIN) {
+        return reply.code(403).send({ message: '无权限查看统计信息' })
+      }
+
+      const stats = await this.teamMembersService.getTeamMemberStats({
+        teamMemberId,
+        startDate,
+        endDate,
+        domain
+      })
+
+      return reply.send(stats)
+    } catch (error) {
+      return reply.code(500).send({ message: '获取团队成员统计信息失败' })
+    }
+  }
 }

+ 4 - 0
src/dto/income-records.dto.ts

@@ -4,6 +4,8 @@ import { Pagination } from './common.dto'
 export interface CreateIncomeRecordBody {
   agentId: number
   userId: number
+  personalAgentId?: number
+  personalIncomeAmount?: number
   incomeAmount: number
   incomeType: IncomeType
   orderType: OrderType
@@ -18,6 +20,8 @@ export interface CreateIncomeRecordBody {
 export interface UpdateIncomeRecordBody {
   id: number
   agentId?: number
+  personalAgentId?: number
+  personalIncomeAmount?: number
   incomeAmount?: number
   incomeType?: IncomeType
   orderType?: OrderType

+ 2 - 0
src/dto/team-domain.dto.ts

@@ -3,6 +3,7 @@ import { Pagination } from './common.dto'
 
 export interface CreateTeamDomainBody {
   teamId: number
+  teamMemberId?: number // 可选的团队成员ID,如果指定则绑定到个人
   domain: string // 支持单个域名或批量域名(用逗号或换行分隔)
   description: string
 }
@@ -10,6 +11,7 @@ export interface CreateTeamDomainBody {
 export interface UpdateTeamDomainBody {
   id: number
   teamId?: number
+  teamMemberId?: number // 可选的团队成员ID,如果指定则绑定到个人
   domain?: string
   description?: string
 }

+ 27 - 0
src/dto/team-members.dto.ts

@@ -8,6 +8,7 @@ export interface CreateTeamMembersBody {
   password?: string
   totalRevenue?: number
   todayRevenue?: number
+  commissionRate?: number // 分成比例
 }
 
 export interface UpdateTeamMembersBody {
@@ -17,6 +18,7 @@ export interface UpdateTeamMembersBody {
   userId?: number
   totalRevenue?: number
   todayRevenue?: number
+  commissionRate?: number // 分成比例
 }
 
 export interface ListTeamMembersQuery extends Pagination {
@@ -34,3 +36,28 @@ export interface UpdateRevenueBody {
   amount: number
   type: 'total' | 'today'
 }
+
+export interface TeamMemberStatsQuery {
+  teamMemberId: number
+  startDate?: string
+  endDate?: string
+  domain?: string
+}
+
+export interface TeamMemberStatsResponse {
+  teamMemberId: number
+  teamMemberName: string
+  totalCommission: number
+  totalOrders: number
+  todayCommission: number
+  todayOrders: number
+  domains: {
+    domain: string
+    commission: number
+    orders: number
+  }[]
+  dateRange: {
+    startDate: string
+    endDate: string
+  }
+}

+ 6 - 0
src/entities/income-records.entity.ts

@@ -31,6 +31,12 @@ export class IncomeRecords {
   @Column({ nullable: true, default: 0 })
   userId: number
 
+  @Column({ nullable: true, default: 0 })
+  personalAgentId: number
+
+  @Column({ type: 'decimal', precision: 10, scale: 5, default: 0 })
+  personalIncomeAmount: number
+
   @Column({
     type: 'decimal',
     precision: 10,

+ 1 - 1
src/entities/member.entity.ts

@@ -31,7 +31,7 @@ export class Member {
   @Column()
   userId: number
 
-  @Column({ nullable: true, default: 1 })
+  @Column({ nullable: true, default: 0 })
   teamId: number
 
   @Column({ nullable: true, default: 0 })

+ 3 - 0
src/entities/team-domain.entity.ts

@@ -8,6 +8,9 @@ export class TeamDomain {
   @Column()
   teamId: number
 
+  @Column({ nullable: true })
+  teamMemberId: number
+
   @Column({ length: 100 })
   domain: string
 

+ 3 - 0
src/entities/team-members.entity.ts

@@ -20,6 +20,9 @@ export class TeamMembers {
   @Column()
   userId: number
 
+  @Column({ type: 'decimal', precision: 5, scale: 2, default: 0 })
+  commissionRate: number
+
   @CreateDateColumn()
   createdAt: Date
 

+ 10 - 2
src/routes/team-members.routes.ts

@@ -7,7 +7,8 @@ import {
   UpdateTeamMembersBody,
   ListTeamMembersQuery,
   TeamMembersParams,
-  UpdateRevenueBody
+  UpdateRevenueBody,
+  TeamMemberStatsQuery
 } from '../dto/team-members.dto'
 
 export default async function teamMembersRoutes(fastify: FastifyInstance) {
@@ -37,7 +38,7 @@ export default async function teamMembersRoutes(fastify: FastifyInstance) {
   // 更新团队成员
   fastify.put<{ Params: TeamMembersParams; Body: UpdateTeamMembersBody }>(
     '/:id',
-    { onRequest: [authenticate, hasRole(UserRole.ADMIN)] },
+    { onRequest: [authenticate, hasAnyRole(UserRole.ADMIN, UserRole.TEAM)] },
     teamMembersController.update.bind(teamMembersController)
   )
 
@@ -68,4 +69,11 @@ export default async function teamMembersRoutes(fastify: FastifyInstance) {
     { onRequest: [authenticate, hasRole(UserRole.ADMIN)] },
     teamMembersController.getStatistics.bind(teamMembersController)
   )
+
+  // 获取团队成员统计信息(根据域名绑定情况)
+  fastify.get<{ Querystring: TeamMemberStatsQuery }>(
+    '/statistics/member',
+    { onRequest: [authenticate, hasAnyRole(UserRole.ADMIN, UserRole.TEAM, UserRole.PROMOTER)] },
+    teamMembersController.getTeamMemberStats.bind(teamMembersController)
+  )
 }

+ 2 - 0
src/services/income-records.service.ts

@@ -18,6 +18,8 @@ export class IncomeRecordsService {
     const incomeRecord = this.incomeRecordsRepository.create({
       agentId: data.agentId,
       userId: data.userId,
+      personalAgentId: data.personalAgentId || 0,
+      personalIncomeAmount: data.personalIncomeAmount || 0,
       incomeAmount: data.incomeAmount,
       incomeType: data.incomeType,
       orderType: data.orderType,

+ 6 - 3
src/services/member.service.ts

@@ -48,7 +48,7 @@ export class MemberService {
       let teamId = 0
       let domainId = 0
 
-      if (code) {
+      if (code && code.trim() !== '') {
         // 使用 code 查找团队
         const team = await manager.findOne(Team, { where: { affCode: code } })
         if (team) {
@@ -358,9 +358,12 @@ export class MemberService {
       }
 
       // 获取推荐团队
-      const team = await manager.findOne(Team, { where: { affCode: code } })
+      let team = null
+      if (code && code.trim() !== '') {
+        team = await manager.findOne(Team, { where: { affCode: code } })
+      }
       const parentId = team ? team.userId : 1
-      const teamId = team ? team.id : 1
+      const teamId = team ? team.id : 0
       const domainId = 0
 
       // 创建用户

+ 315 - 35
src/services/payment.service.ts

@@ -13,6 +13,8 @@ import {
   SingleListResponse
 } from '../dto/payment.dto'
 import axios from 'axios'
+import { TeamDomainService } from './team-domain.service'
+import { TeamMembersService } from './team-members.service'
 import crypto from 'crypto'
 import { randomInt } from 'crypto'
 import Decimal from 'decimal.js'
@@ -35,6 +37,8 @@ export class PaymentService {
   private userService: UserService
   private teamService: TeamService
   private sysConfigService: SysConfigService
+  private teamDomainService: TeamDomainService
+  private teamMembersService: TeamMembersService
 
   private static readonly ORDER_TYPE_TO_VIP_LEVEL_MAP: Record<OrderType, VipLevel> = {
     [OrderType.SINGLE_TIP]: VipLevel.FREE,
@@ -68,6 +72,8 @@ export class PaymentService {
     this.userService = new UserService(app)
     this.teamService = new TeamService(app)
     this.sysConfigService = new SysConfigService(app)
+    this.teamDomainService = new TeamDomainService(app)
+    this.teamMembersService = new TeamMembersService(app)
   }
 
   private generateSign(params: Record<string, any>, key: string): string {
@@ -82,6 +88,189 @@ export class PaymentService {
     return crypto.createHash('md5').update(strToSign, 'utf8').digest('hex')
   }
 
+  /**
+   * 根据member的domainId查找对应的域名绑定,确定分成对象和比例
+   * 支持团队和个人同时分润
+   */
+  private async getCommissionInfo(member: any): Promise<{
+    teamAgentId: number
+    teamCommissionRate: number
+    personalAgentId: number
+    personalCommissionRate: number
+    isPersonalCommission: boolean
+  }> {
+    try {
+      // 如果用户绑定teamId为0,无团队,直接返回无分成
+      if (!member.teamId || member.teamId === 0) {
+        return {
+          teamAgentId: 0,
+          teamCommissionRate: 0,
+          personalAgentId: 0,
+          personalCommissionRate: 0,
+          isPersonalCommission: false
+        }
+      }
+
+      // 如果domainId为0,说明是默认入口,直接走默认分成逻辑
+      if (!member.domainId || member.domainId === 0) {
+        return await this.getDefaultCommission(member)
+      }
+
+      // 根据domainId查找域名绑定信息
+      const teamDomain = await this.teamDomainService.findById(member.domainId)
+      if (!teamDomain) {
+        // 域名绑定不存在,回退到默认分成
+        this.app.log.warn(`Domain binding not found for domainId: ${member.domainId}, using default commission`)
+        return await this.getDefaultCommission(member)
+      }
+
+      // 获取团队分成信息
+      const teamCommission = await this.getTeamCommissionFromDomain(teamDomain, member)
+      
+      // 如果teamDomain绑定teamMemberId为null,无绑定队员,只给团队分成
+      if (!teamDomain.teamMemberId) {
+        return {
+          teamAgentId: teamCommission.agentId,
+          teamCommissionRate: teamCommission.commissionRate,
+          personalAgentId: 0,
+          personalCommissionRate: 0,
+          isPersonalCommission: false
+        }
+      }
+
+      // 如果域名绑定到个人,检查个人分成
+      try {
+        const teamMember = await this.teamMembersService.findById(teamDomain.teamMemberId)
+        if (teamMember?.commissionRate > 0) {
+          // 团队和个人同时分润
+          // 团队分成保持原比例,个人分成从团队分成中扣除
+          return {
+            teamAgentId: teamCommission.agentId,
+            teamCommissionRate: teamCommission.commissionRate, // 团队总分成比例
+            personalAgentId: teamMember.userId,
+            personalCommissionRate: teamMember.commissionRate, // 个人分成比例
+            isPersonalCommission: true
+          }
+        }
+      } catch (memberError) {
+        this.app.log.warn(`Failed to find team member ${teamDomain.teamMemberId}:`, memberError)
+      }
+
+      // 个人分成配置失败,只给团队分成
+      return {
+        teamAgentId: teamCommission.agentId,
+        teamCommissionRate: teamCommission.commissionRate,
+        personalAgentId: 0,
+        personalCommissionRate: 0,
+        isPersonalCommission: false
+      }
+
+    } catch (error) {
+      this.app.log.warn('Failed to get commission info for member:', member.id, error)
+      // 最终回退到默认分成逻辑
+      return await this.getDefaultCommission(member)
+    }
+  }
+
+  /**
+   * 获取默认分成信息(domainId为0时的逻辑)
+   */
+  private async getDefaultCommission(member: any): Promise<{
+    teamAgentId: number
+    teamCommissionRate: number
+    personalAgentId: number
+    personalCommissionRate: number
+    isPersonalCommission: boolean
+  }> {
+    const teamCommission = await this.getTeamCommission(member)
+    return {
+      teamAgentId: teamCommission.agentId,
+      teamCommissionRate: teamCommission.commissionRate,
+      personalAgentId: 0,
+      personalCommissionRate: 0,
+      isPersonalCommission: false
+    }
+  }
+
+  /**
+   * 获取团队分成信息(原有逻辑)
+   */
+  private async getTeamCommission(member: any): Promise<{
+    agentId: number
+    commissionRate: number
+    isPersonalCommission: boolean
+  }> {
+    try {
+      if (member.teamId && member.teamId > 0) {
+        const team = await this.teamService.findById(member.teamId)
+        if (team && team.commissionRate && team.commissionRate > 0) {
+          return {
+            agentId: team.userId,
+            commissionRate: team.commissionRate,
+            isPersonalCommission: false
+          }
+        }
+      }
+      return { agentId: 0, commissionRate: 0, isPersonalCommission: false }
+    } catch (error) {
+      this.app.log.warn('Failed to get team commission:', error)
+      return { agentId: 0, commissionRate: 0, isPersonalCommission: false }
+    }
+  }
+
+  /**
+   * 从域名绑定的团队获取分成信息
+   */
+  private async getTeamCommissionFromDomain(teamDomain: any, member: any): Promise<{
+    agentId: number
+    commissionRate: number
+    isPersonalCommission: boolean
+  }> {
+    try {
+      if (teamDomain.teamId) {
+        const team = await this.teamService.findById(teamDomain.teamId)
+        if (team && team.commissionRate && team.commissionRate > 0) {
+          return {
+            agentId: team.userId,
+            commissionRate: team.commissionRate,
+            isPersonalCommission: false
+          }
+        }
+      }
+      // 如果域名绑定的团队也没有分成比例,回退到member的团队
+      return await this.getTeamCommission(member)
+    } catch (error) {
+      this.app.log.warn('Failed to get team commission from domain:', error)
+      return await this.getTeamCommission(member)
+    }
+  }
+
+  /**
+   * 回退到原有的团队分成逻辑(基于user.parentId)
+   */
+  private async getFallbackCommission(user: any): Promise<{
+    agentId: number
+    commissionRate: number
+    isPersonalCommission: boolean
+  }> {
+    try {
+      if (user.parentId && user.parentId > 0) {
+        const team = await this.teamService.findByUserId(user.parentId)
+        if (team && team.commissionRate && team.commissionRate > 0) {
+          return {
+            agentId: user.parentId,
+            commissionRate: team.commissionRate,
+            isPersonalCommission: false
+          }
+        }
+      }
+      return { agentId: 0, commissionRate: 0, isPersonalCommission: false }
+    } catch (error) {
+      this.app.log.warn('Failed to get fallback commission:', error)
+      return { agentId: 0, commissionRate: 0, isPersonalCommission: false }
+    }
+  }
+
   private verifyNotifySign(params: PaymentNotifyParams): boolean {
     const { sign: receivedSign, ...rest } = params
     const calculatedSign = this.generateSign(rest, this.key)
@@ -185,30 +374,75 @@ export class PaymentService {
 
       // 创建收入记录
       try {
-        // 计算佣金
-        let agentId = user.parentId
-        let incomeAmount = new Decimal(price)
-
-        if (user.parentId && user.parentId > 0) {
-          try {
-            const team = await this.teamService.findByUserId(user.parentId)
-            if (team && team.commissionRate && team.commissionRate > 0) {
-              const commissionRate = new Decimal(team.commissionRate)
-              const hundred = new Decimal(100)
-              incomeAmount = new Decimal(price).mul(commissionRate).div(hundred)
+        // 获取member信息,如果失败则使用原有逻辑
+        let commissionInfo = { 
+          teamAgentId: 0, 
+          teamCommissionRate: 0, 
+          personalAgentId: 0, 
+          personalCommissionRate: 0, 
+          isPersonalCommission: false 
+        }
+        
+        try {
+          const member = await this.memberService.findByUserId(user.id)
+          if (member) {
+            // 使用新的分成逻辑
+            commissionInfo = await this.getCommissionInfo(member)
+          } else {
+            // 如果没有member信息,回退到原有的团队分成逻辑
+            this.app.log.warn(`Member not found for user ${user.id}, using fallback commission logic`)
+            const fallbackCommission = await this.getFallbackCommission(user)
+            commissionInfo = {
+              teamAgentId: fallbackCommission.agentId,
+              teamCommissionRate: fallbackCommission.commissionRate,
+              personalAgentId: 0,
+              personalCommissionRate: 0,
+              isPersonalCommission: false
             }
-          } catch (teamError) {
-            this.app.log.warn('Failed to find team for user:', user.parentId, teamError)
-            agentId = 0
           }
-        } else {
-          agentId = 0
+        } catch (memberError) {
+          // 获取member信息失败,使用原有逻辑
+          this.app.log.warn(`Failed to get member info for user ${user.id}, using fallback commission logic:`, memberError)
+          const fallbackCommission = await this.getFallbackCommission(user)
+          commissionInfo = {
+            teamAgentId: fallbackCommission.agentId,
+            teamCommissionRate: fallbackCommission.commissionRate,
+            personalAgentId: 0,
+            personalCommissionRate: 0,
+            isPersonalCommission: false
+          }
+        }
+
+        // 计算个人分成金额
+        let personalIncomeAmount = new Decimal(0)
+        if (commissionInfo.personalAgentId > 0 && commissionInfo.personalCommissionRate > 0) {
+          const commissionRate = new Decimal(commissionInfo.personalCommissionRate)
+          const hundred = new Decimal(100)
+          personalIncomeAmount = new Decimal(price).mul(commissionRate).div(hundred)
+        }
+
+        // 计算团队分成金额
+        let teamIncomeAmount = new Decimal(0)
+        if (commissionInfo.teamAgentId > 0 && commissionInfo.teamCommissionRate > 0) {
+          const commissionRate = new Decimal(commissionInfo.teamCommissionRate)
+          const hundred = new Decimal(100)
+          const totalTeamIncome = new Decimal(price).mul(commissionRate).div(hundred)
+          
+          // 如果有个人分成,团队实际分到的金额 = 团队总分成 - 个人分成
+          if (commissionInfo.isPersonalCommission && personalIncomeAmount.greaterThan(0)) {
+            teamIncomeAmount = totalTeamIncome.sub(personalIncomeAmount)
+          } else {
+            teamIncomeAmount = totalTeamIncome
+          }
         }
 
+        // 创建收入记录,包含团队和个人分成信息
         await this.incomeRecordsService.create({
-          agentId,
+          agentId: commissionInfo.teamAgentId,
           userId: user.id,
-          incomeAmount: incomeAmount.toNumber(),
+          personalAgentId: commissionInfo.personalAgentId,
+          personalIncomeAmount: personalIncomeAmount.toNumber(),
+          incomeAmount: teamIncomeAmount.toNumber(),
           incomeType: IncomeType.COMMISSION,
           orderType: this.getOrderTypeByType(params.type),
           orderPrice: new Decimal(price).toNumber(),
@@ -268,29 +502,75 @@ export class PaymentService {
 
       // 创建收入记录
       try {
-        // 计算佣金
-        let agentId = user.parentId
-        let incomeAmount = new Decimal(price)
-        if (user.parentId && user.parentId > 0) {
-          try {
-            const team = await this.teamService.findByUserId(user.parentId)
-            if (team && team.commissionRate && team.commissionRate > 0) {
-              const commissionRate = new Decimal(team.commissionRate)
-              const hundred = new Decimal(100)
-              incomeAmount = new Decimal(price).mul(commissionRate).div(hundred)
+        // 获取member信息,如果失败则使用原有逻辑
+        let commissionInfo = { 
+          teamAgentId: 0, 
+          teamCommissionRate: 0, 
+          personalAgentId: 0, 
+          personalCommissionRate: 0, 
+          isPersonalCommission: false 
+        }
+        
+        try {
+          const member = await this.memberService.findByUserId(user.id)
+          if (member) {
+            // 使用新的分成逻辑
+            commissionInfo = await this.getCommissionInfo(member)
+          } else {
+            // 如果没有member信息,回退到原有的团队分成逻辑
+            this.app.log.warn(`Member not found for user ${user.id}, using fallback commission logic`)
+            const fallbackCommission = await this.getFallbackCommission(user)
+            commissionInfo = {
+              teamAgentId: fallbackCommission.agentId,
+              teamCommissionRate: fallbackCommission.commissionRate,
+              personalAgentId: 0,
+              personalCommissionRate: 0,
+              isPersonalCommission: false
             }
-          } catch (teamError) {
-            this.app.log.warn('Failed to find team for user:', user.parentId, teamError)
-            agentId = 0
           }
-        } else {
-          agentId = 0
+        } catch (memberError) {
+          // 获取member信息失败,使用原有逻辑
+          this.app.log.warn(`Failed to get member info for user ${user.id}, using fallback commission logic:`, memberError)
+          const fallbackCommission = await this.getFallbackCommission(user)
+          commissionInfo = {
+            teamAgentId: fallbackCommission.agentId,
+            teamCommissionRate: fallbackCommission.commissionRate,
+            personalAgentId: 0,
+            personalCommissionRate: 0,
+            isPersonalCommission: false
+          }
+        }
+
+        // 计算个人分成金额
+        let personalIncomeAmount = new Decimal(0)
+        if (commissionInfo.personalAgentId > 0 && commissionInfo.personalCommissionRate > 0) {
+          const commissionRate = new Decimal(commissionInfo.personalCommissionRate)
+          const hundred = new Decimal(100)
+          personalIncomeAmount = new Decimal(price).mul(commissionRate).div(hundred)
+        }
+
+        // 计算团队分成金额
+        let teamIncomeAmount = new Decimal(0)
+        if (commissionInfo.teamAgentId > 0 && commissionInfo.teamCommissionRate > 0) {
+          const commissionRate = new Decimal(commissionInfo.teamCommissionRate)
+          const hundred = new Decimal(100)
+          const totalTeamIncome = new Decimal(price).mul(commissionRate).div(hundred)
+          
+          // 如果有个人分成,团队实际分到的金额 = 团队总分成 - 个人分成
+          if (commissionInfo.isPersonalCommission && personalIncomeAmount.greaterThan(0)) {
+            teamIncomeAmount = totalTeamIncome.sub(personalIncomeAmount)
+          } else {
+            teamIncomeAmount = totalTeamIncome
+          }
         }
 
+        // 创建收入记录,包含团队和个人分成信息
         await this.incomeRecordsService.create({
-          agentId,
+          agentId: commissionInfo.teamAgentId,
           userId: user.id,
-          incomeAmount: incomeAmount.toNumber(),
+          personalAgentId: commissionInfo.personalAgentId,
+          personalIncomeAmount: personalIncomeAmount.toNumber(),
+          incomeAmount: teamIncomeAmount.toNumber(),
           incomeType: IncomeType.TIP,
           orderType: OrderType.SINGLE_TIP,
           orderPrice: new Decimal(price).toNumber(),

+ 49 - 11
src/services/team-domain.service.ts

@@ -1,11 +1,11 @@
 import { Repository, Like, Between } from 'typeorm'
 import { FastifyInstance } from 'fastify'
 import { TeamDomain } from '../entities/team-domain.entity'
+import { TeamMembers } from '../entities/team-members.entity'
 import { PaginationResponse } from '../dto/common.dto'
 import { CreateTeamDomainBody, UpdateTeamDomainBody, ListTeamDomainQuery } from '../dto/team-domain.dto'
 import { UserService } from './user.service'
 import { TeamService } from './team.service'
-import { TeamMembersService } from './team-members.service'
 import { Member } from '../entities/member.entity'
 import { IncomeRecords } from '../entities/income-records.entity'
 
@@ -15,19 +15,27 @@ export class TeamDomainService {
   private incomeRecordsRepository: Repository<IncomeRecords>
   private userService: UserService
   private teamService: TeamService
-  private teamMembersService: TeamMembersService
+  private teamMembersRepository: Repository<TeamMembers>
   constructor(app: FastifyInstance) {
     this.teamDomainRepository = app.dataSource.getRepository(TeamDomain)
     this.memberRepository = app.dataSource.getRepository(Member)
     this.incomeRecordsRepository = app.dataSource.getRepository(IncomeRecords)
     this.userService = new UserService(app)
     this.teamService = new TeamService(app)
-    this.teamMembersService = new TeamMembersService(app)
+    this.teamMembersRepository = app.dataSource.getRepository(TeamMembers)
   }
 
   async create(data: CreateTeamDomainBody): Promise<TeamDomain> {
     await this.teamService.findById(data.teamId)
 
+    // 如果指定了团队成员ID,验证团队成员是否存在且属于该团队
+    if (data.teamMemberId) {
+      const teamMember = await this.teamMembersRepository.findOne({ where: { id: data.teamMemberId } })
+      if (!teamMember || teamMember.teamId !== data.teamId) {
+        throw new Error('团队成员不存在或不属于该团队')
+      }
+    }
+
     const existingDomain = await this.teamDomainRepository.findOne({
       where: { domain: data.domain }
     })
@@ -44,6 +52,14 @@ export class TeamDomainService {
   ): Promise<{ success: TeamDomain[]; failed: { domain: string; error: string }[] }> {
     await this.teamService.findById(data.teamId)
 
+    // 如果指定了团队成员ID,验证团队成员是否存在且属于该团队
+    if (data.teamMemberId) {
+      const teamMember = await this.teamMembersRepository.findOne({ where: { id: data.teamMemberId } })
+      if (!teamMember || teamMember.teamId !== data.teamId) {
+        throw new Error('团队成员不存在或不属于该团队')
+      }
+    }
+
     // 解析域名字符串,支持逗号和换行分隔
     const domains = this.parseDomains(data.domain)
 
@@ -67,6 +83,7 @@ export class TeamDomainService {
       const teamDomains = domainsToCreate.map(domain =>
         this.teamDomainRepository.create({
           teamId: data.teamId,
+          teamMemberId: data.teamMemberId,
           domain: domain.trim(),
           description: data.description
         })
@@ -168,6 +185,27 @@ export class TeamDomainService {
     })
   }
 
+  async findByTeamMemberId(teamMemberUserId: number): Promise<TeamDomain[]> {
+    // 首先通过teamMemberId查找绑定的域名
+    const domainsByMember = await this.teamDomainRepository.find({
+      where: { teamMemberId: teamMemberUserId },
+      order: { createdAt: 'DESC' }
+    })
+
+    // 如果直接绑定到个人,返回这些域名
+    if (domainsByMember.length > 0) {
+      return domainsByMember
+    }
+
+    // 如果没有直接绑定,查找该团队成员所属团队的域名
+    const teamMember = await this.teamMembersRepository.findOne({ where: { userId: teamMemberUserId } })
+    if (teamMember && teamMember.teamId) {
+      return await this.findByTeamId(teamMember.teamId)
+    }
+
+    return []
+  }
+
   async findAllGroupedByTeam(query?: ListTeamDomainQuery): Promise<Record<number, TeamDomain[]>> {
     const { id, teamId, domain } = query || {}
 
@@ -239,11 +277,11 @@ export class TeamDomainService {
         }
       })
 
-      // 统计今日收入
+      // 统计今日收入(包括团队分成和个人分成)
       const todayIncomeRecords = await this.incomeRecordsRepository
         .createQueryBuilder('record')
         .innerJoin('member', 'm', 'm.userId = record.userId')
-        .select('SUM(CAST(record.incomeAmount AS DECIMAL(10,5)))', 'totalIncome')
+        .select('SUM(CAST(record.incomeAmount + record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
         .where('m.domainId = :domainId', { domainId: teamDomain.id })
         .andWhere('record.createdAt >= :startDate', { startDate: today })
         .andWhere('record.createdAt < :endDate', { endDate: tomorrow })
@@ -253,11 +291,11 @@ export class TeamDomainService {
 
       const todayIncome = todayIncomeRecords?.totalIncome ? parseFloat(todayIncomeRecords.totalIncome) : 0
 
-      // 统计历史总收入
+      // 统计历史总收入(包括团队分成和个人分成)
       const totalIncomeRecords = await this.incomeRecordsRepository
         .createQueryBuilder('record')
         .innerJoin('member', 'm', 'm.userId = record.userId')
-        .select('SUM(CAST(record.incomeAmount AS DECIMAL(10,5)))', 'totalIncome')
+        .select('SUM(CAST(record.incomeAmount + record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
         .where('m.domainId = :domainId', { domainId: teamDomain.id })
         .andWhere('record.delFlag = :delFlag', { delFlag: false })
         .andWhere('record.status = :status', { status: true })
@@ -342,11 +380,11 @@ export class TeamDomainService {
         }
       })
 
-      // 统计总收入
+      // 统计总收入(包括团队分成和个人分成)
       const totalIncomeRecords = await this.incomeRecordsRepository
         .createQueryBuilder('record')
         .innerJoin('member', 'm', 'm.userId = record.userId')
-        .select('SUM(CAST(record.incomeAmount AS DECIMAL(10,5)))', 'totalIncome')
+        .select('SUM(CAST(record.incomeAmount + record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
         .where('m.domainId = :domainId', { domainId: teamDomain.id })
         .andWhere('record.delFlag = :delFlag', { delFlag: false })
         .andWhere('record.status = :status', { status: true })
@@ -354,11 +392,11 @@ export class TeamDomainService {
 
       const totalIncome = totalIncomeRecords?.totalIncome ? parseFloat(totalIncomeRecords.totalIncome) : 0
 
-      // 统计今日收入
+      // 统计今日收入(包括团队分成和个人分成)
       const todayIncomeRecords = await this.incomeRecordsRepository
         .createQueryBuilder('record')
         .innerJoin('member', 'm', 'm.userId = record.userId')
-        .select('SUM(CAST(record.incomeAmount AS DECIMAL(10,5)))', 'totalIncome')
+        .select('SUM(CAST(record.incomeAmount + record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
         .where('m.domainId = :domainId', { domainId: teamDomain.id })
         .andWhere('record.createdAt >= :startDate', { startDate: today })
         .andWhere('record.createdAt < :endDate', { endDate: tomorrow })

+ 286 - 2
src/services/team-members.service.ts

@@ -3,8 +3,10 @@ import { FastifyInstance } from 'fastify'
 import { TeamMembers } from '../entities/team-members.entity'
 import { IncomeRecords } from '../entities/income-records.entity'
 import { Member } from '../entities/member.entity'
+import { TeamDomain } from '../entities/team-domain.entity'
+import { Team } from '../entities/team.entity'
 import { PaginationResponse } from '../dto/common.dto'
-import { CreateTeamMembersBody, UpdateTeamMembersBody, ListTeamMembersQuery } from '../dto/team-members.dto'
+import { CreateTeamMembersBody, UpdateTeamMembersBody, ListTeamMembersQuery, TeamMemberStatsQuery, TeamMemberStatsResponse } from '../dto/team-members.dto'
 import { UserService } from './user.service'
 import { UserRole } from '../entities/user.entity'
 
@@ -13,17 +15,67 @@ export class TeamMembersService {
   private incomeRecordsRepository: Repository<IncomeRecords>
   private memberRepository: Repository<Member>
   private userService: UserService
+  private teamDomainRepository: Repository<TeamDomain>
+  private teamRepository: Repository<Team>
 
   constructor(app: FastifyInstance) {
     this.teamMembersRepository = app.dataSource.getRepository(TeamMembers)
     this.incomeRecordsRepository = app.dataSource.getRepository(IncomeRecords)
     this.memberRepository = app.dataSource.getRepository(Member)
     this.userService = new UserService(app)
+    this.teamDomainRepository = app.dataSource.getRepository(TeamDomain)
+    this.teamRepository = app.dataSource.getRepository(Team)
+  }
+
+  /**
+   * 验证团队成员分成比例是否合理
+   * @param teamId 团队ID
+   * @param commissionRate 个人分成比例
+   * @param excludeMemberId 排除的成员ID(用于更新时排除自己)
+   */
+  private async validateCommissionRate(teamId: number, commissionRate: number, excludeMemberId?: number): Promise<void> {
+    if (commissionRate <= 0) {
+      return // 0或负数不需要验证
+    }
+
+    // 获取团队的分成比例
+    const team = await this.teamRepository.findOne({ where: { id: teamId } })
+    if (!team) {
+      throw new Error('团队不存在')
+    }
+
+    const teamCommissionRate = Number(team.commissionRate)
+    if (teamCommissionRate <= 0) {
+      throw new Error('团队未设置分成比例,无法设置个人分成比例')
+    }
+
+    // 验证个人分成比例不能高于团队分成比例
+    if (commissionRate > teamCommissionRate) {
+      throw new Error(`个人分成比例(${commissionRate}%)不能高于团队分成比例(${teamCommissionRate}%)`)
+    }
+
+    // 检查是否已有其他成员设置了相同的分成比例
+    const existingMembers = await this.teamMembersRepository.find({
+      where: { 
+        teamId,
+        commissionRate: commissionRate
+      }
+    })
+
+    // 如果存在其他成员且不是当前更新的成员
+    if (existingMembers.length > 0 && (!excludeMemberId || !existingMembers.some(m => m.id === excludeMemberId))) {
+      throw new Error(`团队中已有成员设置了${commissionRate}%的分成比例,请选择其他比例`)
+    }
   }
 
   async create(data: CreateTeamMembersBody, creatorId: number): Promise<TeamMembers> {
     const { password, teamUserId, ...teamMemberData } = data
 
+    // 验证分成比例
+    if (teamMemberData.commissionRate !== undefined && teamMemberData.commissionRate > 0) {
+      await this.validateCommissionRate(teamMemberData.teamId, teamMemberData.commissionRate)
+    }
+
     const existingUser = await this.userService.findByName(teamMemberData.name)
     if (existingUser) {
         throw new Error('操作失败')
@@ -68,8 +120,58 @@ export class TeamMembersService {
       order: { createdAt: 'DESC' }
     })
 
+    // 为每个成员计算实际收入(从income_records表统计)
+    const membersWithRevenue = await Promise.all(
+      members.map(async (member) => {
+        // 统计总收入 - 只计算个人分成金额
+        const totalRevenueRecords = await this.incomeRecordsRepository
+          .createQueryBuilder('record')
+          .where('record.personalAgentId = :teamMemberUserId', { 
+            teamMemberUserId: member.userId 
+          })
+          .andWhere('record.delFlag = :delFlag', { delFlag: false })
+          .andWhere('record.status = :status', { status: true })
+          .andWhere('record.personalIncomeAmount > 0')
+          .getMany()
+
+        const totalRevenue = totalRevenueRecords.reduce((sum, record) => {
+          // 只统计个人分成金额
+          return sum + Number(record.personalIncomeAmount || 0)
+        }, 0)
+
+        // 统计今日收入 - 只计算个人分成金额
+        const today = new Date()
+        const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate())
+        const todayEnd = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59)
+
+        const todayRevenueRecords = await this.incomeRecordsRepository
+          .createQueryBuilder('record')
+          .where('record.personalAgentId = :teamMemberUserId', { 
+            teamMemberUserId: member.userId 
+          })
+          .andWhere('record.delFlag = :delFlag', { delFlag: false })
+          .andWhere('record.status = :status', { status: true })
+          .andWhere('record.personalIncomeAmount > 0')
+          .andWhere('record.createdAt >= :todayStart', { todayStart })
+          .andWhere('record.createdAt <= :todayEnd', { todayEnd })
+          .getMany()
+
+        const todayRevenue = todayRevenueRecords.reduce((sum, record) => {
+          // 只统计个人分成金额
+          return sum + Number(record.personalIncomeAmount || 0)
+        }, 0)
+
+        // 返回更新后的成员数据
+        return {
+          ...member,
+          totalRevenue: totalRevenue,
+          todayRevenue: todayRevenue
+        }
+      })
+    )
+
     return {
-      content: members,
+      content: membersWithRevenue,
       metadata: {
         total: Number(total),
         page: Number(page) || 0,
@@ -80,6 +182,14 @@ export class TeamMembersService {
 
   async update(data: UpdateTeamMembersBody): Promise<TeamMembers> {
     const { id, ...updateData } = data
+
+    // 验证分成比例
+    if (updateData.commissionRate !== undefined && updateData.commissionRate > 0) {
+      // 获取当前成员信息以获取teamId
+      const currentMember = await this.findById(id)
+      await this.validateCommissionRate(currentMember.teamId, updateData.commissionRate, id)
+    }
+
     await this.teamMembersRepository.update(id, updateData)
     return this.findById(id)
   }
@@ -285,4 +395,178 @@ export class TeamMembersService {
   async findByUserId(userId: number): Promise<TeamMembers> {
     return this.teamMembersRepository.findOneOrFail({ where: { userId } })
   }
+
+  /**
+   * 获取团队成员的统计信息(根据域名绑定情况)
+   */
+  async getTeamMemberStats(query: TeamMemberStatsQuery): Promise<TeamMemberStatsResponse> {
+    const { teamMemberId, startDate, endDate, domain } = query
+    
+    // 获取团队成员信息
+    const teamMember = await this.findById(teamMemberId)
+    
+    // 设置日期范围
+    const today = new Date()
+    const defaultStartDate = startDate || today.toISOString().split('T')[0]
+    const defaultEndDate = endDate || today.toISOString().split('T')[0]
+    
+    // 获取该团队成员绑定的域名
+    const teamDomains = await this.teamDomainRepository.find({
+      where: { teamMemberId: teamMember.id },
+      order: { createdAt: 'DESC' }
+    })
+
+    // 如果没有直接绑定,查询该团队成员所属团队的域名
+    let allTeamDomains = teamDomains
+    if (allTeamDomains.length === 0 && teamMember.teamId) {
+      allTeamDomains = await this.teamDomainRepository.find({
+        where: { teamId: teamMember.teamId },
+        order: { createdAt: 'DESC' }
+      })
+    }
+
+    // 构建基础查询条件 - 基于域名绑定查询分润记录
+    let baseQuery = this.incomeRecordsRepository
+      .createQueryBuilder('record')
+      .leftJoin('member', 'm', 'm.userId = record.userId')
+      .where('record.delFlag = :delFlag', { delFlag: false })
+      .andWhere('record.status = :status', { status: true })
+      .andWhere('record.incomeType = :incomeType', { incomeType: 'commission' })
+      .andWhere('record.personalAgentId = :teamMemberUserId', { teamMemberUserId: teamMember.userId })
+      .andWhere('record.personalIncomeAmount > 0')
+
+    // 如果有域名绑定,添加域名过滤
+    if (allTeamDomains.length > 0) {
+      const domainIds = allTeamDomains.map(d => d.id)
+      baseQuery = baseQuery.andWhere('m.domainId IN (:...domainIds)', { domainIds })
+    }
+
+    // 添加日期过滤
+    if (startDate) {
+      baseQuery = baseQuery.andWhere('DATE(record.createdAt) >= :startDate', { startDate })
+    }
+    if (endDate) {
+      baseQuery = baseQuery.andWhere('DATE(record.createdAt) <= :endDate', { endDate })
+    }
+
+    // 获取总收入记录
+    const totalRecords = await baseQuery.getMany()
+    
+    // 获取今日收入记录
+    const todayRecords = await baseQuery
+      .clone()
+      .andWhere('DATE(record.createdAt) = :today', { today: today.toISOString().split('T')[0] })
+      .getMany()
+
+    // 计算总收入 - 只统计个人分成金额
+    const totalCommission = totalRecords.reduce((sum, record) => {
+      // 只统计个人分成金额
+      return sum + Number(record.personalIncomeAmount || 0)
+    }, 0)
+    
+    const totalOrders = totalRecords.length
+    
+    // 计算今日收入 - 只统计个人分成金额
+    const todayCommission = todayRecords.reduce((sum, record) => {
+      // 只统计个人分成金额
+      return sum + Number(record.personalIncomeAmount || 0)
+    }, 0)
+    const todayOrders = todayRecords.length
+
+    // 获取域名统计(需要关联域名绑定信息)
+    const domainStats = await this.getDomainStats(teamMember.userId, startDate, endDate, domain)
+
+    return {
+      teamMemberId: teamMember.id,
+      teamMemberName: teamMember.name,
+      totalCommission,
+      totalOrders,
+      todayCommission,
+      todayOrders,
+      domains: domainStats,
+      dateRange: {
+        startDate: defaultStartDate,
+        endDate: defaultEndDate
+      }
+    }
+  }
+
+  /**
+   * 获取域名统计信息
+   */
+  private async getDomainStats(
+    teamMemberUserId: number, 
+    startDate?: string, 
+    endDate?: string, 
+    domainFilter?: string
+  ): Promise<{ domain: string; commission: number; orders: number }[]> {
+    // 直接查询该团队成员绑定的域名,避免循环依赖
+    const teamMember = await this.teamMembersRepository.findOne({ where: { userId: teamMemberUserId } })
+    if (!teamMember) {
+      return []
+    }
+
+    // 查询直接绑定到该团队成员的域名
+    let teamDomains = await this.teamDomainRepository.find({
+      where: { teamMemberId: teamMember.id },
+      order: { createdAt: 'DESC' }
+    })
+
+    // 如果没有直接绑定,查询该团队成员所属团队的域名
+    if (teamDomains.length === 0 && teamMember.teamId) {
+      teamDomains = await this.teamDomainRepository.find({
+        where: { teamId: teamMember.teamId },
+        order: { createdAt: 'DESC' }
+      })
+    }
+    
+    if (teamDomains.length === 0) {
+      return []
+    }
+
+    let domainStats: { domain: string; commission: number; orders: number }[] = []
+
+    for (const teamDomain of teamDomains) {
+      // 如果指定了域名过滤,只统计匹配的域名
+      if (domainFilter && !teamDomain.domain.includes(domainFilter)) {
+        continue
+      }
+
+      // 查询该域名下的收入记录,基于团队成员的角度
+      let domainQuery = this.incomeRecordsRepository
+        .createQueryBuilder('record')
+        .leftJoin('member', 'm', 'm.userId = record.userId')
+        .where('m.domainId = :domainId', { domainId: teamDomain.id })
+        .andWhere('record.delFlag = :delFlag', { delFlag: false })
+        .andWhere('record.status = :status', { status: true })
+        .andWhere('record.incomeType = :incomeType', { incomeType: 'commission' })
+        .andWhere('record.personalAgentId = :teamMemberUserId', { teamMemberUserId: teamMember.userId })
+        .andWhere('record.personalIncomeAmount > 0')
+
+      // 添加日期过滤
+      if (startDate) {
+        domainQuery = domainQuery.andWhere('DATE(record.createdAt) >= :startDate', { startDate })
+      }
+      if (endDate) {
+        domainQuery = domainQuery.andWhere('DATE(record.createdAt) <= :endDate', { endDate })
+      }
+
+      const domainRecords = await domainQuery.getMany()
+      
+      // 只统计个人分成金额
+      const commission = domainRecords.reduce((sum, record) => {
+        // 只统计个人分成金额
+        return sum + Number(record.personalIncomeAmount || 0)
+      }, 0)
+      const orders = domainRecords.length
+
+      domainStats.push({
+        domain: teamDomain.domain,
+        commission,
+        orders
+      })
+    }
+
+    return domainStats
+  }
 }

+ 10 - 4
src/services/team.service.ts

@@ -158,12 +158,15 @@ export class TeamService {
     // 获取所有团队的 ID 列表,用于查询会员数据
     const teamIds = teams.map(team => team.id)
 
-    // 查询所有团队的总收入统计(通过 userId 关联,包括默认的 agentId 0
+    // 查询所有团队的总收入统计(包括团队分成和个人分成
     const totalRevenueStats =
       allUserIds.length > 0
         ? await this.incomeRecordsRepository
             .createQueryBuilder('record')
-            .select(['record.agentId as userId', 'SUM(record.incomeAmount) as totalRevenue'])
+            .select([
+              'record.agentId as userId', 
+              'SUM(record.incomeAmount + record.personalIncomeAmount) as totalRevenue'
+            ])
             .where('record.delFlag = :delFlag', { delFlag: false })
             .andWhere('record.status = :status', { status: true })
             .andWhere('record.agentId IN (:...allUserIds)', { allUserIds })
@@ -171,12 +174,15 @@ export class TeamService {
             .getRawMany()
         : []
 
-    // 查询所有团队的今日收入统计(通过 userId 关联,包括默认的 agentId 0
+    // 查询所有团队的今日收入统计(包括团队分成和个人分成
     const todayRevenueStats =
       allUserIds.length > 0
         ? await this.incomeRecordsRepository
             .createQueryBuilder('record')
-            .select(['record.agentId as userId', 'SUM(record.incomeAmount) as todayRevenue'])
+            .select([
+              'record.agentId as userId', 
+              'SUM(record.incomeAmount + record.personalIncomeAmount) as todayRevenue'
+            ])
             .where('record.delFlag = :delFlag', { delFlag: false })
             .andWhere('record.status = :status', { status: true })
             .andWhere('record.createdAt >= :today', { today })

+ 1 - 1
src/services/user-invite.service.ts

@@ -221,7 +221,7 @@ export class UserShareService {
     // 创建会员记录
     const member = this.memberRepository.create({
       userId: savedUser.id,
-      teamId: 1, // 默认团队
+      teamId: 0, // 修复:默认团队ID应该为0
       domainId: 0,
       email,
       phone,