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
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'app_tokens.dart';
ThemeData buildCompanyTheme() {
return ThemeData(
useMaterial3: true,
fontFamily: 'Noto Sans SC',
primaryColor: AppColors.primary,
scaffoldBackgroundColor: AppColors.pageBg,
colorScheme: const ColorScheme.light(
primary: AppColors.primary,
onPrimary: AppColors.pageBg,
error: AppColors.danger,
surface: AppColors.pageBg,
onSurface: AppColors.textPrimary,
),
appBarTheme: const AppBarTheme(
backgroundColor: AppColors.pageBg,
foregroundColor: AppColors.textPrimary,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true,
titleTextStyle: TextStyle(
color: AppColors.textPrimary,
fontSize: AppFont.title,
fontWeight: FontWeight.w600,
),
),
dividerTheme: const DividerThemeData(
color: AppColors.divider,
thickness: 0.5,
space: 0,
),
splashFactory: NoSplash.splashFactory,
);
}
@@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
/// 双端唯一视觉 Token。取值只来自 B-91 v2 规范第 2 节,禁止在页面内硬编码色值/字号/间距/圆角。
///
/// 官方 widget 通过 [openim_common] `Styles` 映射到本表(见 apply_official_styles.dart),
/// 公司自建页面直接引用本文件。本阶段保留 OpenIM 标识,不做「畅联」换标。
class AppColors {
AppColors._();
static const Color primary = Color(0xFF3B87F5);
static const Color primaryActive = Color(0xFFEBF3FE);
static const Color primaryPressed = Color(0xFF2E75E0);
static const Color avatarGray = Color(0xFF8593A8);
static const Color pageBg = Color(0xFFFFFFFF);
static const Color chatBg = Color(0xFFF5F6F8);
static const Color searchBg = Color(0xFFF2F3F5);
static const Color bubbleMine = Color(0xFFD6E7FC);
static const Color bubbleOther = Color(0xFFFFFFFF);
static const Color textPrimary = Color(0xFF1D2129);
static const Color textSecondary = Color(0xFF86909C);
static const Color danger = Color(0xFFF53F3F);
static const Color divider = Color(0xFFEEEEEE);
static const Color bannerBg = Color(0xFF3A3F47);
static const Color maskBg = Color(0xFF000000);
static const Color success = Color(0xFF00B42A);
static const Color warning = Color(0xFFFF7D00);
}
class AppFont {
AppFont._();
static const double small = 12;
static const double sub = 14;
static const double body = 16;
static const double title = 18;
}
class AppGap {
AppGap._();
static const double x1 = 4;
static const double x2 = 8;
static const double x3 = 12;
static const double x4 = 16;
static const double x6 = 24;
static const double x8 = 32;
static const double x12 = 48;
}
class AppRadius {
AppRadius._();
static const double control = 8;
static const double modal = 12;
static const double bubble = 8;
static const double logo = 16;
static double avatar(double size) => size * 0.18;
}
class AppIconSize {
AppIconSize._();
static const double sm = 20;
static const double md = 22;
static const double lg = 24;
}
class AppDuration {
AppDuration._();
static const hover = Duration(milliseconds: 100);
static const overlay = Duration(milliseconds: 150);
static const route = Duration(milliseconds: 200);
}
class AppShadows {
AppShadows._();
static const List<BoxShadow> modal = [
BoxShadow(color: Color(0x14000000), offset: Offset(0, 4), blurRadius: 16),
];
}
@@ -0,0 +1,37 @@
import 'package:openim_common/openim_common.dart';
import 'app_tokens.dart';
/// 把官方 `Styles` 静态色值对齐到 v2 Token。
///
/// 官方页面继续读 `Styles.*`,公司页面读 `AppColors.*`。只改这一处映射,
/// 禁止在页面上再叠一套颜色覆盖。必须在首屏构建前调用。
void applyOfficialStylesFromTokens() {
Styles.c_0089FF = AppColors.primary;
Styles.c_0C1C33 = AppColors.textPrimary;
Styles.c_8E9AB0 = AppColors.textSecondary;
Styles.c_E8EAEF = AppColors.divider;
Styles.c_FF381F = AppColors.danger;
Styles.c_CCE7FE = AppColors.bubbleMine;
Styles.c_F4F5F7 = AppColors.chatBg;
Styles.c_F8F9FA = AppColors.pageBg;
Styles.c_F0F2F6 = AppColors.chatBg;
Styles.c_F2F8FF = AppColors.primaryActive;
Styles.c_18E875 = AppColors.success;
Styles.c_FFB300 = AppColors.warning;
Styles.c_6085B1 = AppColors.avatarGray;
Styles.c_0089FF_opacity10 = AppColors.primary.withOpacity(.1);
Styles.c_0089FF_opacity20 = AppColors.primary.withOpacity(.2);
Styles.c_0089FF_opacity50 = AppColors.primary.withOpacity(.5);
Styles.c_FF381F_opacity10 = AppColors.danger.withOpacity(.1);
Styles.c_8E9AB0_opacity13 = AppColors.textSecondary.withOpacity(.13);
Styles.c_8E9AB0_opacity15 = AppColors.textSecondary.withOpacity(.15);
Styles.c_8E9AB0_opacity16 = AppColors.textSecondary.withOpacity(.16);
Styles.c_8E9AB0_opacity30 = AppColors.textSecondary.withOpacity(.3);
Styles.c_8E9AB0_opacity50 = AppColors.textSecondary.withOpacity(.5);
Styles.c_0C1C33_opacity30 = AppColors.textPrimary.withOpacity(.3);
Styles.c_0C1C33_opacity60 = AppColors.textPrimary.withOpacity(.6);
Styles.c_0C1C33_opacity85 = AppColors.textPrimary.withOpacity(.85);
Styles.c_0C1C33_opacity80 = AppColors.textPrimary.withOpacity(.8);
}