chore: 完成项目品牌域名批量替换与功能迭代

本次提交包含多项核心更新:
1. 全量替换项目内所有xianyan.app域名变更为s2ss.com,包含配置文件、路由、隐私政策等
2. 重构图表库从fl_chart迁移至syncfusion_flutter_charts,优化图表渲染效果
3. 新增宽屏分屏布局支持,包含右侧面板注册表与可拖拽分割线
4. 完善触觉反馈服务与认证感知Mixin,修复多处内存泄漏问题
5. 合并勋章墙与金币记录入口至成就中心,简化个人中心导航
6. 新增收藏与时间线数据合并导入功能
7. 修复多处UI样式问题,统一主题颜色使用规范
8. 新增日历同步与跨平台触觉反馈依赖库
9. 修复BotToast初始化流程,避免路由切换时的弹窗崩溃
This commit is contained in:
Developer
2026-05-29 10:06:55 +08:00
parent 5b9a0320d5
commit 5a49d20c8a
93 changed files with 17861 additions and 3340 deletions

View File

@@ -253,8 +253,8 @@ class _LoginPageState extends ConsumerState<LoginPage>
? _handleLogin
: null,
child: authState.isLoading
? const CupertinoActivityIndicator(
color: CupertinoColors.white,
? CupertinoActivityIndicator(
color: ext.textOnAccent,
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -263,13 +263,13 @@ class _LoginPageState extends ConsumerState<LoginPage>
Icon(
_loginModeIcon,
size: 16,
color: CupertinoColors.white,
color: ext.textOnAccent,
),
const SizedBox(width: 6),
Text(
_loginModeButtonText,
style: AppTypography.callout.copyWith(
color: CupertinoColors.white,
color: ext.textOnAccent,
fontWeight: FontWeight.w600,
),
),
@@ -639,10 +639,10 @@ class _LoginPageState extends ConsumerState<LoginPage>
),
),
child: _agreedToTerms
? const Icon(
? Icon(
CupertinoIcons.checkmark,
size: 13,
color: CupertinoColors.white,
color: ext.textOnAccent,
)
: null,
),

View File

@@ -1,9 +1,9 @@
/// ============================================================
/// 闲言APP — 用户安全服务
/// 创建时间: 2026-04-29
/// 更新时间: 2026-05-15
/// 更新时间: 2026-05-29
/// 作用: 用户安全相关API封装登录/注册/密码/邮箱/手机/回执验证/第三方/二维码登录/密保问题)
/// 上次更新: v10.1.0 新增密保问题接口+多验证方式支持
/// 上次更新: changeEmail/changeMobile新增password验证方式支持
/// ============================================================
import 'dart:convert';
@@ -424,12 +424,12 @@ class UserSecurityService {
// 邮箱/手机变更 (回执验证)
// ============================================================
/// 修改邮箱 (需登录,支持回执/密保验证)
/// 修改邮箱 (需登录,支持回执/密保/密码验证)
static Future<void> changeEmail({
required String email,
String verifyMethod = 'receipt',
String? secAnswer,
String? userId,
String? password,
}) async {
try {
final data = <String, dynamic>{
@@ -444,6 +444,15 @@ class UserSecurityService {
}
data['sec_answer'] = secAnswer;
break;
case 'password':
if (password == null || password.isEmpty) {
throw const ApiException(code: 0, message: '请输入密码');
}
data['oldpassword'] = password;
final receipt = ReceiptHelper.generate(ReceiptAction.changeemail, email);
data['receipt'] = receipt.receipt;
data['sig'] = receipt.sig;
break;
case 'receipt':
default:
final receipt = ReceiptHelper.generate(ReceiptAction.changeemail, email);
@@ -468,21 +477,49 @@ class UserSecurityService {
}
}
/// 修改手机号 (需登录,回执验证)
static Future<void> changeMobile({required String mobile}) async {
/// 修改手机号 (需登录,支持回执/密保/密码验证)
static Future<void> changeMobile({
required String mobile,
String verifyMethod = 'receipt',
String? secAnswer,
String? password,
}) async {
try {
final receipt = ReceiptHelper.generate(
ReceiptAction.changemobile,
mobile,
);
final data = <String, dynamic>{
'mobile': mobile,
'verify_method': verifyMethod,
};
switch (verifyMethod) {
case 'sec_question':
if (secAnswer == null || secAnswer.isEmpty) {
throw const ApiException(code: 0, message: '请输入密保答案');
}
data['sec_answer'] = secAnswer;
break;
case 'password':
if (password == null || password.isEmpty) {
throw const ApiException(code: 0, message: '请输入密码');
}
data['oldpassword'] = password;
final receipt = ReceiptHelper.generate(ReceiptAction.changemobile, mobile);
data['receipt'] = receipt.receipt;
data['sig'] = receipt.sig;
break;
case 'receipt':
default:
final receipt = ReceiptHelper.generate(
ReceiptAction.changemobile,
mobile,
);
data['receipt'] = receipt.receipt;
data['sig'] = receipt.sig;
break;
}
final response = await _api.post<Map<String, dynamic>>(
'$_basePath/changemobile',
data: {
'mobile': mobile,
'receipt': receipt.receipt,
'sig': receipt.sig,
},
data: data,
);
final apiResp = ApiResponse<Map<String, dynamic>>.fromJson(
response.data as Map<String, dynamic>,