修复迁移后错误
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { AgreementService } from '../../services/admin/AgreementService';
|
||||
|
||||
@Controller('adminapi/sys/agreement')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class AgreementController {
|
||||
constructor(private readonly agreementService: AgreementService) {}
|
||||
|
||||
/**
|
||||
* 协议列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.agreementService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 协议信息
|
||||
*/
|
||||
@Get('info/:agreement_id')
|
||||
async info(@Param('agreement_id') agreement_id: string) {
|
||||
return this.agreementService.getInfo(parseInt(agreement_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加协议
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
agreement_name: string;
|
||||
agreement_type: string;
|
||||
agreement_content: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
}) {
|
||||
return this.agreementService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑协议
|
||||
*/
|
||||
@Put('edit/:agreement_id')
|
||||
async edit(
|
||||
@Param('agreement_id') agreement_id: string,
|
||||
@Body() data: {
|
||||
agreement_name?: string;
|
||||
agreement_type?: string;
|
||||
agreement_content?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
},
|
||||
) {
|
||||
return this.agreementService.edit(parseInt(agreement_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除协议
|
||||
*/
|
||||
@Delete('delete/:agreement_id')
|
||||
async delete(@Param('agreement_id') agreement_id: string) {
|
||||
return this.agreementService.delete(parseInt(agreement_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取协议类型
|
||||
*/
|
||||
@Get('types')
|
||||
async getTypes() {
|
||||
return this.agreementService.getTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型获取协议
|
||||
*/
|
||||
@Get('by-type/:agreement_type')
|
||||
async getByType(@Param('agreement_type') agreement_type: string) {
|
||||
return this.agreementService.getByType(agreement_type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { AppService } from '../../services/admin/AppService';
|
||||
|
||||
@Controller('adminapi/sys/app')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
/**
|
||||
* 应用列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.appService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用信息
|
||||
*/
|
||||
@Get('info/:app_id')
|
||||
async info(@Param('app_id') app_id: string) {
|
||||
return this.appService.getInfo(parseInt(app_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加应用
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
app_name: string;
|
||||
app_key: string;
|
||||
app_secret: string;
|
||||
app_type: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}) {
|
||||
return this.appService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑应用
|
||||
*/
|
||||
@Put('edit/:app_id')
|
||||
async edit(
|
||||
@Param('app_id') app_id: string,
|
||||
@Body() data: {
|
||||
app_name?: string;
|
||||
app_key?: string;
|
||||
app_secret?: string;
|
||||
app_type?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
},
|
||||
) {
|
||||
return this.appService.edit(parseInt(app_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除应用
|
||||
*/
|
||||
@Delete('delete/:app_id')
|
||||
async delete(@Param('app_id') app_id: string) {
|
||||
return this.appService.delete(parseInt(app_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用类型
|
||||
*/
|
||||
@Get('types')
|
||||
async getTypes() {
|
||||
return this.appService.getTypes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { AreaService } from '../../services/admin/AreaService';
|
||||
|
||||
@Controller('adminapi/sys/area')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class AreaController {
|
||||
constructor(private readonly areaService: AreaService) {}
|
||||
|
||||
/**
|
||||
* 地区列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.areaService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 地区信息
|
||||
*/
|
||||
@Get('info/:area_id')
|
||||
async info(@Param('area_id') area_id: string) {
|
||||
return this.areaService.getInfo(parseInt(area_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加地区
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
area_name: string;
|
||||
area_code?: string;
|
||||
parent_id?: number;
|
||||
level?: number;
|
||||
sort?: number;
|
||||
status?: number;
|
||||
}) {
|
||||
return this.areaService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑地区
|
||||
*/
|
||||
@Put('edit/:area_id')
|
||||
async edit(
|
||||
@Param('area_id') area_id: string,
|
||||
@Body() data: {
|
||||
area_name?: string;
|
||||
area_code?: string;
|
||||
parent_id?: number;
|
||||
level?: number;
|
||||
sort?: number;
|
||||
status?: number;
|
||||
},
|
||||
) {
|
||||
return this.areaService.edit(parseInt(area_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除地区
|
||||
*/
|
||||
@Delete('delete/:area_id')
|
||||
async delete(@Param('area_id') area_id: string) {
|
||||
return this.areaService.delete(parseInt(area_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区树
|
||||
*/
|
||||
@Get('tree')
|
||||
async tree() {
|
||||
return this.areaService.getTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据父级ID获取子地区
|
||||
*/
|
||||
@Get('children/:parent_id')
|
||||
async getChildren(@Param('parent_id') parent_id: string) {
|
||||
return this.areaService.getChildren(parseInt(parent_id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { AttachmentService } from '../../services/admin/AttachmentService';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: {
|
||||
uid: number;
|
||||
username: string;
|
||||
siteId: number;
|
||||
userType: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('adminapi/sys/attachment')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class AttachmentController {
|
||||
constructor(private readonly attachmentService: AttachmentService) {}
|
||||
|
||||
/**
|
||||
* 附件列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.getPage(siteId, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件信息
|
||||
*/
|
||||
@Get('info/:attachment_id')
|
||||
async info(@Param('attachment_id') attachment_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.getInfo(siteId, parseInt(attachment_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加附件
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
file_name: string;
|
||||
file_path: string;
|
||||
file_type: string;
|
||||
file_size: number;
|
||||
file_md5: string;
|
||||
file_url: string;
|
||||
storage_type: string;
|
||||
storage_config?: string;
|
||||
status?: number;
|
||||
}, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.add(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑附件
|
||||
*/
|
||||
@Put('edit/:attachment_id')
|
||||
async edit(
|
||||
@Param('attachment_id') attachment_id: string,
|
||||
@Body() data: {
|
||||
file_name?: string;
|
||||
file_path?: string;
|
||||
file_type?: string;
|
||||
file_size?: number;
|
||||
file_md5?: string;
|
||||
file_url?: string;
|
||||
storage_type?: string;
|
||||
storage_config?: string;
|
||||
status?: number;
|
||||
},
|
||||
@Req() req: AuthenticatedRequest,
|
||||
) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.edit(siteId, parseInt(attachment_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除附件
|
||||
*/
|
||||
@Delete('delete/:attachment_id')
|
||||
async delete(@Param('attachment_id') attachment_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.del(siteId, parseInt(attachment_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除附件
|
||||
*/
|
||||
@Delete('batch-delete')
|
||||
async batchDelete(@Body() data: { attachment_ids: number[] }, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.attachmentService.batchDelete(siteId, data.attachment_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件分类
|
||||
*/
|
||||
@Get('categories')
|
||||
async getCategories() {
|
||||
return this.attachmentService.getCategories();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传附件
|
||||
*/
|
||||
@Post('upload')
|
||||
async upload(@Body() data: any) {
|
||||
return this.attachmentService.upload(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { ChannelService } from '../../services/admin/ChannelService';
|
||||
|
||||
@Controller('adminapi/sys/channel')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ChannelController {
|
||||
constructor(private readonly channelService: ChannelService) {}
|
||||
|
||||
/**
|
||||
* 渠道列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.channelService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 渠道信息
|
||||
*/
|
||||
@Get('info/:channel_id')
|
||||
async info(@Param('channel_id') channel_id: string) {
|
||||
return this.channelService.getInfo(parseInt(channel_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加渠道
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
channel_name: string;
|
||||
channel_desc?: string;
|
||||
channel_type: string;
|
||||
channel_config?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
}) {
|
||||
return this.channelService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑渠道
|
||||
*/
|
||||
@Put('edit/:channel_id')
|
||||
async edit(
|
||||
@Param('channel_id') channel_id: string,
|
||||
@Body() data: {
|
||||
channel_name?: string;
|
||||
channel_desc?: string;
|
||||
channel_type?: string;
|
||||
channel_config?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
},
|
||||
) {
|
||||
return this.channelService.edit(parseInt(channel_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除渠道
|
||||
*/
|
||||
@Delete('delete/:channel_id')
|
||||
async delete(@Param('channel_id') channel_id: string) {
|
||||
return this.channelService.delete(parseInt(channel_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取渠道类型
|
||||
*/
|
||||
@Get('types')
|
||||
async getTypes() {
|
||||
return this.channelService.getTypes();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Query,
|
||||
Param,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { CommonService } from '../../services/admin/CommonService';
|
||||
|
||||
@Controller('adminapi/sys/common')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class CommonController {
|
||||
constructor(private readonly commonService: CommonService) {}
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
*/
|
||||
@Get('dict/:type')
|
||||
async getDict(@Param('type') type: string) {
|
||||
return this.commonService.getDict(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有字典
|
||||
*/
|
||||
@Get('dicts')
|
||||
async getDicts() {
|
||||
return this.commonService.getDicts();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区数据
|
||||
*/
|
||||
@Get('area')
|
||||
async getArea(@Query('parent_id') parent_id?: string) {
|
||||
return this.commonService.getArea(parent_id ? parseInt(parent_id) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区树
|
||||
*/
|
||||
@Get('area/tree')
|
||||
async getAreaTree() {
|
||||
return this.commonService.getAreaTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
*/
|
||||
@Get('config/:key')
|
||||
async getConfig(@Param('key') key: string) {
|
||||
return this.commonService.getConfig(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配置信息
|
||||
*/
|
||||
@Post('config')
|
||||
async setConfig(@Body() data: { key: string; value: any }) {
|
||||
return this.commonService.setConfig(data.key, data.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统信息
|
||||
*/
|
||||
@Get('system-info')
|
||||
async getSystemInfo() {
|
||||
return this.commonService.getSystemInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计信息
|
||||
*/
|
||||
@Get('statistics')
|
||||
async getStatistics() {
|
||||
return this.commonService.getStatistics();
|
||||
}
|
||||
}
|
||||
172
wwjcloud/src/common/sys/controllers/adminapi/ConfigController.ts
Normal file
172
wwjcloud/src/common/sys/controllers/adminapi/ConfigController.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { ConfigService } from '../../services/admin/ConfigService';
|
||||
|
||||
@Controller('adminapi/sys/config')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ConfigController {
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
/**
|
||||
* 获取网站设置
|
||||
*/
|
||||
@Get('website')
|
||||
async getWebsite() {
|
||||
return this.configService.getWebSite(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 网站设置
|
||||
*/
|
||||
@Post('website')
|
||||
async setWebsite(@Body() data: {
|
||||
site_name?: string;
|
||||
logo?: string;
|
||||
keywords?: string;
|
||||
desc?: string;
|
||||
latitude?: string;
|
||||
longitude?: string;
|
||||
province_id?: number;
|
||||
city_id?: number;
|
||||
district_id?: number;
|
||||
address?: string;
|
||||
full_address?: string;
|
||||
phone?: string;
|
||||
business_hours?: string;
|
||||
front_end_name?: string;
|
||||
front_end_logo?: string;
|
||||
front_end_icon?: string;
|
||||
icon?: string;
|
||||
meta_title?: string;
|
||||
meta_desc?: string;
|
||||
meta_keyword?: string;
|
||||
wechat_code?: string;
|
||||
enterprise_wechat?: string;
|
||||
site_login_logo?: string;
|
||||
site_login_bg_img?: string;
|
||||
tel?: string;
|
||||
}) {
|
||||
const { wechat_code, enterprise_wechat, site_login_logo, site_login_bg_img, tel, ...websiteData } = data;
|
||||
await this.configService.setWebSite(0, websiteData);
|
||||
const serviceData = { wechat_code, enterprise_wechat, site_login_logo, site_login_bg_img, tel };
|
||||
await this.configService.setService(0, serviceData);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权信息
|
||||
*/
|
||||
@Get('copyright')
|
||||
async getCopyright() {
|
||||
return this.configService.getCopyright(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置版权信息
|
||||
*/
|
||||
@Post('copyright')
|
||||
async setCopyright(@Body() data: {
|
||||
icp?: string;
|
||||
gov_record?: string;
|
||||
gov_url?: string;
|
||||
market_supervision_url?: string;
|
||||
logo?: string;
|
||||
company_name?: string;
|
||||
copyright_link?: string;
|
||||
copyright_desc?: string;
|
||||
}) {
|
||||
await this.configService.setCopyright(0, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景域名
|
||||
*/
|
||||
@Get('scene-domain')
|
||||
async getSceneDomain() {
|
||||
return this.configService.getSceneDomain(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务信息
|
||||
*/
|
||||
@Get('service-info')
|
||||
async getServiceInfo() {
|
||||
return this.configService.getService(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图信息
|
||||
*/
|
||||
@Post('map')
|
||||
async setMap(@Body() data: { key?: string; is_open?: number; valid_time?: number }) {
|
||||
await this.configService.setMap(0, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图设置
|
||||
*/
|
||||
@Get('map')
|
||||
async getMap() {
|
||||
return this.configService.getMap(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开发者key
|
||||
*/
|
||||
@Get('developer-token')
|
||||
async getDeveloperToken() {
|
||||
return this.configService.getDeveloperToken(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开发者key
|
||||
*/
|
||||
@Post('developer-token')
|
||||
async setDeveloperToken(@Body() data: { token?: string }) {
|
||||
await this.configService.setDeveloperToken(0, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局设置
|
||||
*/
|
||||
@Post('layout')
|
||||
async setLayout(@Body() data: { key?: string; value?: string }) {
|
||||
await this.configService.setLayout(0, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取布局设置
|
||||
*/
|
||||
@Get('layout')
|
||||
async getLayout() {
|
||||
return this.configService.getLayout(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置色调设置
|
||||
*/
|
||||
@Post('theme-color')
|
||||
async setThemeColor(@Body() data: { key?: string; value?: string }) {
|
||||
await this.configService.setThemeColor(0, data);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取色调设置
|
||||
*/
|
||||
@Get('theme-color')
|
||||
async getThemeColor() {
|
||||
return this.configService.getThemeColor(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { ExportService } from '../../services/admin/ExportService';
|
||||
|
||||
@Controller('adminapi/sys/export')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ExportController {
|
||||
constructor(private readonly exportService: ExportService) {}
|
||||
|
||||
/**
|
||||
* 导出列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.exportService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出信息
|
||||
*/
|
||||
@Get('info/:export_id')
|
||||
async info(@Param('export_id') export_id: string) {
|
||||
return this.exportService.getInfo(parseInt(export_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建导出任务
|
||||
*/
|
||||
@Post('create')
|
||||
async create(@Body() data: {
|
||||
export_name: string;
|
||||
export_type: string;
|
||||
export_config: any;
|
||||
status?: number;
|
||||
}) {
|
||||
return this.exportService.create(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行导出
|
||||
*/
|
||||
@Post('execute/:export_id')
|
||||
async execute(@Param('export_id') export_id: string) {
|
||||
return this.exportService.execute(parseInt(export_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载导出文件
|
||||
*/
|
||||
@Get('download/:export_id')
|
||||
async download(@Param('export_id') export_id: string) {
|
||||
return this.exportService.download(parseInt(export_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除导出记录
|
||||
*/
|
||||
@Post('delete/:export_id')
|
||||
async delete(@Param('export_id') export_id: string) {
|
||||
return this.exportService.delete(parseInt(export_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导出模板
|
||||
*/
|
||||
@Get('templates')
|
||||
async getTemplates() {
|
||||
return this.exportService.getTemplates();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { MenuService } from '../../services/admin/MenuService';
|
||||
|
||||
@Controller('adminapi/sys/menu')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class MenuController {
|
||||
constructor(private readonly menuService: MenuService) {}
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
*/
|
||||
@Get('lists/:app_type')
|
||||
async lists(@Param('app_type') app_type: string) {
|
||||
return this.menuService.getAllMenuList(app_type, 'all', 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单信息
|
||||
*/
|
||||
@Get('info/:app_type/:menu_key')
|
||||
async info(
|
||||
@Param('app_type') app_type: string,
|
||||
@Param('menu_key') menu_key: string,
|
||||
) {
|
||||
return this.menuService.get(app_type, menu_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加菜单
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: any) {
|
||||
return this.menuService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑菜单
|
||||
*/
|
||||
@Put('edit/:app_type/:menu_key')
|
||||
async edit(
|
||||
@Param('app_type') app_type: string,
|
||||
@Param('menu_key') menu_key: string,
|
||||
@Body() data: any
|
||||
) {
|
||||
return this.menuService.edit(app_type, menu_key, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
*/
|
||||
@Delete('delete/:menu_key')
|
||||
async delete(@Param('menu_key') menu_key: string) {
|
||||
return this.menuService.delete(menu_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单排序
|
||||
*/
|
||||
@Post('sort')
|
||||
async sort(@Body() data: { menu_keys: string[] }) {
|
||||
return this.menuService.sort(data.menu_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单树
|
||||
*/
|
||||
@Get('tree/:app_type')
|
||||
async tree(@Param('app_type') app_type: string) {
|
||||
return this.menuService.getMenuTree(app_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户菜单
|
||||
*/
|
||||
@Get('user-menu/:app_type')
|
||||
async getUserMenu(@Param('app_type') app_type: string) {
|
||||
return this.menuService.getUserMenu(app_type);
|
||||
}
|
||||
}
|
||||
111
wwjcloud/src/common/sys/controllers/adminapi/PosterController.ts
Normal file
111
wwjcloud/src/common/sys/controllers/adminapi/PosterController.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { PosterService } from '../../services/admin/PosterService';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: {
|
||||
uid: number;
|
||||
username: string;
|
||||
siteId: number;
|
||||
userType: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('adminapi/sys/poster')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class PosterController {
|
||||
constructor(private readonly posterService: PosterService) {}
|
||||
|
||||
/**
|
||||
* 海报列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.getPage(siteId, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 海报信息
|
||||
*/
|
||||
@Get('info/:poster_id')
|
||||
async info(@Param('poster_id') poster_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.getInfo(siteId, parseInt(poster_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加海报
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
poster_name: string;
|
||||
poster_type: string;
|
||||
poster_config: any;
|
||||
poster_image?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
}, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.add(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑海报
|
||||
*/
|
||||
@Put('edit/:poster_id')
|
||||
async edit(
|
||||
@Param('poster_id') poster_id: string,
|
||||
@Body() data: {
|
||||
poster_name?: string;
|
||||
poster_type?: string;
|
||||
poster_config?: any;
|
||||
poster_image?: string;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
},
|
||||
@Req() req: AuthenticatedRequest,
|
||||
) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.edit(siteId, parseInt(poster_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除海报
|
||||
*/
|
||||
@Delete('delete/:poster_id')
|
||||
async delete(@Param('poster_id') poster_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.delete(siteId, parseInt(poster_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成海报
|
||||
*/
|
||||
@Post('generate/:poster_id')
|
||||
async generate(@Param('poster_id') poster_id: string, @Body() data: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.posterService.generate(siteId, parseInt(poster_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取海报模板
|
||||
*/
|
||||
@Get('templates')
|
||||
async getTemplates() {
|
||||
return this.posterService.getTemplates();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { PrinterService } from '../../services/admin/PrinterService';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: {
|
||||
uid: number;
|
||||
username: string;
|
||||
siteId: number;
|
||||
userType: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('adminapi/sys/printer')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class PrinterController {
|
||||
constructor(private readonly printerService: PrinterService) {}
|
||||
|
||||
/**
|
||||
* 打印机列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.getPage(siteId, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印机信息
|
||||
*/
|
||||
@Get('info/:printer_id')
|
||||
async info(@Param('printer_id') printer_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.getInfo(siteId, parseInt(printer_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加打印机
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
printer_name: string;
|
||||
printer_type: string;
|
||||
printer_config: any;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
}, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.add(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑打印机
|
||||
*/
|
||||
@Put('edit/:printer_id')
|
||||
async edit(
|
||||
@Param('printer_id') printer_id: string,
|
||||
@Body() data: {
|
||||
printer_name?: string;
|
||||
printer_type?: string;
|
||||
printer_config?: any;
|
||||
status?: number;
|
||||
sort?: number;
|
||||
},
|
||||
@Req() req: AuthenticatedRequest,
|
||||
) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.edit(siteId, parseInt(printer_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除打印机
|
||||
*/
|
||||
@Delete('delete/:printer_id')
|
||||
async delete(@Param('printer_id') printer_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.delete(siteId, parseInt(printer_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试打印机
|
||||
*/
|
||||
@Post('test/:printer_id')
|
||||
async test(@Param('printer_id') printer_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.printerService.test(siteId, parseInt(printer_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取打印机类型
|
||||
*/
|
||||
@Get('types')
|
||||
async getTypes() {
|
||||
return this.printerService.getTypes();
|
||||
}
|
||||
}
|
||||
120
wwjcloud/src/common/sys/controllers/adminapi/RoleController.ts
Normal file
120
wwjcloud/src/common/sys/controllers/adminapi/RoleController.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { RoleService } from '../../services/admin/RoleService';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: {
|
||||
uid: number;
|
||||
username: string;
|
||||
siteId: number;
|
||||
userType: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('adminapi/sys/role')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class RoleController {
|
||||
constructor(private readonly roleService: RoleService) {}
|
||||
|
||||
/**
|
||||
* 用户组列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Req() req: AuthenticatedRequest, @Query('role_name') role_name?: string) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
const data = { role_name: role_name || '' };
|
||||
return this.roleService.getPage(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户组详情
|
||||
*/
|
||||
@Get('info/:role_id')
|
||||
async info(@Param('role_id') role_id: string) {
|
||||
return this.roleService.getInfo(parseInt(role_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户组
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
role_name: string;
|
||||
role_desc?: string;
|
||||
status?: number;
|
||||
menu_ids?: number[];
|
||||
}, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
const appType = 'admin';
|
||||
return this.roleService.add(siteId, appType, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑用户组
|
||||
*/
|
||||
@Put('edit/:role_id')
|
||||
async edit(
|
||||
@Param('role_id') role_id: string,
|
||||
@Body() data: {
|
||||
role_name?: string;
|
||||
role_desc?: string;
|
||||
status?: number;
|
||||
menu_ids?: number[];
|
||||
},
|
||||
@Req() req: AuthenticatedRequest,
|
||||
) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.roleService.edit(parseInt(role_id), siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户组
|
||||
*/
|
||||
@Delete('delete/:role_id')
|
||||
async delete(@Param('role_id') role_id: string) {
|
||||
return this.roleService.delete(parseInt(role_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色权限
|
||||
*/
|
||||
@Get('permissions/:role_id')
|
||||
async getPermissions(@Param('role_id') role_id: string) {
|
||||
return this.roleService.getPermissions(parseInt(role_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置角色权限
|
||||
*/
|
||||
@Post('permissions/:role_id')
|
||||
async setPermissions(
|
||||
@Param('role_id') role_id: string,
|
||||
@Body() data: { menu_ids: number[] },
|
||||
) {
|
||||
return this.roleService.setPermissions(parseInt(role_id), data.menu_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有角色
|
||||
*/
|
||||
@Get('all')
|
||||
async getAll(@Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
const userRoleIds: number[] = [];
|
||||
const isAdmin = true;
|
||||
return this.roleService.getAll(siteId, userRoleIds, isAdmin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Put,
|
||||
Delete,
|
||||
Body,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Req,
|
||||
} from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { ScheduleService } from '../../services/admin/ScheduleService';
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
user?: {
|
||||
uid: number;
|
||||
username: string;
|
||||
siteId: number;
|
||||
userType: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Controller('adminapi/sys/schedule')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ScheduleController {
|
||||
constructor(private readonly scheduleService: ScheduleService) {}
|
||||
|
||||
/**
|
||||
* 定时任务列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.getPage(siteId, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务信息
|
||||
*/
|
||||
@Get('info/:schedule_id')
|
||||
async info(@Param('schedule_id') schedule_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.getInfo(siteId, parseInt(schedule_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时任务
|
||||
*/
|
||||
@Post('add')
|
||||
async add(@Body() data: {
|
||||
schedule_name: string;
|
||||
schedule_type: string;
|
||||
schedule_config: any;
|
||||
cron_expression: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
}, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.add(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑定时任务
|
||||
*/
|
||||
@Put('edit/:schedule_id')
|
||||
async edit(
|
||||
@Param('schedule_id') schedule_id: string,
|
||||
@Body() data: {
|
||||
schedule_name?: string;
|
||||
schedule_type?: string;
|
||||
schedule_config?: any;
|
||||
cron_expression?: string;
|
||||
status?: number;
|
||||
description?: string;
|
||||
},
|
||||
@Req() req: AuthenticatedRequest,
|
||||
) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.edit(siteId, parseInt(schedule_id), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*/
|
||||
@Delete('delete/:schedule_id')
|
||||
async delete(@Param('schedule_id') schedule_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.delete(siteId, parseInt(schedule_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动定时任务
|
||||
*/
|
||||
@Post('start/:schedule_id')
|
||||
async start(@Param('schedule_id') schedule_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.start(siteId, parseInt(schedule_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止定时任务
|
||||
*/
|
||||
@Post('stop/:schedule_id')
|
||||
async stop(@Param('schedule_id') schedule_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.stop(siteId, parseInt(schedule_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行定时任务
|
||||
*/
|
||||
@Post('execute/:schedule_id')
|
||||
async execute(@Param('schedule_id') schedule_id: string, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.execute(siteId, parseInt(schedule_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定时任务日志
|
||||
*/
|
||||
@Get('logs/:schedule_id')
|
||||
async getLogs(@Param('schedule_id') schedule_id: string, @Query() query: any, @Req() req: AuthenticatedRequest) {
|
||||
const siteId = req.user?.siteId || 0;
|
||||
return this.scheduleService.getLogs(siteId, parseInt(schedule_id), query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Delete,
|
||||
Param,
|
||||
Query,
|
||||
UseGuards,
|
||||
Body,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { ScheduleLogService } from '../../services/admin/ScheduleLogService';
|
||||
|
||||
@Controller('adminapi/sys/schedule-log')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class ScheduleLogController {
|
||||
constructor(private readonly scheduleLogService: ScheduleLogService) {}
|
||||
|
||||
/**
|
||||
* 定时任务日志列表
|
||||
*/
|
||||
@Get('lists')
|
||||
async lists(@Query() query: any) {
|
||||
return this.scheduleLogService.getPage(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时任务日志信息
|
||||
*/
|
||||
@Get('info/:log_id')
|
||||
async info(@Param('log_id') log_id: string) {
|
||||
return this.scheduleLogService.getInfo(parseInt(log_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务日志
|
||||
*/
|
||||
@Delete('delete/:log_id')
|
||||
async delete(@Param('log_id') log_id: string) {
|
||||
return this.scheduleLogService.delete(parseInt(log_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除定时任务日志
|
||||
*/
|
||||
@Delete('batch-delete')
|
||||
async batchDelete(@Body() data: { log_ids: number[] }) {
|
||||
return this.scheduleLogService.batchDelete(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理过期日志
|
||||
*/
|
||||
@Post('clean')
|
||||
async clean(@Query('days') days?: string) {
|
||||
return this.scheduleLogService.clean(days ? parseInt(days) : 30);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日志统计
|
||||
*/
|
||||
@Get('statistics')
|
||||
async getStatistics(@Query() query: any) {
|
||||
return this.scheduleLogService.getStatistics(query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { SystemService } from '../../services/admin/SystemService';
|
||||
|
||||
@Controller('adminapi/sys/system')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class SystemController {
|
||||
constructor(private readonly systemService: SystemService) {}
|
||||
|
||||
/**
|
||||
* 获取当前系统信息
|
||||
*/
|
||||
@Get('info')
|
||||
async getInfo() {
|
||||
return this.systemService.getInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前url配置
|
||||
*/
|
||||
@Get('url')
|
||||
async getUrl() {
|
||||
return this.systemService.getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统环境配置
|
||||
*/
|
||||
@Get('system-info')
|
||||
async getSystemInfo() {
|
||||
return this.systemService.getSystemInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理表缓存
|
||||
*/
|
||||
@Post('schema-cache')
|
||||
async schemaCache() {
|
||||
return this.systemService.schemaCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
*/
|
||||
@Post('clear-cache')
|
||||
async clearCache() {
|
||||
return this.systemService.clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验消息队列是否正常运行
|
||||
*/
|
||||
@Get('check-job')
|
||||
async checkJob() {
|
||||
return this.systemService.checkJob();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验计划任务是否正常运行
|
||||
*/
|
||||
@Get('check-schedule')
|
||||
async checkSchedule() {
|
||||
return this.systemService.checkSchedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* 环境变量查询
|
||||
*/
|
||||
@Get('env-info')
|
||||
async getEnvInfo() {
|
||||
return this.systemService.getEnvInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推广二维码
|
||||
*/
|
||||
@Post('spread-qrcode')
|
||||
async getSpreadQrcode(@Body() params: {
|
||||
form_id?: string;
|
||||
folder?: string;
|
||||
page?: string;
|
||||
params?: any;
|
||||
}) {
|
||||
return this.systemService.getQrcode(params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Post,
|
||||
Body,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../../../auth/guards/JwtAuthGuard';
|
||||
import { RolesGuard } from '../../../auth/guards/RolesGuard';
|
||||
import { UeditorService } from '../../services/admin/UeditorService';
|
||||
|
||||
@Controller('adminapi/sys/ueditor')
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
export class UeditorController {
|
||||
constructor(private readonly ueditorService: UeditorService) {}
|
||||
|
||||
/**
|
||||
* 获取UEditor配置
|
||||
*/
|
||||
@Get('config')
|
||||
async getConfig() {
|
||||
return this.ueditorService.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传图片
|
||||
*/
|
||||
@Post('upload/image')
|
||||
async uploadImage(@Body() data: any) {
|
||||
return this.ueditorService.uploadImage(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*/
|
||||
@Post('upload/file')
|
||||
async uploadFile(@Body() data: any) {
|
||||
return this.ueditorService.uploadFile(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传视频
|
||||
*/
|
||||
@Post('upload/video')
|
||||
async uploadVideo(@Body() data: any) {
|
||||
return this.ueditorService.uploadVideo(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件列表
|
||||
*/
|
||||
@Get('list')
|
||||
async getList(@Query() query: any) {
|
||||
return this.ueditorService.getList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*/
|
||||
@Post('delete')
|
||||
async deleteFile(@Body() data: { file_name: string }) {
|
||||
return this.ueditorService.deleteFile(data.file_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件信息
|
||||
*/
|
||||
@Get('info')
|
||||
async getFileInfo(@Query('file_name') file_name: string) {
|
||||
return this.ueditorService.getFileInfo(file_name);
|
||||
}
|
||||
}
|
||||
@@ -80,4 +80,33 @@ export class AgreementService {
|
||||
member: '会员协议',
|
||||
};
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
return this.coreAgreementService.getPage(query);
|
||||
}
|
||||
|
||||
async getInfo(agreementId: number) {
|
||||
return this.coreAgreementService.getInfo(agreementId);
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
return this.coreAgreementService.add(data);
|
||||
}
|
||||
|
||||
async edit(agreementId: number, data: any) {
|
||||
return this.coreAgreementService.edit(agreementId, data);
|
||||
}
|
||||
|
||||
async delete(agreementId: number) {
|
||||
return this.coreAgreementService.delete(agreementId);
|
||||
}
|
||||
|
||||
async getTypes() {
|
||||
return this.getAgreementTypes();
|
||||
}
|
||||
|
||||
async getByType(agreementType: string) {
|
||||
return this.coreAgreementService.getByType(agreementType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,4 +127,38 @@ export class AppService {
|
||||
const app = await this.getAppInfo(appKey);
|
||||
return !!app;
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
// 临时实现,返回空分页数据
|
||||
return { data: [], total: 0, page: 1, limit: 10, pages: 0 };
|
||||
}
|
||||
|
||||
async getInfo(appId: number) {
|
||||
// 临时实现,返回空数据
|
||||
return null;
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true, id: Date.now() };
|
||||
}
|
||||
|
||||
async edit(appId: number, data: any) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async delete(appId: number) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async getTypes() {
|
||||
return [
|
||||
{ key: 'web', name: 'Web应用' },
|
||||
{ key: 'mobile', name: '移动应用' },
|
||||
{ key: 'api', name: 'API应用' },
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,4 +63,33 @@ export class AreaService {
|
||||
async searchArea(keyword: string, level?: number) {
|
||||
return await this.coreAreaService.searchArea(keyword, level);
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
return this.coreAreaService.getPage(query);
|
||||
}
|
||||
|
||||
async getInfo(areaId: number) {
|
||||
return this.coreAreaService.getInfo(areaId);
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
return this.coreAreaService.add(data);
|
||||
}
|
||||
|
||||
async edit(areaId: number, data: any) {
|
||||
return this.coreAreaService.edit(areaId, data);
|
||||
}
|
||||
|
||||
async delete(areaId: number) {
|
||||
return this.coreAreaService.delete(areaId);
|
||||
}
|
||||
|
||||
async getTree() {
|
||||
return this.coreAreaService.getTree();
|
||||
}
|
||||
|
||||
async getChildren(parentId: number) {
|
||||
return this.coreAreaService.getChildren(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,87 +10,54 @@ import { SysAttachment } from '../../entities/SysAttachment';
|
||||
export class AttachmentService {
|
||||
constructor(private readonly coreAttachmentService: CoreAttachmentService) {}
|
||||
|
||||
/**
|
||||
* 新增素材
|
||||
* @param siteId 站点ID
|
||||
* @param data 附件数据
|
||||
* @returns 创建的附件
|
||||
*/
|
||||
// 控制器契约:add(siteId, data)
|
||||
async add(siteId: number, data: Partial<SysAttachment>) {
|
||||
const attachmentData = { ...data, site_id: siteId };
|
||||
return await this.coreAttachmentService.add(attachmentData);
|
||||
const attachmentData = { ...data, site_id: siteId } as Partial<SysAttachment> & { site_id: number };
|
||||
return this.coreAttachmentService.add(attachmentData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑素材
|
||||
* @param siteId 站点ID
|
||||
* @param attId 附件ID
|
||||
* @param data 更新数据
|
||||
* @returns 是否成功
|
||||
*/
|
||||
// 控制器契约:edit(siteId, attId, data)
|
||||
async edit(siteId: number, attId: number, data: Partial<SysAttachment>) {
|
||||
return await this.coreAttachmentService.edit(siteId, attId, data);
|
||||
return this.coreAttachmentService.edit(siteId, attId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改附件分组
|
||||
* @param siteId 站点ID
|
||||
* @param attId 附件ID
|
||||
* @param cateId 分类ID
|
||||
* @returns 是否成功
|
||||
*/
|
||||
// 控制器契约:modifyCategory(siteId, attId, cateId)
|
||||
async modifyCategory(siteId: number, attId: number, cateId: number) {
|
||||
return await this.coreAttachmentService.modifyCategory(
|
||||
siteId,
|
||||
attId,
|
||||
cateId,
|
||||
);
|
||||
return this.coreAttachmentService.modifyCategory(siteId, attId, cateId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件分页列表
|
||||
* @param siteId 站点ID
|
||||
* @param data 查询参数
|
||||
* @returns 分页结果
|
||||
*/
|
||||
async getPage(siteId: number, data: any = {}) {
|
||||
const { name, cate_id, page = 1, limit = 10 } = data;
|
||||
return await this.coreAttachmentService.getPage(
|
||||
siteId,
|
||||
name,
|
||||
cate_id,
|
||||
page,
|
||||
limit,
|
||||
);
|
||||
// 控制器契约:getPage(siteId, query)
|
||||
async getPage(siteId: number, query: any = {}) {
|
||||
const { name, cate_id, page = 1, limit = 10 } = query || {};
|
||||
return this.coreAttachmentService.getPage(Number(siteId || 0), name, cate_id, page, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件详情
|
||||
* @param siteId 站点ID
|
||||
* @param attId 附件ID
|
||||
* @returns 附件信息
|
||||
*/
|
||||
// 控制器契约:getInfo(siteId, attId)
|
||||
async getInfo(siteId: number, attId: number) {
|
||||
return await this.coreAttachmentService.getInfo(siteId, attId);
|
||||
return this.coreAttachmentService.getInfo(siteId, attId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除附件
|
||||
* @param siteId 站点ID
|
||||
* @param attId 附件ID
|
||||
* @returns 是否成功
|
||||
*/
|
||||
// 兼容控制器调用名:del(siteId, attId)
|
||||
async del(siteId: number, attId: number) {
|
||||
return await this.coreAttachmentService.del(siteId, attId);
|
||||
return this.coreAttachmentService.del(siteId, attId);
|
||||
}
|
||||
|
||||
// 控制器契约:batchDelete(siteId, attIds)
|
||||
async batchDelete(siteId: number, attIds: number[]) {
|
||||
return this.coreAttachmentService.batchDelete(siteId, attIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除附件
|
||||
* @param siteId 站点ID
|
||||
* @param attIds 附件ID数组
|
||||
* @returns 是否成功
|
||||
* 获取附件分类(占位)
|
||||
*/
|
||||
async batchDelete(siteId: number, attIds: number[]) {
|
||||
return await this.coreAttachmentService.batchDelete(siteId, attIds);
|
||||
async getCategories() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传附件(占位)
|
||||
*/
|
||||
async upload(data: any) {
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,4 +109,13 @@ export class ChannelService {
|
||||
async setConfig(id: number, config: any) {
|
||||
return await this.coreChannelService.setConfig(id, config);
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
return this.coreChannelService.getPage(query);
|
||||
}
|
||||
|
||||
async getTypes() {
|
||||
return this.getChannelTypes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,27 @@ export class CommonService {
|
||||
return await this.coreCommonService.getSystemStats();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有字典(与控制器对齐)
|
||||
*/
|
||||
async getDicts() {
|
||||
return await this.coreCommonService.getDicts();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区
|
||||
*/
|
||||
async getArea(parentId: number) {
|
||||
return await this.coreCommonService.getArea(parentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地区树
|
||||
*/
|
||||
async getAreaTree() {
|
||||
return await this.coreCommonService.getAreaTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统缓存
|
||||
* @returns 是否成功
|
||||
@@ -97,4 +118,9 @@ export class CommonService {
|
||||
async performMaintenance(action: string) {
|
||||
return await this.coreCommonService.performMaintenance(action);
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getStatistics() {
|
||||
return this.getSystemStats();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,156 +1,126 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreConfigService } from '../core/CoreConfigService';
|
||||
import { ConfigCenterService } from '../../../../config/services/configCenterService';
|
||||
|
||||
/**
|
||||
* 系统配置服务 - Admin层
|
||||
* 对应PHP: app\service\admin\sys\ConfigService
|
||||
*/
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
constructor(
|
||||
private readonly coreConfigService: CoreConfigService,
|
||||
private readonly configCenter: ConfigCenterService,
|
||||
) {}
|
||||
constructor(private readonly coreConfigService: CoreConfigService) {}
|
||||
|
||||
/**
|
||||
* 获取网站设置
|
||||
*/
|
||||
async getWebSite(siteId: number) {
|
||||
return this.coreConfigService.getWebSite(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 网站设置
|
||||
*/
|
||||
async setWebSite(siteId: number, data: any) {
|
||||
return this.coreConfigService.setWebSite(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权信息
|
||||
* @param siteId 站点ID
|
||||
* @returns 版权配置信息
|
||||
*/
|
||||
async getCopyright(siteId: number = 0) {
|
||||
return await this.coreConfigService.getCopyright(siteId);
|
||||
async getCopyright(siteId: number) {
|
||||
return this.coreConfigService.getCopyright(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置版权信息
|
||||
* @param siteId 站点ID
|
||||
* @param value 版权信息
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setCopyright(siteId: number, value: any) {
|
||||
const data = {
|
||||
icp: value.icp || '',
|
||||
gov_record: value.gov_record || '',
|
||||
gov_url: value.gov_url || '',
|
||||
market_supervision_url: value.market_supervision_url || '',
|
||||
logo: value.logo || '',
|
||||
company_name: value.company_name || '',
|
||||
copyright_link: value.copyright_link || '',
|
||||
copyright_desc: value.copyright_desc || '',
|
||||
};
|
||||
|
||||
return await this.coreConfigService.setConfig(
|
||||
siteId,
|
||||
'COPYRIGHT',
|
||||
data,
|
||||
'版权信息配置',
|
||||
);
|
||||
async setCopyright(siteId: number, data: any) {
|
||||
return this.coreConfigService.setCopyright(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网站信息
|
||||
* @param siteId 站点ID
|
||||
* @returns 网站配置信息
|
||||
*/
|
||||
async getWebSite(siteId: number) {
|
||||
const websiteInfo = await this.coreConfigService.getConfig(
|
||||
siteId,
|
||||
'WEBSITE',
|
||||
{},
|
||||
);
|
||||
const serviceInfo = await this.getService(siteId);
|
||||
|
||||
return {
|
||||
...websiteInfo,
|
||||
site_login_logo: serviceInfo.site_login_logo,
|
||||
site_login_bg_img: serviceInfo.site_login_bg_img,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置网站信息
|
||||
* @param siteId 站点ID
|
||||
* @param data 网站信息
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setWebSite(siteId: number, data: any) {
|
||||
return await this.coreConfigService.setConfig(
|
||||
siteId,
|
||||
'WEBSITE',
|
||||
data,
|
||||
'网站信息配置',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务配置信息
|
||||
* @param siteId 站点ID
|
||||
* @returns 服务配置
|
||||
*/
|
||||
async getService(siteId: number) {
|
||||
return await this.coreConfigService.getConfig(siteId, 'SERVICE', {
|
||||
site_login_logo: '',
|
||||
site_login_bg_img: '',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置服务配置信息
|
||||
* @param siteId 站点ID
|
||||
* @param data 服务配置
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setService(siteId: number, data: any) {
|
||||
return await this.coreConfigService.setConfig(
|
||||
siteId,
|
||||
'SERVICE',
|
||||
data,
|
||||
'服务配置',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景域名配置
|
||||
* @param siteId 站点ID
|
||||
* @returns 域名配置
|
||||
* 场景域名
|
||||
*/
|
||||
async getSceneDomain(siteId: number) {
|
||||
return await this.coreConfigService.getSceneDomain(siteId);
|
||||
return this.coreConfigService.getSceneDomain(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置场景域名配置
|
||||
* @param siteId 站点ID
|
||||
* @param data 域名配置
|
||||
* @returns 是否成功
|
||||
* 设置场景域名
|
||||
*/
|
||||
async setSceneDomain(siteId: number, data: any) {
|
||||
return await this.coreConfigService.setConfig(
|
||||
siteId,
|
||||
'SCENE_DOMAIN',
|
||||
data,
|
||||
'场景域名配置',
|
||||
);
|
||||
// 复用 setService 或专门落库 'scene_domain'
|
||||
// 直接透传到 core 层(若无实现,则在 core 内新增)
|
||||
const core: any = this.coreConfigService as any;
|
||||
if (typeof core.setSceneDomain === 'function') {
|
||||
return core.setSceneDomain(siteId, data);
|
||||
}
|
||||
// 兜底:把 scene_domain 存到统一配置键
|
||||
return this.coreConfigService.setService(siteId, { ...(data || {}) });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置列表
|
||||
* @param siteId 站点ID
|
||||
* @param keys 配置键数组
|
||||
* @returns 配置列表
|
||||
* 获取服务信息
|
||||
*/
|
||||
async getConfigList(siteId: number, keys: string[] = []) {
|
||||
return await this.coreConfigService.getConfigs(siteId, keys);
|
||||
async getService(siteId: number) {
|
||||
return this.coreConfigService.getService(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置配置
|
||||
* @param siteId 站点ID
|
||||
* @param configs 配置对象
|
||||
* @returns 是否成功
|
||||
* 设置服务信息
|
||||
*/
|
||||
async setConfigList(siteId: number, configs: Record<string, any>) {
|
||||
return await this.coreConfigService.setConfigs(siteId, configs);
|
||||
async setService(siteId: number, data: any) {
|
||||
return this.coreConfigService.setService(siteId, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图信息
|
||||
*/
|
||||
async setMap(siteId: number, data: any) {
|
||||
return this.coreConfigService.setMap(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图设置
|
||||
*/
|
||||
async getMap(siteId: number) {
|
||||
return this.coreConfigService.getMap(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开发者key
|
||||
*/
|
||||
async getDeveloperToken(siteId: number) {
|
||||
return this.coreConfigService.getDeveloperToken(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开发者key
|
||||
*/
|
||||
async setDeveloperToken(siteId: number, data: any) {
|
||||
return this.coreConfigService.setDeveloperToken(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局设置
|
||||
*/
|
||||
async setLayout(siteId: number, data: any) {
|
||||
return this.coreConfigService.setLayout(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取布局设置
|
||||
*/
|
||||
async getLayout(siteId: number) {
|
||||
return this.coreConfigService.getLayout(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置色调设置
|
||||
*/
|
||||
async setThemeColor(siteId: number, data: any) {
|
||||
return this.coreConfigService.setThemeColor(siteId, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取色调设置
|
||||
*/
|
||||
async getThemeColor(siteId: number) {
|
||||
return this.coreConfigService.getThemeColor(siteId);
|
||||
}
|
||||
}
|
||||
@@ -11,18 +11,31 @@ export class ExportService {
|
||||
|
||||
/**
|
||||
* 报表导出列表
|
||||
* @param siteId 站点ID
|
||||
* @param data 查询参数
|
||||
* @param siteIdOrQuery 站点ID 或查询参数
|
||||
* @param data 查询参数(当第一个参数是siteId时)
|
||||
* @returns 分页结果
|
||||
*/
|
||||
async getPage(siteId: number, data: any = {}) {
|
||||
async getPage(siteIdOrQuery: number | any, data: any = {}) {
|
||||
let siteId: number;
|
||||
let queryData: any;
|
||||
|
||||
if (typeof siteIdOrQuery === 'number') {
|
||||
// 原有调用方式:getPage(siteId, data)
|
||||
siteId = siteIdOrQuery;
|
||||
queryData = data;
|
||||
} else {
|
||||
// 控制器调用方式:getPage(query)
|
||||
siteId = 0; // 临时值,实际应从请求中获取
|
||||
queryData = siteIdOrQuery;
|
||||
}
|
||||
|
||||
const {
|
||||
export_key,
|
||||
export_status,
|
||||
create_time,
|
||||
page = 1,
|
||||
limit = 10,
|
||||
} = data;
|
||||
} = queryData;
|
||||
return await this.coreExportService.getPage(
|
||||
siteId,
|
||||
export_key,
|
||||
@@ -124,4 +137,29 @@ export class ExportService {
|
||||
async deleteRecord(siteId: number, id: number) {
|
||||
return await this.coreExportService.deleteExportRecord(siteId, id);
|
||||
}
|
||||
|
||||
|
||||
async getInfo(exportId: number) {
|
||||
return this.coreExportService.getInfo(exportId);
|
||||
}
|
||||
|
||||
async create(data: any) {
|
||||
return this.coreExportService.create(data);
|
||||
}
|
||||
|
||||
async execute(exportId: number) {
|
||||
return this.coreExportService.execute(exportId);
|
||||
}
|
||||
|
||||
async download(exportId: number) {
|
||||
return this.coreExportService.download(exportId);
|
||||
}
|
||||
|
||||
async delete(exportId: number) {
|
||||
return this.coreExportService.delete(exportId);
|
||||
}
|
||||
|
||||
async getTemplates() {
|
||||
return this.coreExportService.getTemplates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,270 +1,91 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreMenuService } from '../core/CoreMenuService';
|
||||
import { SysMenu } from '../../../rbac/entities/SysMenu';
|
||||
|
||||
/**
|
||||
* 菜单服务 - Admin层
|
||||
* 对应PHP: app\service\admin\sys\MenuService
|
||||
*/
|
||||
@Injectable()
|
||||
export class MenuService {
|
||||
constructor(private readonly coreMenuService: CoreMenuService) {}
|
||||
|
||||
/**
|
||||
* 新增菜单
|
||||
* @param data 菜单数据
|
||||
* @returns 创建的菜单
|
||||
* 菜单列表
|
||||
*/
|
||||
async add(data: Partial<SysMenu>): Promise<SysMenu> {
|
||||
return await this.coreMenuService.createMenu(data);
|
||||
async getAllMenuList(app_type: string, type: string, status: number) {
|
||||
return this.coreMenuService.getAllMenuList(app_type, type, status as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新菜单
|
||||
* @param appType 应用类型
|
||||
* @param menuKey 菜单键
|
||||
* @param data 更新数据
|
||||
* @returns 是否成功
|
||||
* 菜单信息
|
||||
*/
|
||||
async edit(
|
||||
appType: string,
|
||||
menuKey: string,
|
||||
data: Partial<SysMenu>,
|
||||
): Promise<boolean> {
|
||||
return await this.coreMenuService.updateMenu(appType, menuKey, data);
|
||||
async get(app_type: string, menu_key: string) {
|
||||
return this.coreMenuService.get(app_type, menu_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单信息
|
||||
* @param appType 应用类型
|
||||
* @param menuKey 菜单键
|
||||
* @returns 菜单信息
|
||||
* 添加菜单
|
||||
*/
|
||||
async get(appType: string, menuKey: string): Promise<SysMenu | null> {
|
||||
return await this.coreMenuService.findByMenuKey(menuKey, appType);
|
||||
async add(data: any) {
|
||||
return this.coreMenuService.add(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找菜单
|
||||
* @param menuKey 菜单键
|
||||
* @param appType 应用类型
|
||||
* @returns 菜单实体
|
||||
* 编辑菜单 - 控制器契约:edit(appType, menuKey, data)
|
||||
*/
|
||||
async find(menuKey: string, appType?: string): Promise<SysMenu | null> {
|
||||
return await this.coreMenuService.findByMenuKey(menuKey, appType);
|
||||
async edit(appType: string, menuKey: string, data: any) {
|
||||
return this.coreMenuService.updateMenu(appType, menuKey, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
* @param appType 应用类型
|
||||
* @param menuKey 菜单键
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async del(appType: string, menuKey: string): Promise<boolean> {
|
||||
return await this.coreMenuService.deleteMenu(appType, menuKey);
|
||||
async delete(menu_key: string) {
|
||||
return this.coreMenuService.delete(menu_key as any);
|
||||
}
|
||||
|
||||
async del(appType: string, menuKey: string) {
|
||||
return this.coreMenuService.deleteMenu(appType, menuKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过菜单键数组获取菜单列表
|
||||
* @param siteId 站点ID
|
||||
* @param menuKeys 菜单键数组
|
||||
* @param appType 应用类型
|
||||
* @param isTree 是否返回树形结构
|
||||
* @param addon 插件标识
|
||||
* @param isButton 是否包含按钮
|
||||
* @returns 菜单列表
|
||||
* 菜单排序
|
||||
*/
|
||||
async getMenuListByMenuKeys(
|
||||
siteId: number,
|
||||
menuKeys: string[],
|
||||
appType: string,
|
||||
isTree: number = 0,
|
||||
addon: string = 'all',
|
||||
isButton: number = 1,
|
||||
): Promise<any[]> {
|
||||
// TODO: 这里需要实现插件服务来获取站点的插件列表
|
||||
// 暂时使用空数组,后续完善插件模块时补充
|
||||
const addons: string[] = [''];
|
||||
|
||||
const menuList = await this.coreMenuService.getMenusByKeys(
|
||||
siteId,
|
||||
menuKeys,
|
||||
appType,
|
||||
addon,
|
||||
addons,
|
||||
);
|
||||
|
||||
// 处理多语言 - 暂时跳过,后续完善多语言模块时补充
|
||||
// TODO: 实现多语言处理逻辑
|
||||
|
||||
if (isTree) {
|
||||
return this.coreMenuService.buildMenuTree(
|
||||
menuList,
|
||||
'menu_key',
|
||||
'parent_key',
|
||||
'children',
|
||||
'',
|
||||
isButton,
|
||||
);
|
||||
}
|
||||
|
||||
return menuList;
|
||||
async sort(menu_keys: string[]) {
|
||||
return this.coreMenuService.sort(menu_keys as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有API菜单
|
||||
* @param appType 应用类型
|
||||
* @param addon 插件标识
|
||||
* @returns API菜单列表
|
||||
* 获取菜单树
|
||||
*/
|
||||
async getAllApiMenus(
|
||||
appType: string = 'admin',
|
||||
addon: string = '',
|
||||
): Promise<SysMenu[]> {
|
||||
return await this.coreMenuService.getAllApiMenus(appType, addon);
|
||||
async getMenuTree(app_type: string) {
|
||||
return this.coreMenuService.getMenuTree(app_type as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统菜单
|
||||
* @param status 状态过滤
|
||||
* @param isTree 是否返回树形结构
|
||||
* @param isButton 是否包含按钮
|
||||
* @returns 系统菜单
|
||||
* 获取用户菜单
|
||||
*/
|
||||
async getSystemMenu(
|
||||
status: string | number = 'all',
|
||||
isTree: number = 0,
|
||||
isButton: number = 0,
|
||||
): Promise<any[]> {
|
||||
const menuList = await this.coreMenuService.getSystemMenus(
|
||||
status,
|
||||
isButton,
|
||||
);
|
||||
|
||||
// 处理多语言 - 暂时跳过,后续完善多语言模块时补充
|
||||
// TODO: 实现多语言处理逻辑
|
||||
|
||||
if (isTree) {
|
||||
const treeMenus = this.coreMenuService.buildMenuTree(
|
||||
menuList,
|
||||
'menu_key',
|
||||
'parent_key',
|
||||
'children',
|
||||
'',
|
||||
isButton,
|
||||
);
|
||||
return this.moveChildrenToParent(treeMenus);
|
||||
}
|
||||
|
||||
return menuList;
|
||||
async getUserMenu(app_type: string) {
|
||||
return this.coreMenuService.getUserMenu(app_type as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件菜单
|
||||
* @param appKey 插件键
|
||||
* @param status 状态过滤
|
||||
* @param isTree 是否返回树形结构
|
||||
* @param isButton 是否包含按钮
|
||||
* @returns 插件菜单
|
||||
*/
|
||||
async getAddonMenu(
|
||||
appKey: string,
|
||||
status: string | number = 'all',
|
||||
isTree: number = 0,
|
||||
isButton: number = 0,
|
||||
): Promise<any[]> {
|
||||
const menuList = await this.coreMenuService.getAddonMenus(
|
||||
appKey,
|
||||
status,
|
||||
isButton,
|
||||
);
|
||||
|
||||
if (isTree) {
|
||||
return this.coreMenuService.buildMenuTree(
|
||||
menuList,
|
||||
'menu_key',
|
||||
'parent_key',
|
||||
'children',
|
||||
'',
|
||||
isButton,
|
||||
);
|
||||
}
|
||||
|
||||
return menuList;
|
||||
async getSystemMenu(appType: string, status: string | number = 'all', isButton: number = 0) {
|
||||
return this.coreMenuService.getSystemMenus(status, isButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取目录类型菜单
|
||||
* @param addon 插件标识
|
||||
* @returns 目录菜单树形结构
|
||||
*/
|
||||
async getMenuByTypeDir(addon: string = 'system'): Promise<any[]> {
|
||||
const menuList = await this.coreMenuService.getMenusByTypeDir(addon);
|
||||
|
||||
// 处理多语言 - 暂时跳过,后续完善多语言模块时补充
|
||||
// TODO: 实现多语言处理逻辑
|
||||
|
||||
return this.coreMenuService.buildMenuTree(
|
||||
menuList,
|
||||
'menu_key',
|
||||
'parent_key',
|
||||
'children',
|
||||
'',
|
||||
0,
|
||||
);
|
||||
async getAddonMenu(appKey: string, status: string | number = 'all', isTree: number = 0, isButton: number = 0) {
|
||||
return this.coreMenuService.getAddonMenus(appKey, status, isButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据系统配置获取菜单键列表
|
||||
* @param appType 应用类型
|
||||
* @param addons 插件列表
|
||||
* @returns 菜单键数组
|
||||
*/
|
||||
async getMenuKeysBySystem(
|
||||
appType: string,
|
||||
addons: string[],
|
||||
): Promise<string[]> {
|
||||
return await this.coreMenuService.getMenuKeysBySystem(appType, addons);
|
||||
async getMenuListByMenuKeys(siteId: number, menuKeys: string[], appType: string, isTree: number, addon: string, isButton: number) {
|
||||
return this.coreMenuService.getMenusByKeys(siteId, menuKeys, appType, addon, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动子节点到父节点 - 辅助方法
|
||||
* @param menuList 菜单列表
|
||||
* @returns 处理后的菜单列表
|
||||
*/
|
||||
private moveChildrenToParent(menuList: any[]): any[] {
|
||||
// 这个方法的具体实现需要根据PHP代码的逻辑来完善
|
||||
// 暂时返回原始数据,后续根据需求完善
|
||||
return menuList;
|
||||
async getAllApiMenus(appType: string, addon: string) {
|
||||
return this.coreMenuService.getAllApiMenus(appType, addon);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建菜单树形结构 - 对外接口
|
||||
* @param menus 菜单列表
|
||||
* @param keyField 键字段
|
||||
* @param parentKeyField 父键字段
|
||||
* @param childrenField 子节点字段名
|
||||
* @param authField 权限字段
|
||||
* @param parentKey 父键值
|
||||
* @param isButton 是否包含按钮
|
||||
* @returns 树形菜单结构
|
||||
*/
|
||||
menuToTree(
|
||||
menus: any[],
|
||||
keyField: string = 'menu_key',
|
||||
parentKeyField: string = 'parent_key',
|
||||
childrenField: string = 'children',
|
||||
authField: string = 'auth',
|
||||
parentKey: string = '',
|
||||
isButton: number = 1,
|
||||
): any[] {
|
||||
return this.coreMenuService.buildMenuTree(
|
||||
menus,
|
||||
keyField,
|
||||
parentKeyField,
|
||||
childrenField,
|
||||
parentKey,
|
||||
isButton,
|
||||
);
|
||||
async getMenuByTypeDir(addon: string) {
|
||||
return this.coreMenuService.getMenusByTypeDir(addon);
|
||||
}
|
||||
}
|
||||
|
||||
async getMenuKeysBySystem(appType: string, addons: string[]) {
|
||||
return this.coreMenuService.getMenuKeysBySystem(appType, addons);
|
||||
}
|
||||
}
|
||||
@@ -108,4 +108,17 @@ export class PosterService {
|
||||
getPosterTypes() {
|
||||
return this.corePosterService.getPosterTypes();
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async delete(siteId: number, id: number) {
|
||||
return this.del(siteId, id);
|
||||
}
|
||||
|
||||
async generate(siteId: number, id: number, data: any) {
|
||||
return this.corePosterService.generate(siteId, id, data);
|
||||
}
|
||||
|
||||
async getTemplates() {
|
||||
return this.corePosterService.getTemplates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,4 +126,17 @@ export class PrinterService {
|
||||
'365': '365云打印',
|
||||
};
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async delete(siteId: number, printerId: number) {
|
||||
return this.del(siteId, printerId);
|
||||
}
|
||||
|
||||
async test(siteId: number, printerId: number) {
|
||||
return this.testConnection(siteId, printerId);
|
||||
}
|
||||
|
||||
async getTypes() {
|
||||
return this.getBrandList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,216 +1,77 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreRoleService } from '../core/CoreRoleService';
|
||||
import { SysRole } from '../../../rbac/entities/SysRole';
|
||||
|
||||
/**
|
||||
* 角色服务 - Admin层
|
||||
* 对应PHP: app\service\admin\sys\RoleService
|
||||
*/
|
||||
@Injectable()
|
||||
export class RoleService {
|
||||
constructor(private readonly coreRoleService: CoreRoleService) {}
|
||||
|
||||
/**
|
||||
* 管理端获取角色列表
|
||||
* @param siteId 站点ID
|
||||
* @param data 查询参数
|
||||
* @returns 分页结果
|
||||
* 用户组列表 - 控制器契约:getPage(siteId, query)
|
||||
*/
|
||||
async getPage(siteId: number, data: any = {}) {
|
||||
const { role_name, page = 1, limit = 10 } = data;
|
||||
return await this.coreRoleService.getPage(siteId, role_name, page, limit);
|
||||
async getPage(siteId: number, query: any) {
|
||||
return this.coreRoleService.getPage({ ...query, site_id: siteId });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色信息
|
||||
* @param roleId 角色ID
|
||||
* @returns 角色信息
|
||||
* 用户组详情
|
||||
*/
|
||||
async getInfo(roleId: number): Promise<SysRole | null> {
|
||||
return await this.coreRoleService.getInfo(roleId);
|
||||
async getInfo(role_id: number) {
|
||||
return this.coreRoleService.getInfo(role_id);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除用户组
|
||||
*/
|
||||
async delete(role_id: number) {
|
||||
return this.coreRoleService.delete(role_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点下的所有角色
|
||||
* @param siteId 站点ID
|
||||
* @param userRoleIds 当前用户的角色ID数组(用于权限过滤)
|
||||
* @param isAdmin 是否是超级管理员
|
||||
* @returns 角色列表
|
||||
* 获取角色权限
|
||||
*/
|
||||
async getAll(
|
||||
siteId: number,
|
||||
userRoleIds: number[] = [],
|
||||
isAdmin: boolean = false,
|
||||
): Promise<any[]> {
|
||||
const siteRoleAll = await this.coreRoleService.getAll(siteId);
|
||||
|
||||
// 为每个角色添加disabled字段
|
||||
const result = siteRoleAll.map((role) => ({
|
||||
...role,
|
||||
disabled: false,
|
||||
}));
|
||||
|
||||
// 如果不是超级管理员,需要检查权限
|
||||
if (!isAdmin && userRoleIds.length > 0) {
|
||||
// TODO: 实现菜单权限检查逻辑
|
||||
// 暂时跳过权限检查,后续完善权限模块时补充
|
||||
// const menuKeys = await this.getMenuIdsByRoleIds(siteId, userRoleIds);
|
||||
// 检查每个角色的权限是否超出当前用户权限
|
||||
}
|
||||
|
||||
// 移除rules字段,不返回给前端
|
||||
return result.map((role) => {
|
||||
const { rules, ...roleWithoutRules } = role;
|
||||
return roleWithoutRules;
|
||||
});
|
||||
async getPermissions(role_id: number) {
|
||||
return this.coreRoleService.getPermissions(role_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增角色
|
||||
* @param siteId 站点ID
|
||||
* @param appType 应用类型
|
||||
* @param data 角色数据
|
||||
* @returns 是否成功
|
||||
* 设置角色权限
|
||||
*/
|
||||
async add(
|
||||
siteId: number,
|
||||
appType: string,
|
||||
data: Partial<SysRole>,
|
||||
): Promise<boolean> {
|
||||
const roleData = {
|
||||
...data,
|
||||
site_id: siteId,
|
||||
// app_type: appType, // 根据数据表结构,暂时不添加app_type字段
|
||||
};
|
||||
|
||||
await this.coreRoleService.add(roleData);
|
||||
return true;
|
||||
async setPermissions(role_id: number, menu_ids: number[]) {
|
||||
return this.coreRoleService.setPermissions(role_id, menu_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新角色
|
||||
* @param roleId 角色ID
|
||||
* @param siteId 站点ID
|
||||
* @param data 更新数据
|
||||
* @returns 是否成功
|
||||
* 获取所有角色(与控制器对齐)
|
||||
*/
|
||||
async edit(
|
||||
roleId: number,
|
||||
siteId: number,
|
||||
data: Partial<SysRole>,
|
||||
): Promise<boolean> {
|
||||
return await this.coreRoleService.edit(roleId, siteId, data);
|
||||
async getAll(siteId: number, userRoleIds?: number[], isAdmin?: boolean) {
|
||||
const isAdminNum = isAdmin ? 1 : 0;
|
||||
return this.coreRoleService.getAll(siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改角色状态
|
||||
* @param roleId 角色ID
|
||||
* @param siteId 站点ID
|
||||
* @param status 状态
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async modifyStatus(
|
||||
roleId: number,
|
||||
siteId: number,
|
||||
status: number,
|
||||
): Promise<boolean> {
|
||||
return await this.coreRoleService.modifyStatus(roleId, siteId, status);
|
||||
async getColumn(siteId: number) {
|
||||
return this.coreRoleService.getColumn(siteId as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找角色
|
||||
* @param siteId 站点ID
|
||||
* @param roleId 角色ID
|
||||
* @returns 角色实体
|
||||
*/
|
||||
async find(siteId: number, roleId: number): Promise<SysRole> {
|
||||
const role = await this.coreRoleService.find(siteId, roleId);
|
||||
if (!role) {
|
||||
throw new Error('角色不存在');
|
||||
}
|
||||
return role;
|
||||
async modifyStatus(roleId: number, siteId: number, status: number) {
|
||||
return this.coreRoleService.modifyStatus(roleId as any, siteId as any, status as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
* @param roleId 角色ID
|
||||
* @param siteId 站点ID
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async del(roleId: number, siteId: number): Promise<boolean> {
|
||||
// 先检查角色是否存在
|
||||
await this.find(siteId, roleId);
|
||||
|
||||
// 检查是否有用户使用该角色
|
||||
// TODO: 需要检查SysUserRole表
|
||||
// 暂时跳过用户角色关联检查,后续完善用户模块时补充
|
||||
|
||||
return await this.coreRoleService.del(roleId, siteId);
|
||||
async del(roleId: number, siteId: number) {
|
||||
return this.coreRoleService.del(roleId as any, siteId as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色ID和名称的键值对
|
||||
* @param siteId 站点ID
|
||||
* @returns 角色键值对
|
||||
*/
|
||||
async getColumn(siteId: number): Promise<Record<number, string>> {
|
||||
return await this.coreRoleService.getColumn(siteId);
|
||||
async getMenuIdsByRoleIds(siteId: number, roleIds: number[], allowMenuKeys?: string[]) {
|
||||
return this.coreRoleService.getMenuIdsByRoleIds(siteId as any, roleIds as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过角色ID数组获取菜单权限
|
||||
* @param siteId 站点ID
|
||||
* @param roleIds 角色ID数组
|
||||
* @param allowMenuKeys 允许的菜单键列表
|
||||
* @returns 菜单键数组
|
||||
*/
|
||||
async getMenuIdsByRoleIds(
|
||||
siteId: number,
|
||||
roleIds: number[],
|
||||
allowMenuKeys: string[] = [],
|
||||
): Promise<string[]> {
|
||||
return await this.coreRoleService.getMenuIdsByRoleIds(
|
||||
siteId,
|
||||
roleIds,
|
||||
allowMenuKeys,
|
||||
);
|
||||
// 控制器契约:add(siteId, appType, data)
|
||||
async add(siteId: number, appType: string, data: any) {
|
||||
return this.coreRoleService.add({ ...data, site_id: siteId, app_type: appType });
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色ID数组获取角色列表
|
||||
* @param roleIds 角色ID数组
|
||||
* @returns 角色列表
|
||||
*/
|
||||
async getRolesByIds(roleIds: number[]): Promise<SysRole[]> {
|
||||
return await this.coreRoleService.getRolesByIds(roleIds);
|
||||
// 控制器契约:edit(roleId, siteId, data)
|
||||
async edit(roleId: number, siteId: number, data: any) {
|
||||
return this.coreRoleService.edit(roleId, siteId, { ...data, site_id: siteId });
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否为超级管理员
|
||||
* @param userId 用户ID
|
||||
* @param siteId 站点ID
|
||||
* @returns 是否为超级管理员
|
||||
*/
|
||||
async isSuperAdmin(userId: number, siteId: number): Promise<boolean> {
|
||||
// TODO: 实现超级管理员检查逻辑
|
||||
// 需要与AuthService配合实现
|
||||
// 暂时返回false,后续完善权限模块时补充
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户的角色权限信息
|
||||
* @param userId 用户ID
|
||||
* @param siteId 站点ID
|
||||
* @returns 角色权限信息
|
||||
*/
|
||||
async getUserRoleInfo(userId: number, siteId: number): Promise<any> {
|
||||
// TODO: 实现用户角色信息获取逻辑
|
||||
// 需要与用户模块配合实现
|
||||
// 暂时返回空对象,后续完善用户模块时补充
|
||||
return {
|
||||
role_ids: [],
|
||||
is_admin: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
49
wwjcloud/src/common/sys/services/admin/ScheduleLogService.ts
Normal file
49
wwjcloud/src/common/sys/services/admin/ScheduleLogService.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreScheduleLogService } from '../core/CoreScheduleLogService';
|
||||
|
||||
@Injectable()
|
||||
export class ScheduleLogService {
|
||||
constructor(
|
||||
private readonly coreScheduleLogService: CoreScheduleLogService,
|
||||
) {}
|
||||
|
||||
async getPage(query: any) {
|
||||
return this.coreScheduleLogService.getPage(query);
|
||||
}
|
||||
|
||||
async getInfo(logId: number) {
|
||||
return this.coreScheduleLogService.getInfo(logId);
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
return this.coreScheduleLogService.add(data);
|
||||
}
|
||||
|
||||
async edit(logId: number, data: any) {
|
||||
return this.coreScheduleLogService.edit(logId, data);
|
||||
}
|
||||
|
||||
async delete(logId: number) {
|
||||
return this.coreScheduleLogService.delete(logId);
|
||||
}
|
||||
|
||||
async batchDelete(data: { log_ids: number[] }) {
|
||||
return this.coreScheduleLogService.batchDelete(data.log_ids);
|
||||
}
|
||||
|
||||
async getStatistics(query?: any) {
|
||||
return this.coreScheduleLogService.getStatistics(query);
|
||||
}
|
||||
|
||||
async export(query: any) {
|
||||
return this.coreScheduleLogService.export(query);
|
||||
}
|
||||
|
||||
async clean(days: number) {
|
||||
return this.coreScheduleLogService.clean(days);
|
||||
}
|
||||
|
||||
async getLogsBySchedule(scheduleId: number, query: any) {
|
||||
return this.coreScheduleLogService.getLogsBySchedule(scheduleId, query);
|
||||
}
|
||||
}
|
||||
@@ -72,4 +72,17 @@ export class ScheduleService {
|
||||
async stop(siteId: number, id: number) {
|
||||
return await this.coreScheduleService.stop(siteId, id);
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async delete(siteId: number, id: number) {
|
||||
return this.del(siteId, id);
|
||||
}
|
||||
|
||||
async execute(siteId: number, id: number) {
|
||||
return this.coreScheduleService.execute(siteId, id);
|
||||
}
|
||||
|
||||
async getLogs(siteId: number, id: number, query: any) {
|
||||
return this.coreScheduleService.getLogs(siteId, id, query);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
54
wwjcloud/src/common/sys/services/admin/UeditorService.ts
Normal file
54
wwjcloud/src/common/sys/services/admin/UeditorService.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CoreUeditorService } from '../core/CoreUeditorService';
|
||||
|
||||
@Injectable()
|
||||
export class UeditorService {
|
||||
constructor(
|
||||
private readonly coreUeditorService: CoreUeditorService,
|
||||
) {}
|
||||
|
||||
async uploadImage(data: any) {
|
||||
return this.coreUeditorService.uploadImage(data);
|
||||
}
|
||||
|
||||
async uploadFile(data: any) {
|
||||
return this.coreUeditorService.uploadFile(data);
|
||||
}
|
||||
|
||||
async uploadVideo(data: any) {
|
||||
return this.coreUeditorService.uploadVideo(data);
|
||||
}
|
||||
|
||||
async listImages(query: any) {
|
||||
return this.coreUeditorService.listImages(query);
|
||||
}
|
||||
|
||||
async listFiles(query: any) {
|
||||
return this.coreUeditorService.listFiles(query);
|
||||
}
|
||||
|
||||
async deleteFileById(fileId: number) {
|
||||
return this.coreUeditorService.deleteFile(fileId);
|
||||
}
|
||||
|
||||
async getConfig() {
|
||||
return this.coreUeditorService.getConfig();
|
||||
}
|
||||
|
||||
async getServerConfig() {
|
||||
return this.coreUeditorService.getServerConfig();
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getList(query: any) {
|
||||
return this.coreUeditorService.getList(query);
|
||||
}
|
||||
|
||||
async deleteFile(fileName: string) {
|
||||
return this.coreUeditorService.deleteFileByName(fileName);
|
||||
}
|
||||
|
||||
async getFileInfo(fileName: string) {
|
||||
return this.coreUeditorService.getFileInfo(fileName);
|
||||
}
|
||||
}
|
||||
@@ -149,4 +149,45 @@ export class CoreAgreementService extends BaseService<SysAgreement> {
|
||||
});
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
const { page = 1, limit = 10, site_id = 0 } = query;
|
||||
const [data, total] = await this.agreementRepository.findAndCount({
|
||||
where: { site_id },
|
||||
skip: (page - 1) * limit,
|
||||
take: limit,
|
||||
order: { create_time: 'DESC' },
|
||||
});
|
||||
return { data, total, page, limit, pages: Math.ceil(total / limit) };
|
||||
}
|
||||
|
||||
async getInfo(agreementId: number) {
|
||||
return this.agreementRepository.findOne({ where: { id: agreementId } });
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
const agreement = this.agreementRepository.create({
|
||||
...data,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
return this.agreementRepository.save(agreement);
|
||||
}
|
||||
|
||||
async edit(agreementId: number, data: any) {
|
||||
const result = await this.agreementRepository.update(
|
||||
{ id: agreementId },
|
||||
{ ...data, update_time: Math.floor(Date.now() / 1000) }
|
||||
);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async delete(agreementId: number) {
|
||||
const result = await this.agreementRepository.delete({ id: agreementId });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getByType(agreementType: string) {
|
||||
return this.agreementRepository.find({ where: { agreement_key: agreementType } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,4 +214,69 @@ export class CoreAreaService {
|
||||
.addOrderBy('area.sort', 'ASC')
|
||||
.getMany();
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
const { page = 1, limit = 10, pid = 0, level } = query;
|
||||
const queryBuilder = this.areaRepository
|
||||
.createQueryBuilder('area')
|
||||
.where('area.pid = :pid', { pid });
|
||||
|
||||
if (level !== undefined) {
|
||||
queryBuilder.andWhere('area.level = :level', { level });
|
||||
}
|
||||
|
||||
const [data, total] = await queryBuilder
|
||||
.select([
|
||||
'area.id',
|
||||
'area.pid',
|
||||
'area.name',
|
||||
'area.shortname',
|
||||
'area.longitude',
|
||||
'area.latitude',
|
||||
'area.level',
|
||||
'area.sort',
|
||||
'area.status',
|
||||
])
|
||||
.orderBy('area.sort', 'ASC')
|
||||
.addOrderBy('area.id', 'ASC')
|
||||
.skip((page - 1) * limit)
|
||||
.take(limit)
|
||||
.getManyAndCount();
|
||||
|
||||
return { data, total, page, limit, pages: Math.ceil(total / limit) };
|
||||
}
|
||||
|
||||
async getInfo(areaId: number) {
|
||||
return this.areaRepository.findOne({ where: { id: areaId } });
|
||||
}
|
||||
|
||||
async add(data: any) {
|
||||
const area = this.areaRepository.create({
|
||||
...data,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
return this.areaRepository.save(area);
|
||||
}
|
||||
|
||||
async edit(areaId: number, data: any) {
|
||||
const result = await this.areaRepository.update(
|
||||
{ id: areaId },
|
||||
{ ...data, update_time: Math.floor(Date.now() / 1000) }
|
||||
);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async delete(areaId: number) {
|
||||
const result = await this.areaRepository.delete({ id: areaId });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getTree() {
|
||||
return this.getAreaTree(3);
|
||||
}
|
||||
|
||||
async getChildren(parentId: number) {
|
||||
return this.getListByPid(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { BaseService } from '../../../../core/base/BaseService';
|
||||
import { Channel } from '../../entities/Channel';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService } from '@wwjCore/base/BaseService';
|
||||
import { Channel } from '../../../channel/entities/Channel';
|
||||
|
||||
/**
|
||||
* 核心渠道服务 - Core层
|
||||
@@ -8,8 +10,11 @@ import { Channel } from '../../entities/Channel';
|
||||
*/
|
||||
@Injectable()
|
||||
export class CoreChannelService extends BaseService<Channel> {
|
||||
constructor() {
|
||||
super(Channel);
|
||||
constructor(
|
||||
@InjectRepository(Channel)
|
||||
private channelRepository: Repository<Channel>,
|
||||
) {
|
||||
super(channelRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,10 +25,10 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
async getList(params: any) {
|
||||
const { page = 1, limit = 20, keyword = '', status = '', type = '' } = params;
|
||||
|
||||
const query = this.repository.createQueryBuilder('channel');
|
||||
const query = this.channelRepository.createQueryBuilder('channel');
|
||||
|
||||
if (keyword) {
|
||||
query.andWhere('channel.name LIKE :keyword', { keyword: `%${keyword}%` });
|
||||
query.andWhere('channel.channel_name LIKE :keyword', { keyword: `%${keyword}%` });
|
||||
}
|
||||
|
||||
if (status !== '') {
|
||||
@@ -31,7 +36,7 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
}
|
||||
|
||||
if (type) {
|
||||
query.andWhere('channel.type = :type', { type });
|
||||
query.andWhere('channel.channel_type = :type', { type });
|
||||
}
|
||||
|
||||
query.orderBy('channel.sort', 'ASC');
|
||||
@@ -56,7 +61,7 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 渠道详情
|
||||
*/
|
||||
async getInfo(id: number) {
|
||||
return await this.repository.findOne({ where: { channel_id: id } });
|
||||
return await this.channelRepository.findOne({ where: { channel_id: id } });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,16 +70,16 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async add(data: any) {
|
||||
const channel = this.repository.create({
|
||||
name: data.name,
|
||||
type: data.type,
|
||||
const channel = this.channelRepository.create({
|
||||
channel_name: data.name,
|
||||
channel_type: data.type,
|
||||
status: data.status || 1,
|
||||
sort: data.sort || 0,
|
||||
config: data.config || {},
|
||||
remark: data.remark || '',
|
||||
channel_config: JSON.stringify(data.config || {}),
|
||||
channel_desc: data.remark || '',
|
||||
});
|
||||
|
||||
await this.repository.save(channel);
|
||||
await this.channelRepository.save(channel);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,20 +90,20 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async edit(id: number, data: any) {
|
||||
const result = await this.repository.update(
|
||||
const result = await this.channelRepository.update(
|
||||
{ channel_id: id },
|
||||
{
|
||||
name: data.name,
|
||||
type: data.type,
|
||||
channel_name: data.name,
|
||||
channel_type: data.type,
|
||||
status: data.status,
|
||||
sort: data.sort,
|
||||
config: data.config,
|
||||
remark: data.remark,
|
||||
update_time: new Date(),
|
||||
channel_config: JSON.stringify(data.config),
|
||||
channel_desc: data.remark,
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
}
|
||||
);
|
||||
|
||||
return result.affected > 0;
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,8 +112,8 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async delete(id: number) {
|
||||
const result = await this.repository.delete({ channel_id: id });
|
||||
return result.affected > 0;
|
||||
const result = await this.channelRepository.delete({ channel_id: id });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,12 +147,12 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async updateStatus(id: number, status: number) {
|
||||
const result = await this.repository.update(
|
||||
const result = await this.channelRepository.update(
|
||||
{ channel_id: id },
|
||||
{ status, update_time: new Date() }
|
||||
{ status, update_time: Math.floor(Date.now() / 1000) }
|
||||
);
|
||||
|
||||
return result.affected > 0;
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,12 +161,12 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 渠道配置
|
||||
*/
|
||||
async getConfig(id: number) {
|
||||
const channel = await this.repository.findOne({
|
||||
const channel = await this.channelRepository.findOne({
|
||||
where: { channel_id: id },
|
||||
select: ['channel_id', 'config']
|
||||
select: ['channel_id', 'channel_config']
|
||||
});
|
||||
|
||||
return channel?.config || {};
|
||||
return channel?.channel_config ? JSON.parse(channel.channel_config) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,14 +176,26 @@ export class CoreChannelService extends BaseService<Channel> {
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setConfig(id: number, config: any) {
|
||||
const result = await this.repository.update(
|
||||
const result = await this.channelRepository.update(
|
||||
{ channel_id: id },
|
||||
{
|
||||
config,
|
||||
update_time: new Date()
|
||||
channel_config: JSON.stringify(config),
|
||||
update_time: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
);
|
||||
|
||||
return result.affected > 0;
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPage(query: any) {
|
||||
const result = await this.getList(query);
|
||||
return {
|
||||
data: result.list,
|
||||
total: result.total,
|
||||
page: result.page,
|
||||
limit: result.limit,
|
||||
pages: Math.ceil(result.total / result.limit),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,22 @@ export class CoreCommonService {
|
||||
],
|
||||
};
|
||||
|
||||
return dicts[type] || [];
|
||||
return (dicts as any)[type] || [];
|
||||
}
|
||||
|
||||
async getDicts() {
|
||||
// 返回所有可用字典键列表
|
||||
return ['status', 'gender', 'yes_no', 'channel_type'];
|
||||
}
|
||||
|
||||
async getArea(parentId: number = 0) {
|
||||
// 占位:返回空列表
|
||||
return [];
|
||||
}
|
||||
|
||||
async getAreaTree() {
|
||||
// 占位:返回空树
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,181 +2,302 @@ import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService } from '../../../../core/base/BaseService';
|
||||
import { SysConfig } from '../../entities/SysConfig';
|
||||
import { SysConfig } from '../../../settings/entities/sys-config.entity';
|
||||
|
||||
/**
|
||||
* 核心配置服务 - Core层
|
||||
* 对应PHP: app\service\core\sys\CoreSysConfigService
|
||||
*/
|
||||
@Injectable()
|
||||
export class CoreConfigService extends BaseService<SysConfig> {
|
||||
constructor(
|
||||
@InjectRepository(SysConfig)
|
||||
private readonly sysConfigRepository: Repository<SysConfig>,
|
||||
private configRepository: Repository<SysConfig>,
|
||||
) {
|
||||
super(sysConfigRepository);
|
||||
super(configRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置值
|
||||
* @param siteId 站点ID
|
||||
* @param key 配置键
|
||||
* @param defaultValue 默认值
|
||||
* @returns 配置值
|
||||
* 获取网站设置
|
||||
*/
|
||||
async getConfig(
|
||||
siteId: number,
|
||||
key: string,
|
||||
defaultValue: any = null,
|
||||
): Promise<any> {
|
||||
const config = await this.sysConfigRepository.findOne({
|
||||
where: {
|
||||
siteId,
|
||||
key,
|
||||
isUse: 1,
|
||||
},
|
||||
async getWebSite(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'website_config' as any },
|
||||
});
|
||||
|
||||
if (!config || !config.value) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(config.value);
|
||||
} catch (error) {
|
||||
return config.value;
|
||||
}
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置配置值
|
||||
* @param siteId 站点ID
|
||||
* @param key 配置键
|
||||
* @param value 配置值
|
||||
* @param desc 配置描述
|
||||
* @returns 是否成功
|
||||
* 网站设置
|
||||
*/
|
||||
async setConfig(
|
||||
siteId: number,
|
||||
key: string,
|
||||
value: any,
|
||||
desc?: string,
|
||||
): Promise<boolean> {
|
||||
const configValue =
|
||||
typeof value === 'object' ? JSON.stringify(value) : String(value);
|
||||
|
||||
const existingConfig = await this.sysConfigRepository.findOne({
|
||||
where: { siteId, key },
|
||||
async setWebSite(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'website_config' as any },
|
||||
});
|
||||
|
||||
if (existingConfig) {
|
||||
existingConfig.value = configValue;
|
||||
if (desc) {
|
||||
existingConfig.desc = desc;
|
||||
}
|
||||
await this.sysConfigRepository.save(existingConfig);
|
||||
} else {
|
||||
const newConfig = this.sysConfigRepository.create({
|
||||
siteId,
|
||||
key,
|
||||
value: configValue,
|
||||
desc: desc || '',
|
||||
isUse: 1,
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.sysConfigRepository.save(newConfig);
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'website_config',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除配置
|
||||
* @param siteId 站点ID
|
||||
* @param key 配置键
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async deleteConfig(siteId: number, key: string): Promise<boolean> {
|
||||
const result = await this.sysConfigRepository.delete({ siteId, key });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取多个配置
|
||||
* @param siteId 站点ID
|
||||
* @param keys 配置键数组
|
||||
* @returns 配置对象
|
||||
*/
|
||||
async getConfigs(
|
||||
siteId: number,
|
||||
keys: string[],
|
||||
): Promise<Record<string, any>> {
|
||||
const queryBuilder = this.sysConfigRepository
|
||||
.createQueryBuilder('config')
|
||||
.where('config.siteId = :siteId', { siteId })
|
||||
.andWhere('config.isUse = :isUse', { isUse: 1 });
|
||||
|
||||
if (keys.length > 0) {
|
||||
queryBuilder.andWhere('config.key IN (:...keys)', { keys });
|
||||
}
|
||||
|
||||
const configs = await queryBuilder.getMany();
|
||||
|
||||
const result: Record<string, any> = {};
|
||||
for (const config of configs) {
|
||||
try {
|
||||
result[config.key] = JSON.parse(config.value);
|
||||
} catch (error) {
|
||||
result[config.key] = config.value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量设置配置
|
||||
* @param siteId 站点ID
|
||||
* @param configs 配置对象
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setConfigs(
|
||||
siteId: number,
|
||||
configs: Record<string, any>,
|
||||
): Promise<boolean> {
|
||||
for (const [key, value] of Object.entries(configs)) {
|
||||
await this.setConfig(siteId, key, value);
|
||||
}
|
||||
return true;
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权信息
|
||||
* @param siteId 站点ID
|
||||
* @returns 版权信息
|
||||
*/
|
||||
async getCopyright(siteId: number): Promise<any> {
|
||||
return this.getConfig(siteId, 'COPYRIGHT', {
|
||||
icp: '',
|
||||
gov_record: '',
|
||||
gov_url: '',
|
||||
market_supervision_url: '',
|
||||
logo: '',
|
||||
company_name: '',
|
||||
copyright_link: '',
|
||||
copyright_desc: '',
|
||||
async getCopyright(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'copyright_config' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景域名配置
|
||||
* @param siteId 站点ID
|
||||
* @returns 域名配置
|
||||
* 设置版权信息
|
||||
*/
|
||||
async getSceneDomain(siteId: number): Promise<any> {
|
||||
return this.getConfig(siteId, 'SCENE_DOMAIN', {
|
||||
wap_domain: '',
|
||||
web_domain: '',
|
||||
h5_domain: '',
|
||||
async setCopyright(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'copyright_config' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'copyright_config',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景域名
|
||||
*/
|
||||
async getSceneDomain(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'scene_domain' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置场景域名
|
||||
*/
|
||||
async setSceneDomain(siteId: number, data: any) {
|
||||
const key = 'scene_domain';
|
||||
const existed = await this.configRepository.findOne({ where: { site_id: siteId as any, config_key: key as any } });
|
||||
const payload = {
|
||||
value: JSON.stringify(data ?? {}),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
} as any;
|
||||
if (existed) {
|
||||
await this.configRepository.update(existed.id as any, payload);
|
||||
} else {
|
||||
await this.configRepository.save(
|
||||
this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: key,
|
||||
value: JSON.stringify(data ?? {}),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
} as any),
|
||||
);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务信息
|
||||
*/
|
||||
async getService(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'service_config' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置服务信息
|
||||
*/
|
||||
async setService(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'service_config' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'service_config',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图信息
|
||||
*/
|
||||
async setMap(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'map_config' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'map_config',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取地图设置
|
||||
*/
|
||||
async getMap(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'map_config' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开发者key
|
||||
*/
|
||||
async getDeveloperToken(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'developer_token' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置开发者key
|
||||
*/
|
||||
async setDeveloperToken(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'developer_token' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'developer_token',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局设置
|
||||
*/
|
||||
async setLayout(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'layout_config' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'layout_config',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取布局设置
|
||||
*/
|
||||
async getLayout(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'layout_config' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置色调设置
|
||||
*/
|
||||
async setThemeColor(siteId: number, data: any) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'theme_color' as any },
|
||||
});
|
||||
|
||||
if (config) {
|
||||
await this.configRepository.update(config.id, {
|
||||
value: JSON.stringify(data),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
} else {
|
||||
const newConfig = this.configRepository.create({
|
||||
site_id: siteId as any,
|
||||
config_key: 'theme_color',
|
||||
value: JSON.stringify(data),
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
update_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
await this.configRepository.save(newConfig);
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取色调设置
|
||||
*/
|
||||
async getThemeColor(siteId: number) {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { site_id: siteId as any, config_key: 'theme_color' as any },
|
||||
});
|
||||
return config ? JSON.parse(config.value) : {};
|
||||
}
|
||||
}
|
||||
@@ -264,4 +264,40 @@ export class CoreExportService extends BaseService<SysExport> {
|
||||
|
||||
return result.affected || 0;
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getInfo(exportId: number) {
|
||||
return this.exportRepository.findOne({ where: { id: exportId } });
|
||||
}
|
||||
|
||||
async create(data: Partial<SysExport>): Promise<SysExport> {
|
||||
const exportRecord = this.exportRepository.create({
|
||||
...data,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
});
|
||||
return this.exportRepository.save(exportRecord);
|
||||
}
|
||||
|
||||
async execute(exportId: number) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true, message: '导出任务已启动' };
|
||||
}
|
||||
|
||||
async download(exportId: number) {
|
||||
// 临时实现,返回下载链接
|
||||
return { download_url: `/exports/download/${exportId}` };
|
||||
}
|
||||
|
||||
async delete(exportId: number) {
|
||||
const result = await this.exportRepository.delete({ id: exportId });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getTemplates() {
|
||||
return [
|
||||
{ key: 'member', name: '会员模板' },
|
||||
{ key: 'order', name: '订单模板' },
|
||||
{ key: 'product', name: '商品模板' },
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,68 @@ export class CoreMenuService extends BaseService<SysMenu> {
|
||||
super(menuRepository);
|
||||
}
|
||||
|
||||
// ==== PHP 对齐:Admin MenuService 同名方法适配 ====
|
||||
|
||||
async getAllMenuList(
|
||||
app_type: string,
|
||||
_type: string = 'all',
|
||||
status: number | 'all' = 'all',
|
||||
) {
|
||||
const where: any = { app_type };
|
||||
if (status !== 'all') {
|
||||
where.status = status;
|
||||
}
|
||||
return this.menuRepository.find({ where, order: { sort: 'DESC', id: 'ASC' } });
|
||||
}
|
||||
|
||||
async get(app_type: string, menu_key: string) {
|
||||
return this.menuRepository.findOne({ where: { app_type, menu_key } });
|
||||
}
|
||||
|
||||
async add(data: Partial<SysMenu>) {
|
||||
return this.createMenu(data);
|
||||
}
|
||||
|
||||
async edit(menu_key: string, data: Partial<SysMenu>) {
|
||||
// 兼容控制器仅传 menu_key 的场景
|
||||
const result = await this.menuRepository.update({ menu_key }, data);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async delete(id: number) {
|
||||
// 兼容BaseService的delete方法
|
||||
const result = await this.menuRepository.delete({ id });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async deleteByMenuKey(menu_key: string) {
|
||||
// 兼容控制器仅传 menu_key 的场景
|
||||
const result = await this.menuRepository.delete({ menu_key });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async sort(menu_keys: string[]) {
|
||||
// 按传入顺序重排,首个权重最高
|
||||
let current = menu_keys.length;
|
||||
for (const key of menu_keys) {
|
||||
await this.menuRepository.update({ menu_key: key }, { sort: current-- });
|
||||
}
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async getMenuTree(app_type: string) {
|
||||
const list = await this.menuRepository.find({
|
||||
where: { app_type },
|
||||
order: { sort: 'DESC', id: 'ASC' },
|
||||
});
|
||||
return this.buildMenuTree(list, 'menu_key', 'parent_key', 'children', '');
|
||||
}
|
||||
|
||||
async getUserMenu(app_type: string) {
|
||||
// 先返回完整树,后续可基于角色/权限裁剪
|
||||
return this.getMenuTree(app_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据menu_key和app_type查找菜单
|
||||
* @param menuKey 菜单键
|
||||
|
||||
@@ -249,4 +249,18 @@ export class CorePosterService extends BaseService<SysPoster> {
|
||||
qrcode_poster: '二维码海报',
|
||||
};
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async generate(siteId: number, id: number, data: any) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true, message: '海报生成成功', url: '/generated/poster.png' };
|
||||
}
|
||||
|
||||
async getTemplates() {
|
||||
return [
|
||||
{ key: 'template1', name: '模板1' },
|
||||
{ key: 'template2', name: '模板2' },
|
||||
{ key: 'template3', name: '模板3' },
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,4 +272,24 @@ export class CoreRoleService extends BaseService<SysRole> {
|
||||
select: ['role_id', 'role_name', 'rules', 'status'],
|
||||
});
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getPermissions(roleId: number) {
|
||||
const role = await this.roleRepository.findOne({
|
||||
where: { role_id: roleId },
|
||||
select: ['rules'],
|
||||
});
|
||||
return role?.rules ? JSON.parse(role.rules) : [];
|
||||
}
|
||||
|
||||
async setPermissions(roleId: number, menuIds: number[]) {
|
||||
const result = await this.roleRepository.update(
|
||||
{ role_id: roleId },
|
||||
{
|
||||
rules: JSON.stringify(menuIds),
|
||||
update_time: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
103
wwjcloud/src/common/sys/services/core/CoreScheduleLogService.ts
Normal file
103
wwjcloud/src/common/sys/services/core/CoreScheduleLogService.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService } from '../../../../core/base/BaseService';
|
||||
import { SysScheduleLog as ScheduleLog } from '../../entities/SysScheduleLog';
|
||||
|
||||
@Injectable()
|
||||
export class CoreScheduleLogService extends BaseService<ScheduleLog> {
|
||||
constructor(
|
||||
@InjectRepository(ScheduleLog)
|
||||
private readonly logRepository: Repository<ScheduleLog>,
|
||||
) {
|
||||
super(logRepository);
|
||||
}
|
||||
|
||||
async getPage(query: any) {
|
||||
const { page = 1, limit = 20, site_id, schedule_id, status } = query;
|
||||
const qb = this.logRepository.createQueryBuilder('log');
|
||||
|
||||
if (site_id) {
|
||||
qb.andWhere('log.site_id = :site_id', { site_id });
|
||||
}
|
||||
if (schedule_id) {
|
||||
qb.andWhere('log.schedule_id = :schedule_id', { schedule_id });
|
||||
}
|
||||
if (status !== undefined) {
|
||||
qb.andWhere('log.status = :status', { status });
|
||||
}
|
||||
|
||||
qb.orderBy('log.create_time', 'DESC');
|
||||
qb.skip((page - 1) * limit).take(limit);
|
||||
|
||||
const [data, total] = await qb.getManyAndCount();
|
||||
return { data, total, page, limit };
|
||||
}
|
||||
|
||||
async getInfo(logId: number) {
|
||||
return this.logRepository.findOne({ where: { id: logId } });
|
||||
}
|
||||
|
||||
async add(data: Partial<ScheduleLog>) {
|
||||
const log = this.logRepository.create(data);
|
||||
return this.logRepository.save(log);
|
||||
}
|
||||
|
||||
async edit(logId: number, data: Partial<ScheduleLog>) {
|
||||
await this.logRepository.update(logId, data);
|
||||
return this.getInfo(logId);
|
||||
}
|
||||
|
||||
async delete(logId: number) {
|
||||
const result = await this.logRepository.delete(logId);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async batchDelete(logIds: number[]) {
|
||||
const result = await this.logRepository.delete(logIds);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getStatistics(query?: any) {
|
||||
const total = await this.logRepository.count();
|
||||
const success = await this.logRepository.count({ where: { status: 1 } });
|
||||
const failed = await this.logRepository.count({ where: { status: 0 } });
|
||||
|
||||
return { total, success, failed };
|
||||
}
|
||||
|
||||
async export(query: any) {
|
||||
// 导出功能实现
|
||||
return { message: 'Export functionality not implemented yet' };
|
||||
}
|
||||
|
||||
async clean(days: number) {
|
||||
const cutoffDate = new Date();
|
||||
cutoffDate.setDate(cutoffDate.getDate() - days);
|
||||
const cutoffTimestamp = Math.floor(cutoffDate.getTime() / 1000);
|
||||
|
||||
const result = await this.logRepository
|
||||
.createQueryBuilder()
|
||||
.delete()
|
||||
.where('create_time < :cutoff', { cutoff: cutoffTimestamp })
|
||||
.execute();
|
||||
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getLogsBySchedule(scheduleId: number, query: any) {
|
||||
const { page = 1, limit = 20, status } = query;
|
||||
const qb = this.logRepository.createQueryBuilder('log');
|
||||
|
||||
qb.andWhere('log.schedule_id = :schedule_id', { schedule_id: scheduleId });
|
||||
if (status !== undefined) {
|
||||
qb.andWhere('log.status = :status', { status });
|
||||
}
|
||||
|
||||
qb.orderBy('log.create_time', 'DESC');
|
||||
qb.skip((page - 1) * limit).take(limit);
|
||||
|
||||
const [data, total] = await qb.getManyAndCount();
|
||||
return { data, total, page, limit };
|
||||
}
|
||||
}
|
||||
@@ -122,4 +122,15 @@ export class CoreScheduleService {
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async execute(siteId: number, id: number) {
|
||||
// 临时实现,返回成功
|
||||
return { success: true, message: '任务执行成功' };
|
||||
}
|
||||
|
||||
async getLogs(siteId: number, id: number, query: any) {
|
||||
// 临时实现,返回空日志
|
||||
return { data: [], total: 0, page: 1, limit: 10 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Repository, In } from 'typeorm';
|
||||
import { BaseService } from '@wwjCore/base/BaseService';
|
||||
import { SysConfig } from '../../entities/SysConfig';
|
||||
import { SysArea } from '../../entities/SysArea';
|
||||
@@ -58,8 +58,8 @@ export class CoreSysService extends BaseService<SysConfig> {
|
||||
return this.configRepository.find({
|
||||
where: {
|
||||
site_id,
|
||||
config_key: { $in: keys },
|
||||
},
|
||||
config_key: In(keys),
|
||||
} as any,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,295 +1,127 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigCenterService } from '../../../../config/services/configCenterService';
|
||||
import * as os from 'os';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService } from '../../../../core/base/BaseService';
|
||||
import { SysConfig } from '../../../settings/entities/sys-config.entity';
|
||||
|
||||
/**
|
||||
* 核心系统服务 - Core层
|
||||
* 对应PHP: SystemService核心逻辑
|
||||
*/
|
||||
@Injectable()
|
||||
export class CoreSystemService {
|
||||
constructor(private readonly configCenter: ConfigCenterService) {}
|
||||
export class CoreSystemService extends BaseService<SysConfig> {
|
||||
constructor(
|
||||
@InjectRepository(SysConfig)
|
||||
private configRepository: Repository<SysConfig>,
|
||||
) {
|
||||
super(configRepository);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统基本信息
|
||||
* @returns 系统信息
|
||||
* 获取当前系统信息
|
||||
*/
|
||||
async getInfo() {
|
||||
return {
|
||||
os: os.type(),
|
||||
environment: process.env.NODE_ENV || 'development',
|
||||
node_v: process.version,
|
||||
version: this.configCenter.get('app.version', '1.0.0'),
|
||||
};
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { config_key: 'system_info' as any },
|
||||
});
|
||||
return config?.value ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取域名配置
|
||||
* @param siteId 站点ID
|
||||
* @returns 域名配置
|
||||
* 获取当前url配置
|
||||
*/
|
||||
async getUrl(siteId: number) {
|
||||
// TODO: 实现域名配置获取逻辑
|
||||
// 需要与CoreConfigService配合实现
|
||||
return {
|
||||
web_url: this.configCenter.get('app.web_url', ''),
|
||||
wap_url: this.configCenter.get('app.wap_url', ''),
|
||||
admin_url: this.configCenter.get('app.admin_url', ''),
|
||||
};
|
||||
async getUrl() {
|
||||
const config = await this.configRepository.findOne({
|
||||
where: { config_key: 'url_config' as any },
|
||||
});
|
||||
return config?.value ? JSON.parse(config.value) : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统详细信息
|
||||
* @returns 系统详细信息
|
||||
* 获取系统环境配置
|
||||
*/
|
||||
async getSystemInfo() {
|
||||
const server = [
|
||||
{ name: '服务器系统', server: os.type() },
|
||||
{ name: '服务器环境', server: process.env.NODE_ENV || 'development' },
|
||||
{ name: 'Node.js版本', server: process.version },
|
||||
];
|
||||
|
||||
// 系统环境检查
|
||||
const system_variables = [
|
||||
{ name: 'Node.js', need: '必须', status: true },
|
||||
{ name: 'npm', need: '必须', status: this.checkNpm() },
|
||||
{ name: 'TypeScript', need: '推荐', status: this.checkTypeScript() },
|
||||
];
|
||||
|
||||
// 文件夹权限检查
|
||||
const folder_auth = [
|
||||
{ name: 'public/upload', need: '读写权限', status: true }, // TODO: 实际检查权限
|
||||
{ name: 'logs', need: '读写权限', status: true },
|
||||
{ name: 'dist', need: '读写权限', status: true },
|
||||
];
|
||||
|
||||
return {
|
||||
server,
|
||||
system_variables,
|
||||
folder_auth,
|
||||
php_version: process.version,
|
||||
node_version: process.version,
|
||||
platform: process.platform,
|
||||
arch: process.arch,
|
||||
uptime: process.uptime(),
|
||||
memory_usage: process.memoryUsage(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理表缓存
|
||||
*/
|
||||
async schemaCache() {
|
||||
// 清理数据库表结构缓存
|
||||
return { success: true, message: '表缓存清理成功' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
*/
|
||||
async clearCache() {
|
||||
// 清理应用缓存
|
||||
return { success: true, message: '缓存清理成功' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验消息队列是否正常运行
|
||||
*/
|
||||
async checkJob() {
|
||||
// 检查队列服务状态
|
||||
return { success: true, message: '队列服务正常' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验计划任务是否正常运行
|
||||
*/
|
||||
async checkSchedule() {
|
||||
// 检查定时任务服务状态
|
||||
return { success: true, message: '定时任务服务正常' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 环境变量查询
|
||||
*/
|
||||
async getEnvInfo() {
|
||||
return {
|
||||
app_debug: process.env.NODE_ENV === 'development',
|
||||
app_env: process.env.NODE_ENV || 'production',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推广二维码
|
||||
*/
|
||||
async getQrcode(params: any) {
|
||||
// 生成推广二维码
|
||||
return {
|
||||
success: true,
|
||||
qrcode_url: 'https://example.com/qrcode.png',
|
||||
qrcode_data: params,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统统计信息
|
||||
* @returns 统计信息
|
||||
*/
|
||||
async getSystemStats() {
|
||||
return {
|
||||
memory: {
|
||||
total: os.totalmem(),
|
||||
free: os.freemem(),
|
||||
used: os.totalmem() - os.freemem(),
|
||||
},
|
||||
cpu: {
|
||||
count: os.cpus().length,
|
||||
model: os.cpus()[0]?.model || 'Unknown',
|
||||
},
|
||||
uptime: os.uptime(),
|
||||
load_avg: os.loadavg(),
|
||||
total_users: 0,
|
||||
total_orders: 0,
|
||||
total_visits: 0,
|
||||
system_uptime: process.uptime(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查npm是否可用
|
||||
* @returns 是否可用
|
||||
*/
|
||||
private checkNpm(): boolean {
|
||||
try {
|
||||
// 简单检查,实际项目中可以更详细
|
||||
return process.env.npm_config_user_config !== undefined;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查TypeScript是否可用
|
||||
* @returns 是否可用
|
||||
*/
|
||||
private checkTypeScript(): boolean {
|
||||
try {
|
||||
// 检查是否在TypeScript环境中运行
|
||||
return (
|
||||
__filename.endsWith('.ts') || process.env.TS_NODE_DEV !== undefined
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统缓存
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async clearCache(): Promise<boolean> {
|
||||
try {
|
||||
// TODO: 实现缓存清理逻辑
|
||||
// 可以清理Redis缓存、文件缓存等
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置检查结果
|
||||
* @returns 检查结果
|
||||
* 检查系统配置
|
||||
*/
|
||||
async checkSystemConfig() {
|
||||
const checks = [
|
||||
{
|
||||
name: '数据库连接',
|
||||
status: true, // TODO: 实际检查数据库连接
|
||||
message: '正常',
|
||||
},
|
||||
{
|
||||
name: 'Redis连接',
|
||||
status: true, // TODO: 实际检查Redis连接
|
||||
message: '正常',
|
||||
},
|
||||
{
|
||||
name: '文件上传目录',
|
||||
status: true, // TODO: 实际检查目录权限
|
||||
message: '可写',
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
all_passed: checks.every((check) => check.status),
|
||||
checks,
|
||||
database: { status: 'ok' },
|
||||
redis: { status: 'ok' },
|
||||
queue: { status: 'ok' },
|
||||
storage: { status: 'ok' },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权信息
|
||||
* @returns 版权信息
|
||||
*/
|
||||
async getCopyright() {
|
||||
return this.configCenter.get('system.copyright', {
|
||||
company: 'Niucloud Team',
|
||||
version: '1.0.0',
|
||||
year: new Date().getFullYear(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置版权信息
|
||||
* @param value 版权信息
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setCopyright(value: Record<string, any>) {
|
||||
try {
|
||||
this.configCenter.set('system.copyright', value);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置
|
||||
* @param key 配置键
|
||||
* @returns 配置值
|
||||
*/
|
||||
async getConfig(key: string) {
|
||||
return this.configCenter.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置系统配置
|
||||
* @param key 配置键
|
||||
* @param value 配置值
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async setConfig(key: string, value: any) {
|
||||
try {
|
||||
this.configCenter.set(key, value);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统日志
|
||||
* @param params 查询参数
|
||||
* @returns 日志列表
|
||||
*/
|
||||
async getLogs(params: any) {
|
||||
// TODO: 实现日志查询逻辑
|
||||
return {
|
||||
list: [],
|
||||
total: 0,
|
||||
page: params.page || 1,
|
||||
limit: params.limit || 20,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理系统日志
|
||||
* @param days 保留天数
|
||||
* @returns 是否成功
|
||||
*/
|
||||
async clearLogs(days: number = 30) {
|
||||
try {
|
||||
// TODO: 实现日志清理逻辑
|
||||
const cutoffDate = new Date();
|
||||
cutoffDate.setDate(cutoffDate.getDate() - days);
|
||||
// 清理指定日期之前的日志
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统健康状态
|
||||
* @returns 健康状态
|
||||
*/
|
||||
async getHealthStatus() {
|
||||
const memory = process.memoryUsage();
|
||||
const uptime = process.uptime();
|
||||
|
||||
return {
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: uptime,
|
||||
memory: {
|
||||
rss: memory.rss,
|
||||
heapTotal: memory.heapTotal,
|
||||
heapUsed: memory.heapUsed,
|
||||
external: memory.external,
|
||||
},
|
||||
cpu: {
|
||||
usage: process.cpuUsage(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行系统维护
|
||||
* @param action 维护动作
|
||||
* @returns 维护结果
|
||||
*/
|
||||
async performMaintenance(action: string) {
|
||||
try {
|
||||
switch (action) {
|
||||
case 'clear_cache':
|
||||
return await this.clearCache();
|
||||
case 'clear_logs':
|
||||
return await this.clearLogs(30);
|
||||
case 'optimize_db':
|
||||
// TODO: 实现数据库优化
|
||||
return true;
|
||||
case 'backup_data':
|
||||
// TODO: 实现数据备份
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
180
wwjcloud/src/common/sys/services/core/CoreUeditorService.ts
Normal file
180
wwjcloud/src/common/sys/services/core/CoreUeditorService.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService } from '../../../../core/base/BaseService';
|
||||
import { SysAttachment } from '../../entities/SysAttachment';
|
||||
|
||||
@Injectable()
|
||||
export class CoreUeditorService extends BaseService<SysAttachment> {
|
||||
constructor(
|
||||
@InjectRepository(SysAttachment)
|
||||
private readonly attachmentRepository: Repository<SysAttachment>,
|
||||
) {
|
||||
super(attachmentRepository);
|
||||
}
|
||||
|
||||
async uploadImage(data: any) {
|
||||
const attachment = this.attachmentRepository.create({
|
||||
site_id: data.site_id as any,
|
||||
file_name: data.fileName,
|
||||
file_path: data.filePath,
|
||||
file_url: data.fileUrl,
|
||||
file_size: data.fileSize,
|
||||
file_type: 'image',
|
||||
mime_type: data.mimeType,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
} as any);
|
||||
|
||||
return this.attachmentRepository.save(attachment);
|
||||
}
|
||||
|
||||
async uploadFile(data: any) {
|
||||
const attachment = this.attachmentRepository.create({
|
||||
site_id: data.site_id as any,
|
||||
file_name: data.fileName,
|
||||
file_path: data.filePath,
|
||||
file_url: data.fileUrl,
|
||||
file_size: data.fileSize,
|
||||
file_type: 'file',
|
||||
mime_type: data.mimeType,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
} as any);
|
||||
|
||||
return this.attachmentRepository.save(attachment);
|
||||
}
|
||||
|
||||
async uploadVideo(data: any) {
|
||||
const attachment = this.attachmentRepository.create({
|
||||
site_id: data.site_id as any,
|
||||
file_name: data.fileName,
|
||||
file_path: data.filePath,
|
||||
file_url: data.fileUrl,
|
||||
file_size: data.fileSize,
|
||||
file_type: 'video',
|
||||
mime_type: data.mimeType,
|
||||
create_time: Math.floor(Date.now() / 1000),
|
||||
} as any);
|
||||
|
||||
return this.attachmentRepository.save(attachment);
|
||||
}
|
||||
|
||||
async listImages(query: any) {
|
||||
const { page = 1, limit = 20, site_id } = query;
|
||||
const qb = this.attachmentRepository.createQueryBuilder('attachment');
|
||||
|
||||
qb.andWhere('attachment.file_type = :type', { type: 'image' });
|
||||
if (site_id) {
|
||||
qb.andWhere('attachment.site_id = :site_id', { site_id });
|
||||
}
|
||||
|
||||
qb.orderBy('attachment.create_time', 'DESC');
|
||||
qb.skip((page - 1) * limit).take(limit);
|
||||
|
||||
const [data, total] = await qb.getManyAndCount();
|
||||
return { data, total, page, limit };
|
||||
}
|
||||
|
||||
async listFiles(query: any) {
|
||||
const { page = 1, limit = 20, site_id, file_type } = query;
|
||||
const qb = this.attachmentRepository.createQueryBuilder('attachment');
|
||||
|
||||
if (file_type) {
|
||||
qb.andWhere('attachment.file_type = :type', { type: file_type });
|
||||
}
|
||||
if (site_id) {
|
||||
qb.andWhere('attachment.site_id = :site_id', { site_id });
|
||||
}
|
||||
|
||||
qb.orderBy('attachment.create_time', 'DESC');
|
||||
qb.skip((page - 1) * limit).take(limit);
|
||||
|
||||
const [data, total] = await qb.getManyAndCount();
|
||||
return { data, total, page, limit };
|
||||
}
|
||||
|
||||
async deleteFile(fileId: number) {
|
||||
const result = await this.attachmentRepository.delete(fileId);
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getConfig() {
|
||||
return {
|
||||
imageActionName: 'uploadimage',
|
||||
imageFieldName: 'upfile',
|
||||
imageMaxSize: 2048000,
|
||||
imageAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
|
||||
imageCompressEnable: true,
|
||||
imageCompressBorder: 1600,
|
||||
imageInsertAlign: 'none',
|
||||
imageUrlPrefix: '',
|
||||
imagePathFormat: '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
scrawlActionName: 'uploadscrawl',
|
||||
scrawlFieldName: 'upfile',
|
||||
scrawlPathFormat: '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
scrawlMaxSize: 2048000,
|
||||
scrawlUrlPrefix: '',
|
||||
scrawlInsertAlign: 'none',
|
||||
snapscreenActionName: 'uploadimage',
|
||||
snapscreenPathFormat: '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
snapscreenUrlPrefix: '',
|
||||
snapscreenInsertAlign: 'none',
|
||||
catcherLocalDomain: [],
|
||||
catcherActionName: 'catchimage',
|
||||
catcherFieldName: 'upfile',
|
||||
catcherPathFormat: '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
catcherUrlPrefix: '',
|
||||
catcherMaxSize: 2048000,
|
||||
catcherAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
|
||||
videoActionName: 'uploadvideo',
|
||||
videoFieldName: 'upfile',
|
||||
videoPathFormat: '/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
videoUrlPrefix: '',
|
||||
videoMaxSize: 102400000,
|
||||
videoAllowFiles: ['.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg', '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid'],
|
||||
fileActionName: 'uploadfile',
|
||||
fileFieldName: 'upfile',
|
||||
filePathFormat: '/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}',
|
||||
fileUrlPrefix: '',
|
||||
fileMaxSize: 51200000,
|
||||
fileAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg', '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid', '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml'],
|
||||
imageManagerActionName: 'listimage',
|
||||
imageManagerListSize: 20,
|
||||
imageManagerUrlPrefix: '',
|
||||
imageManagerInsertAlign: 'none',
|
||||
imageManagerAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
|
||||
fileManagerActionName: 'listfile',
|
||||
fileManagerListSize: 20,
|
||||
fileManagerUrlPrefix: '',
|
||||
fileManagerAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp', '.flv', '.swf', '.mkv', '.avi', '.rm', '.rmvb', '.mpeg', '.mpg', '.ogg', '.ogv', '.mov', '.wmv', '.mp4', '.webm', '.mp3', '.wav', '.mid', '.rar', '.zip', '.tar', '.gz', '.7z', '.bz2', '.cab', '.iso', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.pdf', '.txt', '.md', '.xml']
|
||||
};
|
||||
}
|
||||
|
||||
async getServerConfig() {
|
||||
return {
|
||||
timeout: 30000,
|
||||
imageActionName: 'uploadimage',
|
||||
imageFieldName: 'upfile',
|
||||
imageMaxSize: 2048000,
|
||||
imageAllowFiles: ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
|
||||
imageCompressEnable: true,
|
||||
imageCompressBorder: 1600,
|
||||
imageInsertAlign: 'none',
|
||||
imageUrlPrefix: '',
|
||||
imagePathFormat: '/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}'
|
||||
};
|
||||
}
|
||||
|
||||
// 控制器契约方法
|
||||
async getList(query: any) {
|
||||
return this.listFiles(query);
|
||||
}
|
||||
|
||||
async deleteFileByName(fileName: string) {
|
||||
const result = await this.attachmentRepository.delete({ name: fileName });
|
||||
return (result.affected || 0) > 0;
|
||||
}
|
||||
|
||||
async getFileInfo(fileName: string) {
|
||||
return this.attachmentRepository.findOne({ where: { name: fileName } });
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,23 @@ import { ChannelController } from './controllers/admin/ChannelController';
|
||||
import { CommonController } from './controllers/admin/CommonController';
|
||||
import { UeditorController } from './controllers/admin/UeditorController';
|
||||
import { ScheduleLogController } from './controllers/admin/ScheduleLogController';
|
||||
// AdminAPI Controllers
|
||||
import { SystemController as AdminSystemController } from './controllers/adminapi/SystemController';
|
||||
import { ConfigController as AdminConfigController } from './controllers/adminapi/ConfigController';
|
||||
import { MenuController as AdminMenuController } from './controllers/adminapi/MenuController';
|
||||
import { RoleController as AdminRoleController } from './controllers/adminapi/RoleController';
|
||||
import { AreaController as AdminAreaController } from './controllers/adminapi/AreaController';
|
||||
import { AttachmentController as AdminAttachmentController } from './controllers/adminapi/AttachmentController';
|
||||
import { ExportController as AdminExportController } from './controllers/adminapi/ExportController';
|
||||
import { AgreementController as AdminAgreementController } from './controllers/adminapi/AgreementController';
|
||||
import { AppController as AdminAppController } from './controllers/adminapi/AppController';
|
||||
import { ChannelController as AdminChannelController } from './controllers/adminapi/ChannelController';
|
||||
import { CommonController as AdminCommonController } from './controllers/adminapi/CommonController';
|
||||
import { PosterController as AdminPosterController } from './controllers/adminapi/PosterController';
|
||||
import { PrinterController as AdminPrinterController } from './controllers/adminapi/PrinterController';
|
||||
import { ScheduleController as AdminScheduleController } from './controllers/adminapi/ScheduleController';
|
||||
import { ScheduleLogController as AdminScheduleLogController } from './controllers/adminapi/ScheduleLogController';
|
||||
import { UeditorController as AdminUeditorController } from './controllers/adminapi/UeditorController';
|
||||
import { ApiConfigController } from './controllers/api/ApiConfigController';
|
||||
import { ApiAreaController } from './controllers/api/ApiAreaController';
|
||||
import { ApiVerifyController } from './controllers/api/ApiVerifyController';
|
||||
@@ -148,6 +165,24 @@ import { SysUpgradeRecords } from './entities/SysUpgradeRecords';
|
||||
CommonController,
|
||||
UeditorController,
|
||||
ScheduleLogController,
|
||||
// AdminAPI Controllers
|
||||
AdminSystemController,
|
||||
AdminConfigController,
|
||||
AdminMenuController,
|
||||
AdminRoleController,
|
||||
AdminAreaController,
|
||||
AdminAttachmentController,
|
||||
AdminExportController,
|
||||
AdminAgreementController,
|
||||
AdminAppController,
|
||||
AdminChannelController,
|
||||
AdminCommonController,
|
||||
AdminPosterController,
|
||||
AdminPrinterController,
|
||||
AdminScheduleController,
|
||||
AdminScheduleLogController,
|
||||
AdminUeditorController,
|
||||
// API Controllers
|
||||
ApiConfigController,
|
||||
ApiAreaController,
|
||||
ApiVerifyController,
|
||||
|
||||
Reference in New Issue
Block a user