chore: 完成v6.5.58版本迭代更新
本次更新包含多项功能优化与bug修复: 1. 新增flutter_keyboard_visibility依赖替代MediaQuery轮询获取键盘状态 2. 添加远程功能标志API支持与FeatureFlag服务 3. 重构壁纸背景渲染组件,统一全局壁纸展示逻辑 4. 延迟初始化壁纸源健康检测至用户同意协议后 5. 修复预测返回/长按预览锁定问题并移除相关配置项 6. 优化日志输出控制,release模式仅保留错误日志 7. 新增进度模块多语言翻译与相关UI字段 8. 优化稍后读功能,取消时同步删除聊天消息 9. 更新权限说明文档,移除冗余的存储写入权限配置 10. 重构部分UI组件减少参数传递,优化性能
This commit is contained in:
@@ -261,9 +261,9 @@
|
||||
<div class="content-card">
|
||||
<div id="content-zh" class="lang-content">
|
||||
<p><strong>闲言APP</strong> 隐私政策</p>
|
||||
<p>版本号:V6.5</p>
|
||||
<p>更新日期:2026年5月20日</p>
|
||||
<p>生效日期:2026年5月21日</p>
|
||||
<p>版本号:V6.6</p>
|
||||
<p>更新日期:2026年5月30日</p>
|
||||
<p>生效日期:2026年5月31日</p>
|
||||
<p><strong>弥勒市朋普镇微风暴网络科技工作室</strong>(以下简称"我们")深知个人信息对您的重要性,我们将按照法律法规的规定,保护您的个人信息及隐私安全。我们制定本隐私政策以帮助您了解我们如何收集、使用、存储和保护您的个人信息。本政策适用于<strong>闲言APP</strong>提供的所有服务。</p>
|
||||
<h2>零、定义</h2>
|
||||
<p>本隐私政策中使用的术语定义如下:</p>
|
||||
@@ -285,12 +285,17 @@
|
||||
<li>设备信息:设备型号、操作系统版本、设备标识符、屏幕分辨率(用于兼容性优化和崩溃分析)</li>
|
||||
<li>应用信息:应用版本号、构建号(用于版本管理和功能适配)</li>
|
||||
<li>日志信息:崩溃日志、性能指标(用于提升应用稳定性)</li>
|
||||
<li>设备指纹信息:设备唯一标识符(device_id)、User-Agent,用于设备识别和安全验证</li>
|
||||
<li>IP地址信息:您的IP地址及IP归属地,用于安全验证、异常登录检测和城市级位置服务</li>
|
||||
<li>互动行为信息:您的浏览记录、搜索关键词、点赞、收藏、分享、评论等互动行为,用于个性化推荐和服务优化</li>
|
||||
<li>阅读行为信息:阅读时长、阅读进度,用于阅读统计和个性化推荐</li>
|
||||
</ul>
|
||||
<h3>1.2 您主动提供的信息</h3>
|
||||
<ul>
|
||||
<li>账号信息:注册时提供的手机号/邮箱、昵称、头像</li>
|
||||
<li>个人偏好:主题设置、字体大小、阅读偏好等个性化配置</li>
|
||||
<li>用户内容:您发布的笔记、文章、评论等</li>
|
||||
<li>安全信息:密保问题和答案(加密存储),用于账号安全验证</li>
|
||||
</ul>
|
||||
<h3>1.3 我们不会收集的信息</h3>
|
||||
<ul>
|
||||
@@ -421,10 +426,11 @@
|
||||
<h2>三、我们如何存储信息</h2>
|
||||
<h3>3.1 存储方式</h3>
|
||||
<ul>
|
||||
<li>本地存储:个人偏好设置存储在应用沙盒的 SharedPreferences 中</li>
|
||||
<li>缓存数据:内容缓存存储在应用临时目录,可随时清理</li>
|
||||
<li>结构化数据:收藏、笔记等存储在本地 SQLite 数据库</li>
|
||||
<li>服务端数据:账号信息、同步数据等存储在加密的云服务器</li>
|
||||
<li>本地存储:个人偏好设置存储在应用沙盒的 SharedPreferences 和 Hive 数据库中</li>
|
||||
<li>缓存数据:图片缓存、内容缓存存储在应用临时目录,可随时清理</li>
|
||||
<li>结构化数据:收藏、笔记、阅读历史等存储在本地 SQLite 数据库</li>
|
||||
<li>服务端数据:账号信息、用户资料、设备信息、互动记录、搜索历史、用户偏好画像等存储在云服务器MySQL数据库中</li>
|
||||
<li>云端暂存:加密文件通过云端暂存服务在设备间传输,采用端到端加密</li>
|
||||
</ul>
|
||||
<h3>3.2 存储地域</h3>
|
||||
<p>您的数据存储在<span class="highlight">中华人民共和国境内</span>的服务器上。当前我们<span class="highlight">不会</span>将您的个人信息传输至中华人民共和国境外。如未来因业务需要确需跨境传输,我们将按照法律法规要求进行<span class="highlight">安全评估</span>并获得您的<span class="highlight">单独同意</span>,并确保境外接收方的数据保护能力达到法律法规要求的标准。</p>
|
||||
@@ -470,6 +476,26 @@
|
||||
<td>账号存续期间</td>
|
||||
<td>注销或关闭推送时删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>设备信息与IP地址</td>
|
||||
<td>账号存续期间</td>
|
||||
<td>注销后删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>互动行为记录</td>
|
||||
<td>账号存续期间</td>
|
||||
<td>注销后删除,IP数据6个月后匿名化</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>搜索历史</td>
|
||||
<td>账号存续期间</td>
|
||||
<td>注销后删除</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户偏好画像</td>
|
||||
<td>账号存续期间</td>
|
||||
<td>注销后删除</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p>法律法规要求保留的日志信息,保留期限不超过<span class="highlight">6个月</span>。超出上述期限后,我们将删除或匿名化处理您的个人信息。</p>
|
||||
<h3>3.4 安全措施</h3>
|
||||
@@ -527,6 +553,13 @@
|
||||
<td>用户认证、数据存储与同步</td>
|
||||
<td>https://supabase.com/privacy</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>WebRTC</td>
|
||||
<td>Google LLC / 开源社区</td>
|
||||
<td>不额外收集个人信息</td>
|
||||
<td>局域网文件传输</td>
|
||||
<td>https://webrtc.org/privacy</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p class="note">说明:</p>
|
||||
<ul>
|
||||
@@ -632,6 +665,7 @@
|
||||
<li>邮箱:2821981550@qq.com</li>
|
||||
<li>应用内反馈:我的 → 关于 → 用户反馈</li>
|
||||
<li>通信地址:云南省昆明市西山区滇池度假区(碧鸡街道车家壁513号)</li>
|
||||
<li>ICP备案号:滇ICP备2022000863号-18A</li>
|
||||
</ul>
|
||||
<p>我们将在<span class="highlight">15个工作日</span>内回复您的隐私相关请求。</p>
|
||||
<p>个人信息保护负责人:李先生(邮箱:gg@0gg.cc)</p>
|
||||
@@ -664,9 +698,9 @@
|
||||
</div>
|
||||
<div id="content-en" class="lang-content" style="display:none;">
|
||||
<p><strong>Xianyan APP</strong> Privacy Policy</p>
|
||||
<p>Version: V6.5</p>
|
||||
<p>Updated: May 20, 2026</p>
|
||||
<p>Effective: May 21, 2026</p>
|
||||
<p>Version: V6.6</p>
|
||||
<p>Updated: May 30, 2026</p>
|
||||
<p>Effective: May 31, 2026</p>
|
||||
<p>Zero. Definitions</p>
|
||||
<ul>
|
||||
<li>**Personal Information**: Information that can identify a natural person, including but not limited to name, date of birth, ID number, biometric information, address, phone number, email, etc.</li>
|
||||
@@ -685,12 +719,17 @@
|
||||
<li>Profile information: avatar, personal signature</li>
|
||||
<li>Content you publish: sentences, notes, articles, comments</li>
|
||||
<li>Feedback and suggestions: content you submit through the feedback feature</li>
|
||||
<li>Security information: security questions and answers (encrypted storage), used for account security verification</li>
|
||||
</ul>
|
||||
<h3>1.2 Information Collected Automatically During Service Use</h3>
|
||||
<ul>
|
||||
<li>Device information: device model, operating system version, device identifier (IDFA/Android ID), screen resolution</li>
|
||||
<li>Log information: access time, pages visited, click events, crash logs</li>
|
||||
<li>Network information: network type (WiFi/4G/5G), carrier information</li>
|
||||
<li>Device fingerprint information: device unique identifier (device_id), User-Agent, used for device identification and security verification</li>
|
||||
<li>IP address information: your IP address and IP geolocation, used for security verification, abnormal login detection, and city-level location services</li>
|
||||
<li>Interaction behavior information: your browsing history, search keywords, likes, favorites, shares, comments, and other interaction behaviors, used for personalized recommendations and service optimization</li>
|
||||
<li>Reading behavior information: reading duration, reading progress, used for reading statistics and personalized recommendations</li>
|
||||
</ul>
|
||||
<h3>1.3 Information from Third-Party Services</h3>
|
||||
<ul>
|
||||
@@ -764,6 +803,11 @@
|
||||
<ul>
|
||||
<li>Your personal information is stored on servers located within the People's Republic of China</li>
|
||||
<li>We currently do not engage in cross-border data transfer</li>
|
||||
<li>Local storage: personal preferences are stored in the app sandbox's SharedPreferences and Hive database</li>
|
||||
<li>Cached data: image cache and content cache are stored in the app's temporary directory and can be cleared at any time</li>
|
||||
<li>Structured data: favorites, notes, reading history, etc. are stored in the local SQLite database</li>
|
||||
<li>Server data: account information, user profiles, device information, interaction records, search history, user preference profiles, etc. are stored in the cloud server MySQL database</li>
|
||||
<li>Cloud staging: encrypted files are transferred between devices through the cloud staging service, using end-to-end encryption</li>
|
||||
</ul>
|
||||
<h3>3.2 Storage Period</h3>
|
||||
<table><thead><tr>
|
||||
@@ -806,6 +850,26 @@
|
||||
<td>Duration of account existence</td>
|
||||
<td>User can delete at any time</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Device Information & IP Address</td>
|
||||
<td>Duration of account existence</td>
|
||||
<td>Deleted after account deletion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Interaction Behavior Records</td>
|
||||
<td>Duration of account existence</td>
|
||||
<td>Deleted after account deletion, IP data anonymized after 6 months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Search History</td>
|
||||
<td>Duration of account existence</td>
|
||||
<td>Deleted after account deletion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Preference Profile</td>
|
||||
<td>Duration of account existence</td>
|
||||
<td>Deleted after account deletion</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h3>3.3 Security Measures</h3>
|
||||
<ul>
|
||||
@@ -853,6 +917,13 @@
|
||||
<td>Backend services</td>
|
||||
<td>https://supabase.com/privacy</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>WebRTC</td>
|
||||
<td>Google LLC / Open Source Community</td>
|
||||
<td>No additional personal information collected</td>
|
||||
<td>LAN file transfer</td>
|
||||
<td>https://webrtc.org/privacy</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<h2>V. Your Rights</h2>
|
||||
<h3>5.1 You have the right to:</h3>
|
||||
@@ -901,6 +972,7 @@
|
||||
<li>Email: 2821981550@qq.com</li>
|
||||
<li>In-app feedback: My → About → User Feedback</li>
|
||||
<li>Mailing address: Dianchi Resort Area, Xishan District, Kunming, Yunnan Province, China (Bijie Subdistrict, Chejiabi No. 513)</li>
|
||||
<li>ICP Registration: 滇ICP备2022000863号-18A</li>
|
||||
<li>Personal Information Protection Officer: Mr. Li (Email: gg@0gg.cc)</li>
|
||||
</ul>
|
||||
<p>We will respond to your privacy-related requests within <span class="highlight">15 working days</span>.</p>
|
||||
|
||||
210
docs/toolsapi/application/api/controller/FeatureFlag.php
Normal file
210
docs/toolsapi/application/api/controller/FeatureFlag.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\common\controller\Api;
|
||||
|
||||
/**
|
||||
* @name 功能标志接口
|
||||
* @author AI Coder
|
||||
* @date 2026-05-30
|
||||
* @desc 提供Feature Flag远程配置,支持灰度发布和A/B测试
|
||||
* @update v1.0 初始版本,支持列表查询和单个检查
|
||||
*/
|
||||
class FeatureFlag extends Api
|
||||
{
|
||||
protected $noNeedLogin = ['*'];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
private static $flags = [
|
||||
[
|
||||
'key' => 'ai_summary',
|
||||
'name' => 'AI智能摘要',
|
||||
'description' => '自动为长文生成摘要',
|
||||
'emoji' => '🤖',
|
||||
'enabled' => true,
|
||||
'status' => 'testing',
|
||||
'progress' => 0.7,
|
||||
'rollout_percentage' => 0.3,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'theme_store',
|
||||
'name' => '主题商店',
|
||||
'description' => '下载和分享自定义主题',
|
||||
'emoji' => '🎨',
|
||||
'enabled' => false,
|
||||
'status' => 'developing',
|
||||
'progress' => 0.4,
|
||||
'rollout_percentage' => 0.0,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'reading_report',
|
||||
'name' => '阅读报告',
|
||||
'description' => '年度/月度阅读数据可视化',
|
||||
'emoji' => '📊',
|
||||
'enabled' => true,
|
||||
'status' => 'preview',
|
||||
'progress' => 0.9,
|
||||
'rollout_percentage' => 0.5,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'cross_device_sync',
|
||||
'name' => '跨设备同步',
|
||||
'description' => '实时同步阅读进度和收藏',
|
||||
'emoji' => '🔄',
|
||||
'enabled' => false,
|
||||
'status' => 'developing',
|
||||
'progress' => 0.3,
|
||||
'rollout_percentage' => 0.0,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'voice_reading',
|
||||
'name' => '语音朗读',
|
||||
'description' => 'AI语音朗读句子和文章',
|
||||
'emoji' => '🎵',
|
||||
'enabled' => true,
|
||||
'status' => 'testing',
|
||||
'progress' => 0.6,
|
||||
'rollout_percentage' => 0.2,
|
||||
'target_group' => 'ab_test_voice',
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'home_widget',
|
||||
'name' => '桌面小组件',
|
||||
'description' => 'iOS/Android桌面Widget',
|
||||
'emoji' => '📱',
|
||||
'enabled' => true,
|
||||
'status' => 'preview',
|
||||
'progress' => 0.85,
|
||||
'rollout_percentage' => 0.8,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'nearby_discovery',
|
||||
'name' => '近场发现',
|
||||
'description' => '基于蓝牙/WiFi的近场内容发现',
|
||||
'emoji' => '📡',
|
||||
'enabled' => false,
|
||||
'status' => 'developing',
|
||||
'progress' => 0.15,
|
||||
'rollout_percentage' => 0.0,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
[
|
||||
'key' => 'shader_background',
|
||||
'name' => '特效背景',
|
||||
'description' => 'Metal/Vulkan着色器动态背景',
|
||||
'emoji' => '✨',
|
||||
'enabled' => false,
|
||||
'status' => 'developing',
|
||||
'progress' => 0.25,
|
||||
'rollout_percentage' => 0.0,
|
||||
'target_group' => null,
|
||||
'expires_at' => null,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @name 获取所有Feature Flag列表
|
||||
* @desc 返回所有功能标志配置,支持按status筛选
|
||||
*/
|
||||
public function list()
|
||||
{
|
||||
$status = $this->request->param('status', '');
|
||||
|
||||
$flags = self::$flags;
|
||||
|
||||
if (!empty($status)) {
|
||||
$flags = array_values(array_filter($flags, function ($f) use ($status) {
|
||||
return $f['status'] === $status;
|
||||
}));
|
||||
}
|
||||
|
||||
$summary = [
|
||||
'total' => count($flags),
|
||||
'developing' => count(array_filter($flags, function ($f) { return $f['status'] === 'developing'; })),
|
||||
'testing' => count(array_filter($flags, function ($f) { return $f['status'] === 'testing'; })),
|
||||
'preview' => count(array_filter($flags, function ($f) { return $f['status'] === 'preview'; })),
|
||||
'released' => count(array_filter($flags, function ($f) { return $f['status'] === 'released'; })),
|
||||
];
|
||||
|
||||
$this->success('成功', [
|
||||
'flags' => $flags,
|
||||
'summary' => $summary,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name 检查单个Flag状态
|
||||
* @desc 根据key查询单个功能标志的启用状态
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$key = $this->request->param('key', '');
|
||||
|
||||
if (empty($key)) {
|
||||
$this->error('缺少key参数');
|
||||
}
|
||||
|
||||
$flag = null;
|
||||
foreach (self::$flags as $f) {
|
||||
if ($f['key'] === $key) {
|
||||
$flag = $f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($flag === null) {
|
||||
$this->error('未找到该功能标志', null, 404);
|
||||
}
|
||||
|
||||
$userId = $this->request->param('user_id', '');
|
||||
$rolloutAllowed = true;
|
||||
|
||||
if ($flag['enabled'] && $flag['rollout_percentage'] < 1.0) {
|
||||
$rolloutAllowed = $this->_isRolloutAllowed($key, $userId, $flag['rollout_percentage']);
|
||||
}
|
||||
|
||||
$isAvailable = $flag['enabled'] && $rolloutAllowed;
|
||||
|
||||
if (!empty($flag['expires_at'])) {
|
||||
$expiresAt = strtotime($flag['expires_at']);
|
||||
if ($expiresAt !== false && time() > $expiresAt) {
|
||||
$isAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('成功', [
|
||||
'flag' => $flag,
|
||||
'is_available' => $isAvailable,
|
||||
'rollout_allowed' => $rolloutAllowed,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name 灰度放量判断
|
||||
* @desc 基于用户ID哈希判断是否在灰度范围内
|
||||
*/
|
||||
private function _isRolloutAllowed($flagKey, $userId, $percentage)
|
||||
{
|
||||
if ($percentage >= 1.0) return true;
|
||||
if ($percentage <= 0.0) return false;
|
||||
|
||||
$combined = $flagKey . ':' . $userId;
|
||||
$hash = crc32($combined) & 0x7FFFFFFF;
|
||||
$bucket = $hash % 100;
|
||||
|
||||
return $bucket < ($percentage * 100);
|
||||
}
|
||||
}
|
||||
@@ -200,6 +200,12 @@ Route::rule([
|
||||
'api/fortune/push' => 'api/Fortune/push',
|
||||
]);
|
||||
|
||||
// APP API路由 - 功能标志
|
||||
Route::rule([
|
||||
'api/feature_flag/list' => 'api/FeatureFlag/list',
|
||||
'api/feature_flag/check' => 'api/FeatureFlag/check',
|
||||
]);
|
||||
|
||||
// 工具分类
|
||||
Route::get([
|
||||
// 教育学习
|
||||
|
||||
Reference in New Issue
Block a user