chore: 迁移依赖、移除sqlite3_flutter_libs并新增功能
1. 替换hive_flutter为hive_ce_flutter依赖 2. 从各平台插件列表移除sqlite3_flutter_libs 3. 重构API请求体格式,优化历史记录去重逻辑 4. 新增CTC笔记相关功能:桌面小部件、模板模型、本地存储 5. 新增表单收集服务和后台管理接口 6. 优化缓存配置、多语言文案和UI细节 7. 重构首页状态监听组件
This commit is contained in:
@@ -11,7 +11,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
|
||||
import '../../storage/database/app_database.dart';
|
||||
import '../../storage/kv_storage.dart';
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import '../../storage/kv_storage.dart';
|
||||
|
||||
@@ -10,7 +10,7 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/// ============================================================
|
||||
/// 闲言APP — 日历同步服务
|
||||
/// 创建时间: 2026-05-29
|
||||
/// 更新时间: 2026-06-06
|
||||
/// 更新时间: 2026-06-15
|
||||
/// 作用: 跨平台日历事件同步(Android/iOS/HarmonyOS/macOS/Windows)
|
||||
/// 上次更新: 鸿蒙端MethodChannel添加超时保护+MissingPluginException捕获+平台判断早期返回
|
||||
/// 上次更新: 迁移至 device_calendar_plus,适配新 API(DeviceCalendar 单例、CalendarPermissionStatus、listCalendars/createEvent/deleteEvent 新签名)
|
||||
/// ============================================================
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:device_calendar/device_calendar.dart';
|
||||
import 'package:device_calendar_plus/device_calendar_plus.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
|
||||
import 'package:xianyan/core/utils/logger.dart';
|
||||
import 'package:xianyan/core/utils/platform/platform_utils.dart' as pu;
|
||||
@@ -43,7 +42,7 @@ class CalendarService {
|
||||
CalendarService._();
|
||||
static final CalendarService instance = CalendarService._();
|
||||
|
||||
final DeviceCalendarPlugin _plugin = DeviceCalendarPlugin();
|
||||
final DeviceCalendar _plugin = DeviceCalendar.instance;
|
||||
String? _calendarId;
|
||||
bool _isAvailable = false;
|
||||
|
||||
@@ -79,11 +78,12 @@ class CalendarService {
|
||||
Log.w('CalendarService: 当前平台不支持日历');
|
||||
return false;
|
||||
}
|
||||
final hasPermissions = await _plugin.hasPermissions();
|
||||
if (hasPermissions.isSuccess && !hasPermissions.data!) {
|
||||
final status = await _plugin.hasPermissions();
|
||||
if (status != CalendarPermissionStatus.granted) {
|
||||
final result = await _plugin.requestPermissions();
|
||||
if (!result.isSuccess || !result.data!) {
|
||||
Log.w('CalendarService: 日历权限被拒绝');
|
||||
if (result != CalendarPermissionStatus.granted &&
|
||||
result != CalendarPermissionStatus.writeOnly) {
|
||||
Log.w('CalendarService: 日历权限被拒绝 ($result)');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -122,23 +122,18 @@ class CalendarService {
|
||||
|
||||
/// 确保闲言专属日历存在,不存在则创建
|
||||
Future<void> _ensureCalendar() async {
|
||||
final calendars = await _plugin.retrieveCalendars();
|
||||
if (calendars.isSuccess && calendars.data != null) {
|
||||
final existing = calendars.data!.where(
|
||||
(c) => c.name == '闲言' || c.name == 'Xianyan',
|
||||
final calendars = await _plugin.listCalendars();
|
||||
final existing = calendars.where(
|
||||
(c) => c.name == '闲言' || c.name == 'Xianyan',
|
||||
);
|
||||
if (existing.isNotEmpty) {
|
||||
_calendarId = existing.first.id;
|
||||
} else {
|
||||
final calendarId = await _plugin.createCalendar(
|
||||
name: '闲言',
|
||||
colorHex: '#007AFF',
|
||||
);
|
||||
if (existing.isNotEmpty) {
|
||||
_calendarId = existing.first.id;
|
||||
} else {
|
||||
final result = await _plugin.createCalendar(
|
||||
'闲言',
|
||||
calendarColor: const Color(0xFF007AFF),
|
||||
localAccountName: '闲言APP',
|
||||
);
|
||||
if (result.isSuccess) {
|
||||
_calendarId = result.data;
|
||||
}
|
||||
}
|
||||
_calendarId = calendarId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +143,7 @@ class CalendarService {
|
||||
|
||||
/// 添加日历事件
|
||||
/// 鸿蒙端:通过_addEventOhos()桥接,通道未实现时返回false
|
||||
/// 注意:device_calendar_plus 暂不支持 Reminder,reminderMinutesBefore 仅鸿蒙端生效
|
||||
Future<bool> addEvent(CalendarEvent event) async {
|
||||
// 鸿蒙端:直接走鸿蒙通道
|
||||
if (_isOhos()) {
|
||||
@@ -160,31 +156,26 @@ class CalendarService {
|
||||
}
|
||||
|
||||
try {
|
||||
final local = tz.local;
|
||||
final calendarEvent = Event(
|
||||
_calendarId,
|
||||
// device_calendar_plus 使用 createEvent 方法,无需手动构造 Event 对象
|
||||
await _plugin.createEvent(
|
||||
calendarId: _calendarId!,
|
||||
title: event.title,
|
||||
startDate: event.start,
|
||||
endDate: event.end,
|
||||
description: event.description,
|
||||
start: tz.TZDateTime.from(event.start, local),
|
||||
end: tz.TZDateTime.from(event.end, local),
|
||||
location: event.location,
|
||||
);
|
||||
|
||||
// device_calendar_plus 暂不支持 Reminder,记录提示
|
||||
if (event.reminderMinutesBefore != null) {
|
||||
calendarEvent.reminders = [
|
||||
Reminder(minutes: event.reminderMinutesBefore!),
|
||||
];
|
||||
Log.w(
|
||||
'CalendarService: device_calendar_plus 暂不支持 Reminder,'
|
||||
'reminderMinutesBefore=${event.reminderMinutesBefore} 已忽略',
|
||||
);
|
||||
}
|
||||
|
||||
final result = await _plugin.createOrUpdateEvent(calendarEvent);
|
||||
if (result?.isSuccess == true) {
|
||||
Log.i('CalendarService: 事件已添加 - ${event.title}');
|
||||
return true;
|
||||
}
|
||||
Log.e(
|
||||
'CalendarService: 添加事件失败 - ${result?.errors.map((e) => e.errorMessage)}',
|
||||
);
|
||||
return false;
|
||||
Log.i('CalendarService: 事件已添加 - ${event.title}');
|
||||
return true;
|
||||
} catch (e) {
|
||||
Log.e('CalendarService: 添加事件异常', e);
|
||||
return false;
|
||||
@@ -216,10 +207,9 @@ class CalendarService {
|
||||
|
||||
/// 删除日历事件
|
||||
Future<bool> deleteEvent(String eventId) async {
|
||||
if (_calendarId == null) return false;
|
||||
try {
|
||||
final result = await _plugin.deleteEvent(_calendarId!, eventId);
|
||||
return result.isSuccess;
|
||||
await _plugin.deleteEvent(eventId: eventId);
|
||||
return true;
|
||||
} catch (e) {
|
||||
Log.e('CalendarService: 删除事件异常', e);
|
||||
return false;
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'dart:isolate';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
|
||||
import '../../utils/logger.dart';
|
||||
import '../../utils/platform/platform_utils.dart' as pu;
|
||||
|
||||
@@ -11,7 +11,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
|
||||
import '../../network/api_client.dart';
|
||||
import '../../storage/kv_storage.dart';
|
||||
|
||||
82
lib/core/services/form/form_collect_service.dart
Normal file
82
lib/core/services/form/form_collect_service.dart
Normal file
@@ -0,0 +1,82 @@
|
||||
/// ============================================================
|
||||
/// 闲言APP — 表单收集服务
|
||||
/// 创建时间: 2026-06-15
|
||||
/// 更新时间: 2026-06-15
|
||||
/// 作用: 调用 /api/form_collect/submit 提交表单信息(邮箱等)
|
||||
/// 上次更新: v6.73.0 初始版本
|
||||
/// ============================================================
|
||||
|
||||
import '../../network/api_client.dart';
|
||||
import '../../utils/logger.dart';
|
||||
|
||||
/// 表单来源标识
|
||||
enum FormCollectSource {
|
||||
/// app.html Google Play内测
|
||||
appGpBeta('app_gp_beta'),
|
||||
|
||||
/// 注册页面订阅闲言邮箱
|
||||
registerSubscribe('register_subscribe'),
|
||||
|
||||
/// Beta页面问卷填写Gmail
|
||||
betaQuestionnaire('beta_questionnaire');
|
||||
|
||||
const FormCollectSource(this.value);
|
||||
final String value;
|
||||
}
|
||||
|
||||
/// 表单收集服务
|
||||
class FormCollectService {
|
||||
FormCollectService._();
|
||||
static final FormCollectService instance = FormCollectService._();
|
||||
|
||||
static const String _submitPath = '/api/form_collect/submit';
|
||||
|
||||
/// 提交表单
|
||||
///
|
||||
/// [email] 邮箱地址(必填)
|
||||
/// [source] 来源标识(必填)
|
||||
/// [uid] 用户ID(可选)
|
||||
/// [extraJson] 扩展字段JSON字符串(可选)
|
||||
/// [deviceId] 设备ID(可选)
|
||||
///
|
||||
/// 返回 true 提交成功,false 提交失败
|
||||
Future<bool> submit({
|
||||
required String email,
|
||||
required FormCollectSource source,
|
||||
String? uid,
|
||||
String? extraJson,
|
||||
String? deviceId,
|
||||
}) async {
|
||||
try {
|
||||
final data = <String, dynamic>{
|
||||
'email': email,
|
||||
'source': source.value,
|
||||
};
|
||||
if (uid != null && uid.isNotEmpty) data['uid'] = uid;
|
||||
if (extraJson != null && extraJson.isNotEmpty) {
|
||||
data['extra_json'] = extraJson;
|
||||
}
|
||||
if (deviceId != null && deviceId.isNotEmpty) {
|
||||
data['device_id'] = deviceId;
|
||||
}
|
||||
|
||||
final response = await ApiClient.instance.post<Map<String, dynamic>>(
|
||||
_submitPath,
|
||||
data: data,
|
||||
);
|
||||
|
||||
final result = response.data;
|
||||
final code = result?['code'];
|
||||
if (code == 1) {
|
||||
Log.d('FormCollect: 提交成功 source=${source.value} email=$email');
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.w('FormCollect: 提交失败 code=$code msg=${result?['msg']}');
|
||||
return false;
|
||||
} catch (e) {
|
||||
Log.e('FormCollect: 提交异常 $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user