260 lines
7.2 KiB
TypeScript
260 lines
7.2 KiB
TypeScript
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;
|
||
}
|
||
}
|