Compare commits
2 Commits
015113d3b3
...
21d699486b
| Author | SHA1 | Date |
|---|---|---|
|
|
21d699486b | |
|
|
f331e1b86e |
|
|
@ -22,7 +22,7 @@ import { errorResponse, successResponse } from '../utils/response.util';
|
||||||
import { LogisticsService } from '../service/logistics.service';
|
import { LogisticsService } from '../service/logistics.service';
|
||||||
import { ShippingDetailsDTO } from '../dto/freightcom.dto';
|
import { ShippingDetailsDTO } from '../dto/freightcom.dto';
|
||||||
import { ShippingAddress } from '../entity/shipping_address.entity';
|
import { ShippingAddress } from '../entity/shipping_address.entity';
|
||||||
import { QueryServiceDTO, ShipmentBookDTO } from '../dto/logistics.dto';
|
import { QueryServiceDTO, ShipmentBookDTO, ShipmentFeeBookDTO } from '../dto/logistics.dto';
|
||||||
import { User } from '../decorator/user.decorator';
|
import { User } from '../decorator/user.decorator';
|
||||||
|
|
||||||
@Controller('/logistics')
|
@Controller('/logistics')
|
||||||
|
|
@ -180,7 +180,7 @@ export class LogisticsController {
|
||||||
)
|
)
|
||||||
@Post('/getShipmentFee')
|
@Post('/getShipmentFee')
|
||||||
async getShipmentFee(
|
async getShipmentFee(
|
||||||
@Body() data: ShipmentBookDTO
|
@Body() data: ShipmentFeeBookDTO
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const fee = await this.logisticsService.getShipmentFee(data);
|
const fee = await this.logisticsService.getShipmentFee(data);
|
||||||
|
|
|
||||||
|
|
@ -68,11 +68,12 @@ export class OrderController {
|
||||||
@Get('/getOrders')
|
@Get('/getOrders')
|
||||||
async getOrders(
|
async getOrders(
|
||||||
@Query()
|
@Query()
|
||||||
param: QueryOrderDTO
|
param: QueryOrderDTO,
|
||||||
|
@User() user
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const count = await this.orderService.getOrderStatus(param);
|
const count = await this.orderService.getOrderStatus(param);
|
||||||
const data = await this.orderService.getOrders(param);
|
const data = await this.orderService.getOrders(param, user);
|
||||||
return successResponse({
|
return successResponse({
|
||||||
...data,
|
...data,
|
||||||
count,
|
count,
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,50 @@ export class ShipmentBookDTO {
|
||||||
orderIds?: number[];
|
orderIds?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ShipmentFeeBookDTO {
|
||||||
|
@ApiProperty()
|
||||||
|
stockPointId: number;
|
||||||
|
@ApiProperty()
|
||||||
|
sender: string;
|
||||||
|
@ApiProperty()
|
||||||
|
startPhone: string;
|
||||||
|
@ApiProperty()
|
||||||
|
startPostalCode: string;
|
||||||
|
@ApiProperty()
|
||||||
|
pickupAddress: string;
|
||||||
|
// pickupWarehouse: number; // 此处用 stockPointId 到后端解析
|
||||||
|
@ApiProperty()
|
||||||
|
shipperCountryCode: string;
|
||||||
|
@ApiProperty()
|
||||||
|
receiver: string;
|
||||||
|
@ApiProperty()
|
||||||
|
city: string;
|
||||||
|
@ApiProperty()
|
||||||
|
province: string;
|
||||||
|
@ApiProperty()
|
||||||
|
country: string;
|
||||||
|
@ApiProperty()
|
||||||
|
postalCode: string;
|
||||||
|
@ApiProperty()
|
||||||
|
deliveryAddress: string;
|
||||||
|
@ApiProperty()
|
||||||
|
receiverPhone: string;
|
||||||
|
@ApiProperty()
|
||||||
|
receiverEmail: string;
|
||||||
|
@ApiProperty()
|
||||||
|
length: number;
|
||||||
|
@ApiProperty()
|
||||||
|
width: number;
|
||||||
|
@ApiProperty()
|
||||||
|
height: number;
|
||||||
|
@ApiProperty()
|
||||||
|
dimensionUom: string;
|
||||||
|
@ApiProperty()
|
||||||
|
weight: number;
|
||||||
|
@ApiProperty()
|
||||||
|
weightUom: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class PaymentMethodDTO {
|
export class PaymentMethodDTO {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import { Order } from '../entity/order.entity';
|
||||||
import { Shipment } from '../entity/shipment.entity';
|
import { Shipment } from '../entity/shipment.entity';
|
||||||
import { ShipmentItem } from '../entity/shipment_item.entity';
|
import { ShipmentItem } from '../entity/shipment_item.entity';
|
||||||
import { OrderShipment } from '../entity/order_shipment.entity';
|
import { OrderShipment } from '../entity/order_shipment.entity';
|
||||||
import { QueryServiceDTO, ShipmentBookDTO } from '../dto/logistics.dto';
|
import { QueryServiceDTO, ShipmentBookDTO, ShipmentFeeBookDTO } from '../dto/logistics.dto';
|
||||||
import {
|
import {
|
||||||
ErpOrderStatus,
|
ErpOrderStatus,
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
|
|
@ -30,6 +30,7 @@ import { OrderSale } from '../entity/order_sale.entity';
|
||||||
import { UniExpressService } from './uni_express.service';
|
import { UniExpressService } from './uni_express.service';
|
||||||
import { StockPoint } from '../entity/stock_point.entity';
|
import { StockPoint } from '../entity/stock_point.entity';
|
||||||
import { OrderService } from './order.service';
|
import { OrderService } from './order.service';
|
||||||
|
import { convertKeysFromCamelToSnake } from '../utils/object-transform.util';
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
export class LogisticsService {
|
export class LogisticsService {
|
||||||
|
|
@ -283,34 +284,19 @@ export class LogisticsService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getShipmentFee(data: ShipmentBookDTO) {
|
async getShipmentFee(data: ShipmentFeeBookDTO) {
|
||||||
try {
|
try {
|
||||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
sender: data.details.origin.contact_name,
|
...convertKeysFromCamelToSnake(data),
|
||||||
start_phone: data.details.origin.phone_number,
|
|
||||||
start_postal_code: data.details.origin.address.postal_code.replace(/\s/g, ''),
|
|
||||||
pickup_address: data.details.origin.address.address_line_1,
|
|
||||||
pickup_warehouse: stock_point.upStreamStockPointId,
|
pickup_warehouse: stock_point.upStreamStockPointId,
|
||||||
shipper_country_code: data.details.origin.address.country,
|
|
||||||
receiver: data.details.destination.contact_name,
|
|
||||||
city: data.details.destination.address.city,
|
|
||||||
province: data.details.destination.address.region,
|
|
||||||
country: data.details.destination.address.country,
|
|
||||||
postal_code: data.details.destination.address.postal_code.replace(/\s/g, ''),
|
|
||||||
delivery_address: data.details.destination.address.address_line_1,
|
|
||||||
receiver_phone: data.details.destination.phone_number.number,
|
|
||||||
receiver_email: data.details.destination.email_addresses,
|
|
||||||
// item_description: data.sales, // todo: 货品信息
|
|
||||||
length: data.details.packaging_properties.packages[0].measurements.cuboid.l,
|
|
||||||
width: data.details.packaging_properties.packages[0].measurements.cuboid.w,
|
|
||||||
height: data.details.packaging_properties.packages[0].measurements.cuboid.h,
|
|
||||||
dimension_uom: data.details.packaging_properties.packages[0].measurements.cuboid.unit,
|
|
||||||
weight: data.details.packaging_properties.packages[0].measurements.weight.value,
|
|
||||||
weight_uom: data.details.packaging_properties.packages[0].measurements.weight.unit,
|
|
||||||
currency: 'CAD',
|
currency: 'CAD',
|
||||||
|
// item_description: data.sales, // todo: 货品信息
|
||||||
}
|
}
|
||||||
const resShipmentFee = await this.uniExpressService.getRates(reqBody);
|
const resShipmentFee = await this.uniExpressService.getRates(reqBody);
|
||||||
|
if (resShipmentFee.status !== 'SUCCESS') {
|
||||||
|
throw new Error(resShipmentFee.ret_msg);
|
||||||
|
}
|
||||||
return resShipmentFee.data.totalAfterTax * 100;
|
return resShipmentFee.data.totalAfterTax * 100;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
||||||
|
|
@ -546,7 +546,7 @@ export class OrderService {
|
||||||
current,
|
current,
|
||||||
pageSize,
|
pageSize,
|
||||||
customer_email,
|
customer_email,
|
||||||
}) {
|
}, user = undefined) {
|
||||||
const parameters: any[] = [];
|
const parameters: any[] = [];
|
||||||
|
|
||||||
// 基础查询
|
// 基础查询
|
||||||
|
|
@ -629,6 +629,13 @@ export class OrderService {
|
||||||
totalQuery += ` AND o.date_created <= ?`;
|
totalQuery += ` AND o.date_created <= ?`;
|
||||||
parameters.push(endDate);
|
parameters.push(endDate);
|
||||||
}
|
}
|
||||||
|
if (!user.isSuper) {
|
||||||
|
sqlQuery += ` AND o.date_created >= ?`;
|
||||||
|
totalQuery += ` AND o.date_created >= ?`;
|
||||||
|
const tenDaysAgo = new Date();
|
||||||
|
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10);
|
||||||
|
parameters.push(new Date(tenDaysAgo).toISOString().substring(0, 10));
|
||||||
|
}
|
||||||
|
|
||||||
// 处理 status 参数
|
// 处理 status 参数
|
||||||
if (status) {
|
if (status) {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ export class UserService {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
deviceId,
|
deviceId,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
|
isSuper: user.isSuper,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
function camelToSnake(str: string): string {
|
||||||
|
return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function snakeToCamel(str: string): string {
|
||||||
|
return str.replace(/(_[\w])/g, (match) =>
|
||||||
|
match[1].toUpperCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function convertKeysFromSnakeToCamel<T>(obj: T): T {
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return obj.map(convertKeysFromSnakeToCamel) as unknown as T;
|
||||||
|
} else if (obj !== null && typeof obj === 'object') {
|
||||||
|
return Object.keys(obj).reduce((acc, key) => {
|
||||||
|
const newKey = snakeToCamel(key);
|
||||||
|
acc[newKey] = convertKeysFromSnakeToCamel((obj as any)[key]);
|
||||||
|
return acc;
|
||||||
|
}, {} as any);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function convertKeysFromCamelToSnake<T>(obj: T): T {
|
||||||
|
if (Array.isArray(obj)) {
|
||||||
|
return obj.map(convertKeysFromCamelToSnake) as unknown as T;
|
||||||
|
} else if (obj !== null && typeof obj === 'object') {
|
||||||
|
return Object.keys(obj).reduce((acc, key) => {
|
||||||
|
const newKey = camelToSnake(key);
|
||||||
|
acc[newKey] = convertKeysFromCamelToSnake((obj as any)[key]);
|
||||||
|
return acc;
|
||||||
|
}, {} as any);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue