API/src/service/site.service.ts

96 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Site>;
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<Site> = {
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<Site>) {
// 创建新的站点记录
await this.siteModel.insert(data as Site);
return true;
}
async update(id: string | number, data: UpdateSiteDTO) {
// 更新指定站点记录,将布尔 isDisabled 转换为数值 0/1
const payload: Partial<Site> = {
...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;
}
}