import type { SystemConfigFieldMeta, SystemConfigGroupMeta } from '@dukang/shared-types'; /** 运行环境、安全与鉴权仅保留在 .env,不在 HQ 系统设置中维护 */ export const SYSTEM_CONFIG_GROUPS: SystemConfigGroupMeta[] = [ { key: 'feature', label: '功能开关' }, { key: 'sms', label: '短信' }, { key: 'wechat', label: '微信' }, { key: 'wechat_mini', label: '微信小程序配置' }, { key: 'oss', label: '对象存储 OSS' }, { key: 'app', label: '应用链接' }, { key: 'deploy', label: '发布部署' }, { key: 'winery_bank', label: '酒厂银行账户' }, ]; const G = { feature: 'feature', sms: 'sms', wechat: 'wechat', wechat_mini: 'wechat_mini', oss: 'oss', app: 'app', deploy: 'deploy', winery_bank: 'winery_bank', } as const; /** HQ 可维护字段(不含 NODE_ENV / DATABASE_URL / JWT 等基础设施项) */ export const SYSTEM_CONFIG_FIELDS: SystemConfigFieldMeta[] = [ { key: 'MOCK_SMS', label: 'Mock 短信', group: G.feature, type: 'boolean', requiresRestart: false, description: '开启后不发真实短信,验证码为随机 6 位数字,并记录在下方列表', }, { key: 'MOCK_PAY', label: 'Mock 支付', group: G.feature, type: 'boolean', requiresRestart: false, description: '关闭且已配置微信商户参数时走真实 JSAPI 支付', }, { key: 'MOCK_WECHAT', label: 'Mock 微信授权', group: G.feature, type: 'boolean', requiresRestart: false, description: '开启走 Mock OAuth/登录;关闭且已配置 WX_APP_ID/SECRET 时走真实微信', }, { key: 'MOCK_DELIVERY_AUTO', label: 'Mock 配送自动完成', group: G.feature, type: 'boolean', requiresRestart: false }, { key: 'AUTO_APPROVE_STORE', label: '门店自动审核通过', group: G.feature, type: 'boolean', requiresRestart: false }, { key: 'WECOM_AIBOT_ENABLED', label: '启用企微机器人长连接', group: G.feature, type: 'boolean', requiresRestart: false, description: '总开关。开启后连接 HQ「企微机器人」模块中已启用且配置完整的 Bot(每 Bot 同时仅 1 条长连接)', }, { key: 'ALIYUN_SMS_SIGN_NAME', label: '短信签名', group: G.sms, type: 'string', requiresRestart: false }, { key: 'ALIYUN_SMS_TEMPLATE_CODE', label: '默认短信模板', group: G.sms, type: 'string', requiresRestart: false }, { key: 'ALIYUN_SMS_TEMPLATE_CONFIRM_REDEEM', label: '核销确认模板', group: G.sms, type: 'string', requiresRestart: false }, { key: 'ALIYUN_SMS_TEMPLATE_PROXY_ORDER', label: '代下单确认模板', group: G.sms, type: 'string', requiresRestart: false }, { key: 'ALIYUN_SMS_ACCESS_KEY_ID', label: '短信 AccessKey ID', group: G.sms, type: 'password', secret: true, requiresRestart: true }, { key: 'ALIYUN_SMS_ACCESS_KEY_SECRET', label: '短信 AccessKey Secret', group: G.sms, type: 'password', secret: true, requiresRestart: true }, { key: 'WX_APP_ID', label: '服务号 AppID', group: G.wechat, type: 'string', requiresRestart: true }, { key: 'WX_APP_SECRET', label: '服务号 AppSecret', group: G.wechat, type: 'password', secret: true, requiresRestart: true }, { key: 'WX_MINI_APP_ID', label: '小程序 AppID', group: G.wechat, type: 'string', requiresRestart: true }, { key: 'WX_MINI_APP_SECRET', label: '小程序 AppSecret', group: G.wechat, type: 'password', secret: true, requiresRestart: true }, { key: 'WX_MCH_ID', label: '微信商户号', group: G.wechat, type: 'string', requiresRestart: true }, { key: 'WX_MCH_SERIAL_NO', label: '商户证书序列号', group: G.wechat, type: 'string', requiresRestart: true }, { key: 'WX_MCH_PRIVATE_KEY', label: '商户私钥 PEM', group: G.wechat, type: 'textarea', secret: true, requiresRestart: true }, { key: 'WX_API_V3_KEY', label: 'APIv3 密钥', group: G.wechat, type: 'password', secret: true, requiresRestart: true }, { key: 'WX_PLATFORM_CERT', label: '微信平台公钥证书', group: G.wechat, type: 'textarea', secret: true, requiresRestart: true }, { key: 'WX_PAY_NOTIFY_URL', label: '支付回调 URL', group: G.wechat, type: 'string', requiresRestart: false }, { key: 'MINI_HOME_BANNERS', label: '首页轮播图', group: G.wechat_mini, type: 'imageList', requiresRestart: false, description: '小程序商品首页顶部轮播,建议比例 15:8,最多 8 张;上传后需点击右上角「保存」', }, { key: 'MINI_HOME_FOOTER_URL', label: '首页底部图', group: G.wechat_mini, type: 'image', requiresRestart: false, description: '小程序商品首页底部 footer,建议比例 15:4;上传后需点击右上角「保存」', }, { key: 'OSS_ACCESS_KEY_ID', label: 'OSS AccessKey ID', group: G.oss, type: 'password', secret: true, requiresRestart: true }, { key: 'OSS_ACCESS_KEY_SECRET', label: 'OSS AccessKey Secret', group: G.oss, type: 'password', secret: true, requiresRestart: true }, { key: 'OSS_BUCKET', label: 'OSS Bucket', group: G.oss, type: 'string', requiresRestart: true }, { key: 'OSS_REGION', label: 'OSS Region', group: G.oss, type: 'string', requiresRestart: true, placeholder: 'oss-cn-hangzhou' }, { key: 'OSS_ENDPOINT', label: 'OSS Endpoint', group: G.oss, type: 'string', requiresRestart: true, description: '可选,内网 endpoint' }, { key: 'OSS_AUTHORIZATION_V4', label: 'OSS V4 签名', group: G.oss, type: 'boolean', requiresRestart: true }, { key: 'OSS_CDN_BASE', label: 'OSS 公网域名', group: G.oss, type: 'string', requiresRestart: false }, { key: 'OSS_UPLOAD_PREFIX', label: '上传前缀', group: G.oss, type: 'string', requiresRestart: false, placeholder: 'uploads' }, { key: 'OSS_UPLOAD_EXPIRE_SECONDS', label: '直传凭证有效期(秒)', group: G.oss, type: 'number', requiresRestart: false }, { key: 'OSS_MAX_UPLOAD_BYTES', label: '单文件上限(字节)', group: G.oss, type: 'number', requiresRestart: false }, { key: 'USER_H5_URL', label: 'C 端 H5 落地页', group: G.app, type: 'string', requiresRestart: false }, { key: 'TENCENT_LBS_KEY', label: '腾讯位置服务 Key(须开 WebServiceAPI;白名单含 apis.map.qq.com)', group: G.app, type: 'password', secret: true, requiresRestart: false }, { key: 'DEPLOY_WEBHOOK_URL', label: '发布 Webhook URL', group: G.deploy, type: 'string', requiresRestart: false }, { key: 'DEPLOY_WEBHOOK_SECRET', label: '发布 Webhook Secret', group: G.deploy, type: 'password', secret: true, requiresRestart: false }, { key: 'WINERY_BANK_ACCOUNT_NAME', label: '户名', group: G.winery_bank, type: 'string', requiresRestart: false, description: '酒厂收款账户户名,打款时对照', }, { key: 'WINERY_BANK_NAME', label: '开户银行', group: G.winery_bank, type: 'string', requiresRestart: false, }, { key: 'WINERY_BANK_BRANCH', label: '开户支行', group: G.winery_bank, type: 'string', requiresRestart: false, placeholder: '可选', }, { key: 'WINERY_BANK_ACCOUNT_NO', label: '银行账号', group: G.winery_bank, type: 'string', requiresRestart: false, }, ]; /** 已从 HQ 配置移除、仅保留在 .env 的键(启动时从 DB 清理) */ export const SYSTEM_CONFIG_RETIRED_KEYS = [ 'NODE_ENV', 'DATABASE_URL', 'REDIS_URL', 'PORT', 'TRUST_PROXY', 'JWT_SECRET', 'JWT_EXPIRES_IN', 'MOCK_SMS_CODE', 'WX_AUTHORIZE', 'WECHAT_AUTH_ENABLED', 'WECHAT_PAY_ENABLED', 'OSS_ENABLED', 'WECOM_AIBOT_BOT_ID', 'WECOM_AIBOT_SECRET', 'WECOM_AIBOT_WELCOME', 'WECOM_BOT_CS_ENABLED', 'WECOM_BOT_CS_BOT_ID', 'WECOM_BOT_CS_SECRET', 'WECOM_BOT_CS_WELCOME', 'WECOM_BOT_CS_PERMISSIONS', 'WECOM_BOT_TECH_ENABLED', 'WECOM_BOT_TECH_BOT_ID', 'WECOM_BOT_TECH_SECRET', 'WECOM_BOT_TECH_WELCOME', 'WECOM_BOT_TECH_PERMISSIONS', 'WECOM_BOT_TEAM_ENABLED', 'WECOM_BOT_TEAM_BOT_ID', 'WECOM_BOT_TEAM_SECRET', 'WECOM_BOT_TEAM_WELCOME', 'WECOM_BOT_TEAM_PERMISSIONS', ] as const; export const SYSTEM_CONFIG_KEY_SET = new Set(SYSTEM_CONFIG_FIELDS.map((f) => f.key)); export function getSystemConfigField(key: string): SystemConfigFieldMeta | undefined { return SYSTEM_CONFIG_FIELDS.find((f) => f.key === key); }