feat: 初始化 WWJ Cloud 企业级框架项目

- 后端:基于 NestJS 的分层架构设计
- 前端:基于 VbenAdmin + Element Plus 的管理系统
- 支持 SaaS + 独立版双架构模式
- 完整的用户权限管理系统
- 系统设置、文件上传、通知等核心功能
- 多租户支持和插件化扩展架构
This commit is contained in:
万物街
2025-08-23 13:20:01 +08:00
commit f30d64e6cc
172 changed files with 10179 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
import {
Controller,
Get,
Put,
Body,
Post,
UseGuards,
HttpCode,
HttpStatus,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { RolesGuard } from '../../auth/guards/roles.guard';
import { Roles } from '../../auth/roles.decorator';
import { SiteSettingsService } from './site-settings.service';
import { UpdateSiteSettingsDto } from './site-settings.dto';
@ApiTags('站点设置')
@Controller('system/settings/basic')
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBearerAuth()
export class SiteSettingsController {
constructor(private readonly siteSettingsService: SiteSettingsService) {}
@Get()
@ApiOperation({ summary: '获取站点设置' })
@ApiResponse({ status: 200, description: '成功获取站点设置' })
@Roles('super', 'admin')
async getSiteSettings() {
return this.siteSettingsService.getSiteSettings();
}
@Put()
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '更新站点设置' })
@ApiResponse({ status: 200, description: '站点设置更新成功' })
@Roles('super', 'admin')
async updateSiteSettings(@Body() updateSiteSettingsDto: UpdateSiteSettingsDto) {
return this.siteSettingsService.updateSiteSettings(updateSiteSettingsDto);
}
@Post('reset')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '重置站点设置为默认值' })
@ApiResponse({ status: 200, description: '站点设置重置成功' })
@Roles('super')
async resetSiteSettings() {
return this.siteSettingsService.resetSiteSettings();
}
}

View File

@@ -0,0 +1,91 @@
import { IsOptional, IsString } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
/**
* 更新站点设置DTO
*/
export class UpdateSiteSettingsDto {
@ApiProperty({ description: '网站名称', required: false })
@IsOptional()
@IsString()
site_name?: string;
@ApiProperty({ description: '网站标题', required: false })
@IsOptional()
@IsString()
site_title?: string;
@ApiProperty({ description: '网站关键词', required: false })
@IsOptional()
@IsString()
site_keywords?: string;
@ApiProperty({ description: '网站描述', required: false })
@IsOptional()
@IsString()
site_description?: string;
@ApiProperty({ description: '网站Logo', required: false })
@IsOptional()
@IsString()
site_logo?: string;
@ApiProperty({ description: '网站图标', required: false })
@IsOptional()
@IsString()
site_favicon?: string;
@ApiProperty({ description: 'ICP备案号', required: false })
@IsOptional()
@IsString()
icp_number?: string;
@ApiProperty({ description: '版权信息', required: false })
@IsOptional()
@IsString()
copyright?: string;
@ApiProperty({ description: '网站状态', required: false })
@IsOptional()
site_status?: number;
@ApiProperty({ description: '关闭原因', required: false })
@IsOptional()
@IsString()
close_reason?: string;
}
/**
* 站点设置响应DTO
*/
export class SiteSettingsDto {
@ApiProperty({ description: '网站名称' })
site_name: string;
@ApiProperty({ description: '网站标题' })
site_title: string;
@ApiProperty({ description: '网站关键词' })
site_keywords: string;
@ApiProperty({ description: '网站描述' })
site_description: string;
@ApiProperty({ description: '网站Logo' })
site_logo: string;
@ApiProperty({ description: '网站图标' })
site_favicon: string;
@ApiProperty({ description: 'ICP备案号' })
icp_number: string;
@ApiProperty({ description: '版权信息' })
copyright: string;
@ApiProperty({ description: '网站状态' })
site_status: number;
@ApiProperty({ description: '关闭原因' })
close_reason: string;
}

View File

