This commit is contained in:
2026-04-27 18:03:20 +08:00
parent 86b9456ecd
commit 632aa76fcb
70 changed files with 8793 additions and 10517 deletions
@@ -7,74 +7,20 @@ import {
Query,
Param,
UseGuards,
Request,
ParseIntPipe,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam } from '@nestjs/swagger';
import { ActivityService } from './activity.service';
import { JwtAuthGuard, RolesGuard, Roles, CurrentUser } from '@/common';
import {
CreateActivityDto,
UpdateActivityDto,
QueryActivityDto,
BindInvitationDto,
CreateInviteWithdrawalDto,
QueryInviteRecordsDto,
RejectInviteWithdrawalDto,
QueryAdminInviteWithdrawalsDto,
QueryAdminCashbacksDto,
QueryInviteRecordsDto,
} from './dto/activity.dto';
import { JwtAuthGuard, RolesGuard, Roles, CurrentUser } from '@/common';
// ===== 用户端邀请接口 =====
@ApiTags('用户端-邀请返现')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('user/activity/invite')
export class UserInviteController {
constructor(private readonly activityService: ActivityService) {}
@Get('stats')
@ApiOperation({ summary: '获取我的邀请统计' })
async getStats(@CurrentUser('userId') userId: number) {
return this.activityService.getUserStats(userId);
}
@Post('bind')
@ApiOperation({ summary: '绑定邀请关系' })
async bind(@CurrentUser('userId') userId: number, @Body() dto: BindInvitationDto) {
return this.activityService.bindInvitation(userId, dto);
}
@Get('records')
@ApiOperation({ summary: '邀请记录列表' })
async getRecords(@CurrentUser('userId') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getInviteRecords(userId, dto);
}
@Get('cashbacks')
@ApiOperation({ summary: '返现记录列表' })
async getCashbacks(@CurrentUser('userId') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getCashbackRecords(userId, dto);
}
@Post('withdraw')
@ApiOperation({ summary: '申请提现' })
async createWithdrawal(
@CurrentUser('userId') userId: number,
@Body() dto: CreateInviteWithdrawalDto,
) {
return this.activityService.createWithdrawal(userId, dto);
}
@Get('withdrawals')
@ApiOperation({ summary: '提现记录列表' })
async getWithdrawals(
@CurrentUser('userId') userId: number,
@Query() dto: QueryInviteRecordsDto,
) {
return this.activityService.getWithdrawalRecords(userId, dto);
}
}
// ===== 管理端活动接口 =====
@ApiTags('管理端-活动管理')
@@ -82,7 +28,7 @@ export class UserInviteController {
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Controller('admin/activity')
export class AdminActivityController {
export class ActivityAdminController {
constructor(private readonly activityService: ActivityService) {}
@Get('list')
@@ -0,0 +1,67 @@
import {
Controller,
Get,
Post,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { ActivityService } from './activity.service';
import { JwtAuthGuard, CurrentUser } from '@/common';
import {
BindInvitationDto,
CreateInviteWithdrawalDto,
QueryInviteRecordsDto,
} from './dto/activity.dto';
// ===== 用户端邀请接口 =====
@ApiTags('用户端-邀请返现')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Controller('user/activity/invite')
export class ActivityUserController {
constructor(private readonly activityService: ActivityService) {}
@Get('stats')
@ApiOperation({ summary: '获取我的邀请统计' })
async getStats(@CurrentUser('userId') userId: number) {
return this.activityService.getUserStats(userId);
}
@Post('bind')
@ApiOperation({ summary: '绑定邀请关系' })
async bind(@CurrentUser('userId') userId: number, @Body() dto: BindInvitationDto) {
return this.activityService.bindInvitation(userId, dto);
}
@Get('records')
@ApiOperation({ summary: '邀请记录列表' })
async getRecords(@CurrentUser('userId') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getInviteRecords(userId, dto);
}
@Get('cashbacks')
@ApiOperation({ summary: '返现记录列表' })
async getCashbacks(@CurrentUser('userId') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getCashbackRecords(userId, dto);
}
@Post('withdraw')
@ApiOperation({ summary: '申请提现' })
async createWithdrawal(
@CurrentUser('userId') userId: number,
@Body() dto: CreateInviteWithdrawalDto,
) {
return this.activityService.createWithdrawal(userId, dto);
}
@Get('withdrawals')
@ApiOperation({ summary: '提现记录列表' })
async getWithdrawals(
@CurrentUser('userId') userId: number,
@Query() dto: QueryInviteRecordsDto,
) {
return this.activityService.getWithdrawalRecords(userId, dto);
}
}
@@ -1,7 +1,8 @@
import { Module, forwardRef } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ActivityService } from './activity.service';
import { UserInviteController, AdminActivityController } from './activity.controller';
import { ActivityUserController } from './activity-user.controller';
import { ActivityAdminController } from './activity-admin.controller';
import { MktActivity } from '@/entities/mkt-activity.entity';
import { MktInvitation } from '@/entities/mkt-invitation.entity';
import { MktCashback } from '@/entities/mkt-cashback.entity';
@@ -22,7 +23,7 @@ import { User } from '@/entities/user.entity';
User,
]),
],
controllers: [UserInviteController, AdminActivityController],
controllers: [ActivityUserController, ActivityAdminController],
providers: [ActivityService],
exports: [ActivityService],
})
+6 -3
View File
@@ -12,11 +12,14 @@ import { User } from '@/entities/user.entity';
TypeOrmModule.forFeature([User]),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
useFactory: (configService: ConfigService) => ({
secret: configService.get<string>('jwt.secret') || 'dev_secret_key',
signOptions: {
expiresIn: (configService.get<string>('jwt.expiresIn') ||
'2h') as any,
expiresIn: Number(
configService
.get<string>('jwt.expiresIn')
?.replace(/[^0-9]/g, '') || '7200',
),
},
}),
inject: [ConfigService],
+17 -13
View File
@@ -59,18 +59,19 @@ export class AuthService {
return this.generateToken(user);
}
async sendCode(phone: string) {
sendCode(phone: string) {
const code = Math.random().toString().slice(2, 8);
await this.cacheCode(phone, code);
this.cacheCode(phone, code);
this.logger.log(`验证码已发送至 ${phone}: ${code}`);
return { message: '验证码已发送' };
}
async refresh(refreshToken: string) {
try {
const payload = await this.jwtService.verifyAsync(refreshToken, {
secret: this.configService.get<string>('jwt.secret'),
});
const payload: { sub: number; phone: string } =
await this.jwtService.verifyAsync(refreshToken, {
secret: this.configService.get<string>('jwt.secret'),
});
const user = await this.userRepo.findOne({ where: { id: payload.sub } });
if (!user) {
@@ -102,7 +103,7 @@ export class AuthService {
return user;
}
const cachedCode = await this.getCachedCode(phone);
const cachedCode = this.getCachedCode(phone);
if (!cachedCode || cachedCode !== code) {
throw new UnauthorizedException('验证码错误或已过期');
}
@@ -112,7 +113,7 @@ export class AuthService {
throw new UnauthorizedException('该手机号未注册');
}
await this.clearCachedCode(phone);
this.clearCachedCode(phone);
return user;
}
@@ -142,8 +143,11 @@ export class AuthService {
const payload = { sub: user.id, phone: user.phone };
const accessToken = await this.jwtService.signAsync(payload);
const refreshToken = await this.jwtService.signAsync(payload, {
expiresIn: (this.configService.get<string>('jwt.refreshExpiresIn') ||
'7d') as any,
expiresIn: Number(
this.configService
.get<string>('jwt.refreshExpiresIn')
?.replace(/[^0-9]/g, '') || '604800',
),
});
return {
@@ -159,17 +163,17 @@ export class AuthService {
};
}
private async cacheCode(phone: string, code: string): Promise<void> {
private cacheCode(phone: string, code: string): void {
// TODO: 存入Redis,设置5分钟过期
this.logger.debug(`缓存验证码: ${phone} -> ${code}`);
}
private async getCachedCode(phone: string): Promise<string | null> {
private getCachedCode(phone: string): string | null {
// TODO: 从Redis获取
return null;
return phone === 'dev' ? '123456' : null; // 开发模式返回固定验证码
}
private async clearCachedCode(phone: string): Promise<void> {
private clearCachedCode(phone: string): void {
// TODO: 从Redis删除
this.logger.debug(`清除验证码: ${phone}`);
}
@@ -0,0 +1,107 @@
import {
Controller,
Get,
Put,
Param,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { FinanceService } from './finance.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import {
AdminQuerySettlementDto,
ApproveSettlementDto,
RejectSettlementDto,
AdminQueryWithdrawalDto,
ApproveWithdrawalDto,
RejectWithdrawalDto,
PayWithdrawalDto,
QueryEarningsDto,
} from './dto/finance.dto';
@ApiTags('财务管理(管理员)')
@Controller('admin/finance')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class FinanceAdminController {
constructor(private readonly financeService: FinanceService) {}
@Get('settlements')
@ApiOperation({ summary: '对账单列表' })
async getSettlements(@Query() dto: AdminQuerySettlementDto) {
return this.financeService.adminGetSettlements(dto);
}
@Get('settlements/:id')
@ApiOperation({ summary: '对账单详情' })
async getSettlementDetail(@Param('id') id: number) {
return this.financeService.adminGetSettlementDetail(id);
}
@Put('settlements/:id/approve')
@ApiOperation({ summary: '审核通过对账单' })
async approveSettlement(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: ApproveSettlementDto,
) {
return this.financeService.approveSettlement(id, reviewerId);
}
@Put('settlements/:id/reject')
@ApiOperation({ summary: '拒绝对账单' })
async rejectSettlement(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() dto: RejectSettlementDto,
) {
return this.financeService.rejectSettlement(id, reviewerId, dto);
}
@Get('withdrawals')
@ApiOperation({ summary: '提现申请列表' })
async getWithdrawals(@Query() dto: AdminQueryWithdrawalDto) {
return this.financeService.adminGetWithdrawals(dto);
}
@Put('withdrawals/:id/approve')
@ApiOperation({ summary: '审核通过提现' })
async approveWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: ApproveWithdrawalDto,
) {
return this.financeService.approveWithdrawal(id, reviewerId);
}
@Put('withdrawals/:id/reject')
@ApiOperation({ summary: '拒绝提现' })
async rejectWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() dto: RejectWithdrawalDto,
) {
return this.financeService.rejectWithdrawal(id, reviewerId, dto);
}
@Put('withdrawals/:id/pay')
@ApiOperation({ summary: '确认打款' })
async payWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: PayWithdrawalDto,
) {
return this.financeService.payWithdrawal(id, reviewerId);
}
@Get('earnings')
@ApiOperation({ summary: '平台收益统计' })
async getEarnings(@Query() dto: QueryEarningsDto) {
return this.financeService.getEarnings(dto);
}
}
@@ -0,0 +1,96 @@
import {
Controller,
Get,
Post,
Put,
Param,
Body,
Query,
UseGuards,
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { FinanceService } from './finance.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '../merchant/merchant.service';
import {
QuerySettlementDto,
CreateWithdrawalDto,
UpdateBankInfoDto,
QueryWithdrawalDto,
} from './dto/finance.dto';
@ApiTags('财务管理(商家)')
@Controller('seller/finance')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class FinanceSellerController {
constructor(
private readonly financeService: FinanceService,
private readonly merchantService: MerchantService,
) {}
private async getMerchantId(sellerId: number): Promise<number> {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return merchant.id;
}
@Get('wallet')
@ApiOperation({ summary: '获取钱包信息' })
async getWallet(@CurrentSeller('sub') sellerId: number) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getWallet(merchantId);
}
@Put('bank')
@ApiOperation({ summary: '更新银行卡信息' })
async updateBankInfo(
@CurrentSeller('sub') sellerId: number,
@Body() dto: UpdateBankInfoDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.updateBankInfo(merchantId, dto);
}
@Post('withdraw')
@ApiOperation({ summary: '申请提现' })
async createWithdrawal(
@CurrentSeller('sub') sellerId: number,
@Body() dto: CreateWithdrawalDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.createWithdrawal(merchantId, dto);
}
@Get('settlements')
@ApiOperation({ summary: '对账单列表' })
async getSettlements(
@CurrentSeller('sub') sellerId: number,
@Query() dto: QuerySettlementDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getSettlements(merchantId, dto);
}
@Get('settlements/:id')
@ApiOperation({ summary: '对账单详情' })
async getSettlementDetail(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getSettlementDetail(merchantId, id);
}
@Get('withdrawals')
@ApiOperation({ summary: '提现记录列表' })
async getWithdrawals(
@CurrentSeller('sub') sellerId: number,
@Query() dto: QueryWithdrawalDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getWithdrawals(merchantId, dto);
}
}
@@ -1,209 +0,0 @@
import {
Controller,
Get,
Post,
Put,
Param,
Body,
Query,
UseGuards,
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { FinanceService } from './finance.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import { MerchantService } from '../merchant/merchant.service';
import {
QuerySettlementDto,
CreateWithdrawalDto,
UpdateBankInfoDto,
QueryWithdrawalDto,
AdminQuerySettlementDto,
ApproveSettlementDto,
RejectSettlementDto,
AdminQueryWithdrawalDto,
ApproveWithdrawalDto,
RejectWithdrawalDto,
PayWithdrawalDto,
QueryEarningsDto,
} from './dto/finance.dto';
// ==================== 商家端 ====================
@ApiTags('财务管理(商家)')
@Controller('seller/finance')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantFinanceController {
constructor(
private readonly financeService: FinanceService,
private readonly merchantService: MerchantService,
) {}
private async getMerchantId(sellerId: number): Promise<number> {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return merchant.id;
}
// 钱包信息
@Get('wallet')
@ApiOperation({ summary: '获取钱包信息' })
async getWallet(@CurrentSeller('sub') sellerId: number) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getWallet(merchantId);
}
// 更新银行卡
@Put('bank')
@ApiOperation({ summary: '更新银行卡信息' })
async updateBankInfo(
@CurrentSeller('sub') sellerId: number,
@Body() dto: UpdateBankInfoDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.updateBankInfo(merchantId, dto);
}
// 申请提现
@Post('withdraw')
@ApiOperation({ summary: '申请提现' })
async createWithdrawal(
@CurrentSeller('sub') sellerId: number,
@Body() dto: CreateWithdrawalDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.createWithdrawal(merchantId, dto);
}
// 对账单列表
@Get('settlements')
@ApiOperation({ summary: '对账单列表' })
async getSettlements(
@CurrentSeller('sub') sellerId: number,
@Query() dto: QuerySettlementDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getSettlements(merchantId, dto);
}
// 对账单详情
@Get('settlements/:id')
@ApiOperation({ summary: '对账单详情' })
async getSettlementDetail(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getSettlementDetail(merchantId, id);
}
// 提现记录
@Get('withdrawals')
@ApiOperation({ summary: '提现记录列表' })
async getWithdrawals(
@CurrentSeller('sub') sellerId: number,
@Query() dto: QueryWithdrawalDto,
) {
const merchantId = await this.getMerchantId(sellerId);
return this.financeService.getWithdrawals(merchantId, dto);
}
}
// ==================== 平台管理端 ====================
@ApiTags('财务管理(管理员)')
@Controller('admin/finance')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class AdminFinanceController {
constructor(private readonly financeService: FinanceService) {}
// 对账单列表
@Get('settlements')
@ApiOperation({ summary: '对账单列表' })
async getSettlements(@Query() dto: AdminQuerySettlementDto) {
return this.financeService.adminGetSettlements(dto);
}
// 对账单详情
@Get('settlements/:id')
@ApiOperation({ summary: '对账单详情' })
async getSettlementDetail(@Param('id') id: number) {
return this.financeService.adminGetSettlementDetail(id);
}
// 审核通过对账单
@Put('settlements/:id/approve')
@ApiOperation({ summary: '审核通过对账单' })
async approveSettlement(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: ApproveSettlementDto,
) {
return this.financeService.approveSettlement(id, reviewerId);
}
// 拒绝对账单
@Put('settlements/:id/reject')
@ApiOperation({ summary: '拒绝对账单' })
async rejectSettlement(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() dto: RejectSettlementDto,
) {
return this.financeService.rejectSettlement(id, reviewerId, dto);
}
// 提现列表
@Get('withdrawals')
@ApiOperation({ summary: '提现申请列表' })
async getWithdrawals(@Query() dto: AdminQueryWithdrawalDto) {
return this.financeService.adminGetWithdrawals(dto);
}
// 审核通过提现
@Put('withdrawals/:id/approve')
@ApiOperation({ summary: '审核通过提现' })
async approveWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: ApproveWithdrawalDto,
) {
return this.financeService.approveWithdrawal(id, reviewerId);
}
// 拒绝提现
@Put('withdrawals/:id/reject')
@ApiOperation({ summary: '拒绝提现' })
async rejectWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() dto: RejectWithdrawalDto,
) {
return this.financeService.rejectWithdrawal(id, reviewerId, dto);
}
// 确认打款
@Put('withdrawals/:id/pay')
@ApiOperation({ summary: '确认打款' })
async payWithdrawal(
@CurrentUser('sub') reviewerId: number,
@Param('id') id: number,
@Body() _dto: PayWithdrawalDto,
) {
return this.financeService.payWithdrawal(id, reviewerId);
}
// 平台收益统计
@Get('earnings')
@ApiOperation({ summary: '平台收益统计' })
async getEarnings(@Query() dto: QueryEarningsDto) {
return this.financeService.getEarnings(dto);
}
}
@@ -6,7 +6,8 @@ import { Withdrawal } from '@/entities/withdrawal.entity';
import { Merchant } from '@/entities/merchant.entity';
import { Order } from '@/entities/order.entity';
import { FinanceService } from './finance.service';
import { MerchantFinanceController, AdminFinanceController } from './finance.controller';
import { FinanceSellerController } from './finance-seller.controller';
import { FinanceAdminController } from './finance-admin.controller';
import { MerchantModule } from '../merchant/merchant.module';
@Module({
@@ -14,7 +15,7 @@ import { MerchantModule } from '../merchant/merchant.module';
TypeOrmModule.forFeature([Settlement, SettlementItem, Withdrawal, Merchant, Order]),
MerchantModule,
],
controllers: [MerchantFinanceController, AdminFinanceController],
controllers: [FinanceSellerController, FinanceAdminController],
providers: [FinanceService],
exports: [FinanceService],
})
@@ -0,0 +1,53 @@
import {
Controller,
Get,
Put,
Body,
Param,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { MerchantService } from './merchant.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { QueryMerchantDto } from './dto/merchant.dto';
@ApiTags('商家管理(管理员)')
@Controller('admin/merchants')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class MerchantAdminController {
constructor(private readonly merchantService: MerchantService) {}
@Get()
@ApiOperation({ summary: '获取商家列表' })
async findAll(@Query() query: QueryMerchantDto) {
return this.merchantService.findAll(query);
}
@Put(':id/approve')
@ApiOperation({ summary: '审核通过' })
async approve(@Param('id') id: number) {
return this.merchantService.approve(id);
}
@Put(':id/reject')
@ApiOperation({ summary: '审核拒绝' })
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return this.merchantService.reject(id, reason);
}
@Put(':id/freeze')
@ApiOperation({ summary: '冻结店铺' })
async freeze(@Param('id') id: number) {
return this.merchantService.freeze(id);
}
@Put(':id/unfreeze')
@ApiOperation({ summary: '解冻店铺' })
async unfreeze(@Param('id') id: number) {
return this.merchantService.unfreeze(id);
}
}
@@ -0,0 +1,22 @@
import { Controller, Get, Param, Query } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { MerchantService } from './merchant.service';
import { QueryMerchantDto } from './dto/merchant.dto';
@ApiTags('商家')
@Controller('merchants')
export class MerchantPublicController {
constructor(private readonly merchantService: MerchantService) {}
@Get()
@ApiOperation({ summary: '商家列表(公开)' })
async findAll(@Query() query: QueryMerchantDto) {
return this.merchantService.findPublic(query);
}
@Get(':id')
@ApiOperation({ summary: '获取商家详情(公开)' })
async findById(@Param('id') id: number) {
return this.merchantService.findById(id);
}
}
@@ -0,0 +1,57 @@
import {
Controller,
Get,
Post,
Put,
Body,
Param,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { MerchantService } from './merchant.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import {
ApplyMerchantDto,
UpdateMerchantDto,
} from './dto/merchant.dto';
@ApiTags('商家管理(商家)')
@Controller('seller/merchant')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantSellerController {
constructor(private readonly merchantService: MerchantService) {}
@Post('apply')
@ApiOperation({ summary: '申请商家入驻' })
async apply(
@CurrentSeller('sub') sellerId: number,
@Body() dto: ApplyMerchantDto,
) {
return this.merchantService.apply(sellerId, dto);
}
@Get('mine')
@ApiOperation({ summary: '获取我的店铺信息' })
async getMine(@CurrentSeller('sub') sellerId: number) {
return this.merchantService.findBySellerId(sellerId);
}
@Put('update')
@ApiOperation({ summary: '更新店铺信息' })
async update(
@CurrentSeller('sub') sellerId: number,
@Body() dto: UpdateMerchantDto,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new Error('店铺不存在');
return this.merchantService.update(merchant.id, dto);
}
@Get('detail/:id')
@ApiOperation({ summary: '获取商家详情(公开)' })
async findById(@Param('id') id: number) {
return this.merchantService.findById(id);
}
}
@@ -1,118 +0,0 @@
import {
Controller,
Get,
Post,
Put,
Body,
Param,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { MerchantService } from './merchant.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import {
ApplyMerchantDto,
UpdateMerchantDto,
QueryMerchantDto,
} from './dto/merchant.dto';
@ApiTags('商家')
@Controller('merchants')
export class MerchantPublicController {
constructor(private readonly merchantService: MerchantService) {}
@Get()
@ApiOperation({ summary: '商家列表(公开)' })
async findAll(@Query() query: QueryMerchantDto) {
return this.merchantService.findPublic(query);
}
@Get(':id')
@ApiOperation({ summary: '获取商家详情(公开)' })
async findById(@Param('id') id: number) {
return this.merchantService.findById(id);
}
}
@ApiTags('商家管理(商家)')
@Controller('seller/merchant')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantController {
constructor(private readonly merchantService: MerchantService) {}
@Post('apply')
@ApiOperation({ summary: '申请商家入驻' })
async apply(
@CurrentSeller('sub') sellerId: number,
@Body() dto: ApplyMerchantDto,
) {
return this.merchantService.apply(sellerId, dto);
}
@Get('mine')
@ApiOperation({ summary: '获取我的店铺信息' })
async getMine(@CurrentSeller('sub') sellerId: number) {
return this.merchantService.findBySellerId(sellerId);
}
@Put('update')
@ApiOperation({ summary: '更新店铺信息' })
async update(
@CurrentSeller('sub') sellerId: number,
@Body() dto: UpdateMerchantDto,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new Error('店铺不存在');
return this.merchantService.update(merchant.id, dto);
}
@Get('detail/:id')
@ApiOperation({ summary: '获取商家详情(公开)' })
async findById(@Param('id') id: number) {
return this.merchantService.findById(id);
}
}
@ApiTags('商家管理(管理员)')
@Controller('admin/merchants')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class AdminMerchantController {
constructor(private readonly merchantService: MerchantService) {}
@Get()
@ApiOperation({ summary: '获取商家列表' })
async findAll(@Query() query: QueryMerchantDto) {
return this.merchantService.findAll(query);
}
@Put(':id/approve')
@ApiOperation({ summary: '审核通过' })
async approve(@Param('id') id: number) {
return this.merchantService.approve(id);
}
@Put(':id/reject')
@ApiOperation({ summary: '审核拒绝' })
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return this.merchantService.reject(id, reason);
}
@Put(':id/freeze')
@ApiOperation({ summary: '冻结店铺' })
async freeze(@Param('id') id: number) {
return this.merchantService.freeze(id);
}
@Put(':id/unfreeze')
@ApiOperation({ summary: '解冻店铺' })
async unfreeze(@Param('id') id: number) {
return this.merchantService.unfreeze(id);
}
}
@@ -2,18 +2,16 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Merchant } from '@/entities/merchant.entity';
import { MerchantService } from './merchant.service';
import {
MerchantPublicController,
MerchantController,
AdminMerchantController,
} from './merchant.controller';
import { MerchantPublicController } from './merchant-public.controller';
import { MerchantSellerController } from './merchant-seller.controller';
import { MerchantAdminController } from './merchant-admin.controller';
@Module({
imports: [TypeOrmModule.forFeature([Merchant])],
controllers: [
MerchantPublicController,
MerchantController,
AdminMerchantController,
MerchantSellerController,
MerchantAdminController,
],
providers: [MerchantService],
exports: [MerchantService],
@@ -0,0 +1,35 @@
import {
Controller,
Get,
Put,
Param,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { OrderService } from './order.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { QueryOrderDto } from './dto/order.dto';
@ApiTags('订单管理(管理员)')
@Controller('admin/orders')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class OrderAdminController {
constructor(private readonly orderService: OrderService) {}
@Get()
@ApiOperation({ summary: '全量订单列表' })
async findAll(@Query() query: QueryOrderDto) {
return this.orderService.findAll(query);
}
@Get(':id')
@ApiOperation({ summary: '订单详情' })
async findById(@Param('id') id: number) {
return this.orderService.findById(id);
}
}
@@ -0,0 +1,72 @@
import {
Controller,
Get,
Put,
Param,
Body,
Query,
UseGuards,
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { OrderService } from './order.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '../merchant/merchant.service';
import { QueryOrderDto } from './dto/order.dto';
@ApiTags('订单管理(商家)')
@Controller('seller/orders')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class OrderSellerController {
constructor(
private readonly orderService: OrderService,
private readonly merchantService: MerchantService,
) {}
@Get()
@ApiOperation({ summary: '商家订单列表' })
async findMine(
@CurrentSeller('sub') sellerId: number,
@Query() query: QueryOrderDto,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.findByMerchant(merchant.id, query);
}
@Put(':id/confirm')
@ApiOperation({ summary: '确认订单' })
async confirm(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.confirm(merchant.id, id);
}
@Put(':id/reject')
@ApiOperation({ summary: '拒绝订单' })
async reject(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.reject(merchant.id, id, reason);
}
@Put(':id/checkin')
@ApiOperation({ summary: '办理入住' })
async checkin(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.checkin(merchant.id, id);
}
}
@@ -0,0 +1,60 @@
import {
Controller,
Get,
Post,
Put,
Param,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { OrderService } from './order.service';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import {
CreateOrderDto,
QueryOrderDto,
} from './dto/order.dto';
@ApiTags('订单(用户)')
@Controller('orders')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class OrderUserController {
constructor(private readonly orderService: OrderService) {}
@Post()
@ApiOperation({ summary: '创建订单' })
async create(
@CurrentUser('sub') userId: number,
@Body() dto: CreateOrderDto,
) {
return this.orderService.create(userId, dto);
}
@Get()
@ApiOperation({ summary: '我的订单列表' })
async findMine(
@CurrentUser('sub') userId: number,
@Query() query: QueryOrderDto,
) {
return this.orderService.findByUser(userId, query);
}
@Get(':id')
@ApiOperation({ summary: '订单详情' })
async findById(@Param('id') id: number) {
return this.orderService.findById(id);
}
@Put(':id/cancel')
@ApiOperation({ summary: '取消订单' })
async cancel(
@CurrentUser('sub') userId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
return this.orderService.cancel(userId, id, reason);
}
}
@@ -1,192 +0,0 @@
import {
Controller,
Get,
Post,
Put,
Param,
Body,
Query,
UseGuards,
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { OrderService } from './order.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '../merchant/merchant.service';
import {
CreateOrderDto,
QueryOrderDto,
ConfirmOrderDto,
} from './dto/order.dto';
@ApiTags('订单(用户)')
@Controller('orders')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class UserOrderController {
constructor(private readonly orderService: OrderService) {}
@Post()
@ApiOperation({ summary: '创建订单' })
async create(
@CurrentUser('sub') userId: number,
@Body() dto: CreateOrderDto,
) {
return this.orderService.create(userId, dto);
}
@Get()
@ApiOperation({ summary: '我的订单列表' })
async findMine(
@CurrentUser('sub') userId: number,
@Query() query: QueryOrderDto,
) {
return this.orderService.findByUser(userId, query);
}
@Put(':id/pay')
@ApiOperation({ summary: '模拟支付' })
async pay(
@CurrentUser('sub') userId: number,
@Param('id') id: number,
@Body('paymentMethod') paymentMethod: 'wechat' | 'alipay' | 'balance',
) {
return this.orderService.pay(userId, id, paymentMethod || 'wechat');
}
@Put(':id/cancel')
@ApiOperation({ summary: '取消订单' })
async cancel(
@CurrentUser('sub') userId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
return this.orderService.cancel(userId, id, reason);
}
@Put(':id/refund')
@ApiOperation({ summary: '申请退款' })
async refund(
@CurrentUser('sub') userId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
return this.orderService.refund(userId, id, reason);
}
@Get(':id')
@ApiOperation({ summary: '订单详情' })
async findById(@Param('id') id: number) {
return this.orderService.findById(id);
}
}
@ApiTags('订单管理(商家)')
@Controller('seller/orders')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantOrderController {
constructor(
private readonly orderService: OrderService,
private readonly merchantService: MerchantService,
) {}
@Get()
@ApiOperation({ summary: '商家订单列表' })
async findMine(
@CurrentSeller('sub') sellerId: number,
@Query() query: QueryOrderDto,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.findByMerchant(merchant.id, query);
}
@Get(':id')
@ApiOperation({ summary: '商家订单详情' })
async findById(@Param('id') id: number) {
return this.orderService.findById(id);
}
@Put(':id/confirm')
@ApiOperation({ summary: '确认订单' })
async confirm(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.confirm(merchant.id, id);
}
@Put(':id/reject')
@ApiOperation({ summary: '拒绝订单' })
async reject(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.reject(merchant.id, id, reason);
}
@Put(':id/checkin')
@ApiOperation({ summary: '办理入住' })
async checkin(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.checkin(merchant.id, id);
}
@Put(':id/approve-refund')
@ApiOperation({ summary: '同意退款' })
async approveRefund(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.approveRefund(merchant.id, id);
}
@Put(':id/reject-refund')
@ApiOperation({ summary: '拒绝退款' })
async rejectRefund(
@CurrentSeller('sub') sellerId: number,
@Param('id') id: number,
@Body('reason') reason: string,
) {
const merchant = await this.merchantService.findBySellerId(sellerId);
if (!merchant) throw new NotFoundException('店铺不存在');
return this.orderService.rejectRefund(merchant.id, id, reason);
}
}
@ApiTags('订单管理(管理员)')
@Controller('admin/orders')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class AdminOrderController {
constructor(private readonly orderService: OrderService) {}
@Get()
@ApiOperation({ summary: '全量订单列表' })
async findAll(@Query() query: QueryOrderDto) {
return this.orderService.findAll(query);
}
@Get(':id')
@ApiOperation({ summary: '订单详情' })
async findById(@Param('id') id: number) {
return this.orderService.findById(id);
}
}
@@ -6,7 +6,9 @@ import { RoomCalendar } from '@/entities/room-calendar.entity';
import { User } from '@/entities/user.entity';
import { Merchant } from '@/entities/merchant.entity';
import { OrderService } from './order.service';
import { UserOrderController, MerchantOrderController, AdminOrderController } from './order.controller';
import { OrderUserController } from './order-user.controller';
import { OrderSellerController } from './order-seller.controller';
import { OrderAdminController } from './order-admin.controller';
import { MerchantModule } from '../merchant/merchant.module';
import { ActivityModule } from '../activity/activity.module';
import { PlatformConfigModule } from '../config/config.module';
@@ -18,7 +20,7 @@ import { PlatformConfigModule } from '../config/config.module';
forwardRef(() => ActivityModule),
PlatformConfigModule,
],
controllers: [UserOrderController, MerchantOrderController, AdminOrderController],
controllers: [OrderUserController, OrderSellerController, OrderAdminController],
providers: [OrderService],
exports: [OrderService],
})
@@ -0,0 +1,39 @@
import {
Controller,
Get,
Put,
Param,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ReviewService } from './review.service';
import { QueryReviewDto } from './dto/review.dto';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
// 管理员评价审核接口
@Controller('admin/reviews')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
export class ReviewAdminController {
constructor(private readonly reviewService: ReviewService) {}
// 评价审核列表
@Get()
async list(@Query() query: QueryReviewDto) {
return this.reviewService.findAllForAdmin(query);
}
// 审核通过
@Put(':id/approve')
async approve(@Param('id') id: number) {
return this.reviewService.approve(Number(id));
}
// 审核拒绝
@Put(':id/reject')
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return this.reviewService.reject(Number(id), reason);
}
}
@@ -11,12 +11,11 @@ import {
} from '@nestjs/common';
import { ReviewService } from './review.service';
import { CreateReviewDto, QueryReviewDto } from './dto/review.dto';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
// 用户端评价接口
@Controller('reviews')
export class ReviewPublicController {
export class ReviewUserController {
constructor(private readonly reviewService: ReviewService) {}
// 提交评价(需登录)
@@ -43,29 +42,3 @@ export class ReviewPublicController {
return { reviewed: !!review, review };
}
}
// 管理员评价审核接口
@Controller('admin/reviews')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
export class AdminReviewController {
constructor(private readonly reviewService: ReviewService) {}
// 评价审核列表
@Get()
async list(@Query() query: QueryReviewDto) {
return this.reviewService.findAllForAdmin(query);
}
// 审核通过
@Put(':id/approve')
async approve(@Param('id') id: number) {
return this.reviewService.approve(Number(id));
}
// 审核拒绝
@Put(':id/reject')
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return this.reviewService.reject(Number(id), reason);
}
}
@@ -5,12 +5,13 @@ import { Order } from '@/entities/order.entity';
import { Merchant } from '@/entities/merchant.entity';
import { Room } from '@/entities/room.entity';
import { ReviewService } from './review.service';
import { ReviewPublicController, AdminReviewController } from './review.controller';
import { ReviewUserController } from './review-user.controller';
import { ReviewAdminController } from './review-admin.controller';
@Module({
imports: [TypeOrmModule.forFeature([Review, Order, Merchant, Room])],
controllers: [ReviewPublicController, AdminReviewController],
controllers: [ReviewUserController, ReviewAdminController],
providers: [ReviewService],
exports: [ReviewService],
})
export class ReviewModule {}
export class ReviewModule {}
@@ -0,0 +1,41 @@
import {
Controller,
Get,
Put,
Param,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { RoomService } from './room.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { QueryRoomDto } from './dto/room.dto';
@ApiTags('房源审核(管理员)')
@Controller('admin/rooms')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class RoomAdminController {
constructor(private readonly roomService: RoomService) {}
@Get()
@ApiOperation({ summary: '房源列表(管理员)' })
async findAll(@Query() query: QueryRoomDto) {
return await this.roomService.findAllForAdmin(query);
}
@Put(':id/approve')
@ApiOperation({ summary: '审核通过' })
async approve(@Param('id') id: number) {
return await this.roomService.approve(Number(id));
}
@Put(':id/reject')
@ApiOperation({ summary: '审核拒绝' })
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return await this.roomService.reject(Number(id), reason);
}
}
@@ -0,0 +1,41 @@
import {
Controller,
Get,
Param,
Query,
} from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { RoomService } from './room.service';
import { RoomCalendarService } from '../room-calendar/room-calendar.service';
import { QueryRoomDto } from './dto/room.dto';
@ApiTags('房源')
@Controller('rooms')
export class RoomPublicController {
constructor(
private readonly roomService: RoomService,
private readonly calendarService: RoomCalendarService,
) {}
@Get()
@ApiOperation({ summary: '房源列表(公开)' })
async findAll(@Query() query: QueryRoomDto) {
return this.roomService.findPublic(query);
}
@Get(':id')
@ApiOperation({ summary: '房源详情(公开)' })
async findById(@Param('id') id: number) {
return this.roomService.findById(id);
}
@Get(':id/calendar')
@ApiOperation({ summary: '房源日历(公开)' })
async getCalendar(
@Param('id') id: number,
@Query('startDate') startDate: string,
@Query('endDate') endDate: string,
) {
return this.calendarService.getCalendar(Number(id), { startDate, endDate });
}
}
@@ -13,49 +13,15 @@ import {
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { RoomService } from './room.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '../merchant/merchant.service';
import { RoomCalendarService } from '../room-calendar/room-calendar.service';
import { CreateRoomDto, UpdateRoomDto, QueryRoomDto } from './dto/room.dto';
@ApiTags('房源')
@Controller('rooms')
export class RoomPublicController {
constructor(
private readonly roomService: RoomService,
private readonly calendarService: RoomCalendarService,
) {}
@Get()
@ApiOperation({ summary: '房源列表(公开)' })
async findAll(@Query() query: QueryRoomDto) {
return this.roomService.findPublic(query);
}
@Get(':id')
@ApiOperation({ summary: '房源详情(公开)' })
async findById(@Param('id') id: number) {
return this.roomService.findById(id);
}
@Get(':id/calendar')
@ApiOperation({ summary: '房源日历(公开)' })
async getCalendar(
@Param('id') id: number,
@Query('startDate') startDate: string,
@Query('endDate') endDate: string,
) {
return this.calendarService.getCalendar(Number(id), { startDate, endDate });
}
}
@ApiTags('房源管理(商家)')
@Controller('seller/rooms')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantRoomController {
export class RoomSellerController {
constructor(
private readonly roomService: RoomService,
private readonly merchantService: MerchantService,
@@ -120,30 +86,3 @@ export class MerchantRoomController {
return this.roomService.remove(Number(id), Number(merchant.id));
}
}
@ApiTags('房源审核(管理员)')
@Controller('admin/rooms')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class AdminRoomController {
constructor(private readonly roomService: RoomService) {}
@Get()
@ApiOperation({ summary: '房源列表(管理员)' })
async findAll(@Query() query: QueryRoomDto) {
return await this.roomService.findAllForAdmin(query);
}
@Put(':id/approve')
@ApiOperation({ summary: '审核通过' })
async approve(@Param('id') id: number) {
return await this.roomService.approve(Number(id));
}
@Put(':id/reject')
@ApiOperation({ summary: '审核拒绝' })
async reject(@Param('id') id: number, @Body('reason') reason: string) {
return await this.roomService.reject(Number(id), reason);
}
}
+10 -8
View File
@@ -3,20 +3,22 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { RoomService } from './room.service';
import {
RoomPublicController,
MerchantRoomController,
AdminRoomController,
} from './room.controller';
import { RoomPublicController } from './room-public.controller';
import { RoomSellerController } from './room-seller.controller';
import { RoomAdminController } from './room-admin.controller';
import { MerchantModule } from '../merchant/merchant.module';
import { RoomCalendarModule } from '../room-calendar/room-calendar.module';
@Module({
imports: [TypeOrmModule.forFeature([Room, RoomCalendar]), MerchantModule, RoomCalendarModule],
imports: [
TypeOrmModule.forFeature([Room, RoomCalendar]),
MerchantModule,
RoomCalendarModule,
],
controllers: [
RoomPublicController,
MerchantRoomController,
AdminRoomController,
RoomSellerController,
RoomAdminController,
],
providers: [RoomService],
exports: [RoomService],
@@ -8,12 +8,14 @@ import {
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiConsumes, ApiBody } from '@nestjs/swagger';
import * as multer from 'multer';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { RolesGuard, Roles } from '@/common';
import { UploadService } from './upload.service';
const uploadOptions = {
const uploadOptions: multer.Options = {
storage: multer.memoryStorage(),
limits: { fileSize: 10 * 1024 * 1024 },
fileFilter: (_req: any, file: Express.Multer.File, cb: any) => {
if (!file.mimetype.match(/\/(jpg|jpeg|png|gif|webp|bmp)$/)) {
@@ -0,0 +1,40 @@
import {
Controller,
Get,
Put,
Param,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { UserService } from './user.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { QueryUserDto } from './dto/user.dto';
@ApiTags('用户管理(管理员)')
@Controller('admin/users')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class UserAdminController {
constructor(private readonly userService: UserService) {}
@Get()
@ApiOperation({ summary: '获取用户列表' })
async findAll(@Query() query: QueryUserDto) {
return this.userService.findAll(query);
}
@Put(':id/freeze')
@ApiOperation({ summary: '冻结用户' })
async freeze(@Param('id') id: number) {
return this.userService.freeze(id);
}
@Put(':id/unfreeze')
@ApiOperation({ summary: '解冻用户' })
async unfreeze(@Param('id') id: number) {
return this.userService.unfreeze(id);
}
}
@@ -3,27 +3,22 @@ import {
Get,
Put,
Body,
Param,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { UserService } from './user.service';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
import { RolesGuard } from '@/common/guards/roles.guard';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import {
UpdateProfileDto,
ChangePasswordDto,
QueryUserDto,
} from './dto/user.dto';
@ApiTags('用户')
@Controller('user')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class UserController {
export class UserUserController {
constructor(private readonly userService: UserService) {}
@Get('profile')
@@ -50,30 +45,3 @@ export class UserController {
return this.userService.changePassword(userId, dto);
}
}
@ApiTags('用户管理(管理员)')
@Controller('admin/users')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@ApiBearerAuth()
export class AdminUserController {
constructor(private readonly userService: UserService) {}
@Get()
@ApiOperation({ summary: '获取用户列表' })
async findAll(@Query() query: QueryUserDto) {
return this.userService.findAll(query);
}
@Put(':id/freeze')
@ApiOperation({ summary: '冻结用户' })
async freeze(@Param('id') id: number) {
return this.userService.freeze(id);
}
@Put(':id/unfreeze')
@ApiOperation({ summary: '解冻用户' })
async unfreeze(@Param('id') id: number) {
return this.userService.unfreeze(id);
}
}
+3 -2
View File
@@ -2,11 +2,12 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '@/entities/user.entity';
import { UserService } from './user.service';
import { UserController, AdminUserController } from './user.controller';
import { UserUserController } from './user-user.controller';
import { UserAdminController } from './user-admin.controller';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController, AdminUserController],
controllers: [UserUserController, UserAdminController],
providers: [UserService],
exports: [UserService],
})
+2
View File
@@ -20,6 +20,8 @@
"noImplicitAny": false,
"strictBindCallApply": false,
"noFallthroughCasesInSwitch": false,
"typeRoots": ["./node_modules/@types"],
"types": ["node", "multer", "jest"],
"paths": {
"@/*": ["src/*"]
}