|
|
@@ -1,4 +1,4 @@
|
|
|
-import { Repository, Like } from 'typeorm'
|
|
|
+import { Repository, Like, Not } from 'typeorm'
|
|
|
import { FastifyInstance } from 'fastify'
|
|
|
import { TeamMembers } from '../entities/team-members.entity'
|
|
|
import { IncomeRecords } from '../entities/income-records.entity'
|
|
|
@@ -9,6 +9,10 @@ import { PaginationResponse } from '../dto/common.dto'
|
|
|
import { CreateTeamMembersBody, UpdateTeamMembersBody, ListTeamMembersQuery, TeamMemberStatsQuery, TeamMemberStatsResponse, TeamLeaderStatsQuery, TeamLeaderStatsResponse } from '../dto/team-members.dto'
|
|
|
import { UserService } from './user.service'
|
|
|
import { UserRole } from '../entities/user.entity'
|
|
|
+import * as randomstring from 'randomstring'
|
|
|
+import { SysConfigService } from './sys-config.service'
|
|
|
+import { PromotionLinkService } from './promotion-link.service'
|
|
|
+import { LinkType } from '../entities/promotion-link.entity'
|
|
|
|
|
|
export class TeamMembersService {
|
|
|
private teamMembersRepository: Repository<TeamMembers>
|
|
|
@@ -17,14 +21,20 @@ export class TeamMembersService {
|
|
|
private userService: UserService
|
|
|
private teamDomainRepository: Repository<TeamDomain>
|
|
|
private teamRepository: Repository<Team>
|
|
|
+ private sysConfigService: SysConfigService
|
|
|
+ private promotionLinkService: PromotionLinkService
|
|
|
+ private app: FastifyInstance
|
|
|
|
|
|
constructor(app: FastifyInstance) {
|
|
|
+ this.app = app
|
|
|
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)
|
|
|
+ this.sysConfigService = new SysConfigService(app)
|
|
|
+ this.promotionLinkService = new PromotionLinkService(app)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -72,9 +82,22 @@ export class TeamMembersService {
|
|
|
const parentId = teamUserId || creatorId
|
|
|
const createdUser = await this.userService.create(userPassword, teamMemberData.name, UserRole.PROMOTER, parentId)
|
|
|
|
|
|
+ // 生成推广码
|
|
|
+ const randomSuffix = randomstring.generate({
|
|
|
+ length: 10,
|
|
|
+ charset: 'alphanumeric'
|
|
|
+ })
|
|
|
+ let finalPromoCode = randomSuffix
|
|
|
+ let counter = 0
|
|
|
+ while (await this.teamMembersRepository.findOne({ where: { promoCode: finalPromoCode } })) {
|
|
|
+ counter++
|
|
|
+ finalPromoCode = `${randomSuffix}${counter}`
|
|
|
+ }
|
|
|
+
|
|
|
const teamMember = this.teamMembersRepository.create({
|
|
|
...teamMemberData,
|
|
|
- userId: createdUser.id
|
|
|
+ userId: createdUser.id,
|
|
|
+ promoCode: finalPromoCode
|
|
|
})
|
|
|
return this.teamMembersRepository.save(teamMember)
|
|
|
}
|
|
|
@@ -616,4 +639,418 @@ export class TeamMembersService {
|
|
|
membersStats
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成团队成员的推广链接
|
|
|
+ * @param teamMemberId 团队成员ID
|
|
|
+ * @returns 推广链接
|
|
|
+ */
|
|
|
+ async generatePromotionLink(teamMemberId: number): Promise<string> {
|
|
|
+ const teamMember = await this.findById(teamMemberId)
|
|
|
+
|
|
|
+ if (!teamMember.promoCode) {
|
|
|
+ throw new Error('团队成员没有推广码')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从系统配置获取 super_domain
|
|
|
+ let superDomain = ''
|
|
|
+ try {
|
|
|
+ const config = await this.sysConfigService.getSysConfig('super_domain')
|
|
|
+ superDomain = config.value
|
|
|
+ } catch (error) {
|
|
|
+ this.app.log.warn('未找到 super_domain 配置,使用默认值')
|
|
|
+ superDomain = ''
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果配置为空,返回空字符串或抛出错误
|
|
|
+ if (!superDomain || superDomain.trim() === '') {
|
|
|
+ throw new Error('系统未配置 super_domain,无法生成推广链接')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保 super_domain 以 http:// 或 https:// 开头
|
|
|
+ let domain = superDomain.trim()
|
|
|
+ if (!domain.startsWith('http://') && !domain.startsWith('https://')) {
|
|
|
+ domain = `https://${domain}`
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成推广链接:{super_domain}?code={推广码}
|
|
|
+ const promotionLink = `${domain}?code=${teamMember.promoCode}`
|
|
|
+
|
|
|
+ // 创建或更新 PromotionLink 记录,带上当前 member 的 id
|
|
|
+ // 如果已存在相同 memberId 的记录,则覆盖旧的
|
|
|
+ try {
|
|
|
+ await this.promotionLinkService.createOrUpdateByMemberId({
|
|
|
+ teamId: teamMember.teamId,
|
|
|
+ memberId: teamMember.id,
|
|
|
+ name: `${teamMember.name}的推广链接`,
|
|
|
+ image: '',
|
|
|
+ link: promotionLink,
|
|
|
+ type: LinkType.GENERAL
|
|
|
+ })
|
|
|
+ } catch (error) {
|
|
|
+ // 如果创建或更新记录失败,记录日志但不影响返回链接
|
|
|
+ this.app.log.warn('创建或更新推广链接记录失败:', error)
|
|
|
+ }
|
|
|
+
|
|
|
+ return promotionLink
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据 userId 生成推广链接
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @returns 推广链接
|
|
|
+ */
|
|
|
+ async generatePromotionLinkByUserId(userId: number): Promise<string> {
|
|
|
+ const teamMember = await this.findByUserId(userId)
|
|
|
+ return this.generatePromotionLink(teamMember.id)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 为团队成员生成或重新生成推广码
|
|
|
+ * @param teamMemberId 团队成员ID
|
|
|
+ * @returns 更新后的团队成员信息
|
|
|
+ */
|
|
|
+ async generatePromoCode(teamMemberId: number): Promise<TeamMembers> {
|
|
|
+ const teamMember = await this.findById(teamMemberId)
|
|
|
+
|
|
|
+ // 生成推广码
|
|
|
+ const randomSuffix = randomstring.generate({
|
|
|
+ length: 10,
|
|
|
+ charset: 'alphanumeric'
|
|
|
+ })
|
|
|
+ let finalPromoCode = randomSuffix
|
|
|
+ let counter = 0
|
|
|
+
|
|
|
+ // 确保生成的推广码是唯一的(排除当前成员的推广码)
|
|
|
+ // 使用查询构建器来排除当前成员
|
|
|
+ while (await this.teamMembersRepository
|
|
|
+ .createQueryBuilder('tm')
|
|
|
+ .where('tm.promoCode = :promoCode', { promoCode: finalPromoCode })
|
|
|
+ .andWhere('tm.id != :teamMemberId', { teamMemberId })
|
|
|
+ .getOne()) {
|
|
|
+ counter++
|
|
|
+ finalPromoCode = `${randomSuffix}${counter}`
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新推广码
|
|
|
+ await this.teamMembersRepository.update(teamMemberId, {
|
|
|
+ promoCode: finalPromoCode
|
|
|
+ })
|
|
|
+
|
|
|
+ // 返回更新后的团队成员信息
|
|
|
+ return this.findById(teamMemberId)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基于personalAgentId获取IP成交率统计
|
|
|
+ * @param userId 团队成员的用户ID(personalAgentId)
|
|
|
+ * @returns IP成交率统计数据
|
|
|
+ */
|
|
|
+ async getIpConversionRateByPersonalAgentId(userId: number): Promise<{
|
|
|
+ todayIpConversionRate: number
|
|
|
+ totalIpConversionRate: number
|
|
|
+ todayPaidUsers: number
|
|
|
+ todayLoginUsers: number
|
|
|
+ totalPaidUsers: number
|
|
|
+ totalUsers: number
|
|
|
+ }> {
|
|
|
+ // 获取今天的开始时间(使用本地时区),并使用半开区间 [today, tomorrow)
|
|
|
+ const today = new Date()
|
|
|
+ today.setHours(0, 0, 0, 0)
|
|
|
+ const tomorrow = new Date(today)
|
|
|
+ tomorrow.setDate(tomorrow.getDate() + 1)
|
|
|
+
|
|
|
+ // 获取所有通过该团队成员(personalAgentId)产生的订单的用户ID
|
|
|
+ const orderUserIds = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('DISTINCT record.userId', 'userId')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawMany()
|
|
|
+
|
|
|
+ const userIds = orderUserIds.map(item => item.userId).filter(id => id !== null && id !== undefined)
|
|
|
+
|
|
|
+ if (userIds.length === 0) {
|
|
|
+ return {
|
|
|
+ todayIpConversionRate: 0,
|
|
|
+ totalIpConversionRate: 0,
|
|
|
+ todayPaidUsers: 0,
|
|
|
+ todayLoginUsers: 0,
|
|
|
+ totalPaidUsers: 0,
|
|
|
+ totalUsers: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 统计今日登录用户数(基于会员的lastLoginAt字段)
|
|
|
+ const todayLoginUsers = await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .andWhere('member.lastLoginAt >= :today', { today })
|
|
|
+ .andWhere('member.lastLoginAt < :tomorrow', { tomorrow })
|
|
|
+ .getCount()
|
|
|
+
|
|
|
+ // 统计总用户数
|
|
|
+ const totalUsers = await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .getCount()
|
|
|
+
|
|
|
+ // 统计今日付费用户数(通过IncomeRecords表,查询今日有付费记录的用户,去重)
|
|
|
+ const todayPaidUsersResult = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('COUNT(DISTINCT record.userId)', 'count')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.createdAt >= :today', { today })
|
|
|
+ .andWhere('record.createdAt < :tomorrow', { tomorrow })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const todayPaidUsers = Number(todayPaidUsersResult?.count) || 0
|
|
|
+
|
|
|
+ // 统计总付费用户数(通过IncomeRecords表,查询有付费记录的用户,去重)
|
|
|
+ const totalPaidUsersResult = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('COUNT(DISTINCT record.userId)', 'count')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const totalPaidUsers = Number(totalPaidUsersResult?.count) || 0
|
|
|
+
|
|
|
+ // 计算成交率(避免除零错误)
|
|
|
+ const todayIpConversionRate = todayLoginUsers > 0
|
|
|
+ ? Number((todayPaidUsers / todayLoginUsers).toFixed(4))
|
|
|
+ : 0
|
|
|
+
|
|
|
+ const totalIpConversionRate = totalUsers > 0
|
|
|
+ ? Number((totalPaidUsers / totalUsers).toFixed(4))
|
|
|
+ : 0
|
|
|
+
|
|
|
+ return {
|
|
|
+ todayIpConversionRate,
|
|
|
+ totalIpConversionRate,
|
|
|
+ todayPaidUsers,
|
|
|
+ todayLoginUsers,
|
|
|
+ totalPaidUsers,
|
|
|
+ totalUsers
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基于personalAgentId获取全部统计
|
|
|
+ * @param userId 团队成员的用户ID(personalAgentId)
|
|
|
+ * @returns 全部统计数据
|
|
|
+ */
|
|
|
+ async getAllStatisticsByPersonalAgentId(userId: number): Promise<{
|
|
|
+ totalNewUsers: number
|
|
|
+ totalIncome: number
|
|
|
+ todayActiveUsers: number
|
|
|
+ todayIncome: number
|
|
|
+ totalSales: number
|
|
|
+ todaySales: number
|
|
|
+ }> {
|
|
|
+ // 获取今天的开始时间(使用本地时区),并使用半开区间 [today, tomorrow)
|
|
|
+ const today = new Date()
|
|
|
+ today.setHours(0, 0, 0, 0)
|
|
|
+ const tomorrow = new Date(today)
|
|
|
+ tomorrow.setDate(tomorrow.getDate() + 1)
|
|
|
+
|
|
|
+ // 获取所有通过该团队成员(personalAgentId)产生的订单的用户ID
|
|
|
+ const orderUserIds = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('DISTINCT record.userId', 'userId')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawMany()
|
|
|
+
|
|
|
+ const userIds = orderUserIds.map(item => item.userId).filter(id => id !== null && id !== undefined)
|
|
|
+
|
|
|
+ // 重新计算总新增用户数(去重)
|
|
|
+ const totalNewUsersDistinct = userIds.length > 0
|
|
|
+ ? await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .select('COUNT(DISTINCT member.userId)', 'count')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .getRawOne()
|
|
|
+ : { count: 0 }
|
|
|
+
|
|
|
+ // 统计今日活跃用户数(基于lastLoginAt字段)
|
|
|
+ const todayActiveUsers = userIds.length > 0
|
|
|
+ ? await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .andWhere('member.lastLoginAt >= :today', { today })
|
|
|
+ .andWhere('member.lastLoginAt < :tomorrow', { tomorrow })
|
|
|
+ .getCount()
|
|
|
+ : 0
|
|
|
+
|
|
|
+ // 统计总收入(只统计personalIncomeAmount)
|
|
|
+ const totalIncomeRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const totalIncome = totalIncomeRecords?.totalIncome ? parseFloat(totalIncomeRecords.totalIncome) : 0
|
|
|
+
|
|
|
+ // 统计今日收入(只统计personalIncomeAmount)
|
|
|
+ const todayIncomeRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.createdAt >= :startDate', { startDate: today })
|
|
|
+ .andWhere('record.createdAt < :endDate', { endDate: tomorrow })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const todayIncome = todayIncomeRecords?.totalIncome ? parseFloat(todayIncomeRecords.totalIncome) : 0
|
|
|
+
|
|
|
+ // 统计历史总销售额
|
|
|
+ const totalSalesRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.orderPrice AS DECIMAL(10,5)))', 'totalSales')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const totalSales = totalSalesRecords?.totalSales ? parseFloat(totalSalesRecords.totalSales) : 0
|
|
|
+
|
|
|
+ // 统计今日销售额
|
|
|
+ const todaySalesRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.orderPrice AS DECIMAL(10,5)))', 'totalSales')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.createdAt >= :startDate', { startDate: today })
|
|
|
+ .andWhere('record.createdAt < :endDate', { endDate: tomorrow })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const todaySales = todaySalesRecords?.totalSales ? parseFloat(todaySalesRecords.totalSales) : 0
|
|
|
+
|
|
|
+ return {
|
|
|
+ totalNewUsers: Number(totalNewUsersDistinct?.count) || 0,
|
|
|
+ totalIncome,
|
|
|
+ todayActiveUsers,
|
|
|
+ todayIncome,
|
|
|
+ totalSales,
|
|
|
+ todaySales
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 基于personalAgentId获取每日统计
|
|
|
+ * @param userId 团队成员的用户ID(personalAgentId)
|
|
|
+ * @returns 每日统计数据
|
|
|
+ */
|
|
|
+ async getDailyStatisticsByPersonalAgentId(userId: number): Promise<{
|
|
|
+ todayNewUsers: number
|
|
|
+ todayIncome: number
|
|
|
+ todayActiveUsers: number
|
|
|
+ totalIncome: number
|
|
|
+ totalSales: number
|
|
|
+ todaySales: number
|
|
|
+ }> {
|
|
|
+ // 获取今天的开始时间(使用本地时区),并使用半开区间 [today, tomorrow)
|
|
|
+ const today = new Date()
|
|
|
+ today.setHours(0, 0, 0, 0)
|
|
|
+ const tomorrow = new Date(today)
|
|
|
+ tomorrow.setDate(tomorrow.getDate() + 1)
|
|
|
+
|
|
|
+ // 获取所有通过该团队成员(personalAgentId)产生的订单的用户ID
|
|
|
+ const orderUserIds = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('DISTINCT record.userId', 'userId')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawMany()
|
|
|
+
|
|
|
+ const userIds = orderUserIds.map(item => item.userId).filter(id => id !== null && id !== undefined)
|
|
|
+
|
|
|
+ // 统计今日新增用户数
|
|
|
+ const todayNewUsers = userIds.length > 0
|
|
|
+ ? await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .andWhere('member.createdAt >= :today', { today })
|
|
|
+ .andWhere('member.createdAt < :tomorrow', { tomorrow })
|
|
|
+ .getCount()
|
|
|
+ : 0
|
|
|
+
|
|
|
+ // 统计今日活跃用户数(基于lastLoginAt字段)
|
|
|
+ const todayActiveUsers = userIds.length > 0
|
|
|
+ ? await this.memberRepository
|
|
|
+ .createQueryBuilder('member')
|
|
|
+ .where('member.userId IN (:...userIds)', { userIds })
|
|
|
+ .andWhere('member.lastLoginAt >= :today', { today })
|
|
|
+ .andWhere('member.lastLoginAt < :tomorrow', { tomorrow })
|
|
|
+ .getCount()
|
|
|
+ : 0
|
|
|
+
|
|
|
+ // 统计今日收入(只统计personalIncomeAmount)
|
|
|
+ const todayIncomeRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.createdAt >= :startDate', { startDate: today })
|
|
|
+ .andWhere('record.createdAt < :endDate', { endDate: tomorrow })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const todayIncome = todayIncomeRecords?.totalIncome ? parseFloat(todayIncomeRecords.totalIncome) : 0
|
|
|
+
|
|
|
+ // 统计历史总收入(只统计personalIncomeAmount)
|
|
|
+ const totalIncomeRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.personalIncomeAmount AS DECIMAL(10,5)))', 'totalIncome')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const totalIncome = totalIncomeRecords?.totalIncome ? parseFloat(totalIncomeRecords.totalIncome) : 0
|
|
|
+
|
|
|
+ // 统计历史总销售额
|
|
|
+ const totalSalesRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.orderPrice AS DECIMAL(10,5)))', 'totalSales')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const totalSales = totalSalesRecords?.totalSales ? parseFloat(totalSalesRecords.totalSales) : 0
|
|
|
+
|
|
|
+ // 统计今日销售额
|
|
|
+ const todaySalesRecords = await this.incomeRecordsRepository
|
|
|
+ .createQueryBuilder('record')
|
|
|
+ .select('SUM(CAST(record.orderPrice AS DECIMAL(10,5)))', 'totalSales')
|
|
|
+ .where('record.personalAgentId = :personalAgentId', { personalAgentId: userId })
|
|
|
+ .andWhere('record.createdAt >= :startDate', { startDate: today })
|
|
|
+ .andWhere('record.createdAt < :endDate', { endDate: tomorrow })
|
|
|
+ .andWhere('record.delFlag = :delFlag', { delFlag: false })
|
|
|
+ .andWhere('record.status = :status', { status: true })
|
|
|
+ .getRawOne()
|
|
|
+
|
|
|
+ const todaySales = todaySalesRecords?.totalSales ? parseFloat(todaySalesRecords.totalSales) : 0
|
|
|
+
|
|
|
+ return {
|
|
|
+ todayNewUsers,
|
|
|
+ todayIncome,
|
|
|
+ todayActiveUsers,
|
|
|
+ totalIncome,
|
|
|
+ totalSales,
|
|
|
+ todaySales
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|