import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; import { Repository, Like, In } from 'typeorm'; import { Site } from '../entity/site.entity'; import { WpSite } from '../interface'; import { UpdateSiteDTO } from '../dto/site.dto'; @Provide() @Scope(ScopeEnum.Singleton) export class SiteService { @InjectEntityModel(Site) siteModel: Repository; async syncFromConfig(sites: WpSite[] = []) { // 将配置中的 WpSite 同步到数据库 Site 表(用于一次性导入或初始化) for (const siteConfig of sites) { // 按站点名称查询是否已存在记录 const exist = await this.siteModel.findOne({ where: { siteName: siteConfig.siteName } }); // 将 WpSite 字段映射为 Site 实体字段 const payload: Partial = { siteName: siteConfig.siteName, apiUrl: (siteConfig as any).wpApiUrl, consumerKey: (siteConfig as any).consumerKey, consumerSecret: (siteConfig as any).consumerSecret, type: 'woocommerce', }; // 存在则更新,不存在则插入新记录 if (exist) await this.siteModel.update({ id: exist.id }, payload); else await this.siteModel.insert(payload as Site); } } async create(data: Partial) { // 创建新的站点记录 await this.siteModel.insert(data as Site); return true; } async update(id: string | number, data: UpdateSiteDTO) { // 更新指定站点记录,将布尔 isDisabled 转换为数值 0/1 const payload: Partial = { ...data, isDisabled: data.isDisabled === undefined // 未传入则不更新该字段 ? undefined : data.isDisabled // true -> 1, false -> 0 ? 1 : 0, } as any; await this.siteModel.update({ id: Number(id) }, payload); return true; } async get(id: string | number, includeSecret = false) { // 根据主键获取站点;includeSecret 为 true 时返回密钥字段 const site = await this.siteModel.findOne({ where: { id: Number(id) } }); if (!site) return null; if (includeSecret) return site; // 默认不返回密钥,进行字段脱敏 const { ...rest } = site; return rest; } async list(param: { current?: number; pageSize?: number; keyword?: string; isDisabled?: boolean; ids?: string }, includeSecret = false) { // 分页查询站点列表,支持关键字、禁用状态与 ID 列表过滤 const { current = 1, pageSize = 10, keyword, isDisabled, ids } = (param || {}) as any; const where: any = {}; // 按名称模糊查询 if (keyword) where.siteName = Like(`%${keyword}%`); // 按禁用状态过滤(布尔转数值) if (typeof isDisabled === 'boolean') where.isDisabled = isDisabled ? 1 : 0; if (ids) { // 解析逗号分隔的 ID 字符串为数字数组,并过滤非法值 const numIds = String(ids) .split(',') .filter(Boolean) .map((i) => Number(i)) .filter((v) => !Number.isNaN(v)); if (numIds.length > 0) where.id = In(numIds); } // 进行分页查询(skip/take)并返回总条数 const [items, total] = await this.siteModel.findAndCount({ where, skip: (current - 1) * pageSize, take: pageSize }); // 根据 includeSecret 决定是否脱敏返回密钥字段 const data = includeSecret ? items : items.map((item: any) => { const { consumerKey, consumerSecret, ...rest } = item; return rest; }); return { items: data, total, current, pageSize }; } async disable(id: string | number, disabled: boolean) { // 设置站点禁用状态(true -> 1, false -> 0) await this.siteModel.update({ id: Number(id) }, { isDisabled: disabled ? 1 : 0 }); return true; } }