272eca04ce
购买/支付(Phase B): - 新 SegSwitch 段控 widget(镜像 .segswitch 原子) - 购买页重构:顶部支付渠道 switch(默认 USDT→加密货币 / 人民币→支付宝),套餐价随渠道分币种显示,删底部弹窗选方式;点购买直达支付页 - 支付页加订单信息卡(套餐/渠道/金额按币种) - models:PayChannel + PayCatalogItem.priceUsdtMicro/priceLabel(ch)/perMonthLabel(ch) 订单(P0,全新): - payment_api.listOrders() + orders_provider(列表 + 详情 family) - OrdersScreen 列表→详情(状态 pill / 可复制订单号 / 继续支付·重新购买) - 导航:NavView.orders + desktop_shell 分支 + account 入口 配套: - l10n +19 getter(支付渠道 4 + 订单 15)×6 语言,l10n 闸绿 - 图标单源迁移 lucide_icons_flutter + pangolin_icons.dart(codegen) - 联系渠道订正(Telegram/邮件 support@yanmeiai.com/官网) + 前端去广告&时长 - 测试:购买 switch 分币种 + 订单列表/空态/详情 + 假 API listOrders;golden 重录 - flutter analyze 0 error,flutter test 226 全绿 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
81 lines
2.6 KiB
Dart
81 lines
2.6 KiB
Dart
// seg_switch.dart — 分段开关(镜像 design/prototype atoms .segswitch)。
|
|
// 一排等宽选项,每项 leading 图标 + 文字;选中态 surface 底 + 柔和阴影 + fg1,
|
|
// 未选 fg2;容器 bg-subtle + border + full 圆角。渠道/币种/主题等二选一场景通用。
|
|
import 'package:flutter/material.dart';
|
|
import '../pangolin_theme.dart';
|
|
|
|
/// 单个分段项:图标 + 文案。
|
|
typedef SegOption = ({IconData icon, String label});
|
|
|
|
class SegSwitch extends StatelessWidget {
|
|
const SegSwitch({
|
|
super.key,
|
|
required this.options,
|
|
required this.selectedIndex,
|
|
required this.onChanged,
|
|
});
|
|
|
|
final List<SegOption> options;
|
|
final int selectedIndex;
|
|
final ValueChanged<int> onChanged;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final c = context.pangolin;
|
|
return Container(
|
|
// .segswitch:bg-subtle + border + full 圆角 + space-1 内边距/间隙
|
|
padding: const EdgeInsets.all(4),
|
|
decoration: BoxDecoration(
|
|
color: c.bgSubtle,
|
|
border: Border.all(color: c.border),
|
|
borderRadius: BorderRadius.circular(PangolinRadius.full),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
for (var i = 0; i < options.length; i++) ...[
|
|
if (i > 0) const SizedBox(width: 4),
|
|
Expanded(child: _opt(c, i, options[i])),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _opt(PangolinScheme c, int i, SegOption o) {
|
|
final active = i == selectedIndex;
|
|
return GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: active ? null : () => onChanged(i),
|
|
child: AnimatedContainer(
|
|
duration: const Duration(milliseconds: 140),
|
|
curve: Curves.easeOut,
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
decoration: BoxDecoration(
|
|
// .segswitch-opt.is-active:surface 底 + shadow-sm;未选透明
|
|
color: active ? c.surface : Colors.transparent,
|
|
borderRadius: BorderRadius.circular(PangolinRadius.full),
|
|
boxShadow: active ? PangolinShadow.sm : null,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(o.icon, size: 16, color: active ? c.fg1 : c.fg2),
|
|
const SizedBox(width: 8),
|
|
Flexible(
|
|
child: Text(
|
|
o.label,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: PangolinText.sm.copyWith(
|
|
color: active ? c.fg1 : c.fg2,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|