feat(mobile-next): 建立 v2 Token 唯一入口、内网地址与功能开关

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
编码工程师
2026-08-20 02:30:09 +08:00
co-authored by Cursor multica-agent
parent 45d91684bc
commit d787c0a477
11 changed files with 384 additions and 81 deletions
+128
View File
@@ -0,0 +1,128 @@
import 'package:flutter/material.dart';
import '../brand/app_tokens.dart';
class CompanyLoadingView extends StatelessWidget {
const CompanyLoadingView({super.key, this.label = '正在加载'});
final String label;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(strokeWidth: 2, color: AppColors.primary),
),
const SizedBox(height: AppGap.x3),
Text(label, style: const TextStyle(fontSize: AppFont.sub, color: AppColors.textSecondary)),
],
),
);
}
}
class CompanyEmptyView extends StatelessWidget {
const CompanyEmptyView({
super.key,
required this.icon,
required this.title,
required this.subtitle,
});
final IconData icon;
final String title;
final String subtitle;
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: AppGap.x8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 64, color: AppColors.divider),
const SizedBox(height: AppGap.x4),
Text(title, style: const TextStyle(fontSize: AppFont.body, color: AppColors.textPrimary)),
const SizedBox(height: AppGap.x1),
Text(
subtitle,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: AppFont.sub, color: AppColors.textSecondary),
),
],
),
),
);
}
}
class CompanyFailView extends StatelessWidget {
const CompanyFailView({super.key, required this.onRetry, this.title = '加载失败'});
final VoidCallback onRetry;
final String title;
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: AppGap.x8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.chat_bubble_outline, size: 64, color: AppColors.divider),
const SizedBox(height: AppGap.x4),
Text(title, style: const TextStyle(fontSize: AppFont.body, color: AppColors.textPrimary)),
const SizedBox(height: AppGap.x1),
const Text(
'检查一下网络,再点重试',
style: TextStyle(fontSize: AppFont.sub, color: AppColors.textSecondary),
),
const SizedBox(height: AppGap.x4),
OutlinedButton(
onPressed: onRetry,
style: OutlinedButton.styleFrom(
minimumSize: const Size(96, 36),
side: const BorderSide(color: AppColors.textSecondary, width: 0.5),
foregroundColor: AppColors.textPrimary,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppRadius.control)),
),
child: const Text('重试', style: TextStyle(fontSize: AppFont.body)),
),
],
),
),
);
}
}
class CompanyOfflineBanner extends StatelessWidget {
const CompanyOfflineBanner({super.key});
@override
Widget build(BuildContext context) {
return Container(
height: 36,
color: AppColors.bannerBg,
padding: const EdgeInsets.symmetric(horizontal: AppGap.x4),
child: const Row(
children: [
Icon(Icons.info_outline, size: 16, color: Colors.white),
SizedBox(width: AppGap.x2),
Expanded(
child: Text(
'当前网络不可用,请检查网络连接',
style: TextStyle(fontSize: AppFont.sub, color: Colors.white),
),
),
],
),
);
}
}