@@ -0,0 +1,133 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Site } from './site.entity';
import { UpdateSiteSettingsDto } from './site-settings.dto';
@Injectable()
export class SiteSettingsService {
constructor(
@InjectRepository(Site)
private readonly siteRepository: Repository<Site>,
) {}
/**
* 获取站点设置
*/
async getSiteSettings() {
// 获取默认站点id = 1
const site = await this.siteRepository.findOne({
where: { id: 1 },
});
if (!site) {
// 如果没有找到站点,返回默认值
return {
site_name: 'WWJ Cloud',
site_title: 'WWJ Cloud 企业级框架',
site_keywords: 'WWJ Cloud,企业级框架,NestJS,VbenAdmin',
site_description: 'WWJ Cloud 企业级框架 - 快速开发SAAS多用户系统后台管理框架',
site_logo: '',
site_favicon: '',
icp_number: '',
copyright: '',
site_status: 1,
close_reason: '',
};
}
return {
site_name: site.site_name || '',
site_title: site.site_title || '',
site_keywords: site.site_keywords || '',
site_description: site.site_description || '',
site_logo: site.site_logo || '',
site_favicon: site.site_favicon || '',
icp_number: site.icp_number || '',
copyright: site.copyright || '',
site_status: site.site_status || 1,
close_reason: site.close_reason || '',
};
}
/**
* 更新站点设置
*/
async updateSiteSettings(updateSiteSettingsDto: UpdateSiteSettingsDto) {
const {
site_name,
site_title,
site_keywords,
site_description,
site_logo,
site_favicon,
icp_number,
copyright,
site_status,
close_reason,
} = updateSiteSettingsDto;
// 查找或创建默认站点
let site = await this.siteRepository.findOne({
where: { id: 1 },
});
if (!site) {
// 创建默认站点
site = this.siteRepository.create({
id: 1,
site_name: site_name || 'WWJ Cloud',
site_title: site_title || 'WWJ Cloud 企业级框架',
site_keywords: site_keywords || '',
site_description: site_description || '',
site_logo: site_logo || '',
site_favicon: site_favicon || '',
icp_number: icp_number || '',
copyright: copyright || '',
site_status: site_status || 1,
close_reason: close_reason || '',
});
} else {
// 更新现有站点
if (site_name !== undefined) site.site_name = site_name;
if (site_title !== undefined) site.site_title = site_title;
if (site_keywords !== undefined) site.site_keywords = site_keywords;
if (site_description !== undefined) site.site_description = site_description;
if (site_logo !== undefined) site.site_logo = site_logo;
if (site_favicon !== undefined) site.site_favicon = site_favicon;
if (icp_number !== undefined) site.icp_number = icp_number;
if (copyright !== undefined) site.copyright = copyright;
if (site_status !== undefined) site.site_status = site_status;
if (close_reason !== undefined) site.close_reason = close_reason;
}
await this.siteRepository.save(site);
return { message: '站点设置更新成功' };
}
/**
* 重置站点设置为默认值
*/
async resetSiteSettings() {
// 删除现有站点配置
await this.siteRepository.delete({ id: 1 });
// 创建默认站点配置
const defaultSite = this.siteRepository.create({
id: 1,
site_name: 'WWJ Cloud',
site_title: 'WWJ Cloud 企业级框架',
site_keywords: 'WWJ Cloud,企业级框架,NestJS,VbenAdmin',
site_description: 'WWJ Cloud 企业级框架 - 快速开发SAAS多用户系统后台管理框架',
site_logo: '',
site_favicon: '',
icp_number: '',
copyright: '',
site_status: 1,
close_reason: '',
});
await this.siteRepository.save(defaultSite);
return { message: '站点设置已重置为默认值' };
}
}

View File

@@ -0,0 +1,41 @@
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
/**
* 站点信息实体
* 对应数据库表site
*/
@Entity('site')
export class Site {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', length: 100, comment: '网站名称' })
site_name: string;
@Column({ type: 'varchar', length: 255, comment: '网站标题' })
site_title: string;
@Column({ type: 'varchar', length: 255, comment: '网站关键词' })
site_keywords: string;
@Column({ type: 'text', comment: '网站描述' })
site_description: string;
@Column({ type: 'varchar', length: 255, comment: '网站Logo' })
site_logo: string;
@Column({ type: 'varchar', length: 255, comment: '网站图标' })
site_favicon: string;
@Column({ type: 'varchar', length: 50, comment: 'ICP备案号' })
icp_number: string;
@Column({ type: 'varchar', length: 255, comment: '版权信息' })
copyright: string;
@Column({ type: 'tinyint', default: 1, comment: '网站状态 1:开启 0:关闭' })
site_status: number;
@Column({ type: 'varchar', length: 255, comment: '关闭原因' })
close_reason: string;
}

View File

@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { SiteSettingsController } from './site-settings.controller';
import { SiteSettingsService } from './site-settings.service';
import { Site } from './site.entity';
@Module({
imports: [TypeOrmModule.forFeature([Site])],
controllers: [SiteSettingsController],
providers: [SiteSettingsService],
exports: [SiteSettingsService],
})
export class SiteModule {}