Merge pull request '更新架构文档' (#2) from cody/update-Architecture-doc into dev

Reviewed-on: https://gitea.winwayinfo.com/CUS-IM/customer-im-client/pulls/2
This commit is contained in:
wangfeng
2026-03-06 18:53:35 +08:00
6 changed files with 80 additions and 15 deletions

View File

@@ -1400,7 +1400,7 @@ flowchart LR
<li>无法精确控制重建范围</li>
</ul>
<p><strong>实际案例UUTalk</strong></p>
<p><strong>实际案例:</strong></p>
<pre><code class="language-dart">// 整个 Container 都会重建
Obx(() =&gt; Container(
@@ -1636,7 +1636,7 @@ Get.put&lt;BaseController&gt;(ChatController());
final controller = Get.find&lt;UserController&gt;(); // 找到 ChatController类型不匹配
</code></pre>
<p><strong>运行时错误案例UUTalk 实际问题)</strong></p>
<p><strong>运行时错误案例:</strong></p>
<ul>
<li>Controller 未初始化</li>
<li>类型转换错误</li>
@@ -1683,16 +1683,16 @@ ChatViewModel
<li>重构安全IDE 自动提示依赖变化</li>
<li>团队协作:依赖关系明确,不会互相影响</li>
</ul>
<h4>GetX + Obx vs Riverpod来自 UUTalk 项目的实践教训</h4>
<h4>GetX + Obx vs Riverpod实践教训</h4>
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0;">
<p><strong>真实案例警示</strong></p>
<p>以下内容基于 <strong>UUTalk 项目</strong>的实际经验,展示了 GetX + Obx 在大型项目中暴露的严重问题</p>
<p><strong>典型问题示例</strong></p>
<p>以下内容展示了 GetX + Obx 在大型项目中暴露的典型问题,作为选型参考</p>
</div>
<h5>1. 状态管理混乱</h5>
<p><strong>UUTalk 项目的 GetX + Obx 问题代码chat_list_controller.dart</strong></p>
<p><strong>GetX + Obx 问题代码示例chat_list_controller.dart</strong></p>
<pre><code class="language-dart">class ChatListController extends GetxController {
var lastClickedSpecialChatId = (-1).obs;
@@ -1728,7 +1728,7 @@ ChatViewModel
<h5>2. 过度嵌套和性能问题</h5>
<p><strong>UUTalk 项目的 Obx 嵌套地狱home_view.dart</strong></p>
<p><strong>Obx 嵌套地狱示例home_view.dart</strong></p>
<pre><code class="language-dart">body: Obx(() =&gt; AnimatedPadding(
child: GetBuilder(
@@ -1765,7 +1765,7 @@ ChatViewModel
<h5>3. Controller 过于臃肿</h5>
<p><strong>UUTalk 项目的巨型 Controller</strong></p>
<p><strong>巨型 Controller 反模式示例</strong></p>
<pre><code class="language-dart">// chat_list_controller.dart
import 'dart:async';
@@ -1811,7 +1811,7 @@ class ChatListController extends GetxController
<h5>4. 没有编译时安全</h5>
<p><strong>UUTalk 项目的运行时陷阱:</strong></p>
<p><strong>GetX 运行时陷阱:</strong></p>
<pre><code class="language-dart">// 通过字符串查找 Controller运行时才知道对错
Get.find&lt;ChatListController&gt;();
@@ -1839,7 +1839,7 @@ class ChatListController extends GetxController {
<h5>5. 难以测试</h5>
<p><strong>UUTalk 项目的测试困境:</strong></p>
<p><strong>GetX 测试困境:</strong></p>
<pre><code class="language-dart">// 测试时必须初始化整个 GetX 框架
testWidgets('test chat list', (tester) async {
@@ -1865,7 +1865,7 @@ testWidgets('test chat list', (tester) async {
</ul>
</div>
<h5>GetX + Obx vs Riverpod 实际对比(基于 UUTalk 项目经验)</h5>
<h5>GetX + Obx vs Riverpod 实际对比</h5>
<table>
<thead>
@@ -1933,7 +1933,7 @@ testWidgets('test chat list', (tester) async {
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0;">
<div style="background-color: #f8d7da; border: 2px solid #dc3545; padding: 15px; border-radius: 8px;">
<p><strong>GetX + ObxUUTalk 现状)</strong></p>
<p><strong>GetX + Obx</strong></p>
<p><strong>状态混乱:</strong></p>
<pre><code class="language-dart">class ChatListController extends GetxController {
@@ -1999,10 +1999,10 @@ class ChatListViewModel extends StateNotifier&lt;ChatListState&gt; {
</div>
<h5>UUTalk 项目的痛点总结</h5>
<h5>GetX + Obx 痛点总结</h5>
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0;">
<p> UUTalk 项目的实际经验中,我们总结出 GetX + Obx 的核心问题:</p>
<p>实践经验中,我们总结出 GetX + Obx 的核心问题:</p>
<ol>
<li><strong>"快速开发"变成"技术债"</strong>:初期确实快,但 6 个月后代码无法维护</li>
<li><strong>"响应式"变成"性能杀手"</strong>Obx 嵌套导致过度重建,页面卡顿</li>
@@ -2014,7 +2014,7 @@ class ChatListViewModel extends StateNotifier&lt;ChatListState&gt; {
<div style="background-color: #d4edda; border-left: 4px solid #28a745; padding: 15px; margin: 20px 0;">
<p><strong>Riverpod 的技术优势</strong></p>
<p>基于 UUTalk 项目的实践教训,我们选择 Riverpod 作为新架构的状态管理方案,因为它从根本上解决了 GetX 的所有问题:</p>
<p>基于以上实践教训,我们选择 Riverpod 作为新架构的状态管理方案,因为它从根本上解决了 GetX 的所有问题:</p>
<ul>
<li><strong>编译时安全</strong>:不会再有运行时崩溃</li>
<li><strong>结构化状态</strong>@freezed 强制统一状态结构</li>

View File

@@ -47,6 +47,7 @@ if [ "$FORMAT" = "aab" ]; then
cd "$APP_DIR"
flutter build appbundle \
--release \
--no-pub \
--dart-define-from-file=config/config.json \
--split-debug-info="$DEBUG_INFO_DIR" \
--obfuscate
@@ -57,6 +58,7 @@ else
cd "$APP_DIR"
flutter build apk \
--release \
--no-pub \
--dart-define-from-file=config/config.json \
--split-debug-info="$DEBUG_INFO_DIR" \
--obfuscate

View File

@@ -41,6 +41,7 @@ cd "$APP_DIR"
flutter build ipa \
--release \
--no-pub \
--dart-define-from-file=config/config.json \
--split-debug-info="$DEBUG_INFO_DIR" \
--obfuscate

View File

@@ -37,6 +37,7 @@ cd "$APP_DIR"
flutter build macos \
--release \
--no-pub \
--dart-define-from-file=config/config.json \
--split-debug-info="$DEBUG_INFO_DIR" \
--obfuscate

View File

@@ -39,6 +39,7 @@ cd "$APP_DIR"
flutter build windows \
--release \
--no-pub \
--dart-define-from-file=config/config.json \
--split-debug-info="$DEBUG_INFO_DIR" \
--obfuscate

60
scripts/pre-commit Normal file
View File

@@ -0,0 +1,60 @@
#!/bin/bash
# Git pre-commit hook提交前自动 formatanalyze 有 error 则拦截提交
#
# 安装bash scripts/setup.shsetup.sh 自动把本文件复制到 .git/hooks/pre-commit
# 手动安装cp scripts/pre-commit .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
set -euo pipefail
ROOT_DIR="$(git rev-parse --show-toplevel)"
DART="$(command -v dart 2>/dev/null || echo "")"
if [[ -z "$DART" ]]; then
echo "[pre-commit] dart not found, skipping checks."
exit 0
fi
# ── pubspec.lock 保护 ────────────────────────────────────────────────────────
# flutter run / flutter build 会在未经授权的情况下触发 pub get 并修改 lock。
# 规则lock 有未暂存的改动(意外修改)→ 自动还原;
# 开发者主动 git add pubspec.lock 后(暂存)→ 正常放行。
LOCK_UNSTAGED=$(git diff --name-only pubspec.lock 2>/dev/null || true)
LOCK_STAGED=$(git diff --cached --name-only pubspec.lock 2>/dev/null || true)
if [[ -n "$LOCK_UNSTAGED" && -z "$LOCK_STAGED" ]]; then
git checkout HEAD -- pubspec.lock
echo "[pre-commit] pubspec.lock was auto-modified by flutter, restored to HEAD."
echo " To intentionally update: run 'dart pub get' or 'dart pub upgrade',"
echo " then 'git add pubspec.lock' before committing."
fi
# ── dart format + analyze ────────────────────────────────────────────────────
STAGED_DART=$(git diff --cached --name-only --diff-filter=ACM | grep '\.dart$' || true)
if [[ -z "$STAGED_DART" ]]; then
exit 0
fi
echo "[pre-commit] formatting staged dart files..."
echo "$STAGED_DART" | xargs dart format --line-length=80
echo "$STAGED_DART" | xargs git add
echo "[pre-commit] running dart analyze..."
cd "$ROOT_DIR"
ANALYZE_OUTPUT=$(dart analyze 2>&1)
if echo "$ANALYZE_OUTPUT" | grep -q "^ error"; then
echo "[pre-commit] dart analyze found errors, commit blocked."
echo "$ANALYZE_OUTPUT" | grep "^ error"
exit 1
fi
if echo "$ANALYZE_OUTPUT" | grep -q "^ warning"; then
echo "[pre-commit] dart analyze found warnings, commit blocked."
echo "$ANALYZE_OUTPUT" | grep "^ warning"
exit 1
fi
echo "[pre-commit] all checks passed."
exit 0