fix(core): 明细用量美元保留 6 位小数
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
|||||||
resolveQpuTimeline,
|
resolveQpuTimeline,
|
||||||
sumUsage,
|
sumUsage,
|
||||||
toUnixSec,
|
toUnixSec,
|
||||||
|
usageRowPrecise,
|
||||||
type LogItem,
|
type LogItem,
|
||||||
} from "@new-api-key-usage/core";
|
} from "@new-api-key-usage/core";
|
||||||
import {
|
import {
|
||||||
@@ -337,8 +338,9 @@ export function adminUsageRoutes() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const items: LogItem[] = rows.map((row) => {
|
const items: LogItem[] = rows.map((row) => {
|
||||||
const { quota_usd } = sumUsage(
|
const { quota_usd } = usageRowPrecise(
|
||||||
[{ quota: row.quota, created_at: row.created_at }],
|
row.quota,
|
||||||
|
row.created_at,
|
||||||
timeline,
|
timeline,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ERR,
|
ERR,
|
||||||
resolveQpuTimeline,
|
resolveQpuTimeline,
|
||||||
sumUsage,
|
sumUsage,
|
||||||
|
usageRowPrecise,
|
||||||
toUnixSec,
|
toUnixSec,
|
||||||
type LogItem,
|
type LogItem,
|
||||||
type PaymentItem,
|
type PaymentItem,
|
||||||
@@ -265,8 +266,9 @@ export function memberViewRoutes() {
|
|||||||
page_size,
|
page_size,
|
||||||
});
|
});
|
||||||
const items: LogItem[] = rows.map((row) => {
|
const items: LogItem[] = rows.map((row) => {
|
||||||
const { quota_usd } = sumUsage(
|
const { quota_usd } = usageRowPrecise(
|
||||||
[{ quota: row.quota, created_at: row.created_at }],
|
row.quota,
|
||||||
|
row.created_at,
|
||||||
timeline,
|
timeline,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ export function microUsdToQuotaUsdStr(micro: number): string {
|
|||||||
return `${dollars}.${String(rem).padStart(2, "0")}`;
|
return `${dollars}.${String(rem).padStart(2, "0")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 明细行等小额场景:保留更多小数位(默认 4 位,仍是字符串两位小数契约的展示增强) */
|
||||||
|
export function microUsdToQuotaUsdStrPrecise(
|
||||||
|
micro: number,
|
||||||
|
fractionDigits = 4,
|
||||||
|
): string {
|
||||||
|
const usd = micro / 1_000_000;
|
||||||
|
return usd.toFixed(fractionDigits);
|
||||||
|
}
|
||||||
|
|
||||||
export function quotaToUsdStr(quota: number, qpu: number): string {
|
export function quotaToUsdStr(quota: number, qpu: number): string {
|
||||||
return microUsdToQuotaUsdStr(quotaToMicroUsd(quota, qpu));
|
return microUsdToQuotaUsdStr(quotaToMicroUsd(quota, qpu));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
microSumToUsdStr,
|
microSumToUsdStr,
|
||||||
|
microUsdToQuotaUsdStrPrecise,
|
||||||
qpuAt,
|
qpuAt,
|
||||||
quotaToMicroUsd,
|
quotaToMicroUsd,
|
||||||
quotaToUsdStr,
|
quotaToUsdStr,
|
||||||
@@ -54,6 +55,21 @@ export function usageAt(
|
|||||||
return { count: 1, quota, quota_usd: quotaToUsdStr(quota, qpu) };
|
return { count: 1, quota, quota_usd: quotaToUsdStr(quota, qpu) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 明细行:按当时 QPU 换算,展示保留 6 位小数(微美元级,小额不被抹成 0) */
|
||||||
|
export function usageRowPrecise(
|
||||||
|
quota: number,
|
||||||
|
created_at: Date | number,
|
||||||
|
timeline: readonly QpuPoint[],
|
||||||
|
): UsageSum {
|
||||||
|
const qpu = qpuAt(created_at, timeline);
|
||||||
|
const micro = quotaToMicroUsd(quota, qpu);
|
||||||
|
return {
|
||||||
|
count: 1,
|
||||||
|
quota,
|
||||||
|
quota_usd: microUsdToQuotaUsdStrPrecise(micro, 6),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function addUsage(a: UsageSum, b: UsageSum): UsageSum {
|
export function addUsage(a: UsageSum, b: UsageSum): UsageSum {
|
||||||
// 合并已成形的两段时,quota_usd 需重算——调用方应尽量走 sumUsage
|
// 合并已成形的两段时,quota_usd 需重算——调用方应尽量走 sumUsage
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user