Merge branch 'main' into dev_match

This commit is contained in:
2026-11-06 17:39:08 +08:00
59 changed files with 3319 additions and 956 deletions
@@ -1,16 +1,12 @@
/**
* 成本中心 · 商品与映射路由。
*
* 覆盖:接单模板初始化、自动发货/接单平台商品同步与回填、人工商品归一、
* 覆盖:接单模板初始化、自动发货/接单平台商品同步与回填、人工商品自动投影、
* 标准商品 CRUD、渠道映射 CRUD、未归一队列、归一数量回填。
*/
import { Router } from 'express'
import { ensureVoucherChannelRules } from '../../services/fulfillment/channel-assign-service.js'
import {
archiveHistoricalManualProducts,
archiveSupersededManualProducts,
backfillAdminNormalizedQuantities,
backfillAdminProductMappings,
createAdminChannelMapping,
@@ -27,6 +23,7 @@ import {
updateAdminChannelMapping,
updateAdminProduct,
} from '../../services/cost-center/product-catalog-service.js'
import { upsertAdminVoucherProduct } from '../../services/cost-center/voucher-product-service.js'
import {
importAdminAffiliateDashPricesBaseline,
setAdminAffiliateProductPrice,
@@ -164,38 +161,6 @@ router.post(
}),
)
router.post(
'/cost-center/products/archive-historical-manual',
requireAdminPermission('finance.config'),
createJsonHandler((req) => archiveHistoricalManualProducts(bodyOf(req)), {
successMessage: '历史人工商品已归档',
errorMessage: '归档历史人工商品失败',
scope: '[admin/cost-center/products/archive-historical-manual]',
audit: (_req, data) => ({
action: 'cost_historical_manual_products_archived',
targetType: 'product_catalog',
targetId: '',
data: data as Record<string, unknown>,
}),
}),
)
router.post(
'/cost-center/products/archive-superseded-manual',
requireAdminPermission('finance.config'),
createJsonHandler((req) => archiveSupersededManualProducts(bodyOf(req)), {
successMessage: '重复人工归一商品已归档',
errorMessage: '归档重复人工归一商品失败',
scope: '[admin/cost-center/products/archive-superseded-manual]',
audit: (_req, data) => ({
action: 'cost_superseded_manual_products_archived',
targetType: 'product_catalog',
targetId: '',
data: data as Record<string, unknown>,
}),
}),
)
router.patch(
'/cost-center/products/:productId',
requireAdminPermission('finance.config'),
@@ -402,16 +367,16 @@ router.post(
)
router.post(
'/cost-center/voucher-products/ensure-rules',
'/cost-center/voucher-products',
requireAdminPermission('finance.config'),
createJsonHandler(() => ensureVoucherChannelRules(), {
successMessage: '卡券渠道规则已补齐',
errorMessage: '补齐卡券渠道规则失败',
scope: '[admin/cost-center/voucher-products/ensure-rules]',
createJsonHandler((req) => upsertAdminVoucherProduct(bodyOf(req), sessionOf(req)), {
successMessage: '卡券 SKU 已保存',
errorMessage: '保存卡券 SKU 失败',
scope: '[admin/cost-center/voucher-products]',
audit: (_req, data) => ({
action: 'voucher_internal_channels_ensured',
targetType: 'internal_sku_channels',
targetId: '',
action: 'voucher_product_upserted',
targetType: 'product_catalog',
targetId: String((data as { product?: { id?: number } })?.product?.id || ''),
data: data as Record<string, unknown>,
}),
}),
+44
View File
@@ -13,6 +13,10 @@ import {
confirmManualFulfillment,
listManualFulfillmentPending,
} from '../../services/finance/manual-fulfillment-service.js'
import {
listOnAccountBills,
reconcileOnAccountBill,
} from '../../services/finance/on-account-bill-service.js'
import {
createJsonHandler,
requireAdminPermission,
@@ -152,4 +156,44 @@ router.post(
}),
)
router.get(
'/finance/on-account-bills',
requireAdminRoles(['admin', 'operator', 'support', 'finance']),
createJsonHandler((req) => listOnAccountBills(req.query as Record<string, unknown>), {
successMessage: 'ok',
errorMessage: '读取统一结算账单失败',
scope: '[admin/finance/on-account-bills]',
}),
)
router.post(
'/finance/on-account-bills/:billId/reconcile',
requireAdminPermission('finance.reconcile'),
createJsonHandler(
(req) => reconcileOnAccountBill(req.params.billId, bodyOf(req), sessionOf(req)),
{
successMessage: '统一结算账单已对账',
errorMessage: '统一结算账单对账失败',
scope: '[admin/finance/on-account-bills/:billId/reconcile]',
audit: (req, data) => {
const result = data as {
bill?: { id?: number; billNo?: string }
amountFen?: number
snapshotId?: number
}
return {
action: 'on_account_bill_reconciled',
targetType: 'on_account_bill',
targetId: String(result.bill?.id || req.params.billId || ''),
data: {
billNo: result.bill?.billNo || '',
amountFen: result.amountFen || 0,
costSnapshotId: result.snapshotId || null,
},
}
},
},
),
)
export default router
@@ -9,6 +9,7 @@ import {
listAdminKuaishouIndustryRefunds,
listAdminKuaishouIndustryShops,
listAdminKuaishouIndustryVouchers,
reissueAndConsumeAdminKuaishouIndustryVoucher,
resendAdminKuaishouIndustryVoucherCode,
reverseAdminKuaishouIndustryVoucher,
} from '../../services/admin/kuaishou-industry-admin-service.js'
@@ -21,6 +22,7 @@ import type {
AdminKuaishouIndustryVoucherCheckAvailableRouteBody,
AdminKuaishouIndustryVoucherConsumeRouteBody,
AdminKuaishouIndustryVoucherDestroyRouteBody,
AdminKuaishouIndustryVoucherReissueConsumeRouteBody,
AdminKuaishouIndustryVoucherResendRouteBody,
AdminKuaishouIndustryVoucherReverseRouteBody,
} from '../../types/admin/route-inputs.js'
@@ -204,6 +206,24 @@ router.post(
),
)
router.post(
'/kuaishou-industry/vouchers/reissue-consume',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) =>
reissueAndConsumeAdminKuaishouIndustryVoucher(
req.body as AdminKuaishouIndustryVoucherReissueConsumeRouteBody,
),
{
successMessage: '历史券补发并核销已执行',
errorMessage: '历史券补发并核销失败',
scope: '[admin/kuaishou-industry/vouchers/reissue-consume]',
audit: (req, data) =>
buildKuaishouIndustryAudit('kuaishou_industry_voucher_reissue_consume', req.body, data),
},
),
)
router.post(
'/kuaishou-industry/vouchers/destroy',
requireAdminRoles(['admin', 'operator']),
@@ -238,6 +258,13 @@ function buildKuaishouIndustryAudit(action: string, body: unknown, data: unknown
success: Boolean(result.success),
httpStatus: Number(result.httpStatus || 0) || 0,
error: String(result.error || ''),
stage: String(result.stage || ''),
reason: String(result.reason || ''),
validMinutes: Number(result.validMinutes || 0) || 0,
originalValidEndTime: Number(result.originalValidEndTime || 0) || 0,
validEndTime: Number(result.validEndTime || 0) || 0,
sendSuccess: Boolean(result.sendSuccess),
consumeSuccess: Boolean(result.consumeSuccess),
},
}
}