import { Inject, Provide } from '@midwayjs/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository, Like } from 'typeorm'; import { WPService } from './wp.service'; import { Subscription } from '../entity/subscription.entity'; import { plainToClass } from 'class-transformer'; import { SubscriptionStatus } from '../enums/base.enum'; import { QuerySubscriptionDTO } from '../dto/subscription.dto'; @Provide() export class SubscriptionService { @Inject() wPService: WPService; @InjectEntityModel(Subscription) subscriptionModel: Repository; /** * 同步指定站点的订阅列表 * - 从 WooCommerce 拉取订阅并逐条入库/更新 */ async syncSubscriptions(siteId: string) { const subs = await this.wPService.getSubscriptions(siteId); for (const sub of subs) { await this.syncSingleSubscription(siteId, sub); } } /** * 同步单条订阅 * - 规范化字段、设置幂等键 externalSubscriptionId * - 已存在则更新,不存在则新增 */ async syncSingleSubscription(siteId: string, sub: any) { const { line_items, ...raw } = sub; const entity: Partial = { ...raw, externalSubscriptionId: String(raw.id), siteId, status: raw.status as SubscriptionStatus, customer_email: raw?.billing?.email || raw?.customer_email || '', line_items, }; delete (entity as any).id; const existing = await this.subscriptionModel.findOne({ where: { externalSubscriptionId: String(sub.id), siteId }, }); const saveEntity = plainToClass(Subscription, entity); if (existing) { await this.subscriptionModel.update({ id: existing.id }, saveEntity); } else { await this.subscriptionModel.save(saveEntity); } } /** * 获取订阅分页列表(支持站点、状态、邮箱与关键字筛选) */ async getSubscriptionList({ current = 1, pageSize = 10, siteId, status, customer_email, keyword, }: QuerySubscriptionDTO) { const where: any = {}; if (siteId) where.siteId = siteId; if (status) where.status = status; if (customer_email) where.customer_email = Like(`%${customer_email}%`); if (keyword) { where.externalSubscriptionId = Like(`%${keyword}%`); } const [list, total] = await this.subscriptionModel.findAndCount({ where, order: { id: 'DESC' }, skip: (current - 1) * pageSize, take: pageSize, }); return { list, total, current, pageSize, }; } }