ops-console v1.0.2 (versionCode 8) 源码入库
This commit is contained in:
122
lib/screens/admin/admin_hub_page.dart
Normal file
122
lib/screens/admin/admin_hub_page.dart
Normal file
@@ -0,0 +1,122 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../../providers/auth_provider.dart';
|
||||
import '../../utils/i10n.dart';
|
||||
import '../../utils/permissions.dart';
|
||||
import '../../utils/responsive.dart';
|
||||
|
||||
/// 管理中心页(底部导航第 4 个 tab):各管理模块入口。
|
||||
///
|
||||
/// 模块可见性由 [SessionPermissions] 统一驱动,与 [router.dart] 的路由可达性
|
||||
/// 保持一致:
|
||||
/// - 用户管理:所有已登录账号可见(数据范围由后端按会话权限收敛);
|
||||
/// - 渠道商管理:管理员 + 渠道商可见,代理商不可见;
|
||||
/// - 其余模块(设备/激活码/公司介绍/滚动字幕)对所有账号可见。
|
||||
class AdminHubPage extends ConsumerWidget {
|
||||
const AdminHubPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final t = AppLocalizations.of(context);
|
||||
// 注:按需求「设备分组」整合进设备管理功能(设备详情/设备列表内可改分组),
|
||||
// 「应用管理」移除以简化管理页。故网格不再单列这两项。
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
final user = ref.watch(authProvider).user;
|
||||
// 菜单可见性与路由可达性由同一套 SessionPermissions 谓词驱动:
|
||||
// - 用户管理:所有已登录账号(各角色看自己范围内用户);
|
||||
// - 渠道商管理:管理员 + 渠道商(代理商不可见,路由层亦会拦截其深链)。
|
||||
final showUserManagement = SessionPermissions.canViewUserManagement(user);
|
||||
final showChannelManagement =
|
||||
SessionPermissions.canViewChannelManagement(user);
|
||||
|
||||
final items = [
|
||||
_MenuItem(
|
||||
title: t.deviceManagement,
|
||||
icon: Icons.devices_outlined,
|
||||
color: scheme.primary,
|
||||
route: '/admin/device',
|
||||
),
|
||||
_MenuItem(
|
||||
title: t.activationCode,
|
||||
icon: Icons.vpn_key_outlined,
|
||||
color: Colors.amber,
|
||||
route: '/admin/activation',
|
||||
),
|
||||
if (showUserManagement)
|
||||
_MenuItem(
|
||||
title: t.userManagement,
|
||||
icon: Icons.people_outlined,
|
||||
color: scheme.outline,
|
||||
route: '/admin/sys/user',
|
||||
),
|
||||
_MenuItem(
|
||||
title: t.companyIntro,
|
||||
icon: Icons.business_outlined,
|
||||
color: Colors.teal,
|
||||
route: '/admin/intro/store-list',
|
||||
),
|
||||
_MenuItem(
|
||||
title: t.marqueeManagement,
|
||||
icon: Icons.subtitles_outlined,
|
||||
color: Colors.deepPurple,
|
||||
route: '/admin/marquee',
|
||||
),
|
||||
if (showChannelManagement)
|
||||
_MenuItem(
|
||||
title: t.channelManagement,
|
||||
icon: Icons.account_tree_outlined,
|
||||
color: Colors.blue,
|
||||
route: '/admin/channel',
|
||||
),
|
||||
];
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(t.admin)),
|
||||
body: GridView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: context.responsive.gridCount(minTileWidth: 300),
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
childAspectRatio: 1.2,
|
||||
),
|
||||
itemCount: items.length,
|
||||
itemBuilder: (context, index) {
|
||||
final item = items[index];
|
||||
return Card(
|
||||
child: InkWell(
|
||||
onTap: () => context.push(item.route),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(item.icon, size: 40, color: item.color),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
item.title,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MenuItem {
|
||||
const _MenuItem({
|
||||
required this.title,
|
||||
required this.icon,
|
||||
required this.color,
|
||||
required this.route,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
final String route;
|
||||
}
|
||||
Reference in New Issue
Block a user