1280 lines
20 KiB
TypeScript
1280 lines
20 KiB
TypeScript
import { Type } from 'class-transformer';
|
|
import {
|
|
IsArray,
|
|
IsBoolean,
|
|
IsIn,
|
|
IsNotEmpty,
|
|
IsNumber,
|
|
IsObject,
|
|
IsOptional,
|
|
IsString,
|
|
Min,
|
|
Max,
|
|
MinLength,
|
|
ValidateIf,
|
|
} from 'class-validator';
|
|
|
|
export class UpdateStoreStatusDto {
|
|
@IsString()
|
|
@IsIn(['OPEN', 'PAUSED', 'CLOSED'])
|
|
status: string;
|
|
}
|
|
|
|
export class CreateStoreDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
partnerAccountId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
cityId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
categoryId: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
province?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
city?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
district?: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
address: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
intro?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
coverUrl?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
accountName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankBranch?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
envPhotoUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contractUrl?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
settlementRate?: number;
|
|
}
|
|
|
|
export class UpdateStoreDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
intro?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
coverUrl?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
address?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
district?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
settlementRate?: number;
|
|
}
|
|
|
|
export class CreateStoreAccountDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
}
|
|
|
|
export class UpdateStoreAccountDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class CreatePartnerDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
cityId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
companyName: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
address: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contactPhone?: string;
|
|
|
|
@IsString()
|
|
@IsIn(['CITY_WIDE', 'DISTRICT'])
|
|
scopeType: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
districtCodes?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
orderCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
redeemCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
bindingStatus?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
managedWarehouseId?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contractNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankBranch?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
weeklyStoreTarget?: number;
|
|
}
|
|
|
|
export class UpdatePartnerDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
companyName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
address?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contactPhone?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['CITY_WIDE', 'DISTRICT'])
|
|
scopeType?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
districtCodes?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
orderCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
redeemCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
bindingStatus?: string;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsString()
|
|
managedWarehouseId?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contractNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankBranch?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
weeklyStoreTarget?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class UpdatePartnerAccountDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PARTNER', 'INTERNAL', 'PROMOTER'])
|
|
staffRole?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
permissions?: string[];
|
|
}
|
|
|
|
export class CreatePartnerAccountDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
parentAccountId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PARTNER', 'INTERNAL', 'PROMOTER'])
|
|
staffRole?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
permissions?: string[];
|
|
}
|
|
|
|
export class CreateCityDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
province: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PENDING', 'ACTIVE', 'PAUSED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class UpdateCityDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
province?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PENDING', 'ACTIVE', 'PAUSED'])
|
|
status?: string;
|
|
|
|
@IsOptional()
|
|
localMinQty?: number;
|
|
|
|
@IsOptional()
|
|
crossMinQty?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
@Max(1)
|
|
maxPartnerCommissionRate?: number;
|
|
}
|
|
|
|
export class BindCityPartnerDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
partnerId: string;
|
|
|
|
@IsString()
|
|
@IsIn(['CITY_WIDE', 'DISTRICT'])
|
|
scopeType: 'CITY_WIDE' | 'DISTRICT';
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
districtCodes?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
orderCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
redeemCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
status?: 'ACTIVE' | 'PAUSED';
|
|
}
|
|
|
|
export class UpdateCityPartnerDto {
|
|
@IsOptional()
|
|
@IsIn(['CITY_WIDE', 'DISTRICT'])
|
|
scopeType?: 'CITY_WIDE' | 'DISTRICT';
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
districtCodes?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
orderCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
redeemCommissionRate?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
status?: 'ACTIVE' | 'PAUSED';
|
|
}
|
|
|
|
export class CreateCityWarehouseDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
address: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
contactName: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
contactPhone: string;
|
|
|
|
@IsString()
|
|
@IsIn(['HQ', 'PARTNER'])
|
|
managerType: 'HQ' | 'PARTNER';
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
partnerAccountId?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
status?: 'ACTIVE' | 'PAUSED';
|
|
|
|
@IsOptional()
|
|
@IsIn(['API_AUTO', 'MANUAL'])
|
|
fulfillmentMode?: 'API_AUTO' | 'MANUAL';
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
fulfillmentProviderId?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
manualCarrierLabel?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
manualQueryUrlTemplate?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
lng?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
lat?: number;
|
|
}
|
|
|
|
export class UpdateCityWarehouseDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
address?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contactName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
contactPhone?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['HQ', 'PARTNER'])
|
|
managerType?: 'HQ' | 'PARTNER';
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsString()
|
|
partnerAccountId?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'PAUSED'])
|
|
status?: 'ACTIVE' | 'PAUSED';
|
|
|
|
@IsOptional()
|
|
@IsIn(['API_AUTO', 'MANUAL'])
|
|
fulfillmentMode?: 'API_AUTO' | 'MANUAL';
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsString()
|
|
fulfillmentProviderId?: string | null;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsString()
|
|
manualCarrierLabel?: string | null;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsString()
|
|
manualQueryUrlTemplate?: string | null;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsNumber()
|
|
lng?: number | null;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null)
|
|
@IsNumber()
|
|
lat?: number | null;
|
|
}
|
|
|
|
export class CreateFulfillmentProviderDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsIn(['API', 'MANUAL'])
|
|
type: 'API' | 'MANUAL';
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: 'ACTIVE' | 'DISABLED';
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
configJson?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
capabilitiesJson?: string;
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
xiaofeixiaConfig?: {
|
|
apiUrl?: string;
|
|
mchId?: string;
|
|
apiKey?: string;
|
|
signType?: 'MD5' | 'HMAC-SHA256';
|
|
appId?: string;
|
|
};
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountName?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankName?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankBranch?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountNo?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PREPAID', 'MONTHLY_CREDIT'])
|
|
settlementMethod?: 'PREPAID' | 'MONTHLY_CREDIT';
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
pricingRules?: {
|
|
baseBottles: number;
|
|
baseFee: number;
|
|
extraBottleFee: number;
|
|
boxBottles?: number;
|
|
boxFee?: number;
|
|
} | null;
|
|
}
|
|
|
|
export class UpdateFulfillmentProviderDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['API', 'MANUAL'])
|
|
type?: 'API' | 'MANUAL';
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: 'ACTIVE' | 'DISABLED';
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
configJson?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
capabilitiesJson?: string;
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
xiaofeixiaConfig?: {
|
|
apiUrl?: string;
|
|
mchId?: string;
|
|
apiKey?: string;
|
|
signType?: 'MD5' | 'HMAC-SHA256';
|
|
appId?: string;
|
|
};
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountName?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankName?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankBranch?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
bankAccountNo?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsIn(['PREPAID', 'MONTHLY_CREDIT'])
|
|
settlementMethod?: 'PREPAID' | 'MONTHLY_CREDIT';
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
pricingRules?: {
|
|
baseBottles: number;
|
|
baseFee: number;
|
|
extraBottleFee: number;
|
|
boxBottles?: number;
|
|
boxFee?: number;
|
|
} | null;
|
|
}
|
|
|
|
export class RechargeFulfillmentProviderDto {
|
|
@IsNumber()
|
|
amount: number;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
remark?: string;
|
|
}
|
|
|
|
export class ManualShipOrderDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
logisticsCompany: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
trackingNo: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
manualQueryUrl?: string;
|
|
}
|
|
|
|
export class HqLogisticsShipDto extends ManualShipOrderDto {}
|
|
|
|
export class CreateStoreMediaDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsIn(['IMAGE', 'VIDEO'])
|
|
mediaType: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
url: string;
|
|
|
|
@IsOptional()
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export class UpdateStoreMediaDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
url?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['IMAGE', 'VIDEO'])
|
|
mediaType?: string;
|
|
|
|
@IsOptional()
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export class UpdateOrderStatusDto {
|
|
@IsString()
|
|
@IsIn([
|
|
'PENDING_PAY',
|
|
'PENDING_SHIP',
|
|
'OUT_WAREHOUSE',
|
|
'SHIPPING',
|
|
'PENDING_RECEIVE',
|
|
'COMPLETED',
|
|
'CANCELLED',
|
|
'REFUNDING',
|
|
'REFUNDED',
|
|
])
|
|
status: string;
|
|
}
|
|
|
|
export class BatchDeleteOrdersDto {
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
ids: string[];
|
|
}
|
|
|
|
export class BatchDeleteUsersDto {
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
ids: string[];
|
|
}
|
|
|
|
export class BatchDeleteUsersConfirmDto extends BatchDeleteUsersDto {
|
|
@IsBoolean()
|
|
confirmRisk: boolean;
|
|
}
|
|
|
|
/** HQ 订单发货(目前仅小飞侠 XFX) */
|
|
export class AdminShipOrderDto {
|
|
@IsIn(['XFX'])
|
|
provider: string;
|
|
|
|
/** 可选:指定/改派履约仓后再推仓配 */
|
|
@IsOptional()
|
|
@IsString()
|
|
warehouseId?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
fromName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
fromMobile?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
fromAddress?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
fromAddressDetail?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
fromLng?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
fromLat?: number;
|
|
|
|
@IsOptional()
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
weight?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['1', '2'])
|
|
payMode?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
remark?: string;
|
|
}
|
|
|
|
export class AdminRedeemDebugCreateTokenDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
userId: string;
|
|
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
amount: number;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
couponId?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
storeId?: string;
|
|
}
|
|
|
|
export class AdminRedeemDebugStoreTokenDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
token: string;
|
|
}
|
|
|
|
export class AdminRedeemDebugPhoneStoreDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
}
|
|
|
|
export class AdminRedeemDebugPhoneBalanceDto extends AdminRedeemDebugPhoneStoreDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
}
|
|
|
|
export class AdminRedeemDebugPhonePrepareDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
sessionId: string;
|
|
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
amount: number;
|
|
}
|
|
|
|
export class AdminRedeemDebugPhoneConfirmDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
storeId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
sessionId: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
}
|
|
|
|
export class UpdateDeliveryDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
provider?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
providerOrderNo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
trackingNo?: string;
|
|
}
|
|
|
|
export class CreateHqAccountDto {
|
|
@IsIn(['phone', 'password'])
|
|
credentialType: 'phone' | 'password';
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@ValidateIf((o: CreateHqAccountDto) => o.credentialType === 'password')
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
loginName?: string;
|
|
|
|
@ValidateIf((o: CreateHqAccountDto) => o.credentialType === 'password')
|
|
@IsString()
|
|
@MinLength(6)
|
|
password?: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['SUPER_ADMIN', 'OPS', 'FINANCE', 'CUSTOMER_SERVICE'])
|
|
adminRole?: string;
|
|
}
|
|
|
|
export class UpdateHqAccountDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
loginName?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
phone?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
@MinLength(6)
|
|
password?: string;
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['SUPER_ADMIN', 'OPS', 'FINANCE', 'CUSTOMER_SERVICE'])
|
|
adminRole?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class SaveHqRolePermissionsDto {
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
permissionKeys: string[];
|
|
}
|
|
|
|
export class SaveHqAccountPermissionsDto {
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
permissionKeys: string[];
|
|
}
|
|
|
|
export class CreateProductDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
skuCode: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
barcode69: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
subtitle?: string;
|
|
|
|
@IsIn(['QINGXIANG', 'JIANGXIANG', 'NONGXIANG'])
|
|
aromaType: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
spec: string;
|
|
|
|
@IsNumber()
|
|
price: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
benefitAmount?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['DRAFT', 'ON_SALE', 'OFF_SALE'])
|
|
status?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
sortOrder?: number;
|
|
|
|
@IsOptional()
|
|
@IsBoolean()
|
|
allowOnSitePickup?: boolean;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
coverUrl?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
carouselUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
detailImageUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
detailContent?: Record<string, unknown>;
|
|
}
|
|
|
|
export class UpdateProductDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
subtitle?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
spec?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
price?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
benefitAmount?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['DRAFT', 'ON_SALE', 'OFF_SALE'])
|
|
status?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
sortOrder?: number;
|
|
|
|
@IsOptional()
|
|
@IsBoolean()
|
|
allowOnSitePickup?: boolean;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
coverUrl?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
carouselUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
detailImageUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsObject()
|
|
detailContent?: Record<string, unknown>;
|
|
}
|
|
|
|
class ProductDetailFeatureInputDto {
|
|
@IsString()
|
|
icon: string;
|
|
|
|
@IsString()
|
|
title: string;
|
|
|
|
@IsString()
|
|
desc: string;
|
|
}
|
|
|
|
export class CreateProductDetailTemplateDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
description?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['QINGXIANG', 'JIANGXIANG', 'NONGXIANG'])
|
|
aromaType?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
storyTitle?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
storyText?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
features?: ProductDetailFeatureInputDto[];
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
detailImageUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
suggestedDetailImageCount?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
sortOrder?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class UpdateProductDetailTemplateDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
code?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
description?: string;
|
|
|
|
@IsOptional()
|
|
@IsIn(['QINGXIANG', 'JIANGXIANG', 'NONGXIANG', null])
|
|
aromaType?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
storyTitle?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
storyText?: string;
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
features?: ProductDetailFeatureInputDto[];
|
|
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
detailImageUrls?: string[];
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
suggestedDetailImageCount?: number;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
sortOrder?: number;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class CreatePromoCodeDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
code?: string;
|
|
}
|
|
|
|
export class UpdatePromoCodeStatusDto {
|
|
@IsString()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status: 'ACTIVE' | 'DISABLED';
|
|
}
|
|
|
|
export class AdminBenefitGrantDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
phone: string;
|
|
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
@Max(999999.99)
|
|
amount: number;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
remark?: string;
|
|
}
|
|
|
|
export class CreateStoreCategoryDto {
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code: string;
|
|
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name: string;
|
|
|
|
@IsOptional()
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
sort?: number;
|
|
|
|
/** 空/不传 = 一级分类;传入一级 id = 二级分类 */
|
|
@IsOptional()
|
|
@IsString()
|
|
parentId?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|
|
|
|
export class UpdateStoreCategoryDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
code?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
@IsNotEmpty()
|
|
name?: string;
|
|
|
|
@IsOptional()
|
|
@Type(() => Number)
|
|
@IsNumber()
|
|
sort?: number;
|
|
|
|
@IsOptional()
|
|
@ValidateIf((_, v) => v !== null && v !== undefined)
|
|
@IsString()
|
|
parentId?: string | null;
|
|
|
|
@IsOptional()
|
|
@IsIn(['ACTIVE', 'DISABLED'])
|
|
status?: string;
|
|
}
|