feat(M01-B): 严格转换旧库订单金额

This commit is contained in:
Codex
2026-06-18 09:40:40 +08:00
parent 2715405c7d
commit b8b384ed67
5 changed files with 273 additions and 5 deletions
+99 -3
View File
@@ -1,4 +1,5 @@
import type { MySqlPool } from './mysql.js';
import { legacyDecimalToCents } from './legacy-money.js';
type LegacyEntity = 'stores' | 'rooms' | 'orders' | 'devices';
@@ -12,6 +13,11 @@ export interface LegacyTableMapping {
codeColumn?: string;
startColumn?: string;
endColumn?: string;
totalAmountColumn?: string;
paidAmountColumn?: string;
renewalAmountColumn?: string;
groupAmountColumn?: string;
refundAmountColumn?: string;
}
export interface LegacyReadOptions {
@@ -29,6 +35,11 @@ export interface LegacyRecord {
status: string | null;
startAt: Date | string | null;
endAt: Date | string | null;
totalAmountCents: number | null;
paidAmountCents: number | null;
renewalAmountCents: number | null;
groupAmountCents: number | null;
refundAmountCents: number | null;
}
export const defaultLegacyMappings: Record<LegacyEntity, LegacyTableMapping> = {
@@ -56,7 +67,12 @@ export const defaultLegacyMappings: Record<LegacyEntity, LegacyTableMapping> = {
codeColumn: 'order_no',
statusColumn: 'status',
startColumn: 'start_time',
endColumn: 'end_time'
endColumn: 'end_time',
totalAmountColumn: 'price',
paidAmountColumn: 'pay_price',
renewalAmountColumn: 'renew_price',
groupAmountColumn: 'group_pay_price',
refundAmountColumn: 'refund_price'
},
devices: {
table: 'member_device_info',
@@ -89,6 +105,81 @@ function normalizeLimit(limit = 100): number {
return limit;
}
interface LegacyQueryRow extends Omit<
LegacyRecord,
| 'totalAmountCents'
| 'paidAmountCents'
| 'renewalAmountCents'
| 'groupAmountCents'
| 'refundAmountCents'
> {
totalAmountDecimal: unknown;
paidAmountDecimal: unknown;
renewalAmountDecimal: unknown;
groupAmountDecimal: unknown;
refundAmountDecimal: unknown;
}
function normalizeMoney(
value: unknown,
mapping: LegacyTableMapping,
column: string | undefined,
nullable: boolean
): number | null {
if (!column) {
return null;
}
return legacyDecimalToCents(value, {
field: `${mapping.table}.${column}`,
nullable
});
}
function normalizeRecord(row: LegacyQueryRow, mapping: LegacyTableMapping): LegacyRecord {
const {
totalAmountDecimal,
paidAmountDecimal,
renewalAmountDecimal,
groupAmountDecimal,
refundAmountDecimal,
...record
} = row;
return {
...record,
totalAmountCents: normalizeMoney(
totalAmountDecimal,
mapping,
mapping.totalAmountColumn,
false
),
paidAmountCents: normalizeMoney(
paidAmountDecimal,
mapping,
mapping.paidAmountColumn,
true
),
renewalAmountCents: normalizeMoney(
renewalAmountDecimal,
mapping,
mapping.renewalAmountColumn,
true
),
groupAmountCents: normalizeMoney(
groupAmountDecimal,
mapping,
mapping.groupAmountColumn,
true
),
refundAmountCents: normalizeMoney(
refundAmountDecimal,
mapping,
mapping.refundAmountColumn,
true
)
};
}
export class LegacyReadRepository {
constructor(
private readonly pool: Pick<MySqlPool, 'query'>,
@@ -132,7 +223,12 @@ export class LegacyReadRepository {
`${selectedColumn(mapping.codeColumn, 'code')},`,
`${selectedColumn(mapping.statusColumn, 'status')},`,
`${selectedColumn(mapping.startColumn, 'startAt')},`,
selectedColumn(mapping.endColumn, 'endAt'),
`${selectedColumn(mapping.endColumn, 'endAt')},`,
`${selectedColumn(mapping.totalAmountColumn, 'totalAmountDecimal')},`,
`${selectedColumn(mapping.paidAmountColumn, 'paidAmountDecimal')},`,
`${selectedColumn(mapping.renewalAmountColumn, 'renewalAmountDecimal')},`,
`${selectedColumn(mapping.groupAmountColumn, 'groupAmountDecimal')},`,
selectedColumn(mapping.refundAmountColumn, 'refundAmountDecimal'),
`FROM ${quoteIdentifier(mapping.table)}`,
`WHERE ${clauses.join(' AND ')}`,
`ORDER BY ${quoteIdentifier(mapping.idColumn)} ASC`,
@@ -140,6 +236,6 @@ export class LegacyReadRepository {
].join(' ');
const [rows] = await this.pool.query(sql, parameters);
return rows as LegacyRecord[];
return (rows as LegacyQueryRow[]).map((row) => normalizeRecord(row, mapping));
}
}