Compare commits
No commits in common. "2ad48143b7226af3ced7af2f460456ea6c580484" and "b2cddad10af800e4d47b916c2f2c55bd9f62c33c" have entirely different histories.
2ad48143b7
...
b2cddad10a
|
|
@ -37,9 +37,9 @@ export default {
|
|||
siteName: 'Admin',
|
||||
email: '444693295@qq.com',
|
||||
},
|
||||
{
|
||||
{
|
||||
id: '2',
|
||||
wpApiUrl: 'http://t2-shop.local/',
|
||||
wpApiUrl: 'http://t1-shop.local/',
|
||||
consumerKey: 'ck_a369473a6451dbaec63d19cbfd74a074b2c5f742',
|
||||
consumerSecret: 'cs_0946bbbeea1bfefff08a69e817ac62a48412df8c',
|
||||
siteName: 'Local',
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import { errorResponse, successResponse } from '../utils/response.util';
|
|||
import { LogisticsService } from '../service/logistics.service';
|
||||
import { ShippingDetailsDTO } from '../dto/freightcom.dto';
|
||||
import { ShippingAddress } from '../entity/shipping_address.entity';
|
||||
import { QueryServiceDTO, ShipmentBookDTO, ShipmentFeeBookDTO } from '../dto/logistics.dto';
|
||||
import { QueryServiceDTO, ShipmentBookDTO } from '../dto/logistics.dto';
|
||||
import { User } from '../decorator/user.decorator';
|
||||
|
||||
@Controller('/logistics')
|
||||
|
|
@ -180,7 +180,7 @@ export class LogisticsController {
|
|||
)
|
||||
@Post('/getShipmentFee')
|
||||
async getShipmentFee(
|
||||
@Body() data: ShipmentFeeBookDTO
|
||||
@Body() data: ShipmentBookDTO
|
||||
) {
|
||||
try {
|
||||
const fee = await this.logisticsService.getShipmentFee(data);
|
||||
|
|
@ -222,7 +222,7 @@ export class LogisticsController {
|
|||
}
|
||||
|
||||
@ApiOkResponse()
|
||||
@Post('/updateState/:shipmentId')
|
||||
@Post('/updateState/:id')
|
||||
async updateShipmentState(
|
||||
@Param('shipmentId') shipmentId: number
|
||||
) {
|
||||
|
|
@ -247,11 +247,11 @@ export class LogisticsController {
|
|||
}
|
||||
|
||||
@ApiOkResponse()
|
||||
@Post('/getOrderList')
|
||||
async getOrderList(@Query('number') number: string) {
|
||||
@Post('/getTrackingNumber')
|
||||
async getTrackingNumber(@Query('number') number: string) {
|
||||
try {
|
||||
return successResponse(
|
||||
await this.logisticsService.getOrderList(number)
|
||||
await this.logisticsService.getTrackingNumber(number)
|
||||
);
|
||||
} catch (error) {
|
||||
return errorResponse(error?.message || '获取失败');
|
||||
|
|
@ -259,11 +259,11 @@ export class LogisticsController {
|
|||
}
|
||||
|
||||
@ApiOkResponse()
|
||||
@Post('/getListByOrderId')
|
||||
async getListByOrderId(@Query('id') orderId: number) {
|
||||
@Post('/getListByTrackingId')
|
||||
async getListByTrackingId(@Query('shipment_id') shipment_id: number) {
|
||||
try {
|
||||
return successResponse(
|
||||
await this.logisticsService.getListByOrderId(orderId)
|
||||
await this.logisticsService.getListByTrackingId(shipment_id)
|
||||
);
|
||||
} catch (error) {
|
||||
return errorResponse(error?.message || '获取失败');
|
||||
|
|
|
|||
|
|
@ -68,12 +68,11 @@ export class OrderController {
|
|||
@Get('/getOrders')
|
||||
async getOrders(
|
||||
@Query()
|
||||
param: QueryOrderDTO,
|
||||
@User() user
|
||||
param: QueryOrderDTO
|
||||
) {
|
||||
try {
|
||||
const count = await this.orderService.getOrderStatus(param);
|
||||
const data = await this.orderService.getOrders(param, user.id);
|
||||
const data = await this.orderService.getOrders(param);
|
||||
return successResponse({
|
||||
...data,
|
||||
count,
|
||||
|
|
|
|||
|
|
@ -12,15 +12,11 @@ export class UserController {
|
|||
@Inject()
|
||||
userService: UserService;
|
||||
|
||||
@Inject()
|
||||
ctx;
|
||||
|
||||
@ApiOkResponse({
|
||||
type: LoginRes,
|
||||
})
|
||||
@Post('/login')
|
||||
async login(@Body() body) {
|
||||
this.ctx.logger.info('ip:', this.ctx.ip, '; path:', this.ctx.path, '; user:', body?.username);
|
||||
try {
|
||||
const result = await this.userService.login(body);
|
||||
return successResponse(result, '登录成功');
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ export class WebhookController {
|
|||
switch (topic) {
|
||||
case 'product.created':
|
||||
case 'product.updated':
|
||||
const site = await this.wpProductService.getSite(siteId);
|
||||
const site = await this.wpProductService.geSite(siteId);
|
||||
// 变体更新
|
||||
if (body.type === 'variation') {
|
||||
const variation = await this.wpApiService.getVariation(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
Query,
|
||||
Put,
|
||||
Body,
|
||||
Config,
|
||||
} from '@midwayjs/core';
|
||||
import { WpProductService } from '../service/wp_product.service';
|
||||
import { errorResponse, successResponse } from '../utils/response.util';
|
||||
|
|
@ -20,21 +19,9 @@ import {
|
|||
UpdateWpProductDTO,
|
||||
} from '../dto/wp_product.dto';
|
||||
import { WPService } from '../service/wp.service';
|
||||
import { WpSite } from '../interface';
|
||||
|
||||
@Controller('/wp_product')
|
||||
export class WpProductController {
|
||||
@Inject()
|
||||
wpService: WPService;
|
||||
|
||||
@Config('wpSite')
|
||||
sites: WpSite[];
|
||||
|
||||
getSite(id: string): WpSite {
|
||||
let idx = this.sites.findIndex(item => item.id === id);
|
||||
return this.sites[idx];
|
||||
}
|
||||
|
||||
@Inject()
|
||||
private readonly wpProductService: WpProductService;
|
||||
|
||||
|
|
@ -86,22 +73,6 @@ export class WpProductController {
|
|||
}
|
||||
}
|
||||
|
||||
@ApiOkResponse({
|
||||
type: BooleanRes
|
||||
})
|
||||
@Post('/updateState/:id')
|
||||
async updateWPProductState(
|
||||
@Param('id') id: number,
|
||||
@Body() body: any, // todo
|
||||
) {
|
||||
try {
|
||||
await this.wpProductService.updateProductStatus(id, body?.status);
|
||||
return successResponse(true);
|
||||
} catch (error) {
|
||||
return errorResponse(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新产品接口
|
||||
* @param productId 产品 ID
|
||||
|
|
@ -125,7 +96,7 @@ export class WpProductController {
|
|||
if (isDuplicate) {
|
||||
return errorResponse('SKU已存在');
|
||||
}
|
||||
const site = await this.wpProductService.getSite(siteId);
|
||||
const site = await this.wpProductService.geSite(siteId);
|
||||
const result = await this.wpApiService.updateProduct(
|
||||
site,
|
||||
productId,
|
||||
|
|
@ -165,7 +136,7 @@ export class WpProductController {
|
|||
if (isDuplicate) {
|
||||
return errorResponse('SKU已存在');
|
||||
}
|
||||
const site = await this.wpProductService.getSite(siteId);
|
||||
const site = await this.wpProductService.geSite(siteId);
|
||||
const result = await this.wpApiService.updateVariation(
|
||||
site,
|
||||
productId,
|
||||
|
|
|
|||
|
|
@ -21,50 +21,6 @@ export class ShipmentBookDTO {
|
|||
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 {
|
||||
@ApiProperty()
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -90,10 +90,6 @@ export class QueryOrderSalesDTO {
|
|||
@Rule(RuleType.bool().default(false))
|
||||
isSource: boolean;
|
||||
|
||||
@ApiProperty()
|
||||
@Rule(RuleType.bool().default(false))
|
||||
exceptPackage: boolean;
|
||||
|
||||
@ApiProperty({ example: '1', description: '页码' })
|
||||
@Rule(RuleType.number())
|
||||
current: number;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export class OrderItem {
|
|||
externalOrderId: string; // WooCommerce 订单 ID
|
||||
|
||||
@ApiProperty()
|
||||
@Column({ nullable: true })
|
||||
@Column()
|
||||
@Expose()
|
||||
externalOrderItemId: string; // WooCommerce 订单item ID
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ export class OrderSaleOriginal {
|
|||
@ApiProperty()
|
||||
@ManyToOne(() => Order)
|
||||
@JoinColumn({ name: 'order_id' })
|
||||
@Column({ name: 'order_id' })
|
||||
@Expose()
|
||||
orderId: number; // 订单 ID
|
||||
|
||||
|
|
@ -32,7 +31,7 @@ export class OrderSaleOriginal {
|
|||
siteId: string; // 来源站点唯一标识
|
||||
|
||||
@ApiProperty()
|
||||
@Column({ nullable: true })
|
||||
@Column()
|
||||
@Expose()
|
||||
externalOrderItemId: string; // WooCommerce 订单item ID
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Order } from '../entity/order.entity';
|
|||
import { Shipment } from '../entity/shipment.entity';
|
||||
import { ShipmentItem } from '../entity/shipment_item.entity';
|
||||
import { OrderShipment } from '../entity/order_shipment.entity';
|
||||
import { QueryServiceDTO, ShipmentBookDTO, ShipmentFeeBookDTO } from '../dto/logistics.dto';
|
||||
import { QueryServiceDTO, ShipmentBookDTO } from '../dto/logistics.dto';
|
||||
import {
|
||||
ErpOrderStatus,
|
||||
OrderStatus,
|
||||
|
|
@ -30,7 +30,6 @@ import { OrderSale } from '../entity/order_sale.entity';
|
|||
import { UniExpressService } from './uni_express.service';
|
||||
import { StockPoint } from '../entity/stock_point.entity';
|
||||
import { OrderService } from './order.service';
|
||||
import { convertKeysFromCamelToSnake } from '../utils/object-transform.util';
|
||||
|
||||
@Provide()
|
||||
export class LogisticsService {
|
||||
|
|
@ -85,7 +84,7 @@ export class LogisticsService {
|
|||
@Config('wpSite')
|
||||
sites: WpSite[];
|
||||
|
||||
getSite(id: string): WpSite {
|
||||
geSite(id: string): WpSite {
|
||||
let idx = this.sites.findIndex(item => item.id === id);
|
||||
return this.sites[idx];
|
||||
}
|
||||
|
|
@ -129,7 +128,6 @@ export class LogisticsService {
|
|||
async updateShipmentState(shipment: Shipment) {
|
||||
try {
|
||||
const data = await this.uniExpressService.getOrderStatus(shipment.return_tracking_number);
|
||||
console.log('updateShipmentState data:', data);
|
||||
shipment.state = data.data[0].state;
|
||||
if (shipment.state in [203, 215, 216, 230]) { // todo,写常数
|
||||
shipment.finished = true;
|
||||
|
|
@ -137,13 +135,12 @@ export class LogisticsService {
|
|||
this.shipmentModel.save(shipment);
|
||||
return shipment.state;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
// throw new Error(`更新运单状态失败 ${error.message}`);
|
||||
throw new Error(`更新运单状态失败 ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async updateShipmentStateById(id: number) {
|
||||
const shipment: Shipment = await this.shipmentModel.findOneBy({ id: id });
|
||||
const shipment:Shipment = await this.shipmentModel.findOneBy({ id : id });
|
||||
return this.updateShipmentState(shipment);
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +217,7 @@ export class LogisticsService {
|
|||
|
||||
async getShipmentLabel(shipmentId) {
|
||||
try {
|
||||
const shipment: Shipment = await this.shipmentModel.findOneBy({ id: shipmentId });
|
||||
const shipment:Shipment = await this.shipmentModel.findOneBy({id: shipmentId});
|
||||
if (!shipment) {
|
||||
throw new Error('运单不存在');
|
||||
}
|
||||
|
|
@ -232,11 +229,11 @@ export class LogisticsService {
|
|||
|
||||
async removeShipment(shipmentId: number) {
|
||||
try {
|
||||
const shipment: Shipment = await this.shipmentModel.findOneBy({ id: shipmentId });
|
||||
const shipment:Shipment = await this.shipmentModel.findOneBy({id: shipmentId});
|
||||
if (shipment.state !== '190') { // todo,写常数
|
||||
throw new Error('订单当前状态无法删除');
|
||||
}
|
||||
const order: Order = await this.orderModel.findOneBy({ id: shipment.order_id });
|
||||
const order:Order = await this.orderModel.findOneBy({id: shipment.order_id});
|
||||
const dataSource = this.dataSourceManager.getDataSource('default');
|
||||
let transactionError = undefined;
|
||||
await dataSource.transaction(async manager => {
|
||||
|
|
@ -263,7 +260,7 @@ export class LogisticsService {
|
|||
|
||||
try {
|
||||
// 同步订单状态到woocommerce
|
||||
const site = await this.getSite(order.siteId);
|
||||
const site = await this.geSite(order.siteId);
|
||||
if (order.status === OrderStatus.COMPLETED) {
|
||||
await this.wpService.updateOrder(site, order.externalOrderId, {
|
||||
status: OrderStatus.PROCESSING,
|
||||
|
|
@ -272,7 +269,7 @@ export class LogisticsService {
|
|||
}
|
||||
order.orderStatus = ErpOrderStatus.PROCESSING;
|
||||
this.orderModel.save(order);
|
||||
|
||||
|
||||
// todo 同步到wooccommerce删除运单信息
|
||||
await this.wpService.deleteShipment(site, order.externalOrderId, shipment.tracking_id);
|
||||
} catch (error) {
|
||||
|
|
@ -286,19 +283,34 @@ export class LogisticsService {
|
|||
}
|
||||
}
|
||||
|
||||
async getShipmentFee(data: ShipmentFeeBookDTO) {
|
||||
async getShipmentFee(data: ShipmentBookDTO) {
|
||||
try {
|
||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId });
|
||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
||||
const reqBody = {
|
||||
...convertKeysFromCamelToSnake(data),
|
||||
sender: data.details.origin.contact_name,
|
||||
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,
|
||||
currency: 'CAD',
|
||||
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',
|
||||
}
|
||||
const resShipmentFee = await this.uniExpressService.getRates(reqBody);
|
||||
if (resShipmentFee.status !== 'SUCCESS') {
|
||||
throw new Error(resShipmentFee.ret_msg);
|
||||
}
|
||||
return resShipmentFee.data.totalAfterTax * 100;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
|
@ -320,7 +332,7 @@ export class LogisticsService {
|
|||
|
||||
let resShipmentOrder;
|
||||
try {
|
||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId });
|
||||
const stock_point = await this.stockPointModel.findOneBy({ id: data.stockPointId});
|
||||
const reqBody = {
|
||||
sender: data.details.origin.contact_name,
|
||||
start_phone: data.details.origin.phone_number,
|
||||
|
|
@ -367,7 +379,7 @@ export class LogisticsService {
|
|||
const tracking_provider = 'UniUni'; // todo: id未确定,后写进常数
|
||||
|
||||
// 同步物流信息到woocommerce
|
||||
const site = await this.getSite(order.siteId);
|
||||
const site = await this.geSite(order.siteId);
|
||||
const res = await this.wpService.createShipment(site, order.externalOrderId, {
|
||||
tracking_number: resShipmentOrder.data.tno,
|
||||
tracking_provider: tracking_provider,
|
||||
|
|
@ -410,12 +422,10 @@ export class LogisticsService {
|
|||
// 更新产品发货信息
|
||||
this.orderService.updateOrderSales(order.id, sales);
|
||||
|
||||
return {
|
||||
data: {
|
||||
shipmentId
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
return { data: {
|
||||
shipmentId
|
||||
} };
|
||||
} catch(error) {
|
||||
if (resShipmentOrder.status === 'SUCCESS') {
|
||||
await this.uniExpressService.deleteShipment(resShipmentOrder.data.tno);
|
||||
}
|
||||
|
|
@ -472,7 +482,7 @@ export class LogisticsService {
|
|||
}
|
||||
|
||||
async getShipment(id: number) {
|
||||
const orderShipments: OrderShipment[] = await this.orderShipmentModel.find({
|
||||
const orderShipments:OrderShipment[] = await this.orderShipmentModel.find({
|
||||
where: { shipment_id: id },
|
||||
});
|
||||
if (!orderShipments || orderShipments.length === 0) return;
|
||||
|
|
@ -493,7 +503,7 @@ export class LogisticsService {
|
|||
const order = await this.orderModel.findOneBy({
|
||||
id: orderShipment.order_id,
|
||||
});
|
||||
const site = this.getSite(order.siteId);
|
||||
const site = this.geSite(order.siteId);
|
||||
await this.wpService.updateOrder(site, order.externalOrderId, {
|
||||
status: OrderStatus.COMPLETED,
|
||||
});
|
||||
|
|
@ -556,7 +566,7 @@ export class LogisticsService {
|
|||
});
|
||||
}
|
||||
|
||||
async getOrderList(number: string) {
|
||||
async getTrackingNumber(number: string) {
|
||||
const orders = await this.orderModel.find({
|
||||
where: {
|
||||
externalOrderId: Like(`%${number}%`),
|
||||
|
|
@ -571,14 +581,56 @@ export class LogisticsService {
|
|||
}));
|
||||
}
|
||||
|
||||
async getListByOrderId(id: number) {
|
||||
const item = await this.orderItem.find({ where: { orderId: id } });
|
||||
const saleItem = await this.orderSaleModel.find({ where: { orderId: id } });
|
||||
async getListByTrackingId(id: number) {
|
||||
const qb = `
|
||||
SELECT
|
||||
oi.name,
|
||||
oi.quantity,
|
||||
CASE
|
||||
WHEN oi.externalVariationId != 0 THEN v.constitution
|
||||
ELSE p.constitution
|
||||
END AS constitution
|
||||
FROM order_item oi
|
||||
LEFT JOIN wp_product p ON oi.siteId=p.siteId AND oi.externalProductId=p.externalProductId
|
||||
LEFT JOIN variation v ON oi.siteId=v.siteId AND oi.externalVariationId=v.externalVariationId
|
||||
WHERE oi.orderId=?
|
||||
`;
|
||||
const saleItem = await this.orderSaleModel.query(qb, [id]);
|
||||
const allSkus = new Set<string>();
|
||||
for (const item of saleItem) {
|
||||
if (!item.constitution) continue;
|
||||
try {
|
||||
item.constitution.forEach(c => allSkus.add(c.sku));
|
||||
} catch (e) {
|
||||
console.warn('Invalid constitution JSON:', item.constitution);
|
||||
}
|
||||
}
|
||||
console.log(allSkus);
|
||||
const skuList = Array.from(allSkus);
|
||||
let skuNameMap = new Map<string, string>();
|
||||
|
||||
return {
|
||||
item,
|
||||
saleItem
|
||||
};
|
||||
if (skuList.length > 0) {
|
||||
const placeholders = skuList.map(() => '?').join(', ');
|
||||
const productRows = await this.orderSaleModel.query(
|
||||
`SELECT sku, name FROM product WHERE sku IN (${placeholders})`,
|
||||
skuList
|
||||
);
|
||||
skuNameMap = new Map(productRows.map(p => [p.sku, p.name]));
|
||||
}
|
||||
|
||||
for (const item of saleItem) {
|
||||
if (!item.constitution) continue;
|
||||
try {
|
||||
item.constitution = item.constitution.map(c => ({
|
||||
...c,
|
||||
name: skuNameMap.get(c.sku) || null,
|
||||
}));
|
||||
} catch (e) {
|
||||
item.constitution = [];
|
||||
}
|
||||
}
|
||||
|
||||
return saleItem;
|
||||
}
|
||||
|
||||
async getList(param: Record<string, any>) {
|
||||
|
|
|
|||
|
|
@ -45,9 +45,6 @@ export class OrderService {
|
|||
@InjectEntityModel(Order)
|
||||
orderModel: Repository<Order>;
|
||||
|
||||
@InjectEntityModel(User)
|
||||
userModel: Repository<User>;
|
||||
|
||||
@InjectEntityModel(OrderItem)
|
||||
orderItemModel: Repository<OrderItem>;
|
||||
|
||||
|
|
@ -549,7 +546,7 @@ export class OrderService {
|
|||
current,
|
||||
pageSize,
|
||||
customer_email,
|
||||
}, userId = undefined) {
|
||||
}) {
|
||||
const parameters: any[] = [];
|
||||
|
||||
// 基础查询
|
||||
|
|
@ -632,14 +629,6 @@ export class OrderService {
|
|||
totalQuery += ` AND o.date_created <= ?`;
|
||||
parameters.push(endDate);
|
||||
}
|
||||
const user = await this.userModel.findOneBy({id: userId});
|
||||
if (user?.permissions?.includes('order-10-days')) {
|
||||
sqlQuery += ` AND o.date_created >= ?`;
|
||||
totalQuery += ` AND o.date_created >= ?`;
|
||||
const tenDaysAgo = new Date();
|
||||
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10);
|
||||
parameters.push(tenDaysAgo.toISOString());
|
||||
}
|
||||
|
||||
// 处理 status 参数
|
||||
if (status) {
|
||||
|
|
@ -749,7 +738,7 @@ export class OrderService {
|
|||
return await query.getRawMany();
|
||||
}
|
||||
|
||||
async getOrderSales({ siteId, startDate, endDate, current, pageSize, name, exceptPackage }: QueryOrderSalesDTO) {
|
||||
async getOrderSales({ siteId, startDate, endDate, current, pageSize, name }: QueryOrderSalesDTO) {
|
||||
const nameKeywords = name ? name.split(' ').filter(Boolean) : [];
|
||||
const offset = (current - 1) * pageSize;
|
||||
|
||||
|
|
@ -796,16 +785,6 @@ export class OrderService {
|
|||
itemSql += ' AND os.siteId = ?';
|
||||
itemParams.push(siteId);
|
||||
}
|
||||
if (exceptPackage) {
|
||||
itemSql += `
|
||||
AND os.orderId IN (
|
||||
SELECT orderId
|
||||
FROM order_sale
|
||||
GROUP BY orderId
|
||||
HAVING COUNT(*) = 1
|
||||
)
|
||||
`;
|
||||
}
|
||||
itemSql += nameCondition;
|
||||
itemSql += `
|
||||
GROUP BY os.productId, os.name
|
||||
|
|
@ -823,17 +802,17 @@ export class OrderService {
|
|||
const pcParams: any[] = [...productIds, startDate, endDate];
|
||||
if (siteId) pcParams.push(siteId);
|
||||
|
||||
let pcSql = `
|
||||
const pcSql = `
|
||||
SELECT
|
||||
os.productId,
|
||||
SUM(CASE WHEN t.purchaseIndex = 1 THEN os.quantity ELSE 0 END) AS firstOrderYOONEBoxCount,
|
||||
COUNT(DISTINCT CASE WHEN t.purchaseIndex = 1 THEN os.orderId END) AS firstOrderCount,
|
||||
COUNT(CASE WHEN t.purchaseIndex = 1 THEN 1 END) AS firstOrderCount,
|
||||
SUM(CASE WHEN t.purchaseIndex = 2 THEN os.quantity ELSE 0 END) AS secondOrderYOONEBoxCount,
|
||||
COUNT(DISTINCT CASE WHEN t.purchaseIndex = 2 THEN os.orderId END) AS secondOrderCount,
|
||||
COUNT(CASE WHEN t.purchaseIndex = 2 THEN 1 END) AS secondOrderCount,
|
||||
SUM(CASE WHEN t.purchaseIndex = 3 THEN os.quantity ELSE 0 END) AS thirdOrderYOONEBoxCount,
|
||||
COUNT(DISTINCT CASE WHEN t.purchaseIndex = 3 THEN os.orderId END) AS thirdOrderCount,
|
||||
COUNT(CASE WHEN t.purchaseIndex = 3 THEN 1 END) AS thirdOrderCount,
|
||||
SUM(CASE WHEN t.purchaseIndex > 3 THEN os.quantity ELSE 0 END) AS moreThirdOrderYOONEBoxCount,
|
||||
COUNT(DISTINCT CASE WHEN t.purchaseIndex > 3 THEN os.orderId END) AS moreThirdOrderCount
|
||||
COUNT(CASE WHEN t.purchaseIndex > 3 THEN 1 END) AS moreThirdOrderCount
|
||||
FROM order_sale os
|
||||
INNER JOIN (
|
||||
SELECT o2.id AS orderId,
|
||||
|
|
@ -850,22 +829,9 @@ export class OrderService {
|
|||
WHERE date_paid BETWEEN ? AND ?
|
||||
${siteId ? 'AND siteId = ?' : ''}
|
||||
)
|
||||
`;
|
||||
if (exceptPackage) {
|
||||
pcSql += `
|
||||
AND os.orderId IN (
|
||||
SELECT orderId
|
||||
FROM order_sale
|
||||
GROUP BY orderId
|
||||
HAVING COUNT(*) = 1
|
||||
)
|
||||
`;
|
||||
}
|
||||
pcSql += `
|
||||
GROUP BY os.productId
|
||||
`;
|
||||
|
||||
console.log('------3.5-----', pcSql, pcParams, exceptPackage);
|
||||
const pcResults = await this.orderSaleModel.query(pcSql, pcParams);
|
||||
|
||||
const pcMap = new Map<number, any>();
|
||||
|
|
@ -1320,8 +1286,7 @@ export class OrderService {
|
|||
productId: product.id,
|
||||
name: product.name,
|
||||
sku: sale.sku,
|
||||
quantity: sale.quantity,
|
||||
// externalOrderItemId:
|
||||
quantity: sale.quantity
|
||||
});
|
||||
};
|
||||
}).catch(error => {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ export class UserService {
|
|||
id: user.id,
|
||||
deviceId,
|
||||
username: user.username,
|
||||
isSuper: user.isSuper,
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import { WpSite } from '../interface';
|
|||
import { WpProduct } from '../entity/wp_product.entity';
|
||||
import { Variation } from '../entity/variation.entity';
|
||||
import { UpdateVariationDTO, UpdateWpProductDTO } from '../dto/wp_product.dto';
|
||||
import { ProductStatus } from '../enums/base.enum';
|
||||
|
||||
@Provide()
|
||||
export class WPService {
|
||||
|
|
@ -223,23 +222,6 @@ export class WPService {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 WooCommerce 产品 上下架状态
|
||||
* @param productId 产品 ID
|
||||
* @param status 状态
|
||||
*/
|
||||
async updateProductStatus(
|
||||
site: WpSite,
|
||||
productId: string,
|
||||
status: ProductStatus,
|
||||
): Promise<Boolean> {
|
||||
const res = await this.updateData(`/wc/v3/products/${productId}`, site, {
|
||||
status
|
||||
});
|
||||
console.log('res', res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 WooCommerce 产品变体
|
||||
* @param productId 产品 ID
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import {
|
|||
UpdateWpProductDTO,
|
||||
} from '../dto/wp_product.dto';
|
||||
import { Product } from '../entity/product.entty';
|
||||
import { ProductStatus } from '../enums/base.enum';
|
||||
|
||||
@Provide()
|
||||
export class WpProductService {
|
||||
|
|
@ -27,7 +26,7 @@ export class WpProductService {
|
|||
@InjectEntityModel(Variation)
|
||||
variationModel: Repository<Variation>;
|
||||
|
||||
getSite(id: string): WpSite {
|
||||
geSite(id: string): WpSite {
|
||||
let idx = this.sites.findIndex(item => item.id === id);
|
||||
return this.sites[idx];
|
||||
}
|
||||
|
|
@ -46,7 +45,7 @@ export class WpProductService {
|
|||
}
|
||||
|
||||
async syncSite(siteId: string) {
|
||||
const site = this.getSite(siteId);
|
||||
const site = this.geSite(siteId);
|
||||
const products = await this.wpApiService.getProducts(site);
|
||||
for (const product of products) {
|
||||
const variations =
|
||||
|
|
@ -57,20 +56,6 @@ export class WpProductService {
|
|||
}
|
||||
}
|
||||
|
||||
// 控制产品上下架
|
||||
async updateProductStatus(id: number, status: ProductStatus) {
|
||||
const wpProduct = await this.wpProductModel.findOneBy({ id });
|
||||
const site = await this.getSite(wpProduct.siteId);
|
||||
wpProduct.status = status;
|
||||
const res = await this.wpApiService.updateProductStatus(site, wpProduct.externalProductId, status);
|
||||
if (res === true) {
|
||||
this.wpProductModel.save(wpProduct);
|
||||
return true;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
async findProduct(
|
||||
siteId: string,
|
||||
externalProductId: string
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
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