forked from yoone/API
106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
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<Subscription>;
|
|
|
|
/**
|
|
* 同步指定站点的订阅列表
|
|
* - 从 WooCommerce 拉取订阅并逐条入库/更新
|
|
*/
|
|
async syncSubscriptions(siteId: number) {
|
|
try {
|
|
const subs = await this.wpService.getSubscriptions(siteId);
|
|
let successCount = 0;
|
|
let failureCount = 0;
|
|
for (const sub of subs) {
|
|
try {
|
|
await this.syncSingleSubscription(siteId, sub);
|
|
successCount++;
|
|
} catch (error) {
|
|
console.error(`同步订阅 ${sub.id} 失败:`, error);
|
|
failureCount++;
|
|
}
|
|
}
|
|
return {
|
|
success: failureCount === 0,
|
|
successCount,
|
|
failureCount,
|
|
message: `同步完成: 成功 ${successCount}, 失败 ${failureCount}`,
|
|
};
|
|
} catch (error) {
|
|
console.error('同步订阅失败:', error);
|
|
return { success: false, successCount: 0, failureCount: 0, message: `同步失败: ${error.message}` };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 同步单条订阅
|
|
* - 规范化字段,设置幂等键 externalSubscriptionId
|
|
* - 已存在则更新,不存在则新增
|
|
*/
|
|
async syncSingleSubscription(siteId: number, sub: any) {
|
|
const { line_items, ...raw } = sub;
|
|
const entity: Partial<Subscription> = {
|
|
...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: 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,
|
|
};
|
|
}
|
|
} |