chore: align common layer to PHP; add addon/member account; fix addon schema; clean old tools; wire modules; build passes

This commit is contained in:
万物街
2025-09-23 00:27:02 +08:00
parent 37f84efbdf
commit 2fb35eda53
85 changed files with 4194 additions and 1934 deletions

View File

@@ -0,0 +1,21 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Agreement } from './entity/agreement.entity';
import { AgreementService } from './services/agreement.service';
import { AgreementController } from './controllers/api/agreement.controller';
@Module({
imports: [
TypeOrmModule.forFeature([Agreement]),
],
controllers: [
AgreementController,
],
providers: [
AgreementService,
],
exports: [
AgreementService,
],
})
export class AgreementModule {}

View File

@@ -0,0 +1,39 @@
import { Controller, Get, Query, Req, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { ApiOptionalAuthGuard } from '../../../../core/security/apiOptionalAuth.guard';
import { SiteScopeGuard } from '../../../../core/security/siteScopeGuard';
import { AgreementService } from '../../services/agreement.service';
@ApiTags('前台-协议')
@UseGuards(ApiOptionalAuthGuard, SiteScopeGuard)
@Controller('api/agreement')
export class AgreementController {
constructor(private readonly agreementService: AgreementService) {}
/**
* 获取协议内容
*/
@Get('info')
@ApiOperation({ summary: '获取协议内容' })
@ApiResponse({ status: 200 })
async info(
@Query('type') type: string,
@Req() req: any
) {
const siteId = Number(req.auth?.('site_id') ?? req.siteId ?? 0) || 0;
const result = await this.agreementService.getInfo(type, siteId);
return { code: 0, data: result, msg: 'success' };
}
/**
* 获取协议列表
*/
@Get('list')
@ApiOperation({ summary: '获取协议列表' })
@ApiResponse({ status: 200 })
async list(@Req() req: any) {
const siteId = Number(req.auth?.('site_id') ?? req.siteId ?? 0) || 0;
const result = await this.agreementService.getList(siteId);
return { code: 0, data: result, msg: 'success' };
}
}

View File

@@ -0,0 +1,60 @@
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity('sys_agreement')
export class Agreement {
@PrimaryGeneratedColumn({ name: 'id', type: 'int', unsigned: true })
id: number;
@Column({ name: 'site_id', type: 'int', nullable: false, default: () => '0' })
siteId: number;
@Column({
name: 'title',
type: 'varchar',
length: 255,
nullable: false,
default: '',
})
title: string;
@Column({
name: 'content',
type: 'text',
nullable: true,
})
content: string;
@Column({
name: 'type',
type: 'varchar',
length: 50,
nullable: false,
default: '',
})
type: string;
@Column({
name: 'status',
type: 'tinyint',
nullable: false,
default: () => '1',
})
status: number;
@Column({
name: 'create_time',
type: 'timestamp',
nullable: false,
default: () => 'CURRENT_TIMESTAMP',
})
createTime: Date;
@Column({
name: 'update_time',
type: 'timestamp',
nullable: false,
default: () => 'CURRENT_TIMESTAMP',
onUpdate: 'CURRENT_TIMESTAMP',
})
updateTime: Date;
}

View File

@@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Agreement } from '../entity/agreement.entity';
@Injectable()
export class AgreementService {
constructor(
@InjectRepository(Agreement)
private readonly agreementRepo: Repository<Agreement>,
) {}
/**
* 获取协议内容
*/
async getInfo(type: string, siteId: number) {
const agreement = await this.agreementRepo.findOne({
where: { type, siteId, status: 1 }
});
if (!agreement) {
return null;
}
return {
id: agreement.id,
title: agreement.title,
content: agreement.content,
type: agreement.type
};
}
/**
* 获取协议列表
*/
async getList(siteId: number) {
const agreements = await this.agreementRepo.find({
where: { siteId, status: 1 },
order: { createTime: 'DESC' }
});
return agreements.map(item => ({
id: item.id,
title: item.title,
type: item.type,
createTime: item.createTime
}));
}
}