fix:购买商品饰品

This commit is contained in:
jingyun committed 2026-09-08 14:27:32 +08:00
1 parent 1f9a8b67a2
commit e29ed0a2c8
5 files changed
+88 -4

No files matched your search

@@ -14,6 +14,7 @@ class MallEntryController {
Future<MallEntryOpenResult> open(
BuildContext context, {
MallEntryRequest request = MallEntryRequest.home,
MallTabConfig? initialConfig,
}) async {
if (_opening) return MallEntryOpenResult.alreadyOpening;
@@ -42,6 +43,7 @@ class MallEntryController {
final uri = config.attributedUri(
clickId: clickId,
isDark: Theme.of(context).brightness == Brightness.dark,
entry: request,
);
if (uri == null) return MallEntryOpenResult.unavailable;
// The bottom mall entry is always resident. Server open-mode metadata is
@@ -11,6 +11,33 @@ import '../../../common/network/dio_provider.dart';
/// 金值商城广告位的公共契约;商城是否展示完全由服务端配置决定。
const mallSourceApp = 'jinzhi';
/// The native entry that opened the resident mall. H5 uses this context to
/// choose the appropriate landing flow while sharing the same WebView host.
class MallEntryRequest {
const MallEntryRequest({
required this.sourceEntry,
required this.hookType,
this.entryScene,
this.entryMetal,
});
static const home = MallEntryRequest(
sourceEntry: 'mall_tab',
hookType: 'mall_tab',
);
static const quoteRetailGold = MallEntryRequest(
sourceEntry: 'market_quote',
hookType: 'quote_cta',
entryScene: 'retail',
entryMetal: 'au',
);
final String sourceEntry;
final String hookType;
final String? entryScene;
final String? entryMetal;
}
class MallTabConfig {
const MallTabConfig({
required this.enabled,
@@ -49,7 +76,11 @@ class MallTabConfig {
Uri? get initialUri => attributedUri(clickId: '');
Uri? attributedUri({required String clickId, bool isDark = false}) {
Uri? attributedUri({
required String clickId,
bool isDark = false,
MallEntryRequest entry = MallEntryRequest.home,
}) {
final uri = Uri.tryParse(url.trim());
if (!_isAllowed(uri)) return null;
return uri!.replace(
@@ -59,9 +90,13 @@ class MallTabConfig {
? uri.queryParameters['from']!
: mallSourceApp,
'source_app': mallSourceApp,
'source_entry': 'mall_tab',
'source_entry': entry.sourceEntry,
'placement': 'mall_tab',
'hook_type': 'mall_tab',
'hook_type': entry.hookType,
if (entry.entryScene?.isNotEmpty == true)
'entry_scene': entry.entryScene!,
if (entry.entryMetal?.isNotEmpty == true)
'entry_metal': entry.entryMetal!,
'target_app': 'mall',
if (adId.isNotEmpty) 'ad_id': adId,
if (trackingId.isNotEmpty) 'tracking_id': trackingId,
@@ -5,6 +5,8 @@ import 'package:shadcn_ui/shadcn_ui.dart';
import '../../../common/domain/metal_type.dart';
import '../../../common/domain/money.dart';
import '../../../common/widgets/adaptive.dart';
import '../../mall/application/mall_entry_controller.dart';
import '../../mall/application/mall_tab_config.dart';
import '../application/exchange_calculator_controller.dart';
import '../application/market_controller.dart';
import '../data/market_models.dart';
@@ -93,6 +95,28 @@ class MarketPage extends ConsumerWidget {
),
),
const SizedBox(height: 12),
FilledButton.icon(
key: const ValueKey('market-mall-retail-cta'),
onPressed: () async {
final result = await ref
.read(mallEntryControllerProvider)
.open(
context,
request: MallEntryRequest.quoteRetailGold,
);
if (!context.mounted ||
(result != MallEntryOpenResult.unavailable &&
result != MallEntryOpenResult.failed)) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('商城暂时无法打开,请稍后重试')),
);
},
icon: const Icon(Icons.shopping_bag_outlined),
label: const Text('买商城饰品(全款)'),
),
const SizedBox(height: 12),
_Card(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,