情景推荐
This commit is contained in:
38
.vscode/launch.json
vendored
38
.vscode/launch.json
vendored
@@ -1,25 +1,51 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "flutter_application_2",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
"type": "dart",
|
||||
"args": [
|
||||
"--device-timeout=60"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_application_2 (profile mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
"flutterMode": "profile",
|
||||
"args": [
|
||||
"--device-timeout=60"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_application_2 (release mode)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
"flutterMode": "release",
|
||||
"args": [
|
||||
"--device-timeout=60"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_application_2 (WiFi Device)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"deviceId": "192.168.50.213:44263",
|
||||
"args": [
|
||||
"--device-timeout=120",
|
||||
"--device-connection=wireless"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "flutter_application_2 (USB Device)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"deviceId": "S48DTKPRVK4H8PKB",
|
||||
"args": [
|
||||
"--device-timeout=30",
|
||||
"--device-connection=attached"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
44
CHANGELOG.md
44
CHANGELOG.md
@@ -4,8 +4,52 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
---
|
||||
|
||||
## [1.4.3] - 2026-04-04
|
||||
|
||||
### 修复
|
||||
- 🐛 **修复 Trae 环境下 WiFi 设备安装卡顿问题**
|
||||
- 问题:在 Trae 中运行到三星平板时,一直显示 "Installing build\app\outputs\flutter-apk\app-debug.apk...",但 Android Studio 能正常安装
|
||||
- 根本原因:WiFi 连接的设备建立 VM Service 连接较慢,导致 Flutter 认为安装卡住
|
||||
- 解决方案:
|
||||
- 在 VS Code launch.json 中为所有配置添加 `--device-timeout=60` 参数
|
||||
- 新增 WiFi 设备专用配置,使用 `--device-timeout=120` 和 `--device-connection=wireless`
|
||||
- 新增 USB 设备专用配置,使用 `--device-timeout=30` 和 `--device-connection=attached`
|
||||
- 创建 WiFi 设备连接辅助脚本(wifi_device_helper.bat 和 wifi_device_helper.ps1)
|
||||
- 提供手动安装 APK 的选项,绕过 VM Service 连接等待
|
||||
- 涉及文件:
|
||||
- `.vscode/launch.json` - 优化设备连接配置
|
||||
- `wifi_device_helper.bat` - Windows 批处理辅助脚本
|
||||
- `wifi_device_helper.ps1` - PowerShell 辅助脚本
|
||||
- 使用说明:
|
||||
- 在 VS Code 中运行时,选择 "flutter_application_2 (WiFi Device)" 配置
|
||||
- 或使用辅助脚本 `wifi_device_helper.bat` 或 `wifi_device_helper.ps1`
|
||||
- 如仍卡住,可选择选项 4 手动安装 APK
|
||||
|
||||
---
|
||||
|
||||
## [1.4.2] - 2026-04-04
|
||||
|
||||
### 新增
|
||||
- ✨ **创建统一的平台判断工具类 PlatformUtils**
|
||||
- 新建 `lib/controllers/settings/is_platform.dart` 文件
|
||||
- 统一管理平台判断逻辑,支持 Web、Android、iOS、HarmonyOS、Windows、macOS、Linux 等平台
|
||||
- 提供平台检测、操作系统信息获取、平台显示名称等功能
|
||||
- 所有平台判断方法都包含异常处理,确保在 Web 平台也能正常工作
|
||||
|
||||
### 重构
|
||||
- ♻️ **统一平台判断代码**
|
||||
- 将分散在多个文件中的平台判断代码统一使用 PlatformUtils
|
||||
- 移除了各文件中重复的 `import 'dart:io'` 和 `import 'package:flutter/foundation.dart'`
|
||||
- 简化了平台判断逻辑,提高了代码可维护性
|
||||
- 涉及文件:
|
||||
- `lib/views/profile/app-info.dart` - 使用 PlatformUtils 替代 io.Platform
|
||||
- `lib/views/profile/expand/manu-script.dart` - 使用 PlatformUtils.platformDisplayName
|
||||
- `lib/views/profile/profile_page.dart` - 使用 PlatformUtils.isWeb
|
||||
- `lib/views/profile/components/pop-menu.dart` - 使用 PlatformUtils
|
||||
- `lib/services/get/profile_controller.dart` - 使用 PlatformUtils
|
||||
- `lib/views/profile/guide/app-data.dart` - 使用 PlatformUtils.pathSeparator
|
||||
- `lib/utils/http/vote_api.dart` - 使用 PlatformUtils
|
||||
|
||||
### 修复
|
||||
- 🐛 **修复三星平板卡 Logo 启动页的问题**
|
||||
- 将屏幕适配从初始化阶段移到第一帧绘制后执行
|
||||
|
||||
155
WIFI_DEVICE_FIX.md
Normal file
155
WIFI_DEVICE_FIX.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# WiFi 设备连接问题解决方案
|
||||
|
||||
## 问题描述
|
||||
|
||||
在 Trae 环境下,运行应用到三星平板(WiFi 连接)时,一直显示 "Installing build\app\outputs\flutter-apk\app-debug.apk...",但 Android Studio 能正常安装。
|
||||
|
||||
## 根本原因
|
||||
|
||||
WiFi 连接的设备建立 VM Service 连接较慢,导致 Flutter 认为安装卡住。实际上 APK 已经成功安装,只是 Flutter 在等待 VM Service 端口连接时超时。
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 方案 1:使用 VS Code 专用配置(推荐)
|
||||
|
||||
1. 在 VS Code 中按 `F5` 或点击调试按钮
|
||||
2. 在配置下拉菜单中选择 **"flutter_application_2 (WiFi Device)"**
|
||||
3. 该配置已优化为:
|
||||
- 设备超时时间:120 秒
|
||||
- 连接类型:仅 WiFi 设备
|
||||
- 目标设备:192.168.50.213:44263(三星平板)
|
||||
|
||||
### 方案 2:使用辅助脚本
|
||||
|
||||
#### Windows 批处理脚本
|
||||
```bash
|
||||
wifi_device_helper.bat
|
||||
```
|
||||
|
||||
#### PowerShell 脚本
|
||||
```powershell
|
||||
.\wifi_device_helper.ps1
|
||||
```
|
||||
|
||||
脚本提供以下功能:
|
||||
- 选项 1:运行到 WiFi 设备(三星平板)
|
||||
- 选项 2:运行到 USB 设备
|
||||
- 选项 3:仅构建 APK
|
||||
- 选项 4:手动安装 APK 到 WiFi 设备(绕过 VM Service 连接)
|
||||
- 选项 5:检查设备连接状态
|
||||
- 选项 6:使用详细日志运行(调试用)
|
||||
|
||||
### 方案 3:手动命令
|
||||
|
||||
#### 运行到 WiFi 设备
|
||||
```bash
|
||||
flutter run --device-id=192.168.50.213:44263 --device-timeout=120 --device-connection=wireless
|
||||
```
|
||||
|
||||
#### 仅构建 APK
|
||||
```bash
|
||||
flutter build apk --debug
|
||||
```
|
||||
|
||||
#### 手动安装 APK
|
||||
```bash
|
||||
# 构建后手动安装
|
||||
flutter build apk --debug
|
||||
|
||||
# 使用 ADB 安装
|
||||
E:\sdk\android\platform-tools\adb.exe -s 192.168.50.213:44263 install -r build\app\outputs\flutter-apk\app-debug.apk
|
||||
|
||||
# 启动应用
|
||||
E:\sdk\android\platform-tools\adb.exe -s 192.168.50.213:44263 shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER app.wushu.poes/app.wushu.poes.MainActivity
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### VS Code launch.json 配置
|
||||
|
||||
所有配置已添加 `--device-timeout=60` 参数,默认超时时间从 10 秒增加到 60 秒。
|
||||
|
||||
#### 新增配置
|
||||
|
||||
**WiFi 设备配置:**
|
||||
```json
|
||||
{
|
||||
"name": "flutter_application_2 (WiFi Device)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"deviceId": "192.168.50.213:44263",
|
||||
"args": [
|
||||
"--device-timeout=120",
|
||||
"--device-connection=wireless"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**USB 设备配置:**
|
||||
```json
|
||||
{
|
||||
"name": "flutter_application_2 (USB Device)",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"deviceId": "S48DTKPRVK4H8PKB",
|
||||
"args": [
|
||||
"--device-timeout=30",
|
||||
"--device-connection=attached"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 为什么 Android Studio 能正常安装?
|
||||
|
||||
A: Android Studio 有更完善的超时处理和重试机制,并且对 WiFi 设备有专门的优化。
|
||||
|
||||
### Q: 如何确认设备已连接?
|
||||
|
||||
A: 运行以下命令:
|
||||
```bash
|
||||
flutter devices
|
||||
# 或
|
||||
E:\sdk\android\platform-tools\adb.exe devices
|
||||
```
|
||||
|
||||
### Q: 如果还是卡住怎么办?
|
||||
|
||||
A: 使用辅助脚本的选项 4(手动安装 APK),这会绕过 VM Service 连接等待。
|
||||
|
||||
### Q: 如何查看详细日志?
|
||||
|
||||
A: 使用 `--verbose` 参数:
|
||||
```bash
|
||||
flutter run --device-id=192.168.50.213:44263 --verbose
|
||||
```
|
||||
|
||||
或使用辅助脚本的选项 6。
|
||||
|
||||
## 技术细节
|
||||
|
||||
### 问题分析过程
|
||||
|
||||
1. **设备连接检查**:Flutter 和 ADB 都能识别到设备
|
||||
2. **APK 构建**:构建成功完成
|
||||
3. **安装过程**:APK 实际已安装成功(显示 "Success")
|
||||
4. **卡住位置**:在 "Waiting for VM Service port to be available..." 阶段
|
||||
5. **根本原因**:WiFi 连接延迟导致 VM Service 端口连接建立较慢
|
||||
|
||||
### 解决方案原理
|
||||
|
||||
1. **增加超时时间**:从默认 10 秒增加到 60-120 秒
|
||||
2. **指定连接类型**:使用 `--device-connection=wireless` 优化 WiFi 连接
|
||||
3. **手动安装**:绕过 VM Service 连接等待,直接安装 APK
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `.vscode/launch.json` - VS Code 调试配置
|
||||
- `wifi_device_helper.bat` - Windows 批处理辅助脚本
|
||||
- `wifi_device_helper.ps1` - PowerShell 辅助脚本
|
||||
- `CHANGELOG.md` - 更新日志(版本 1.4.3)
|
||||
|
||||
## 更新日志
|
||||
|
||||
详见 [CHANGELOG.md](CHANGELOG.md) 版本 1.4.3。
|
||||
228
lib/controllers/settings/is_platform.dart
Normal file
228
lib/controllers/settings/is_platform.dart
Normal file
@@ -0,0 +1,228 @@
|
||||
import 'dart:io' as io show Platform;
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
|
||||
/// 时间: 2026-04-04
|
||||
/// 功能: 平台判断工具类
|
||||
/// 介绍: 统一管理平台判断逻辑,支持 Web、Android、iOS、HarmonyOS、Windows、macOS、Linux 等平台
|
||||
/// 最新变化: 新建文件,统一平台判断逻辑
|
||||
|
||||
class PlatformUtils {
|
||||
PlatformUtils._();
|
||||
|
||||
/// 是否是 Web 平台
|
||||
static bool get isWeb => kIsWeb;
|
||||
|
||||
/// 是否是移动平台(Android、iOS、HarmonyOS)
|
||||
static bool get isMobile => isAndroid || isIOS || isHarmonyOS;
|
||||
|
||||
/// 是否是桌面平台(Windows、macOS、Linux)
|
||||
static bool get isDesktop => isWindows || isMacOS || isLinux;
|
||||
|
||||
/// 是否是 Android 平台
|
||||
static bool get isAndroid {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isAndroid;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是 iOS 平台
|
||||
static bool get isIOS {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isIOS;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是鸿蒙平台
|
||||
static bool get isHarmonyOS {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
final osName = io.Platform.operatingSystem.toLowerCase();
|
||||
return osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是 Windows 平台
|
||||
static bool get isWindows {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isWindows;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是 macOS 平台
|
||||
static bool get isMacOS {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isMacOS;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是 Linux 平台
|
||||
static bool get isLinux {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isLinux;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否是 Fuchsia 平台
|
||||
static bool get isFuchsia {
|
||||
if (kIsWeb) return false;
|
||||
try {
|
||||
return io.Platform.isFuchsia;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取操作系统名称
|
||||
static String get operatingSystem {
|
||||
if (kIsWeb) return 'web';
|
||||
try {
|
||||
return io.Platform.operatingSystem;
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取操作系统版本
|
||||
static String get operatingSystemVersion {
|
||||
if (kIsWeb) return 'web browser';
|
||||
try {
|
||||
return io.Platform.operatingSystemVersion;
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取平台显示名称(带 Flutter 后缀)
|
||||
static String get platformDisplayName {
|
||||
if (kIsWeb) return 'Web Flutter';
|
||||
|
||||
try {
|
||||
final osName = io.Platform.operatingSystem.toLowerCase();
|
||||
|
||||
if (osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony') {
|
||||
return 'HarmonyOS Flutter';
|
||||
} else if (io.Platform.isAndroid) {
|
||||
return 'Android Flutter';
|
||||
} else if (io.Platform.isIOS) {
|
||||
return 'iOS Flutter';
|
||||
} else if (io.Platform.isWindows) {
|
||||
return 'Windows Flutter';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
return 'macOS Flutter';
|
||||
} else if (io.Platform.isLinux) {
|
||||
return 'Linux Flutter';
|
||||
} else if (io.Platform.isFuchsia) {
|
||||
return 'Fuchsia Flutter';
|
||||
} else {
|
||||
return 'Flutter';
|
||||
}
|
||||
} catch (e) {
|
||||
return 'Flutter';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取简短的平台名称
|
||||
static String get platformShortName {
|
||||
if (kIsWeb) return 'Web';
|
||||
|
||||
try {
|
||||
final osName = io.Platform.operatingSystem.toLowerCase();
|
||||
|
||||
if (osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony') {
|
||||
return 'HarmonyOS';
|
||||
} else if (io.Platform.isAndroid) {
|
||||
return 'Android';
|
||||
} else if (io.Platform.isIOS) {
|
||||
return 'iOS';
|
||||
} else if (io.Platform.isWindows) {
|
||||
return 'Windows';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
return 'macOS';
|
||||
} else if (io.Platform.isLinux) {
|
||||
return 'Linux';
|
||||
} else if (io.Platform.isFuchsia) {
|
||||
return 'Fuchsia';
|
||||
} else {
|
||||
return 'Unknown';
|
||||
}
|
||||
} catch (e) {
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取路径分隔符
|
||||
static String get pathSeparator {
|
||||
if (kIsWeb) return '/';
|
||||
try {
|
||||
return io.Platform.pathSeparator;
|
||||
} catch (e) {
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取本地主机名
|
||||
static String get localHostname {
|
||||
if (kIsWeb) return 'web';
|
||||
try {
|
||||
return io.Platform.localHostname;
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取环境变量
|
||||
static Map<String, String> get environment {
|
||||
if (kIsWeb) return {};
|
||||
try {
|
||||
return io.Platform.environment;
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取 Dart 版本
|
||||
static String get dartVersion {
|
||||
if (kIsWeb) return 'web';
|
||||
try {
|
||||
return io.Platform.version;
|
||||
} catch (e) {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取平台信息摘要
|
||||
static String get platformSummary {
|
||||
if (kIsWeb) return 'Web Browser';
|
||||
|
||||
try {
|
||||
final osName = operatingSystem;
|
||||
final osVersion = operatingSystemVersion;
|
||||
return '$osName ($osVersion)';
|
||||
} catch (e) {
|
||||
return 'Unknown Platform';
|
||||
}
|
||||
}
|
||||
}
|
||||
150
lib/models/scenario/jinrishici_sdk_config.dart
Normal file
150
lib/models/scenario/jinrishici_sdk_config.dart
Normal file
@@ -0,0 +1,150 @@
|
||||
/// 今日诗词安卓 SDK 用法和接口文档
|
||||
///
|
||||
/// 创建时间:2026-04-08
|
||||
/// 作用:记录今日诗词 SDK 的使用方法和 API 接口信息
|
||||
/// 最后更新:2026-04-08 - 初始创建
|
||||
|
||||
/// 今日诗词 SDK 配置信息
|
||||
class JinrishiciSdkConfig {
|
||||
/// SDK 名称
|
||||
static const String sdkName = '今日诗词安卓 SDK';
|
||||
|
||||
/// SDK 包名
|
||||
static const String packageName = 'com.jinrishici:android-sdk';
|
||||
|
||||
/// GitHub 仓库地址
|
||||
static const String githubUrl = 'https://github.com/xenv/jinrishici-sdk-android';
|
||||
|
||||
/// 许可证
|
||||
static const String license = 'BSD 3-Clause "New" or "Revised" License';
|
||||
|
||||
/// Token 获取接口
|
||||
static const String tokenUrl = 'https://v2.jinrishici.com/token';
|
||||
|
||||
/// 获取诗词接口
|
||||
static const String sentenceUrl = 'https://v2.jinrishici.com/sentence';
|
||||
|
||||
/// SDK 版本号(需要根据实际发布版本更新)
|
||||
static const String version = '{release-version}';
|
||||
}
|
||||
|
||||
/// SDK 使用方法说明
|
||||
class JinrishiciSdkUsage {
|
||||
/// 初始化方法
|
||||
static const String initMethod = '''
|
||||
// 初始化(两种方式任选一种)
|
||||
JinrishiciFactory.init(getContext());
|
||||
JinrishiciClient.getInstance().init(getContext());
|
||||
''';
|
||||
|
||||
/// 异步获取诗词方法
|
||||
static const String asyncMethod = '''
|
||||
// 异步方法
|
||||
JinrishiciClient client = JinrishiciClient.getInstance();
|
||||
client.getOneSentenceBackground(new JinrishiciCallback() {
|
||||
@Override
|
||||
public void done(PoetySentence poetySentence) {
|
||||
// 处理成功结果
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(JinrishiciRuntimeException e) {
|
||||
// 处理错误
|
||||
}
|
||||
});
|
||||
''';
|
||||
|
||||
/// 同步获取诗词方法
|
||||
static const String syncMethod = '''
|
||||
// 同步方法(会抛出 JinrishiciRuntimeException)
|
||||
PoetySentence poetySentence = JinrishiciClient.getInstance().getOneSentence();
|
||||
''';
|
||||
|
||||
/// 自定义控件使用方法
|
||||
static const String customWidget = '''
|
||||
// XML 布局中使用
|
||||
<com.jinrishici.sdk.android.view.JinrishiciTextView
|
||||
android:id="@+id/jinrisiciTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorAccent"
|
||||
android:textSize="18sp" />
|
||||
''';
|
||||
}
|
||||
|
||||
/// SDK 自定义控件属性
|
||||
class JinrishiciWidgetAttributes {
|
||||
/// 点击 TextView 时是否刷新
|
||||
static const String refreshOnClick = 'jrsc_refresh_on_click';
|
||||
|
||||
/// 当请求出现错误时,是否直接将错误信息显示到 TextView 上
|
||||
static const String showError = 'jrsc_show_error';
|
||||
|
||||
/// 是否在加载数据时显示加载文本
|
||||
static const String showLoadingText = 'jrsc_show_loading_text';
|
||||
|
||||
/// 加载数据时显示的文本
|
||||
static const String textLoading = 'jrsc_text_loading';
|
||||
|
||||
/// 加载失败时显示的文本
|
||||
static const String textError = 'jrsc_text_error';
|
||||
}
|
||||
|
||||
/// SDK 工作流程
|
||||
class JinrishiciSdkWorkflow {
|
||||
/// 工作流程步骤
|
||||
static const List<String> steps = [
|
||||
'SDK 首先从本地 SharedPreferences 检查是否有缓存的 token',
|
||||
'如果没有 token,调用 https://v2.jinrishici.com/token 获取 token',
|
||||
'使用 token 调用 https://v2.jinrishici.com/one.json 获取诗词内容',
|
||||
'返回 PoetySentence 对象,包含诗词内容、来源、作者等信息',
|
||||
];
|
||||
|
||||
/// Gradle 依赖配置
|
||||
static const String gradleDependency = '''
|
||||
implementation 'com.jinrishici:android-sdk:{release-version}'
|
||||
''';
|
||||
|
||||
/// Maven 依赖配置
|
||||
static const String mavenDependency = '''
|
||||
<dependency>
|
||||
<groupId>com.jinrishici</groupId>
|
||||
<artifactId>android-sdk</artifactId>
|
||||
<version>{release-version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
''';
|
||||
}
|
||||
|
||||
/// SDK 数据模型
|
||||
class JinrishiciSdkData {
|
||||
/// PoetySentence - 诗词句子对象
|
||||
static const Map<String, String> poetySentenceFields = {
|
||||
'ipAddress': 'IP 地址',
|
||||
'data': '诗词数据对象(DataBean)',
|
||||
};
|
||||
|
||||
/// DataBean - 诗词数据对象
|
||||
static const Map<String, String> dataBeanFields = {
|
||||
'content': '诗词内容',
|
||||
'origin': '诗词来源信息(OriginBean)',
|
||||
'matchTags': '匹配标签',
|
||||
'recommendedReason': '推荐理由',
|
||||
};
|
||||
|
||||
/// OriginBean - 诗词来源对象
|
||||
static const Map<String, String> originBeanFields = {
|
||||
'title': '诗词标题',
|
||||
'dynasty': '朝代',
|
||||
'author': '作者',
|
||||
'content': '完整诗词内容',
|
||||
'translate': '翻译',
|
||||
'note': '注释',
|
||||
};
|
||||
|
||||
/// PoetyToken - Token 对象
|
||||
static const Map<String, String> poetyTokenFields = {
|
||||
'token': '访问令牌',
|
||||
'status': '状态',
|
||||
};
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:math' show Random;
|
||||
import 'dart:io' as io;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constants/app_constants.dart';
|
||||
import '../../controllers/history_controller.dart';
|
||||
import '../../controllers/shared_preferences_storage_controller.dart';
|
||||
import '../../controllers/settings/is_platform.dart';
|
||||
import '../isweb/wakelock_service.dart';
|
||||
import '../../views/profile/guide/tongji.dart';
|
||||
import 'theme_controller.dart';
|
||||
@@ -217,7 +216,7 @@ class ProfileController extends GetxController with WidgetsBindingObserver {
|
||||
Future<void> toggleScreenWake(bool enable) async {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
// Web 平台不支持 wakelock_plus
|
||||
if (kIsWeb) {
|
||||
if (PlatformUtils.isWeb) {
|
||||
Get.snackbar(
|
||||
'提示',
|
||||
'Web 平台不支持屏幕常亮功能',
|
||||
@@ -227,9 +226,9 @@ class ProfileController extends GetxController with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用 io.Platform 检测平台
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final String osVersion = io.Platform.operatingSystemVersion;
|
||||
// 获取平台信息
|
||||
final String osName = PlatformUtils.operatingSystem;
|
||||
final String osVersion = PlatformUtils.operatingSystemVersion;
|
||||
print('Current platform: $osName, version: $osVersion');
|
||||
|
||||
if (enable) {
|
||||
|
||||
150
lib/services/jinrishici_service.dart
Normal file
150
lib/services/jinrishici_service.dart
Normal file
@@ -0,0 +1,150 @@
|
||||
/// 今日诗词 API 服务
|
||||
///
|
||||
/// 创建时间:2026-04-08
|
||||
/// 作用:调用今日诗词 API 获取每日诗词
|
||||
/// 最后更新:2026-04-08 - 初始创建
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../models/scenario/jinrishici_sdk_config.dart';
|
||||
|
||||
class JinrishiciService {
|
||||
static final JinrishiciService _instance = JinrishiciService._internal();
|
||||
factory JinrishiciService() => _instance;
|
||||
JinrishiciService._internal();
|
||||
|
||||
final Dio _dio = Dio(BaseOptions(
|
||||
connectTimeout: const Duration(seconds: 10),
|
||||
receiveTimeout: const Duration(seconds: 10),
|
||||
));
|
||||
|
||||
static const String _tokenKey = 'jinrishici_token';
|
||||
|
||||
/// 获取 token
|
||||
Future<String?> _getToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString(_tokenKey);
|
||||
}
|
||||
|
||||
/// 保存 token
|
||||
Future<void> _saveToken(String token) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_tokenKey, token);
|
||||
}
|
||||
|
||||
/// 生成 token
|
||||
Future<String> generateToken() async {
|
||||
try {
|
||||
print('正在请求 token: ${JinrishiciSdkConfig.tokenUrl}');
|
||||
final response = await _dio.get(JinrishiciSdkConfig.tokenUrl);
|
||||
print('Token 响应状态码: ${response.statusCode}');
|
||||
print('Token 响应数据: ${response.data}');
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
// 根据官方文档,token 在 data 字段中
|
||||
String? token;
|
||||
if (response.data is Map) {
|
||||
token = response.data['data'] as String?;
|
||||
}
|
||||
|
||||
if (token != null && token.isNotEmpty) {
|
||||
await _saveToken(token);
|
||||
print('Token 获取成功: $token');
|
||||
return token;
|
||||
}
|
||||
}
|
||||
throw Exception('获取 token 失败: 响应数据格式不正确');
|
||||
} catch (e) {
|
||||
print('获取 token 异常: $e');
|
||||
throw Exception('获取 token 异常: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取今日诗词
|
||||
Future<Map<String, dynamic>> getTodayPoetry() async {
|
||||
try {
|
||||
// 获取或生成 token
|
||||
String? token = await _getToken();
|
||||
if (token == null || token.isEmpty) {
|
||||
try {
|
||||
token = await generateToken();
|
||||
} catch (e) {
|
||||
print('Token 获取失败,尝试不带 token 请求: $e');
|
||||
token = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 token 获取诗词
|
||||
print('正在请求诗词: ${JinrishiciSdkConfig.sentenceUrl}');
|
||||
final response = await _dio.get(
|
||||
JinrishiciSdkConfig.sentenceUrl,
|
||||
options: token != null
|
||||
? Options(
|
||||
headers: {
|
||||
'X-User-Token': token,
|
||||
},
|
||||
)
|
||||
: null,
|
||||
);
|
||||
|
||||
print('诗词响应状态码: ${response.statusCode}');
|
||||
print('诗词响应数据: ${response.data}');
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
return response.data as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
throw Exception('获取诗词失败');
|
||||
} catch (e) {
|
||||
print('获取诗词异常: $e');
|
||||
throw Exception('获取诗词异常: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// 清除缓存的 token
|
||||
Future<void> clearToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_tokenKey);
|
||||
}
|
||||
|
||||
/// 获取用户信息(IP、地区、天气等)
|
||||
Future<Map<String, dynamic>> getUserInfo() async {
|
||||
try {
|
||||
// 获取或生成 token
|
||||
String? token = await _getToken();
|
||||
if (token == null || token.isEmpty) {
|
||||
try {
|
||||
token = await generateToken();
|
||||
} catch (e) {
|
||||
print('Token 获取失败,尝试不带 token 请求: $e');
|
||||
token = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 调用 info 接口
|
||||
print('正在请求用户信息: https://v2.jinrishici.com/info');
|
||||
final response = await _dio.get(
|
||||
'https://v2.jinrishici.com/info',
|
||||
options: token != null
|
||||
? Options(
|
||||
headers: {
|
||||
'X-User-Token': token,
|
||||
},
|
||||
)
|
||||
: null,
|
||||
);
|
||||
|
||||
print('用户信息响应状态码: ${response.statusCode}');
|
||||
print('用户信息响应数据: ${response.data}');
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
return response.data as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
throw Exception('获取用户信息失败');
|
||||
} catch (e) {
|
||||
print('获取用户信息异常: $e');
|
||||
throw Exception('获取用户信息异常: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
/// 最新变化: 添加Cookie管理器支持PHP Session认证
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io' as io show Platform;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'package:platform_info/platform_info.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../controllers/settings/is_platform.dart';
|
||||
|
||||
class VoteApi {
|
||||
static const String _baseUrl = 'https://poe.vogov.cn/toupiao/';
|
||||
@@ -246,34 +246,30 @@ class VoteApi {
|
||||
String platformName = 'Unknown';
|
||||
|
||||
try {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final String osVersion = io.Platform.operatingSystemVersion.toLowerCase();
|
||||
|
||||
if (osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony') {
|
||||
if (PlatformUtils.isHarmonyOS) {
|
||||
platformName = 'HarmonyOS';
|
||||
isHarmonyOS = true;
|
||||
} else if (io.Platform.isAndroid) {
|
||||
} else if (PlatformUtils.isAndroid) {
|
||||
platformName = 'Android';
|
||||
final osVersion = PlatformUtils.operatingSystemVersion.toLowerCase();
|
||||
if (osVersion.contains('harmony') ||
|
||||
osVersion.contains('ohos') ||
|
||||
osVersion.contains('openharmony')) {
|
||||
platformName = 'HarmonyOS';
|
||||
isHarmonyOS = true;
|
||||
}
|
||||
} else if (io.Platform.isIOS) {
|
||||
} else if (PlatformUtils.isIOS) {
|
||||
platformName = 'iOS';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
} else if (PlatformUtils.isMacOS) {
|
||||
platformName = 'macOS';
|
||||
} else if (io.Platform.isWindows) {
|
||||
} else if (PlatformUtils.isWindows) {
|
||||
platformName = 'Windows';
|
||||
} else if (io.Platform.isLinux) {
|
||||
} else if (PlatformUtils.isLinux) {
|
||||
platformName = 'Linux';
|
||||
} else if (io.Platform.isFuchsia) {
|
||||
} else if (PlatformUtils.isFuchsia) {
|
||||
platformName = 'Fuchsia';
|
||||
} else {
|
||||
platformName = osName[0].toUpperCase() + osName.substring(1);
|
||||
platformName = PlatformUtils.platformShortName;
|
||||
}
|
||||
} catch (e) {
|
||||
platformName = switch (platform.operatingSystem) {
|
||||
@@ -289,7 +285,7 @@ class VoteApi {
|
||||
|
||||
String deviceType = 'Unknown';
|
||||
if (isHarmonyOS) {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final osName = PlatformUtils.operatingSystem.toLowerCase();
|
||||
if (osName == 'ohos') {
|
||||
deviceType = 'OHOS';
|
||||
} else if (osName == 'harmonyos') {
|
||||
@@ -302,12 +298,12 @@ class VoteApi {
|
||||
} else {
|
||||
deviceType =
|
||||
platform.when<String?>(
|
||||
mobile: () => 'Mobile',
|
||||
desktop: () => 'Desktop',
|
||||
js: () => 'Web',
|
||||
mobile: () => '移动设备',
|
||||
desktop: () => '桌面设备',
|
||||
js: () => 'Web浏览器',
|
||||
orElse: () => null,
|
||||
) ??
|
||||
'Unknown';
|
||||
'未知设备';
|
||||
}
|
||||
|
||||
return '$platformName-$deviceType-Flutter';
|
||||
|
||||
@@ -270,18 +270,20 @@ class _PopularPageState extends State<PopularPage>
|
||||
NetworkEventType.noteUpdate,
|
||||
data: noteId,
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('已创建笔记')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'成功',
|
||||
'已创建笔记',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('创建笔记失败: $e')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'错误',
|
||||
'创建笔记失败: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -684,18 +684,20 @@ class _CorrPageState extends State<CorrPage>
|
||||
NetworkEventType.noteUpdate,
|
||||
data: noteId,
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('已创建笔记')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'成功',
|
||||
'已创建笔记',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('创建笔记失败: $e')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'错误',
|
||||
'创建笔记失败: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -670,19 +670,21 @@ class AllListPageState extends State<AllListPage> {
|
||||
NetworkEventType.noteUpdate,
|
||||
data: noteId,
|
||||
);
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('已创建笔记')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'成功',
|
||||
'已创建笔记',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('创建笔记失败: $e');
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('创建笔记失败: $e')));
|
||||
}
|
||||
Get.snackbar(
|
||||
'错误',
|
||||
'创建笔记失败: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
colorText: _themeController.currentThemeColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,66 @@
|
||||
/// 时间: 2026-04-02
|
||||
/// 功能: 关怀模式相关组件
|
||||
/// 介绍: 包含关怀按钮和开关的UI组件
|
||||
/// 最新变化: 2026-04-02 初始创建
|
||||
/// 最新变化: 2026-04-09 添加情景推荐按钮组件
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../../services/get/theme_controller.dart';
|
||||
import '../../../services/get/care_controller.dart';
|
||||
import 'care-page.dart';
|
||||
import '../components/pre-page.dart';
|
||||
|
||||
/// 情景推荐按钮组件
|
||||
class PrePageButton extends StatelessWidget {
|
||||
const PrePageButton({super.key, required this.isDark});
|
||||
|
||||
final bool isDark;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final themeController = Get.find<ThemeController>();
|
||||
final primaryColor = themeController.currentThemeColor;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => const PrePage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withAlpha(isDark ? 40 : 20),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.auto_stories, color: primaryColor, size: 20),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'情景推荐',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isDark ? Colors.white : Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 关怀按钮组件
|
||||
class CareButton extends StatelessWidget {
|
||||
|
||||
1229
lib/views/home/components/pre-page.dart
Normal file
1229
lib/views/home/components/pre-page.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -124,15 +124,8 @@ class _HomePageState extends State<HomePage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
// 关怀按钮 - 左上角
|
||||
Positioned(
|
||||
top: 8,
|
||||
left: 16,
|
||||
child: CareButton(
|
||||
onTap: _careController.toggleCareButtonVisibility,
|
||||
isDark: isDark,
|
||||
),
|
||||
),
|
||||
// 情景推荐按钮 - 左上角
|
||||
Positioned(top: 8, left: 16, child: PrePageButton(isDark: isDark)),
|
||||
// 关怀模式开关
|
||||
Obx(
|
||||
() => _careController.isCareButtonVisible.value
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'dart:ui';
|
||||
import 'dart:io' as io show Platform;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -10,6 +9,7 @@ import '../../../config/app_config.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import '../../../models/colors/theme_colors.dart';
|
||||
import '../../../controllers/shared_preferences_storage_controller.dart';
|
||||
import '../../../controllers/settings/is_platform.dart';
|
||||
import '../../../services/get/theme_controller.dart';
|
||||
|
||||
/// 时间: 2026-03-26
|
||||
@@ -398,20 +398,17 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
) {
|
||||
String buildSdk = 'Unknown';
|
||||
try {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
if (osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony') {
|
||||
if (PlatformUtils.isHarmonyOS) {
|
||||
buildSdk = 'Deveco API 23';
|
||||
} else if (io.Platform.isAndroid) {
|
||||
} else if (PlatformUtils.isAndroid) {
|
||||
buildSdk = 'Android Target 36';
|
||||
} else if (io.Platform.isWindows) {
|
||||
} else if (PlatformUtils.isWindows) {
|
||||
buildSdk = 'Win10 SDK';
|
||||
} else if (io.Platform.isIOS) {
|
||||
} else if (PlatformUtils.isIOS) {
|
||||
buildSdk = 'iOS 26';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
} else if (PlatformUtils.isMacOS) {
|
||||
buildSdk = 'macOS 18';
|
||||
} else if (io.Platform.isLinux) {
|
||||
} else if (PlatformUtils.isLinux) {
|
||||
buildSdk = 'Linux 20';
|
||||
} else {
|
||||
buildSdk = 'PHP 7.4';
|
||||
@@ -700,32 +697,30 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
String platformName = 'Unknown';
|
||||
|
||||
try {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final String osVersion = io.Platform.operatingSystemVersion.toLowerCase();
|
||||
|
||||
if (osName == 'ohos' || osName == 'harmonyos' || osName == 'harmonyos') {
|
||||
if (PlatformUtils.isHarmonyOS) {
|
||||
platformName = 'HarmonyOS';
|
||||
isHarmonyOS = true;
|
||||
} else if (io.Platform.isAndroid) {
|
||||
} else if (PlatformUtils.isAndroid) {
|
||||
platformName = 'Android';
|
||||
final osVersion = PlatformUtils.operatingSystemVersion.toLowerCase();
|
||||
if (osVersion.contains('harmony') ||
|
||||
osVersion.contains('ohos') ||
|
||||
osVersion.contains('openharmony')) {
|
||||
platformName = 'HarmonyOS';
|
||||
isHarmonyOS = true;
|
||||
}
|
||||
} else if (io.Platform.isIOS) {
|
||||
} else if (PlatformUtils.isIOS) {
|
||||
platformName = 'iOS';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
} else if (PlatformUtils.isMacOS) {
|
||||
platformName = 'macOS';
|
||||
} else if (io.Platform.isWindows) {
|
||||
} else if (PlatformUtils.isWindows) {
|
||||
platformName = 'Windows';
|
||||
} else if (io.Platform.isLinux) {
|
||||
} else if (PlatformUtils.isLinux) {
|
||||
platformName = 'Linux';
|
||||
} else if (io.Platform.isFuchsia) {
|
||||
} else if (PlatformUtils.isFuchsia) {
|
||||
platformName = 'Fuchsia';
|
||||
} else {
|
||||
platformName = osName[0].toUpperCase() + osName.substring(1);
|
||||
platformName = PlatformUtils.platformShortName;
|
||||
}
|
||||
} catch (e) {
|
||||
platformName = switch (platform.operatingSystem) {
|
||||
@@ -749,7 +744,7 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
|
||||
String deviceType = '未知设备';
|
||||
if (isHarmonyOS) {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final osName = PlatformUtils.operatingSystem.toLowerCase();
|
||||
if (osName == 'ohos') {
|
||||
deviceType = 'OHOS';
|
||||
} else if (osName == 'harmonyos') {
|
||||
|
||||
1171
lib/views/profile/components/jinrishici_sdk_page.dart
Normal file
1171
lib/views/profile/components/jinrishici_sdk_page.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../../models/colors/app_colors.dart';
|
||||
import '../../../services/isweb/wakelock_service.dart';
|
||||
import '../../../services/get/theme_controller.dart';
|
||||
import '../../../controllers/settings/is_platform.dart';
|
||||
import '../guide/beginner_page.dart';
|
||||
import 'dart:io' as io;
|
||||
import 'jinrishici_sdk_page.dart';
|
||||
import '../../home/care/care-page.dart';
|
||||
|
||||
class PopMenu extends StatelessWidget {
|
||||
final VoidCallback? onRefresh;
|
||||
@@ -51,7 +52,7 @@ class PopMenu extends StatelessWidget {
|
||||
|
||||
static Future<void> toggleScreenWake(BuildContext context) async {
|
||||
// Web 平台不支持 wakelock_plus
|
||||
if (kIsWeb) {
|
||||
if (PlatformUtils.isWeb) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
@@ -61,9 +62,9 @@ class PopMenu extends StatelessWidget {
|
||||
}
|
||||
|
||||
try {
|
||||
// 使用 io.Platform 检测平台
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
final String osVersion = io.Platform.operatingSystemVersion;
|
||||
// 获取平台信息
|
||||
final String osName = PlatformUtils.operatingSystem;
|
||||
final String osVersion = PlatformUtils.operatingSystemVersion;
|
||||
print('Current platform: $osName, version: $osVersion');
|
||||
|
||||
// 直接尝试启用屏幕常亮
|
||||
@@ -93,7 +94,10 @@ class PopMenu extends StatelessWidget {
|
||||
builder: (context) => AlertDialog(
|
||||
backgroundColor: AppColors.surface,
|
||||
title: Text('提示', style: TextStyle(color: AppColors.primaryText)),
|
||||
content: Text(errorMessage, style: TextStyle(color: AppColors.secondaryText)),
|
||||
content: Text(
|
||||
errorMessage,
|
||||
style: TextStyle(color: AppColors.secondaryText),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
@@ -186,10 +190,21 @@ class PopMenu extends StatelessWidget {
|
||||
}),
|
||||
_buildBottomSheetItem(
|
||||
context,
|
||||
'取消',
|
||||
Icons.settings,
|
||||
onSettings,
|
||||
'今日诗词SDK',
|
||||
Icons.book_outlined,
|
||||
() {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => const JinrishiciSdkPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
_buildBottomSheetItem(context, '关怀模式', Icons.people, () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(builder: (_) => const CarePage()),
|
||||
);
|
||||
}),
|
||||
const SizedBox(height: 20),
|
||||
_buildBottomSheetItem(context, '返回桌面', Icons.exit_to_app, () {
|
||||
SystemNavigator.pop();
|
||||
@@ -210,14 +225,8 @@ class PopMenu extends StatelessWidget {
|
||||
VoidCallback? onTap,
|
||||
) {
|
||||
return ListTile(
|
||||
leading: Icon(
|
||||
icon,
|
||||
color: AppColors.primary,
|
||||
),
|
||||
title: Text(
|
||||
title,
|
||||
style: TextStyle(color: AppColors.primaryText),
|
||||
),
|
||||
leading: Icon(icon, color: AppColors.primary),
|
||||
title: Text(title, style: TextStyle(color: AppColors.primaryText)),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
HapticFeedback.lightImpact();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'dart:io' as io;
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -6,6 +5,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import '../../../utils/http/http_client.dart';
|
||||
import '../../../services/get/theme_controller.dart';
|
||||
import '../../../controllers/settings/is_platform.dart';
|
||||
import 'tougao.dart';
|
||||
|
||||
/// 时间: 2026-03-30
|
||||
@@ -55,28 +55,7 @@ class _ManuscriptPageState extends State<ManuscriptPage> {
|
||||
}
|
||||
|
||||
String _getPlatform() {
|
||||
try {
|
||||
final String osName = io.Platform.operatingSystem;
|
||||
if (osName == 'ohos' ||
|
||||
osName == 'harmonyos' ||
|
||||
osName == 'openharmony') {
|
||||
return 'HarmonyOS Flutter';
|
||||
} else if (io.Platform.isAndroid) {
|
||||
return 'Android Flutter';
|
||||
} else if (io.Platform.isIOS) {
|
||||
return 'iOS Flutter';
|
||||
} else if (io.Platform.isWindows) {
|
||||
return 'Windows Flutter';
|
||||
} else if (io.Platform.isMacOS) {
|
||||
return 'macOS Flutter';
|
||||
} else if (io.Platform.isLinux) {
|
||||
return 'Linux Flutter';
|
||||
} else {
|
||||
return 'Flutter';
|
||||
}
|
||||
} catch (e) {
|
||||
return 'Flutter';
|
||||
}
|
||||
return PlatformUtils.platformDisplayName;
|
||||
}
|
||||
|
||||
Future<void> _loadCategories() async {
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import '../../../services/get/theme_controller.dart';
|
||||
import '../../../controllers/settings/is_platform.dart';
|
||||
|
||||
/// 时间: 2026-03-27
|
||||
/// 功能: 应用数据管理页面
|
||||
@@ -95,7 +96,7 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
if (await parentDir.exists()) {
|
||||
await for (FileSystemEntity entity in parentDir.list()) {
|
||||
if (entity is Directory) {
|
||||
final dirName = entity.path.split(Platform.pathSeparator).last;
|
||||
final dirName = entity.path.split(PlatformUtils.pathSeparator).last;
|
||||
if (!dirName.startsWith('.')) {
|
||||
totalSize += await _getDirectorySize(entity);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ import 'dart:io' as io;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../constants/app_constants.dart';
|
||||
import '../../config/app_config.dart';
|
||||
import '../../models/colors/theme_colors.dart';
|
||||
import '../../controllers/settings/is_platform.dart';
|
||||
import 'history_page.dart';
|
||||
import 'per_card.dart';
|
||||
import 'settings/app_fun.dart';
|
||||
@@ -697,7 +697,7 @@ class ProfilePage extends StatelessWidget {
|
||||
bool isDark,
|
||||
Color primaryColor,
|
||||
) {
|
||||
if (kIsWeb) {
|
||||
if (PlatformUtils.isWeb) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: poes
|
||||
description: "腹有诗书气自华"
|
||||
publish_to: 'none'
|
||||
version: 1.4.1+26040202
|
||||
version: 1.4.3+26040203
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.2
|
||||
@@ -37,6 +37,7 @@ dependencies:
|
||||
get:
|
||||
git:
|
||||
url: https://gitcode.com/openharmony-sig/fluttertpc_get
|
||||
|
||||
pinyin: ^3.3.0
|
||||
|
||||
package_info_plus: ^9.0.1
|
||||
|
||||
70
wifi_device_helper.bat
Normal file
70
wifi_device_helper.bat
Normal file
@@ -0,0 +1,70 @@
|
||||
@echo off
|
||||
REM Flutter WiFi Device Connection Helper
|
||||
REM Helps connect and debug Flutter apps on WiFi-connected Android devices
|
||||
|
||||
echo ========================================
|
||||
echo Flutter WiFi Device Connection Helper
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Check if device is connected
|
||||
echo Checking connected devices...
|
||||
flutter devices
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo Available Actions:
|
||||
echo ========================================
|
||||
echo 1. Run on WiFi Device (SM T970 - 192.168.50.213:44263)
|
||||
echo 2. Run on USB Device (PKB110 - S48DTKPRVK4H8PKB)
|
||||
echo 3. Build APK only
|
||||
echo 4. Install APK to WiFi Device
|
||||
echo 5. Check device connection status
|
||||
echo 6. Exit
|
||||
echo ========================================
|
||||
|
||||
set /p choice="Enter your choice (1-6): "
|
||||
|
||||
if "%choice%"=="1" (
|
||||
echo.
|
||||
echo Running on WiFi Device with extended timeout...
|
||||
flutter run --device-id=192.168.50.213:44263 --device-timeout=120 --device-connection=wireless
|
||||
) else if "%choice%"=="2" (
|
||||
echo.
|
||||
echo Running on USB Device...
|
||||
flutter run --device-id=S48DTKPRVK4H8PKB --device-timeout=30 --device-connection=attached
|
||||
) else if "%choice%"=="3" (
|
||||
echo.
|
||||
echo Building APK...
|
||||
flutter build apk --debug
|
||||
) else if "%choice%"=="4" (
|
||||
echo.
|
||||
echo Installing APK to WiFi Device...
|
||||
if exist "build\app\outputs\flutter-apk\app-debug.apk" (
|
||||
"E:\sdk\android\platform-tools\adb.exe" -s 192.168.50.213:44263 install -r "build\app\outputs\flutter-apk\app-debug.apk"
|
||||
echo.
|
||||
echo APK installed successfully!
|
||||
echo Launching app...
|
||||
"E:\sdk\android\platform-tools\adb.exe" -s 192.168.50.213:44263 shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER app.wushu.poes/app.wushu.poes.MainActivity
|
||||
) else (
|
||||
echo APK not found. Please build it first (option 3).
|
||||
)
|
||||
) else if "%choice%"=="5" (
|
||||
echo.
|
||||
echo Checking device connection status...
|
||||
echo.
|
||||
echo ADB Devices:
|
||||
"E:\sdk\android\platform-tools\adb.exe" devices
|
||||
echo.
|
||||
echo Flutter Devices:
|
||||
flutter devices
|
||||
) else if "%choice%"=="6" (
|
||||
echo.
|
||||
echo Exiting...
|
||||
exit /b
|
||||
) else (
|
||||
echo Invalid choice. Please try again.
|
||||
)
|
||||
|
||||
echo.
|
||||
pause
|
||||
108
wifi_device_helper.ps1
Normal file
108
wifi_device_helper.ps1
Normal file
@@ -0,0 +1,108 @@
|
||||
# Flutter WiFi Device Connection Helper (PowerShell Version)
|
||||
# Helps connect and debug Flutter apps on WiFi-connected Android devices
|
||||
|
||||
function Show-Menu {
|
||||
Clear-Host
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Flutter WiFi Device Connection Helper" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Available Actions:" -ForegroundColor Yellow
|
||||
Write-Host "1. Run on WiFi Device (SM T970 - 192.168.50.213:44263)"
|
||||
Write-Host "2. Run on USB Device (PKB110 - S48DTKPRVK4H8PKB)"
|
||||
Write-Host "3. Build APK only"
|
||||
Write-Host "4. Install APK to WiFi Device"
|
||||
Write-Host "5. Check device connection status"
|
||||
Write-Host "6. Run with verbose logging (WiFi Device)"
|
||||
Write-Host "7. Exit"
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
function Check-Devices {
|
||||
Write-Host ""
|
||||
Write-Host "Checking connected devices..." -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "ADB Devices:" -ForegroundColor Yellow
|
||||
& "E:\sdk\android\platform-tools\adb.exe" devices
|
||||
Write-Host ""
|
||||
Write-Host "Flutter Devices:" -ForegroundColor Yellow
|
||||
flutter devices
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
function Run-OnWiFiDevice {
|
||||
Write-Host ""
|
||||
Write-Host "Running on WiFi Device with extended timeout..." -ForegroundColor Green
|
||||
flutter run --device-id=192.168.50.213:44263 --device-timeout=120 --device-connection=wireless
|
||||
}
|
||||
|
||||
function Run-OnUSBDevice {
|
||||
Write-Host ""
|
||||
Write-Host "Running on USB Device..." -ForegroundColor Green
|
||||
flutter run --device-id=S48DTKPRVK4H8PKB --device-timeout=30 --device-connection=attached
|
||||
}
|
||||
|
||||
function Build-APK {
|
||||
Write-Host ""
|
||||
Write-Host "Building APK..." -ForegroundColor Green
|
||||
flutter build apk --debug
|
||||
}
|
||||
|
||||
function Install-APK-WiFi {
|
||||
Write-Host ""
|
||||
$apkPath = "build\app\outputs\flutter-apk\app-debug.apk"
|
||||
|
||||
if (Test-Path $apkPath) {
|
||||
Write-Host "Installing APK to WiFi Device..." -ForegroundColor Green
|
||||
& "E:\sdk\android\platform-tools\adb.exe" -s 192.168.50.213:44263 install -r $apkPath
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host ""
|
||||
Write-Host "APK installed successfully!" -ForegroundColor Green
|
||||
Write-Host "Launching app..." -ForegroundColor Green
|
||||
& "E:\sdk\android\platform-tools\adb.exe" -s 192.168.50.213:44263 shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER app.wushu.poes/app.wushu.poes.MainActivity
|
||||
} else {
|
||||
Write-Host "APK installation failed!" -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host "APK not found at $apkPath" -ForegroundColor Red
|
||||
Write-Host "Please build it first (option 3)." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
function Run-Verbose-WiFi {
|
||||
Write-Host ""
|
||||
Write-Host "Running on WiFi Device with verbose logging..." -ForegroundColor Green
|
||||
flutter run --device-id=192.168.50.213:44263 --device-timeout=120 --device-connection=wireless --verbose
|
||||
}
|
||||
|
||||
# Main loop
|
||||
do {
|
||||
Show-Menu
|
||||
Check-Devices
|
||||
|
||||
$choice = Read-Host "Enter your choice (1-7)"
|
||||
|
||||
switch ($choice) {
|
||||
"1" { Run-OnWiFiDevice }
|
||||
"2" { Run-OnUSBDevice }
|
||||
"3" { Build-APK }
|
||||
"4" { Install-APK-WiFi }
|
||||
"5" { Check-Devices }
|
||||
"6" { Run-Verbose-WiFi }
|
||||
"7" {
|
||||
Write-Host ""
|
||||
Write-Host "Exiting..." -ForegroundColor Yellow
|
||||
exit
|
||||
}
|
||||
default {
|
||||
Write-Host ""
|
||||
Write-Host "Invalid choice. Please try again." -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
|
||||
if ($choice -ne "7") {
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue..."
|
||||
}
|
||||
} while ($choice -ne "7")
|
||||
Reference in New Issue
Block a user