v3.5.3版本更新1
CI / verify (pull_request) Has been cancelled

This commit is contained in:
2026-08-20 18:54:15 +08:00
parent ee493823bf
commit fc2e5b65de
65 changed files with 2297 additions and 875 deletions
+8 -1
View File
@@ -4,6 +4,7 @@ import { forceReloadAfterAccountMerge } from './auth-nav';
import { resetStoresSessionBootstrap } from './stores-session';
import { resetHomeCatalogBootstrap } from './home-catalog-session';
import { reportClientValidationError } from './client-error';
import { showFloatingToast } from './floating-toast';
function resolveApiBase(): string {
const origin =
@@ -126,7 +127,13 @@ export async function request<T = unknown>(path: string, options: ReqOptions = {
}
export function toast(title: string, icon: 'success' | 'error' | 'none' = 'none') {
Taro.showToast({ title, icon, duration: 1800 });
const text = title.trim();
if (!text) return;
if (icon !== 'success' && showFloatingToast(text)) {
void Taro.hideToast();
return;
}
Taro.showToast({ title: text, icon, duration: 1800 });
}
export type SessionPayload = {
+18
View File
@@ -0,0 +1,18 @@
type FloatingToastListener = (message: string) => void;
const listeners = new Set<FloatingToastListener>();
export function registerFloatingToastListener(fn: FloatingToastListener) {
listeners.add(fn);
return () => {
listeners.delete(fn);
};
}
/** 已有页面宿主时返回 true,否则调用方应回退到原生 toast */
export function showFloatingToast(message: string): boolean {
const text = message.trim();
if (!text || listeners.size === 0) return false;
listeners.forEach((fn) => fn(text));
return true;
}
+21 -2
View File
@@ -1,7 +1,26 @@
/** 金额展示(不依赖 Intl / toLocaleString,兼容微信小程序) */
export function toMoneyNumber(amount: unknown): number {
if (typeof amount === 'number') return Number.isFinite(amount) ? amount : 0;
if (typeof amount === 'string' && amount.trim()) {
const n = Number(amount);
return Number.isFinite(n) ? n : 0;
}
if (amount && typeof amount === 'object') {
const o = amount as { toNumber?: () => number; toString?: () => string };
if (typeof o.toNumber === 'function') {
const n = Number(o.toNumber());
if (Number.isFinite(n)) return n;
}
if (typeof o.toString === 'function' && o.toString !== Object.prototype.toString) {
const n = Number(o.toString());
if (Number.isFinite(n)) return n;
}
}
return 0;
}
export function formatMoney(amount: number | string): string {
const n = typeof amount === 'number' ? amount : Number(amount);
if (!Number.isFinite(n)) return '0.00';
const n = toMoneyNumber(amount);
const fixed = n.toFixed(2);
const [intPart, dec] = fixed.split('.');
const withComma = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+28 -16
View File
@@ -82,8 +82,10 @@ function sceneConfig(scene?: ShareScene): MiniShareSceneConfig {
}
/**
* 组装页面分享:场景配置优先;空字段用 dynamic → 默认分享
* orderDetail 标题支持 {productName}。
* 组装页面分享。
* - productDetail / storeDetailtitle 与 imageUrl 固定用业务字段(不被 HQ 场景配置覆盖)
* - 其它场景:场景配置优先;空字段用 dynamic → 默认分享
* - orderDetail 标题支持 {productName}
*/
export function buildSceneSharePayload(
scene: ShareScene,
@@ -98,23 +100,33 @@ export function buildSceneSharePayload(
): PageSharePayload {
const def = getShareRuntimeSync().default;
const sc = sceneConfig(scene);
let title = (sc.title || '').trim();
if (title && options?.titleVars) {
const vars = options.titleVars;
const missingRequired = Object.entries(vars).some(
([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()),
);
title = missingRequired ? '' : applyShareTitleTemplate(title, vars);
}
if (!title) {
const preferEntity = scene === 'productDetail' || scene === 'storeDetail';
let title: string;
if (preferEntity) {
title = (options?.dynamicTitle || '').trim() || def.title;
} else {
title = (sc.title || '').trim();
if (title && options?.titleVars) {
const vars = options.titleVars;
const missingRequired = Object.entries(vars).some(
([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()),
);
title = missingRequired ? '' : applyShareTitleTemplate(title, vars);
}
if (!title) {
title = (options?.dynamicTitle || '').trim() || def.title;
}
}
const desc = (sc.desc || '').trim() || (options?.dynamicDesc || '').trim() || def.desc;
const imgUrl =
(sc.imageUrl || '').trim() ||
(options?.dynamicImageUrl || '').trim() ||
def.imageUrl ||
getDefaultShareImageUrl();
const imgUrl = preferEntity
? (options?.dynamicImageUrl || '').trim() || def.imageUrl || getDefaultShareImageUrl()
: (sc.imageUrl || '').trim() ||
(options?.dynamicImageUrl || '').trim() ||
def.imageUrl ||
getDefaultShareImageUrl();
return {
title,
desc,
+24 -14
View File
@@ -97,23 +97,33 @@ export function buildSceneSharePayload(
): PageSharePayload {
const def = getShareRuntimeSync().default;
const sc = sceneConfig(scene);
let title = (sc.title || '').trim();
if (title && options?.titleVars) {
const vars = options.titleVars;
const missingRequired = Object.entries(vars).some(
([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()),
);
title = missingRequired ? '' : applyShareTitleTemplate(title, vars);
}
if (!title) {
const preferEntity = scene === 'productDetail' || scene === 'storeDetail';
let title: string;
if (preferEntity) {
title = (options?.dynamicTitle || '').trim() || def.title;
} else {
title = (sc.title || '').trim();
if (title && options?.titleVars) {
const vars = options.titleVars;
const missingRequired = Object.entries(vars).some(
([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()),
);
title = missingRequired ? '' : applyShareTitleTemplate(title, vars);
}
if (!title) {
title = (options?.dynamicTitle || '').trim() || def.title;
}
}
const desc = (sc.desc || '').trim() || (options?.dynamicDesc || '').trim() || def.desc;
const imgUrl =
(sc.imageUrl || '').trim() ||
(options?.dynamicImageUrl || '').trim() ||
def.imageUrl ||
getDefaultShareImageUrl();
const imgUrl = preferEntity
? (options?.dynamicImageUrl || '').trim() || def.imageUrl || getDefaultShareImageUrl()
: (sc.imageUrl || '').trim() ||
(options?.dynamicImageUrl || '').trim() ||
def.imageUrl ||
getDefaultShareImageUrl();
return {
title,
desc,