style: 统一代码格式 (prettier)

This commit is contained in:
erio
2026-03-10 18:20:36 +08:00
parent abff49222b
commit 9f621713c3
31 changed files with 631 additions and 406 deletions

View File

@@ -4,7 +4,10 @@ const BODY_CHARSET_RE = /(?:^|&)charset=([^&]+)/i;
function normalizeCharset(charset: string | null | undefined): string | null {
if (!charset) return null;
const normalized = charset.trim().replace(/^['"]|['"]$/g, '').toLowerCase();
const normalized = charset
.trim()
.replace(/^['"]|['"]$/g, '')
.toLowerCase();
if (!normalized) return null;
switch (normalized) {
@@ -67,9 +70,7 @@ export function decodeAlipayPayload(rawBody: string | Buffer, headers: Record<st
return fallbackDecoded;
}
throw new Error(
`Failed to decode Alipay payload${lastError instanceof Error ? `: ${lastError.message}` : ''}`,
);
throw new Error(`Failed to decode Alipay payload${lastError instanceof Error ? `: ${lastError.message}` : ''}`);
}
export function normalizeAlipaySignature(sign: string): string {

View File

@@ -11,11 +11,7 @@ import type {
import { pageExecute, execute } from './client';
import { verifySign } from './sign';
import { getEnv } from '@/lib/config';
import type {
AlipayTradeQueryResponse,
AlipayTradeRefundResponse,
AlipayTradeCloseResponse,
} from './types';
import type { AlipayTradeQueryResponse, AlipayTradeRefundResponse, AlipayTradeCloseResponse } from './types';
import { parseAlipayNotificationParams } from './codec';
export interface BuildAlipayPaymentUrlInput {
@@ -165,8 +161,7 @@ export class AlipayProvider implements PaymentProvider {
tradeNo,
orderId,
amount: Math.round(amount * 100) / 100,
status:
tradeStatus === 'TRADE_SUCCESS' || tradeStatus === 'TRADE_FINISHED' ? 'success' : 'failed',
status: tradeStatus === 'TRADE_SUCCESS' || tradeStatus === 'TRADE_FINISHED' ? 'success' : 'failed',
rawData: params,
};
}

View File

@@ -6,7 +6,11 @@ function wrapBase64(b64: string): string {
}
function normalizePemLikeValue(key: string): string {
return key.trim().replace(/\r\n/g, '\n').replace(/\\r\\n/g, '\n').replace(/\\n/g, '\n');
return key
.trim()
.replace(/\r\n/g, '\n')
.replace(/\\r\\n/g, '\n')
.replace(/\\n/g, '\n');
}
function shouldLogVerifyDebug(): boolean {
@@ -42,7 +46,9 @@ export function generateSign(params: Record<string, string>, privateKey: string)
/** 用支付宝公钥验证签名(回调验签:排除 sign 和 sign_type */
export function verifySign(params: Record<string, string>, alipayPublicKey: string, sign: string): boolean {
const filtered = Object.entries(params)
.filter(([key, value]) => key !== 'sign' && key !== 'sign_type' && value !== '' && value !== undefined && value !== null)
.filter(
([key, value]) => key !== 'sign' && key !== 'sign_type' && value !== '' && value !== undefined && value !== null,
)
.sort(([a], [b]) => a.localeCompare(b));
const signStr = filtered.map(([key, value]) => `${key}=${value}`).join('&');

View File

@@ -62,7 +62,11 @@ export async function createOrder(input: CreateOrderInput): Promise<CreateOrderR
if (pendingCount >= MAX_PENDING_ORDERS) {
throw new OrderError(
'TOO_MANY_PENDING',
message(locale, `待支付订单过多(最多 ${MAX_PENDING_ORDERS} 笔)`, `Too many pending orders (${MAX_PENDING_ORDERS})`),
message(
locale,
`待支付订单过多(最多 ${MAX_PENDING_ORDERS} 笔)`,
`Too many pending orders (${MAX_PENDING_ORDERS})`,
),
429,
);
}
@@ -228,13 +232,21 @@ export async function createOrder(input: CreateOrderInput): Promise<CreateOrderR
if (msg.includes('environment variables') || msg.includes('not configured') || msg.includes('not found')) {
throw new OrderError(
'PAYMENT_GATEWAY_ERROR',
message(locale, `支付渠道(${input.paymentType})暂未配置,请联系管理员`, `Payment method (${input.paymentType}) is not configured. Please contact the administrator`),
message(
locale,
`支付渠道(${input.paymentType})暂未配置,请联系管理员`,
`Payment method (${input.paymentType}) is not configured. Please contact the administrator`,
),
503,
);
}
throw new OrderError(
'PAYMENT_GATEWAY_ERROR',
message(locale, '支付渠道暂时不可用,请稍后重试或更换支付方式', 'Payment method is temporarily unavailable. Please try again later or use another payment method'),
message(
locale,
'支付渠道暂时不可用,请稍后重试或更换支付方式',
'Payment method is temporarily unavailable. Please try again later or use another payment method',
),
502,
);
}
@@ -413,10 +425,7 @@ export async function confirmPayment(input: {
const result = await prisma.order.updateMany({
where: {
id: order.id,
OR: [
{ status: ORDER_STATUS.PENDING },
{ status: ORDER_STATUS.EXPIRED, updatedAt: { gte: graceDeadline } },
],
OR: [{ status: ORDER_STATUS.PENDING }, { status: ORDER_STATUS.EXPIRED, updatedAt: { gte: graceDeadline } }],
},
data: {
status: ORDER_STATUS.PAID,
@@ -574,11 +583,19 @@ export async function executeRecharge(orderId: string): Promise<void> {
function assertRetryAllowed(order: { status: string; paidAt: Date | null }, locale: Locale): void {
if (!order.paidAt) {
throw new OrderError('INVALID_STATUS', message(locale, '订单未支付,不允许重试', 'Order is not paid, retry denied'), 400);
throw new OrderError(
'INVALID_STATUS',
message(locale, '订单未支付,不允许重试', 'Order is not paid, retry denied'),
400,
);
}
if (isRefundStatus(order.status)) {
throw new OrderError('INVALID_STATUS', message(locale, '退款相关订单不允许重试', 'Refund-related order cannot retry'), 400);
throw new OrderError(
'INVALID_STATUS',
message(locale, '退款相关订单不允许重试', 'Refund-related order cannot retry'),
400,
);
}
if (order.status === ORDER_STATUS.FAILED || order.status === ORDER_STATUS.PAID) {
@@ -586,14 +603,22 @@ function assertRetryAllowed(order: { status: string; paidAt: Date | null }, loca
}
if (order.status === ORDER_STATUS.RECHARGING) {
throw new OrderError('CONFLICT', message(locale, '订单正在充值中,请稍后重试', 'Order is recharging, retry later'), 409);
throw new OrderError(
'CONFLICT',
message(locale, '订单正在充值中,请稍后重试', 'Order is recharging, retry later'),
409,
);
}
if (order.status === ORDER_STATUS.COMPLETED) {
throw new OrderError('INVALID_STATUS', message(locale, '订单已完成', 'Order already completed'), 400);
}
throw new OrderError('INVALID_STATUS', message(locale, '仅已支付和失败订单允许重试', 'Only paid and failed orders can retry'), 400);
throw new OrderError(
'INVALID_STATUS',
message(locale, '仅已支付和失败订单允许重试', 'Only paid and failed orders can retry'),
400,
);
}
export async function retryRecharge(orderId: string, locale: Locale = 'zh'): Promise<void> {
@@ -638,7 +663,11 @@ export async function retryRecharge(orderId: string, locale: Locale = 'zh'): Pro
const derived = deriveOrderState(latest);
if (derived.rechargeStatus === 'recharging' || latest.status === ORDER_STATUS.PAID) {
throw new OrderError('CONFLICT', message(locale, '订单正在充值中,请稍后重试', 'Order is recharging, retry later'), 409);
throw new OrderError(
'CONFLICT',
message(locale, '订单正在充值中,请稍后重试', 'Order is recharging, retry later'),
409,
);
}
if (derived.rechargeStatus === 'success') {
@@ -646,10 +675,18 @@ export async function retryRecharge(orderId: string, locale: Locale = 'zh'): Pro
}
if (isRefundStatus(latest.status)) {
throw new OrderError('INVALID_STATUS', message(locale, '退款相关订单不允许重试', 'Refund-related order cannot retry'), 400);
throw new OrderError(
'INVALID_STATUS',
message(locale, '退款相关订单不允许重试', 'Refund-related order cannot retry'),
400,
);
}
throw new OrderError('CONFLICT', message(locale, '订单状态已变更,请刷新后重试', 'Order status changed, refresh and retry'), 409);
throw new OrderError(
'CONFLICT',
message(locale, '订单状态已变更,请刷新后重试', 'Order status changed, refresh and retry'),
409,
);
}
await prisma.auditLog.create({
@@ -682,7 +719,11 @@ export async function processRefund(input: RefundInput): Promise<RefundResult> {
const order = await prisma.order.findUnique({ where: { id: input.orderId } });
if (!order) throw new OrderError('NOT_FOUND', message(locale, '订单不存在', 'Order not found'), 404);
if (order.status !== ORDER_STATUS.COMPLETED) {
throw new OrderError('INVALID_STATUS', message(locale, '仅已完成订单允许退款', 'Only completed orders can be refunded'), 400);
throw new OrderError(
'INVALID_STATUS',
message(locale, '仅已完成订单允许退款', 'Only completed orders can be refunded'),
400,
);
}
const rechargeAmount = Number(order.amount);
@@ -716,7 +757,11 @@ export async function processRefund(input: RefundInput): Promise<RefundResult> {
data: { status: ORDER_STATUS.REFUNDING },
});
if (lockResult.count === 0) {
throw new OrderError('CONFLICT', message(locale, '订单状态已变更,请刷新后重试', 'Order status changed, refresh and retry'), 409);
throw new OrderError(
'CONFLICT',
message(locale, '订单状态已变更,请刷新后重试', 'Order status changed, refresh and retry'),
409,
);
}
try {

View File

@@ -101,7 +101,8 @@ export function getOrderDisplayState(
label: '支付成功',
color: 'text-amber-600',
icon: '!',
message: '支付已完成,但余额充值暂未完成。系统可能会自动重试,请稍后在订单列表查看;如长时间未到账请联系管理员。',
message:
'支付已完成,但余额充值暂未完成。系统可能会自动重试,请稍后在订单列表查看;如长时间未到账请联系管理员。',
};
}
}

View File

@@ -1,9 +1,4 @@
import {
ORDER_STATUS,
PAYMENT_TYPE,
PAYMENT_PREFIX,
REDIRECT_PAYMENT_TYPES,
} from './constants';
import { ORDER_STATUS, PAYMENT_TYPE, PAYMENT_PREFIX, REDIRECT_PAYMENT_TYPES } from './constants';
import type { Locale } from './locale';
export interface UserInfo {
@@ -211,7 +206,10 @@ export function getPaymentTypeLabel(type: string, locale: Locale = 'zh'): string
return locale === 'en' ? `${meta.label} (${meta.provider})` : `${meta.label}${meta.provider}`;
}
export function getPaymentDisplayInfo(type: string, locale: Locale = 'zh'): { channel: string; provider: string; sublabel?: string } {
export function getPaymentDisplayInfo(
type: string,
locale: Locale = 'zh',
): { channel: string; provider: string; sublabel?: string } {
const meta = getPaymentText(type, locale);
return { channel: meta.label, provider: meta.provider, sublabel: meta.sublabel };
}

View File

@@ -125,12 +125,7 @@ export async function subtractBalance(
}
}
export async function addBalance(
userId: number,
amount: number,
notes: string,
idempotencyKey: string,
): Promise<void> {
export async function addBalance(userId: number, amount: number, notes: string, idempotencyKey: string): Promise<void> {
const env = getEnv();
const response = await fetch(`${env.SUB2API_BASE_URL}/api/v1/admin/users/${userId}/balance`, {
method: 'POST',