feat: multi-module iteration
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import {
|
||||
IsEmail,
|
||||
IsIn,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
|
||||
export class CreateAfterSaleTicketDto {
|
||||
@IsString()
|
||||
@IsIn(['REFUND', 'RESHIPMENT', 'DAMAGE_RETURN', 'RETURN_REFUND', 'PACKAGE_DISPUTE'])
|
||||
ticketType: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(512)
|
||||
remark?: string;
|
||||
|
||||
@IsOptional()
|
||||
evidenceUrls?: string[];
|
||||
}
|
||||
|
||||
export class CreatePackageDisputeDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
storeId: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(512)
|
||||
remark?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
redeemRecordId?: string;
|
||||
}
|
||||
|
||||
export class CreateInvoiceDto {
|
||||
@IsString()
|
||||
@IsIn(['PERSONAL', 'ENTERPRISE'])
|
||||
titleType: string;
|
||||
|
||||
@IsString()
|
||||
@IsIn(['NORMAL', 'SPECIAL'])
|
||||
invoiceKind: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MaxLength(128)
|
||||
titleName: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
taxNo?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(256)
|
||||
addressPhone?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(256)
|
||||
bankAccount?: string;
|
||||
|
||||
@IsEmail()
|
||||
email: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MaxLength(20)
|
||||
phone: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(512)
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export class AdminCreateInvoiceDto extends CreateInvoiceDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@MaxLength(32)
|
||||
orderNo: string;
|
||||
}
|
||||
|
||||
export class IssueInvoiceDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
fileUrl: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
resourceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(512)
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export class RejectInvoiceDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(512)
|
||||
remark?: string;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsIn,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Matches,
|
||||
MaxLength,
|
||||
Min,
|
||||
ValidateIf,
|
||||
} from 'class-validator';
|
||||
|
||||
export class PartnerProxyOrderPreviewDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
productId: string;
|
||||
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
quantity: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsIn(['ADDRESS', 'ON_SITE_PICKUP'])
|
||||
deliveryMode?: 'ADDRESS' | 'ON_SITE_PICKUP';
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
storeId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
receiverCity?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
receiverDistrict?: string;
|
||||
}
|
||||
|
||||
export class PartnerProxyOrderCreateDto {
|
||||
@IsString()
|
||||
@Matches(/^1\d{10}$/, { message: '请输入有效手机号' })
|
||||
phone: string;
|
||||
|
||||
@IsIn(['ADDRESS', 'ON_SITE_PICKUP'])
|
||||
deliveryMode: 'ADDRESS' | 'ON_SITE_PICKUP';
|
||||
|
||||
@ValidateIf((o: PartnerProxyOrderCreateDto) => o.deliveryMode === 'ADDRESS')
|
||||
@IsBoolean()
|
||||
autoReceive?: boolean;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
storeId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
receiverName?: string;
|
||||
|
||||
@ValidateIf((o: PartnerProxyOrderCreateDto) => o.deliveryMode === 'ADDRESS')
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
province?: string;
|
||||
|
||||
@ValidateIf((o: PartnerProxyOrderCreateDto) => o.deliveryMode === 'ADDRESS')
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
city?: string;
|
||||
|
||||
@ValidateIf((o: PartnerProxyOrderCreateDto) => o.deliveryMode === 'ADDRESS')
|
||||
@IsString()
|
||||
@MaxLength(32)
|
||||
district?: string;
|
||||
|
||||
@ValidateIf((o: PartnerProxyOrderCreateDto) => o.deliveryMode === 'ADDRESS')
|
||||
@IsString()
|
||||
@MaxLength(256)
|
||||
addressDetail?: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
productId: string;
|
||||
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@Min(1)
|
||||
quantity: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
promoCodeId?: string;
|
||||
}
|
||||
|
||||
export class PartnerProxyOrderPayDto {
|
||||
@IsIn(['NATIVE', 'JSAPI'])
|
||||
payMethod: 'NATIVE' | 'JSAPI';
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
import { Body, Controller, Get, Param, Post, Put, Query, Req, UseGuards } from '@nestjs/common';
|
||||
import type { Request } from 'express';
|
||||
import { TradeService } from './trade.service';
|
||||
import { JwtAuthGuard, AuthUser } from '../../common/guards/jwt-auth.guard';
|
||||
import { PartnerPrimaryGuard } from '../../common/guards/partner-primary.guard';
|
||||
import { RequirePartnerPermissions } from '../../common/decorators/partner-permission.decorator';
|
||||
import { PartnerPermissionGuard } from '../../common/guards/partner-permission.guard';
|
||||
import { CurrentUser } from '../../common/decorators/current-user.decorator';
|
||||
import {
|
||||
PartnerProxyOrderCreateDto,
|
||||
PartnerProxyOrderPayDto,
|
||||
PartnerProxyOrderPreviewDto,
|
||||
} from './dto/partner-proxy-order.dto';
|
||||
import { ManualShipOrderDto } from '../ops/dto/admin-mutate.dto';
|
||||
import { CreateAfterSaleTicketDto, CreateInvoiceDto, CreatePackageDisputeDto } from './dto/after-sale.dto';
|
||||
|
||||
@Controller('trade/orders')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class TradeController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Post('preview')
|
||||
preview(@CurrentUser() user: AuthUser, @Body() body: Record<string, unknown>) {
|
||||
return this.tradeService.preview(user.actorId, body as never);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@CurrentUser() user: AuthUser, @Body() body: Record<string, unknown>, @Req() req: Request) {
|
||||
return this.tradeService.createOrder(user.actorId, body as never, req);
|
||||
}
|
||||
|
||||
@Get()
|
||||
list(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Query('tab') tab = 'all',
|
||||
@Query('page') page = '1',
|
||||
@Query('pageSize') pageSize = '20',
|
||||
) {
|
||||
return this.tradeService.listOrders(user.actorId, tab, Number(page), Number(pageSize));
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
detail(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getOrder(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Get(':id/track')
|
||||
track(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getOrderTrack(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Post(':id/pay')
|
||||
pay(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.payOrder(user.actorId, BigInt(id), user.clientApp);
|
||||
}
|
||||
|
||||
@Put(':id/address')
|
||||
updateAddress(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: Record<string, unknown>,
|
||||
) {
|
||||
return this.tradeService.updateAddress(user.actorId, BigInt(id), body);
|
||||
}
|
||||
|
||||
@Post(':id/confirm-receive')
|
||||
confirmReceive(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body?: { onSitePickup?: boolean; source?: 'USER' | 'WECHAT_COMPONENT' },
|
||||
) {
|
||||
return this.tradeService.confirmReceive(user.actorId, BigInt(id), {
|
||||
onSitePickup: !!body?.onSitePickup,
|
||||
source: body?.source === 'WECHAT_COMPONENT' ? 'WECHAT_COMPONENT' : 'USER',
|
||||
});
|
||||
}
|
||||
|
||||
@Post(':id/refund-requests')
|
||||
refundRequest(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: { remark?: string },
|
||||
) {
|
||||
return this.tradeService.createRefundRequest(user.actorId, BigInt(id), body.remark);
|
||||
}
|
||||
|
||||
@Post(':id/after-sale-tickets')
|
||||
createAfterSale(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: CreateAfterSaleTicketDto,
|
||||
) {
|
||||
return this.tradeService.createAfterSaleTicket(user.actorId, BigInt(id), body);
|
||||
}
|
||||
|
||||
@Post(':id/invoices')
|
||||
createInvoice(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: CreateInvoiceDto,
|
||||
) {
|
||||
return this.tradeService.createInvoice(user.actorId, BigInt(id), body);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('trade/package-disputes')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class TradePackageDisputeController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Post()
|
||||
create(@CurrentUser() user: AuthUser, @Body() body: CreatePackageDisputeDto) {
|
||||
return this.tradeService.createPackageDispute(user.actorId, body);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('trade/after-sale-tickets')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class TradeAfterSaleTicketController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Get()
|
||||
list(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Query('page') page = '1',
|
||||
@Query('pageSize') pageSize = '20',
|
||||
) {
|
||||
return this.tradeService.listAfterSaleTickets(user.actorId, Number(page), Number(pageSize));
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
detail(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getAfterSaleTicket(user.actorId, BigInt(id));
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('trade/invoices')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
export class TradeInvoiceController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Get()
|
||||
list(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Query('page') page = '1',
|
||||
@Query('pageSize') pageSize = '20',
|
||||
) {
|
||||
return this.tradeService.listInvoices(user.actorId, Number(page), Number(pageSize));
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
detail(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getInvoice(user.actorId, BigInt(id));
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('partner/orders')
|
||||
@UseGuards(JwtAuthGuard, PartnerPermissionGuard)
|
||||
@RequirePartnerPermissions('order:view', 'warehouse:manage')
|
||||
export class PartnerOrderController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Get()
|
||||
list(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Query('page') page = '1',
|
||||
@Query('pageSize') pageSize = '20',
|
||||
) {
|
||||
return this.tradeService.listPartnerOrders(user.actorId, Number(page), Number(pageSize));
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
detail(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getPartnerOrder(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Get(':id/track')
|
||||
track(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getPartnerOrderTrack(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Post(':id/manual-ship')
|
||||
@RequirePartnerPermissions('warehouse:manage')
|
||||
manualShip(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: ManualShipOrderDto,
|
||||
) {
|
||||
return this.tradeService.partnerManualShip(user.actorId, BigInt(id), body);
|
||||
}
|
||||
|
||||
@Post(':id/mock-advance-delivery')
|
||||
mockAdvance(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() body: { targetStatus: string },
|
||||
) {
|
||||
return this.tradeService.advanceDelivery(user.actorId, BigInt(id), body.targetStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('partner/reshipments')
|
||||
@UseGuards(JwtAuthGuard, PartnerPrimaryGuard)
|
||||
export class PartnerReshipmentController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Get()
|
||||
list(@CurrentUser() user: AuthUser) {
|
||||
return this.tradeService.listPartnerReshipments(user.actorId);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('partner/proxy-orders')
|
||||
@UseGuards(JwtAuthGuard, PartnerPrimaryGuard)
|
||||
export class PartnerProxyOrderController {
|
||||
constructor(private readonly tradeService: TradeService) {}
|
||||
|
||||
@Get('options')
|
||||
options(@CurrentUser() user: AuthUser) {
|
||||
return this.tradeService.getPartnerProxyOrderOptions(user.actorId);
|
||||
}
|
||||
|
||||
@Get()
|
||||
list(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Query('page') page = '1',
|
||||
@Query('pageSize') pageSize = '20',
|
||||
@Query('keyword') keyword?: string,
|
||||
) {
|
||||
return this.tradeService.listPartnerProxyOrders(
|
||||
user.actorId,
|
||||
Number(page),
|
||||
Number(pageSize),
|
||||
keyword,
|
||||
);
|
||||
}
|
||||
|
||||
@Post('preview')
|
||||
preview(@CurrentUser() user: AuthUser, @Body() dto: PartnerProxyOrderPreviewDto) {
|
||||
return this.tradeService.previewPartnerProxyOrderForPartner(user.actorId, dto);
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Body() dto: PartnerProxyOrderCreateDto,
|
||||
@Req() req: Request,
|
||||
) {
|
||||
return this.tradeService.createPartnerProxyOrder(user.actorId, dto, req);
|
||||
}
|
||||
|
||||
@Post(':id/pay')
|
||||
pay(
|
||||
@CurrentUser() user: AuthUser,
|
||||
@Param('id') id: string,
|
||||
@Body() dto: PartnerProxyOrderPayDto,
|
||||
) {
|
||||
return this.tradeService.payPartnerProxyOrder(user.actorId, BigInt(id), dto.payMethod);
|
||||
}
|
||||
|
||||
@Post(':id/cancel-pay')
|
||||
cancelPay(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.cancelPartnerProxyOrder(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Post(':id/pay/mock-confirm')
|
||||
mockConfirmPay(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.mockConfirmProxyPay(BigInt(id), {
|
||||
partnerAccountId: user.actorId,
|
||||
});
|
||||
}
|
||||
|
||||
@Get(':id/pay-status')
|
||||
async payStatus(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
await this.tradeService.getPartnerProxyOrder(user.actorId, BigInt(id));
|
||||
return this.tradeService.getProxyPayStatus(BigInt(id));
|
||||
}
|
||||
|
||||
@Get(':id/track')
|
||||
track(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getPartnerProxyOrderTrack(user.actorId, BigInt(id));
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
detail(@CurrentUser() user: AuthUser, @Param('id') id: string) {
|
||||
return this.tradeService.getPartnerProxyOrder(user.actorId, BigInt(id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Module, forwardRef } from '@nestjs/common';
|
||||
import { AnalyticsModule } from '../analytics/analytics.module';
|
||||
import { IntegrationsModule } from '../../integrations/integrations.module';
|
||||
import { IamModule } from '../iam/iam.module';
|
||||
import { BenefitModule } from '../benefit/benefit.module';
|
||||
import { CatalogModule } from '../catalog/catalog.module';
|
||||
import { CommonModule } from '../common/common.module';
|
||||
import { CityScopeModule } from '../city-scope/city-scope.module';
|
||||
import { PromoModule } from '../promo/promo.module';
|
||||
import { FulfillmentModule } from '../fulfillment/fulfillment.module';
|
||||
import {
|
||||
TradeController,
|
||||
PartnerOrderController,
|
||||
PartnerProxyOrderController,
|
||||
PartnerReshipmentController,
|
||||
TradeAfterSaleTicketController,
|
||||
TradeInvoiceController,
|
||||
TradePackageDisputeController,
|
||||
} from './trade.controller';
|
||||
import { TradeService } from './trade.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
IntegrationsModule,
|
||||
IamModule,
|
||||
CatalogModule,
|
||||
AnalyticsModule,
|
||||
CityScopeModule,
|
||||
PromoModule,
|
||||
forwardRef(() => BenefitModule),
|
||||
forwardRef(() => FulfillmentModule),
|
||||
CommonModule,
|
||||
],
|
||||
controllers: [
|
||||
TradeController,
|
||||
TradePackageDisputeController,
|
||||
TradeAfterSaleTicketController,
|
||||
TradeInvoiceController,
|
||||
PartnerOrderController,
|
||||
PartnerProxyOrderController,
|
||||
PartnerReshipmentController,
|
||||
],
|
||||
providers: [TradeService],
|
||||
exports: [TradeService],
|
||||
})
|
||||
export class TradeModule {}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user