webadmin系统设置

This commit is contained in:
2026-07-12 22:52:40 +08:00
parent 236a2a87a5
commit 1bd152073a
41 changed files with 1413 additions and 151 deletions
+55 -18
View File
@@ -1,21 +1,18 @@
export interface AppConfig {
mockSms: boolean;
mockSmsCode: string;
mockPay: boolean;
mockDeliveryAuto: boolean;
autoApproveStore: boolean;
/** preV1 Mock 微信授权登录:点击授权按钮走 Mock 流程直接登录,不接真实微信 */
/** Mock 微信 OAuth/登录/绑定;关闭且凭证齐全时走真实微信 */
mockWechat: boolean;
/** 登录后是否走微信 SDK OAuth 授权(WX_AUTHORIZE=false 时三端跳过授权流程 */
/** 前端是否展示微信授权入口(由 mockWechat 或真实凭证推导 */
wxAuthorize: boolean;
wechatAuthEnabled: boolean;
/** 是否可走真实 JSAPI 支付(由 MOCK_PAY 与商户凭证推导) */
wechatPayEnabled: boolean;
wxAppId: string;
/** 小程序 AppIDcode2session 与小程序支付;未配置时回退 wxAppId) */
wxMiniAppId: string;
wxMchId: string;
/** OSS_ENABLED=true 且 AccessKey/Bucket 齐全时走阿里云直传 */
ossEnabled: boolean;
aliyunSmsSignName: string;
aliyunSmsTemplateCode: string;
/** 核销确认短信模板(REDEEM_PHONE_CONFIRM);env: ALIYUN_SMS_TEMPLATE_CONFIRM_REDEEM */
@@ -48,25 +45,60 @@ export const BRAND_LOGO_MARK_URL = `${BRAND_LOGO_OSS_BASE}logo2.png`;
/** 总部客服电话(C 端联系客服) */
export const CUSTOMER_SERVICE_PHONE = '400-888-1234';
export function loadAppConfig(env?: Record<string, string | undefined>): AppConfig {
const e =
function readEnv(env?: Record<string, string | undefined>) {
return (
env ??
(globalThis as { process?: { env: Record<string, string | undefined> } }).process?.env ??
{};
return {
mockSms: e.MOCK_SMS !== 'false',
mockSmsCode: e.MOCK_SMS_CODE ?? '123456',
mockPay: e.MOCK_PAY !== 'false',
{}
);
}
export function hasWechatAuthCredentials(env?: Record<string, string | undefined>): boolean {
const e = readEnv(env);
return !!(e.WX_APP_ID?.trim() && e.WX_APP_SECRET?.trim());
}
export function hasWechatPayCredentials(env?: Record<string, string | undefined>): boolean {
const e = readEnv(env);
return !!(
e.WX_APP_ID?.trim() &&
e.WX_MCH_ID?.trim() &&
e.WX_MCH_SERIAL_NO?.trim() &&
e.WX_MCH_PRIVATE_KEY?.trim() &&
e.WX_API_V3_KEY?.trim()
);
}
/** 是否应使用真实微信 API(授权或支付任一需要) */
export function needsRealWechatApi(cfg: Pick<AppConfig, 'mockWechat' | 'mockPay'>, env?: Record<string, string | undefined>): boolean {
return (
(!cfg.mockWechat && hasWechatAuthCredentials(env)) ||
(!cfg.mockPay && hasWechatPayCredentials(env))
);
}
export function resolveWxAuthorize(cfg: Pick<AppConfig, 'mockWechat'>, env?: Record<string, string | undefined>): boolean {
return cfg.mockWechat || hasWechatAuthCredentials(env);
}
export function resolveWechatPayEnabled(cfg: Pick<AppConfig, 'mockPay'>, env?: Record<string, string | undefined>): boolean {
return !cfg.mockPay && hasWechatPayCredentials(env);
}
export function loadAppConfig(env?: Record<string, string | undefined>): AppConfig {
const e = readEnv(env);
const mockSms = e.MOCK_SMS !== 'false';
const mockPay = e.MOCK_PAY !== 'false';
const mockWechat = e.MOCK_WECHAT === 'true';
const base = {
mockSms,
mockPay,
mockDeliveryAuto: e.MOCK_DELIVERY_AUTO !== 'false',
autoApproveStore: e.AUTO_APPROVE_STORE !== 'false',
mockWechat: e.MOCK_WECHAT === 'true',
wxAuthorize: e.WX_AUTHORIZE !== 'false',
wechatAuthEnabled: e.WECHAT_AUTH_ENABLED === 'true',
wechatPayEnabled: e.WECHAT_PAY_ENABLED === 'true' || e.MOCK_PAY === 'false',
mockWechat,
wxAppId: e.WX_APP_ID ?? '',
wxMiniAppId: e.WX_MINI_APP_ID ?? e.WX_APP_ID ?? '',
wxMchId: e.WX_MCH_ID ?? '',
ossEnabled: e.OSS_ENABLED === 'true',
aliyunSmsSignName: e.ALIYUN_SMS_SIGN_NAME ?? '',
aliyunSmsTemplateCode: e.ALIYUN_SMS_TEMPLATE_CODE ?? '',
aliyunSmsRedeemConfirmTemplateCode:
@@ -82,4 +114,9 @@ export function loadAppConfig(env?: Record<string, string | undefined>): AppConf
tencentLbsKey: e.TENCENT_LBS_KEY ?? '',
userH5Url: (e.USER_H5_URL || DEFAULT_USER_H5_URL).replace(/\/$/, ''),
};
return {
...base,
wxAuthorize: resolveWxAuthorize(base, e),
wechatPayEnabled: resolveWechatPayEnabled(base, e),
};
}
@@ -13,6 +13,7 @@ export const HQ_PERMISSION_CATALOG = [
{ key: 'logs', label: '日志' },
{ key: 'hq_permissions', label: '权限分配' },
{ key: 'hq_accounts', label: 'HQ 账户' },
{ key: 'system_settings', label: '系统设置' },
] as const;
export type HqPermissionKey = (typeof HQ_PERMISSION_CATALOG)[number]['key'];
+1
View File
@@ -18,3 +18,4 @@ export * from './partner';
export * from './shop';
export * from './city-partner';
export * from './city-warehouse';
export * from './system-config';
@@ -0,0 +1,53 @@
export type SystemConfigFieldType = 'string' | 'boolean' | 'number' | 'password' | 'textarea';
export interface SystemConfigFieldMeta {
key: string;
label: string;
group: string;
type: SystemConfigFieldType;
secret?: boolean;
requiresRestart: boolean;
description?: string;
placeholder?: string;
}
export interface SystemConfigGroupMeta {
key: string;
label: string;
}
export interface SystemConfigFormField extends SystemConfigFieldMeta {
value: string;
/** 密钥类字段:是否已配置(不返回明文) */
configured?: boolean;
}
export interface SystemConfigFormResponse {
groups: SystemConfigGroupMeta[];
fields: SystemConfigFieldMeta[];
values: Record<string, string>;
configuredSecrets: string[];
envFilePath: string;
updatedAt: string | null;
/** Mock 短信最近生成的验证码(仅 HQ 系统设置展示) */
mockSmsCodes: MockSmsCodeItem[];
}
export interface MockSmsCodeItem {
id: string;
phone: string;
scene: string;
code: string;
createdAt: string;
}
export interface SystemConfigUpdateRequest {
values: Record<string, string>;
}
export interface SystemConfigSyncResult {
envFilePath: string;
writtenKeys: number;
requiresRestartKeys: string[];
message: string;
}
+2 -2
View File
@@ -29,11 +29,11 @@ export type ClientRuntimeConfig = {
wechatPayEnabled: boolean;
mockSms: boolean;
mockWechat?: boolean;
/** false 时三端跳过微信 SDK OAuth 授权 */
/** false 时三端跳过微信 SDK OAuth 授权(由 MOCK_WECHAT 或真实凭证推导) */
wxAuthorize?: boolean;
};
/** 是否启用登录后微信 SDK 授权(默认 true,仅 WX_AUTHORIZE=false 时关闭) */
/** 是否展示微信授权入口 */
export function isWxAuthorizeEnabled(config?: Pick<ClientRuntimeConfig, 'wxAuthorize'> | null): boolean {
return config?.wxAuthorize !== false;
}