feat(mini-user): configurable WeChat mini share scenes in system settings

Add HQ group for default and per-page share title/desc/image; expose via client-config and wire all mini-user share entry points.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-06 15:45:57 +08:00
parent a2abbb6169
commit 83b1b0e5f6
12 changed files with 526 additions and 106 deletions
+91
View File
@@ -104,6 +104,97 @@ export function resolveMockSmsFixedCode(env?: Record<string, string | undefined>
return code || MOCK_SMS_FIXED_CODE;
}
/** 小程序 / H5 默认分享文案与引导(系统设置「小程序分享配置」可覆盖) */
export const DEFAULT_SHARE_TITLE = '你吃饭,我买单';
export const DEFAULT_SHARE_DESC = '杜康好客 · 买美酒,享好礼,全城门店可用';
export const DEFAULT_SHARE_HINT = '请点击右上角 ··· 分享给好友';
export const DEFAULT_SHARE_STORES_TITLE = '杜康好客门店';
export const DEFAULT_SHARE_BENEFIT_TITLE = '好客权益 · 杜康好客';
export const DEFAULT_SHARE_MINE_TITLE = '杜康好客 · 我的';
/** 订单详情分享标题模板,可用 {productName} */
export const DEFAULT_SHARE_ORDER_TITLE = '我买了{productName} · 杜康好客';
export type MiniShareSceneConfig = {
title: string;
desc: string;
imageUrl: string;
};
/** 各场景分享文案/图(空字符串表示该字段走动态内容或默认分享) */
export type MiniShareRuntime = {
hint: string;
default: MiniShareSceneConfig;
home: MiniShareSceneConfig;
stores: MiniShareSceneConfig;
storeDetail: MiniShareSceneConfig;
benefit: MiniShareSceneConfig;
mine: MiniShareSceneConfig;
productDetail: MiniShareSceneConfig;
orderDetail: MiniShareSceneConfig;
};
function pickShareScene(
e: Record<string, string | undefined>,
prefix: string,
fallback: Partial<MiniShareSceneConfig> = {},
): MiniShareSceneConfig {
return {
title: (e[`${prefix}_TITLE`] || '').trim() || fallback.title || '',
desc: (e[`${prefix}_DESC`] || '').trim() || fallback.desc || '',
imageUrl: (e[`${prefix}_IMAGE_URL`] || '').trim() || fallback.imageUrl || '',
};
}
/** 从 env / 系统设置解析小程序分享配置 */
export function resolveMiniShareRuntime(
env?: Record<string, string | undefined>,
): MiniShareRuntime {
const e = readEnv(env);
const brand = resolveClientBrandRuntime(e);
const defaults: MiniShareSceneConfig = {
title: (e.SHARE_DEFAULT_TITLE || '').trim() || DEFAULT_SHARE_TITLE,
desc: (e.SHARE_DEFAULT_DESC || '').trim() || DEFAULT_SHARE_DESC,
imageUrl: (e.SHARE_DEFAULT_IMAGE_URL || '').trim() || brand.brandLogoUrl,
};
return {
hint: (e.SHARE_HINT || '').trim() || DEFAULT_SHARE_HINT,
default: defaults,
home: pickShareScene(e, 'SHARE_HOME', {
title: defaults.title,
desc: defaults.desc,
}),
stores: pickShareScene(e, 'SHARE_STORES', {
title: DEFAULT_SHARE_STORES_TITLE,
desc: defaults.desc,
}),
storeDetail: pickShareScene(e, 'SHARE_STORE_DETAIL'),
benefit: pickShareScene(e, 'SHARE_BENEFIT', {
title: DEFAULT_SHARE_BENEFIT_TITLE,
desc: defaults.desc,
}),
mine: pickShareScene(e, 'SHARE_MINE', {
title: DEFAULT_SHARE_MINE_TITLE,
desc: defaults.desc,
}),
productDetail: pickShareScene(e, 'SHARE_PRODUCT_DETAIL'),
orderDetail: pickShareScene(e, 'SHARE_ORDER_DETAIL', {
title: DEFAULT_SHARE_ORDER_TITLE,
desc: defaults.desc,
}),
};
}
/** 订单等标题模板:替换 {productName} 等占位符 */
export function applyShareTitleTemplate(
template: string,
vars: Record<string, string | undefined | null>,
): string {
return template.replace(/\{(\w+)\}/g, (_, key: string) => {
const v = vars[key];
return v != null && String(v).trim() ? String(v).trim() : '';
}).replace(/\s{2,}/g, ' ').trim();
}
function readEnv(env?: Record<string, string | undefined>) {
return (
env ??
+4
View File
@@ -1,3 +1,5 @@
import type { MiniShareRuntime } from './config';
/** 微信 JSSDK 初始化参数(后端签名下发) */
export interface WechatJssdkConfig {
appId: string;
@@ -62,6 +64,8 @@ export type ClientRuntimeConfig = {
qualificationDisclosureUrl?: string;
/** 总部客服电话 */
customerServicePhone?: string;
/** 小程序各场景分享文案/图 */
share?: MiniShareRuntime;
};
/** 是否展示微信授权入口 */