Files
wwjcloud/wwjcloud/src/common/diy/services/admin/DiyService.ts
2025-09-11 22:06:19 +08:00

260 lines
7.2 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 { Injectable } from '@nestjs/common';
import { CoreDiyService } from '../core/CoreDiyService';
import { DiyPage } from '../../entities/DiyPage';
/**
* DIY 管理服务 - Admin层
* 对应PHP: app\service\admin\diy\DiyService
*/
@Injectable()
export class DiyService {
constructor(
private readonly coreDiyService: CoreDiyService,
) {}
/**
* 加载 DIY 数据(对齐 PHP: loadDiyData
* @param params 参数
*/
async loadDiyData(params: {
site_id: number;
main_app: string[];
tag: 'add' | 'update';
}): Promise<void> {
const { site_id, main_app, tag } = params;
const count = main_app.length;
const addon = ['', ...main_app];
for (let k = 0; k < addon.length; k++) {
const v = addon[k];
let is_start = 0;
if (tag === 'add') {
if (count > 1) {
// 站点多应用,使用系统的页面
is_start = k === 0 ? 1 : 0;
} else {
// 站点单应用,将应用的设为使用中
is_start = k === 0 ? 0 : 1;
}
} else {
// 编辑站点套餐的情况
if (count > 1) {
// 站点多应用,将不更新启动页
is_start = 0;
} else {
// 站点单应用,将应用的设为使用中
is_start = k === 0 ? 0 : 1;
}
}
// 设置首页默认模板
await this.setDiyData({
key: 'DIY_INDEX',
type: 'index',
addon: v,
is_start,
site_id,
main_app: addon,
});
// 设置个人中心默认模板
await this.setDiyData({
key: 'DIY_MEMBER_INDEX',
type: 'member_index',
addon: v,
is_start,
site_id,
main_app: addon,
});
}
}
/**
* 控制器所需:分页
*/
async getPage(query: any) {
const { site_id = 0, key } = query || {};
const list = await this.coreDiyService.getPageListByType(Number(site_id), key);
const page = Number(query?.page || 1);
const limit = Number(query?.limit || list.length || 20);
const start = (page - 1) * limit;
const data = list.slice(start, start + limit);
return { data, total: list.length, page, limit, pages: Math.ceil((list.length || 0) / (limit || 1)) };
}
async getInfo(pageId: number) {
return this.coreDiyService.getPageInfo(pageId);
}
async add(data: any) {
// 对齐 PHP 字段映射
const payload = {
site_id: data.site_id || 0,
name: data.page_name,
type: data.page_type || data.key || 'custom',
value: JSON.stringify(data.page_data || {}),
is_default: 0,
mode: 'diy',
title: data.page_name,
} as any;
return this.coreDiyService.addPage(payload);
}
async edit(pageId: number, data: any) {
const payload: any = {};
if (data.page_name) payload.title = data.page_name;
if (data.page_type || data.key) payload.type = data.page_type || data.key;
if (data.page_data) payload.value = JSON.stringify(data.page_data);
if (typeof data.sort === 'number') payload.sort = data.sort;
return this.coreDiyService.editPage(pageId, payload);
}
async delete(pageId: number) {
return this.coreDiyService.delete(pageId as any);
}
async copy(pageId: number, newName: string) {
const info = await this.coreDiyService.getPageInfo(pageId);
if (!info) return null;
return this.coreDiyService.addPage({
site_id: (info as any).site_id || 0,
name: newName,
type: (info as any).type,
value: (info as any).value,
is_default: 0,
mode: (info as any).mode || 'diy',
title: newName,
} as any);
}
async preview(pageId: number) {
return this.coreDiyService.getPageInfo(pageId);
}
async publish(pageId: number) {
const info = await this.coreDiyService.getPageInfo(pageId);
if (!info) return false;
// 对齐 PHP设置为默认
await this.coreDiyService.setDefaultPage((info as any).site_id || 0, (info as any).name, (info as any).id);
return true;
}
async getTemplates() {
// 简化返回可用模板列表
return [
{ key: 'DIY_INDEX', name: '首页', template: 'default_index' },
{ key: 'DIY_MEMBER_INDEX', name: '个人中心', template: 'default_member' },
];
}
/**
* 设置 DIY 数据(对齐 PHP: setDiyData
* @param params 参数
*/
private async setDiyData(params: {
key: string;
type: string;
addon: string;
is_start: number;
site_id: number;
main_app: string[];
}): Promise<void> {
const { key, type, addon, is_start, site_id, main_app } = params;
// 获取默认模板数据(这里简化处理,实际应该从模板字典获取)
const defaultTemplate = this.getDefaultTemplate(key, type, addon);
if (!defaultTemplate) {
return;
}
// 检查是否已存在页面
const existingPage = await this.coreDiyService.getPageInfoBySiteAndType(site_id, key, 1);
if (!existingPage) {
// 创建新页面
await this.coreDiyService.addPage({
site_id,
page_title: defaultTemplate.title,
title: defaultTemplate.title,
name: key,
type: key,
template: defaultTemplate.template,
mode: defaultTemplate.mode,
value: JSON.stringify(defaultTemplate.data),
is_default: 1,
is_change: 0,
});
} else {
// 针对多应用首页的数据更新
if (key === 'DIY_INDEX' && (existingPage as any).type === 'DIY_INDEX') {
if ((existingPage as any).is_change === 0) {
await this.coreDiyService.editPage((existingPage as any).id, {
value: JSON.stringify(defaultTemplate.data),
});
}
}
}
// 设置默认页面
const pageList = await this.coreDiyService.getPageListByType(site_id, key);
for (const page of pageList as any[]) {
if ((page as any).name === key) {
await this.coreDiyService.setDefaultPage(site_id, (page as any).name, (page as any).id);
break;
}
}
// 如果 is_start 为 1设置启动页配置留空占位按需接入
if (is_start === 1) {
// TODO: 调用 DiyConfigService 设置启动页
}
}
/**
* 获取默认模板数据(简化实现)
* @param key 模板键
* @param type 类型
* @param addon 插件
*/
private getDefaultTemplate(key: string, type: string, addon: string) {
// 这里应该从模板字典获取,暂时返回默认数据
const templates: Record<string, any> = {
'DIY_INDEX': {
title: '首页',
template: 'default_index',
mode: 'diy',
data: {
components: [
{
componentName: 'Banner',
data: {
title: '欢迎使用',
subtitle: '这是一个默认首页',
},
},
],
},
},
'DIY_MEMBER_INDEX': {
title: '个人中心',
template: 'default_member',
mode: 'diy',
data: {
components: [
{
componentName: 'MemberInfo',
data: {
title: '个人中心',
},
},
],
},
},
};
return templates[key] || null;
}
}