feat: 积分商城-供应商

This commit is contained in:
2026-09-01 18:03:37 +08:00
parent 20d059443c
commit 750c36116d
39 changed files with 3692 additions and 9 deletions
@@ -23,6 +23,13 @@ export const merchantOrderListController = withErrorBoundary(async (request: Req
return toHttpResponse(await merchantService.listOrders(await readJson<MerchantOrderListInput>(request)))
})
export const merchantSupplierListController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
return toHttpResponse(await merchantService.listSuppliers())
})
export const merchantOrderShipController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
@@ -14,7 +14,11 @@ import { orderActionService } from '../services/order-action.service.js'
import { orderCreateService, type CheckoutGoods } from '../services/order-create.service.js'
import { orderListService } from '../services/order-list.service.js'
import { orderPushEventService, type OrderPushEventInput } from '../services/order-push-event.service.js'
import { supplierOpenOrderService, type SupplierOrderQueryRequest } from '../services/supplier-open-order.service.js'
import {
supplierOpenOrderService,
type SupplierOrderQueryRequest,
type SupplierReconciliationQueryRequest
} from '../services/supplier-open-order.service.js'
import { toHttpResponse } from './controller-response.js'
type OrderListRequest = {
@@ -239,3 +243,21 @@ export const supplierOrderInfoController = withErrorBoundary(async (request: Req
return Response.json(await supplierOpenOrderService.queryOrderInfo(body))
})
export const supplierReconciliationInfoController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
let body: SupplierReconciliationQueryRequest
try {
body = supplierOpenOrderService.parseBody(await readJson<SupplierReconciliationQueryRequest>(request))
} catch (error) {
return Response.json({
resultCode: 400,
message: error instanceof Error ? error.message : '请求参数解密失败',
orderInfos: []
})
}
return Response.json(await supplierOpenOrderService.queryReconciliationInfo(body))
})
@@ -1,5 +1,6 @@
import type { Context } from '../utils/handler.js'
import { guardMethod } from '../utils/method.js'
import { readJson } from '../utils/request.js'
import { withErrorBoundary } from '../utils/handler.js'
import { productService } from '../services/product.service.js'
import { toHttpResponse } from './controller-response.js'
@@ -25,3 +26,28 @@ export const productDetailController = withErrorBoundary(async (request: Request
return toHttpResponse(await productService.getProductDetail(id, sku))
})
export const merchantProductListController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
const body = await readJson<{ keyword?: string; categoryId?: string }>(request)
return toHttpResponse(await productService.listManageProducts(String(body.keyword || '').trim(), String(body.categoryId || '').trim()))
})
export const merchantProductSaveController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
return toHttpResponse(await productService.saveManageProduct(
await readJson<Parameters<typeof productService.saveManageProduct>[0]>(request)
))
})
export const merchantProductDeleteController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
const body = await readJson<{ id?: number }>(request)
return toHttpResponse(await productService.deleteManageProduct(Number(body.id || 0)))
})
@@ -0,0 +1,75 @@
import type { Context } from '../utils/handler.js'
import { withErrorBoundary } from '../utils/handler.js'
import { guardMethod } from '../utils/method.js'
import { readJson } from '../utils/request.js'
import { toHttpResponse } from './controller-response.js'
import { supplierOpenOrderService } from '../services/supplier-open-order.service.js'
import {
reconciliationResultService,
type ReconciliationResultCallbackInput,
type ReconciliationResultListInput,
type ReconciliationResultUpdateInput
} from '../services/reconciliation-result.service.js'
type UnReconciledMsgInput = {
supplierId?: string
token?: string
timestamp?: number
orderIds?: string
unReconciledType?: number
unReconciledMsg?: string
uniqueSeqNo?: string
AplParmObjct?: string
}
export const supplierReconciliationResultController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
let body: ReconciliationResultCallbackInput
try {
body = supplierOpenOrderService.parseBody(await readJson<ReconciliationResultCallbackInput>(request)) as ReconciliationResultCallbackInput
} catch (error) {
return Response.json({ resultCode: 400, message: error instanceof Error ? error.message : '请求参数解密失败' })
}
return Response.json(await reconciliationResultService.receiveCallback(body))
})
export const supplierUnReconciledMsgController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
let body: UnReconciledMsgInput
try {
body = supplierOpenOrderService.parseBody(await readJson<UnReconciledMsgInput>(request)) as UnReconciledMsgInput
} catch (error) {
return Response.json({ resultCode: 400, message: error instanceof Error ? error.message : '请求参数解密失败' })
}
const reconciliationResults = String(body.orderIds || '').split(',').map(orderId => orderId.trim()).filter(Boolean).map(orderId => ({
orderId,
reconciliationStatus: 2,
diffType: body.unReconciledType === undefined ? undefined : Number(body.unReconciledType),
diffReason: body.unReconciledMsg
}))
return Response.json(await reconciliationResultService.receiveCallback({
supplierId: body.supplierId,
token: body.token,
timestamp: body.timestamp,
reconciliationBatchNo: body.uniqueSeqNo,
reconciliationResults
}))
})
export const merchantReconciliationListController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
return toHttpResponse(await reconciliationResultService.list(await readJson<ReconciliationResultListInput>(request)))
})
export const merchantReconciliationUpdateController = withErrorBoundary(async (request: Request, _context: Context) => {
const methodResponse = guardMethod(request, ['POST'])
if (methodResponse) return methodResponse
return toHttpResponse(await reconciliationResultService.update(await readJson<ReconciliationResultUpdateInput>(request)))
})
+28 -2
View File
@@ -137,12 +137,38 @@ export const orderDao = {
})
},
findMerchantSubOrders(supplierId: string, orderState?: number) {
findOpenApiReconciliationSubOrders(supplierId: string, orderIds: string[], startDate?: Date, endDate?: Date, orderState?: number) {
return prisma.supplierOrderSub.findMany({
where: {
supplierId,
deleted: 0,
...(Number.isInteger(orderState) ? { orderState } : {})
...(Number.isInteger(orderState) ? { orderState } : {}),
...(orderIds.length ? { orderId: { in: orderIds } } : {}),
...(startDate || endDate ? {
completeTime: {
...(startDate ? { gte: startDate } : {}),
...(endDate ? { lte: endDate } : {})
}
} : {})
},
include: {
products: {
where: { deleted: 0 },
orderBy: { createAt: 'asc' }
}
},
orderBy: { createAt: 'asc' }
})
},
findMerchantSubOrders(supplierId: string, orderState?: number, orderId?: string, userId?: string) {
return prisma.supplierOrderSub.findMany({
where: {
supplierId,
deleted: 0,
...(Number.isInteger(orderState) ? { orderState } : {}),
...(orderId ? { OR: [{ orderId: { contains: orderId } }, { orderNumberId: { contains: orderId } }] } : {}),
...(userId ? { userId: { contains: userId } } : {})
},
include: {
products: {
+26
View File
@@ -33,5 +33,31 @@ export const productDao = {
]
}
})
},
findManageProducts(keyword: string, categoryId: string) {
return prisma.supplierProduct.findMany({
where: {
deleted: 0,
...(keyword ? { OR: [{ name: { contains: keyword } }, { sku: { contains: keyword } }] } : {}),
...(categoryId ? { categoryId } : {})
},
orderBy: [
{ sortOrder: 'asc' },
{ createdAt: 'desc' }
]
})
},
createProduct(data: Parameters<typeof prisma.supplierProduct.create>[0]['data']) {
return prisma.supplierProduct.create({ data })
},
updateProduct(id: number, data: Parameters<typeof prisma.supplierProduct.update>[0]['data']) {
return prisma.supplierProduct.update({ where: { id }, data })
},
findManageProduct(id: number) {
return prisma.supplierProduct.findFirst({ where: { id, deleted: 0 } })
}
}
+8
View File
@@ -11,5 +11,13 @@ export const supplierDao = {
return prisma.supplierInfo.findFirst({
where: { supplierId, deleted: 0 }
})
},
findActiveSuppliers() {
return prisma.supplierInfo.findMany({
where: { deleted: 0 },
select: { supplierId: true, supplierName: true },
orderBy: { supplierName: 'asc' }
})
}
}
+30 -3
View File
@@ -33,8 +33,15 @@ import {
orderPayController,
orderPushEventController,
orderShipController,
supplierOrderInfoController
supplierOrderInfoController,
supplierReconciliationInfoController
} from './controllers/order.controller.js'
import {
merchantReconciliationListController,
merchantReconciliationUpdateController,
supplierReconciliationResultController,
supplierUnReconciledMsgController
} from './controllers/reconciliation.controller.js'
import {
merchantAfterSaleAuditController,
merchantAfterSaleDetailController,
@@ -42,9 +49,16 @@ import {
merchantAfterSaleReceiveController,
merchantAfterSaleShipController,
merchantOrderListController,
merchantOrderShipController
merchantOrderShipController,
merchantSupplierListController
} from './controllers/merchant.controller.js'
import { productDetailController, productListController } from './controllers/product.controller.js'
import {
merchantProductDeleteController,
merchantProductListController,
merchantProductSaveController,
productDetailController,
productListController
} from './controllers/product.controller.js'
import {
supplierDebugTokensController,
supplierInfoController,
@@ -75,6 +89,7 @@ const handlers: Record<string, FunctionHandler> = {
'merchant-after-sale-ship': merchantAfterSaleShipController,
'merchant-order-list': merchantOrderListController,
'merchant-order-ship': merchantOrderShipController,
'merchant-supplier-list': merchantSupplierListController,
'order-cancel-main': orderCancelMainController,
'order-cancel-paid-main': orderCancelPaidMainController,
'order-cancel-sub': orderCancelSubController,
@@ -87,9 +102,17 @@ const handlers: Record<string, FunctionHandler> = {
'order-ship': orderShipController,
'product-detail': productDetailController,
'product-list': productListController,
'merchant-product-list': merchantProductListController,
'merchant-product-save': merchantProductSaveController,
'merchant-product-delete': merchantProductDeleteController,
'supplier-debug-tokens': supplierDebugTokensController,
'supplier-info': supplierInfoController,
'supplier-order-info': supplierOrderInfoController,
'supplier-reconciliation-info': supplierReconciliationInfoController,
'supplier-reconciliation-result': supplierReconciliationResultController,
'supplier-unreconciled-msg': supplierUnReconciledMsgController,
'merchant-reconciliation-list': merchantReconciliationListController,
'merchant-reconciliation-update': merchantReconciliationUpdateController,
'supplier-points': supplierPointsController,
'supplier-token': supplierTokenController,
upload: uploadController,
@@ -174,7 +197,11 @@ router.delete('/api/supplier-logs', ctx => {
}
})
router.all('/api/:name', async ctx => dispatch(ctx.params.name)(ctx))
router.all('/api/admin/:name', async ctx => dispatch(ctx.params.name)(ctx))
router.post('/supplierOpenApi/pointOrder/queryOrderInfo', dispatch('supplier-order-info'))
router.post('/supplierOpenApi/pointOrder/queryReconciliationInfo', dispatch('supplier-reconciliation-info'))
router.post('/supplierOpenApi/pointOrder/reconciliationResult', dispatch('supplier-reconciliation-result'))
router.post('/supplierOpenApi/pointOrder/unReconciledMsg', dispatch('supplier-unreconciled-msg'))
router.post('/supplierOpenApi/debug/tokens', dispatch('supplier-debug-tokens'))
app.use(router.routes())
@@ -5,6 +5,7 @@ import {
ORDER_STATE
} from '../constants/order.js'
import { orderDao } from '../dao/order.dao.js'
import { supplierDao } from '../dao/supplier.dao.js'
import { afterSaleService, type AfterSaleAuditInput, type AfterSaleLogisticsInput } from './after-sale.service.js'
import { orderActionService } from './order-action.service.js'
import { logger } from '../utils/logger.js'
@@ -13,6 +14,8 @@ import { serviceFail, serviceOk } from '../types/service-result.js'
export type MerchantOrderListInput = {
supplierId?: string
orderState?: number
orderId?: string
userId?: string
}
export type MerchantShipInput = {
@@ -105,14 +108,16 @@ const isOrderSigned = (orderState?: number | null) => signedOrderStates.has(Numb
export const merchantService = {
async listOrders(input: MerchantOrderListInput) {
const supplierId = String(input.supplierId || '').trim()
const orderState = Number(input.orderState ?? ORDER_STATE.FINISH_PAY)
const orderState = input.orderState === undefined ? undefined : Number(input.orderState)
const orderId = String(input.orderId || '').trim()
const userId = String(input.userId || '').trim()
logger.info('merchant order list query', { supplierId, orderState })
if (!supplierId) {
return serviceFail('供应商不能为空')
}
const orders = await orderDao.findMerchantSubOrders(supplierId, orderState)
const orders = await orderDao.findMerchantSubOrders(supplierId, orderState, orderId, userId)
const afterSales = await orderDao.findMerchantAfterSales(supplierId, pendingShipExcludeAfterSaleStates)
const afterSaleSubOrderIds = new Set(afterSales.map(item => item.subOrderId).filter(Boolean))
const orderItems = orders.filter(order => !afterSaleSubOrderIds.has(order.orderId)).map(order => ({
@@ -139,6 +144,11 @@ export const merchantService = {
return serviceOk({ orderItems })
},
async listSuppliers() {
const suppliers = await supplierDao.findActiveSuppliers()
return serviceOk({ suppliers })
},
shipOrder(input: MerchantShipInput) {
return orderActionService.shipOrder({
supplierId: String(input.supplierId || '').trim(),
@@ -35,7 +35,9 @@ const toProductItem = (product: ProductRecord) => {
category: product.category || '',
tag: product.tag || '',
sales: product.sales || '',
stock: product.stock
stock: product.stock,
sortOrder: product.sortOrder,
enabled: product.enabled
}
}
@@ -64,5 +66,67 @@ export const productService = {
}
return serviceOk(toProductItem(product))
},
async listManageProducts(keyword: string, categoryId: string) {
const products = await productDao.findManageProducts(keyword, categoryId)
return serviceOk({ categories, products: products.map(toProductItem) })
},
async saveManageProduct(input: {
id?: number
sku?: string
name?: string
price?: number
number?: number
stock?: number
taxRate?: number
categoryId?: string
category?: string
imageUrl?: string
description?: string
detail?: string
originPrice?: number
tag?: string
sales?: string
sortOrder?: number
enabled?: boolean
}) {
const sku = String(input.sku || '').trim()
const name = String(input.name || '').trim()
const price = Number(input.price)
if (!sku || !name || Number.isNaN(price) || price < 0) {
return serviceFail('商品SKU、名称和价格不能为空')
}
const data = {
sku,
name,
price,
number: Math.max(Number(input.number || 0), 0),
stock: Math.max(Number(input.stock || 0), 0),
taxRate: Number(input.taxRate ?? 0.13),
categoryId: String(input.categoryId || '').trim() || null,
category: String(input.category || '').trim() || null,
imageUrl: String(input.imageUrl || '').trim() || null,
description: String(input.description || '').trim() || null,
detail: String(input.detail || '').trim() || null,
originPrice: input.originPrice === undefined || input.originPrice === null ? null : Number(input.originPrice),
tag: String(input.tag || '').trim() || null,
sales: String(input.sales || '').trim() || null,
sortOrder: Math.max(Number(input.sortOrder || 0), 0),
enabled: input.enabled !== false
}
const id = Number(input.id || 0)
const product = id > 0 ? await productDao.updateProduct(id, data) : await productDao.createProduct(data)
return serviceOk(toProductItem(product))
},
async deleteManageProduct(id: number) {
if (!Number.isInteger(id) || id <= 0) return serviceFail('商品ID不正确')
const product = await productDao.findManageProduct(id)
if (!product) return serviceFail('商品不存在')
await productDao.updateProduct(id, { deleted: 1 })
return serviceOk({})
}
}
@@ -0,0 +1,176 @@
import type { Prisma } from '@prisma/client'
import { prisma } from '../utils/prisma.js'
import { supplierDao } from '../dao/supplier.dao.js'
import { verifySupplierOpenSignature } from '../utils/supplier-open-crypto.js'
import { serviceFail, serviceOk } from '../types/service-result.js'
export type ReconciliationResultItem = {
orderId?: string
mainOrderId?: string
userId?: string
reconciliationStatus?: number
diffType?: number
diffReason?: string
platformTotalPrice?: number
platformCashAmount?: number
platformPointsPrice?: number
platformRefundPrice?: number
supplierTotalPrice?: number
supplierCashAmount?: number
supplierPointsPrice?: number
supplierRefundPrice?: number
}
export type ReconciliationResultCallbackInput = {
supplierId?: string
token?: string
timestamp?: number
reconciliationBatchNo?: string
reconciliationTime?: string
reconciliationResults?: ReconciliationResultItem[]
AplParmObjct?: string
}
export type ReconciliationResultListInput = {
supplierId?: string
reconciliationStatus?: number
orderId?: string
}
export type ReconciliationResultUpdateInput = {
supplierId?: string
orderId?: string
reconciliationStatus?: number
diffType?: number
diffReason?: string
}
const toNumber = (value?: number) => value === undefined || value === null ? null : Number(value)
const toTime = (value?: string) => {
if (!value) return new Date()
const time = new Date(value)
return Number.isNaN(time.getTime()) ? new Date() : time
}
const resultItem = (record: Awaited<ReturnType<typeof prisma.supplierReconciliationOrder.findMany>>[number]) => ({
supplierId: record.supplierId,
orderId: record.orderId,
mainOrderId: record.mainOrderId || '',
userId: record.userId || '',
reconciliationStatus: record.reconciliationStatus,
diffType: record.diffType,
diffReason: record.diffReason || '',
platformTotalPrice: record.platformTotalPrice?.toFixed(2) || '',
platformCashAmount: record.platformCashAmount?.toFixed(2) || '',
platformPointsPrice: record.platformPointsPrice?.toFixed(2) || '',
platformRefundPrice: record.platformRefundPrice?.toFixed(2) || '',
supplierTotalPrice: record.supplierTotalPrice?.toFixed(2) || '',
supplierCashAmount: record.supplierCashAmount?.toFixed(2) || '',
supplierPointsPrice: record.supplierPointsPrice?.toFixed(2) || '',
supplierRefundPrice: record.supplierRefundPrice?.toFixed(2) || '',
reconciliationBatchNo: record.reconciliationBatchNo || '',
reconciliationTime: record.reconciliationTime,
updateAt: record.updateAt
})
export const reconciliationResultService = {
async receiveCallback(input: ReconciliationResultCallbackInput) {
const supplierId = String(input.supplierId || '').trim()
const token = String(input.token || '').trim()
const timestamp = Number(input.timestamp || 0)
const records = Array.isArray(input.reconciliationResults) ? input.reconciliationResults : []
if (!supplierId || !token || !timestamp || !records.length) {
return { resultCode: 400, message: '供应商、签名或对账结果不能为空' }
}
const supplier = await supplierDao.findActiveBySupplierId(supplierId)
if (!supplier) return { resultCode: 404, message: '供应商信息不存在' }
if (!verifySupplierOpenSignature(supplier.supplierId, supplier.clientId, timestamp, token)) {
return { resultCode: 401, message: '签名无效或已过期' }
}
const reconciliationTime = toTime(input.reconciliationTime)
for (const record of records) {
const orderId = String(record.orderId || '').trim()
const status = Number(record.reconciliationStatus)
if (!orderId || ![0, 1, 2].includes(status)) {
return { resultCode: 400, message: '子订单ID或对账状态不正确' }
}
}
await prisma.$transaction(records.map(record => {
const orderId = String(record.orderId || '').trim()
const data = {
mainOrderId: String(record.mainOrderId || '').trim() || null,
userId: String(record.userId || '').trim() || null,
reconciliationStatus: Number(record.reconciliationStatus),
diffType: record.diffType === undefined || record.diffType === null ? null : Number(record.diffType),
diffReason: String(record.diffReason || '').trim() || null,
platformTotalPrice: toNumber(record.platformTotalPrice),
platformCashAmount: toNumber(record.platformCashAmount),
platformPointsPrice: toNumber(record.platformPointsPrice),
platformRefundPrice: toNumber(record.platformRefundPrice),
supplierTotalPrice: toNumber(record.supplierTotalPrice),
supplierCashAmount: toNumber(record.supplierCashAmount),
supplierPointsPrice: toNumber(record.supplierPointsPrice),
supplierRefundPrice: toNumber(record.supplierRefundPrice),
reconciliationBatchNo: String(input.reconciliationBatchNo || '').trim() || null,
reconciliationTime,
resultPayload: record as Prisma.InputJsonValue,
deleted: 0
}
return prisma.supplierReconciliationOrder.upsert({
where: { supplierId_orderId: { supplierId, orderId } },
update: data,
create: { supplierId, orderId, ...data }
})
}))
return { resultCode: 0, message: '成功' }
},
async list(input: ReconciliationResultListInput) {
const supplierId = String(input.supplierId || '').trim()
if (!supplierId) return serviceFail('供应商不能为空')
const reconciliationStatus = input.reconciliationStatus === undefined ? undefined : Number(input.reconciliationStatus)
if (reconciliationStatus !== undefined && ![0, 1, 2].includes(reconciliationStatus)) {
return serviceFail('对账状态不正确')
}
const records = await prisma.supplierReconciliationOrder.findMany({
where: {
supplierId,
deleted: 0,
...(reconciliationStatus === undefined ? {} : { reconciliationStatus }),
...(String(input.orderId || '').trim() ? { orderId: { contains: String(input.orderId).trim() } } : {})
},
orderBy: { updateAt: 'desc' }
})
return serviceOk({ reconciliationItems: records.map(resultItem) })
},
async update(input: ReconciliationResultUpdateInput) {
const supplierId = String(input.supplierId || '').trim()
const orderId = String(input.orderId || '').trim()
const reconciliationStatus = Number(input.reconciliationStatus)
if (!supplierId || !orderId || ![0, 1, 2].includes(reconciliationStatus)) {
return serviceFail('供应商、子订单或对账状态不正确')
}
const record = await prisma.supplierReconciliationOrder.findUnique({
where: { supplierId_orderId: { supplierId, orderId } }
})
if (!record || record.deleted !== 0) return serviceFail('对账结果不存在')
await prisma.supplierReconciliationOrder.update({
where: { supplierId_orderId: { supplierId, orderId } },
data: {
reconciliationStatus,
diffType: input.diffType === undefined || input.diffType === null ? null : Number(input.diffType),
diffReason: String(input.diffReason || '').trim() || null
}
})
return serviceOk({})
}
}
@@ -13,6 +13,19 @@ export type SupplierOrderQueryRequest = {
AplParmObjct?: string
}
export type SupplierReconciliationQueryRequest = {
supplierId?: string
token?: string
reconciliationType?: number
orderId?: string
startDate?: string
endDate?: string
page?: number
pageSize?: number
timestamp?: number
AplParmObjct?: string
}
const parseBody = (body: SupplierOrderQueryRequest) => {
if (!body.AplParmObjct) return body
@@ -149,5 +162,66 @@ export const supplierOpenOrderService = {
}))
return { resultCode: 0, message: '成功', orderInfo }
},
async queryReconciliationInfo(body: SupplierReconciliationQueryRequest) {
const supplierId = String(body.supplierId || '').trim()
const token = String(body.token || '').trim()
const reconciliationType = Number(body.reconciliationType || 0)
const orderIds = String(body.orderId || '')
.split(',')
.map(item => item.trim())
.filter(Boolean)
const timestamp = Number(body.timestamp || 0)
if (!supplierId || !token || !timestamp) {
return { resultCode: 400, message: '供应商或签名信息不能为空', orderInfos: [] }
}
if (reconciliationType === 1 && !body.startDate) {
return { resultCode: 400, message: '请选择开始日期', orderInfos: [] }
}
if (reconciliationType === 2 && !orderIds.length) {
return { resultCode: 400, message: '订单号不能为空', orderInfos: [] }
}
if (![1, 2].includes(reconciliationType)) {
return { resultCode: 400, message: '对账类型不正确', orderInfos: [] }
}
const supplier = await supplierDao.findActiveBySupplierId(supplierId)
if (!supplier) {
return { resultCode: 404, message: '供应商信息不存在', orderInfos: [] }
}
if (!verifySupplierOpenSignature(supplier.supplierId, supplier.clientId, timestamp, token)) {
return { resultCode: 401, message: '签名无效或已过期', orderInfos: [] }
}
const startDate = body.startDate ? new Date(`${body.startDate}T00:00:00`) : undefined
const endDate = body.endDate ? new Date(`${body.endDate}T23:59:59`) : undefined
if ((startDate && Number.isNaN(startDate.getTime())) || (endDate && Number.isNaN(endDate.getTime()))) {
return { resultCode: 400, message: '对账日期格式不正确', orderInfos: [] }
}
const orders = await orderDao.findOpenApiReconciliationSubOrders(
supplierId,
orderIds,
startDate,
endDate,
reconciliationType === 1 ? ORDER_STATE.COMPLETED : undefined
)
const page = Math.max(Number(body.page || 1), 1)
const pageSize = Math.max(Number(body.pageSize || 100), 1)
const totalPage = Math.max(Math.ceil(orders.length / pageSize), 1)
const pagedOrders = orders.slice((page - 1) * pageSize, page * pageSize)
const orderInfos = pagedOrders.map(order => ({
orderId: order.orderId,
supplierId: order.supplierId,
totalPrice: toMoney(order.totalPrice),
pointsPrice: toMoney(order.pointsPrice),
wPayOrAPay: toMoney(order.wPayOrAPay),
invoiceNakedPrice: toMoney(order.totalPrice),
orderProInfos: toOrderProductInfo(order)
}))
return { resultCode: 0, message: '成功', totalPage, currentPage: page, orderInfos }
}
}