hookehuyr

docs(architecture): 添加项目完整架构图

- 新增 docs/architecture.drawio 架构图文件
- 展示技术栈层:Taro + Vue 3 + NutUI + Pinia + TailwindCSS
- 展示核心架构层:认证流程、状态管理、Composables 体系
- 展示可复用组件体系:导航、列表、业务组件
- 展示业务模块层:7 大业务模块及关系
- 包含数据流向和架构特性说明

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 +<mxfile host="65bd71144e">
2 + <diagram id="b5dOQcsEGuaq2pC0fEqS" name="第 1 页">
3 + <mxGraphModel dx="1990" dy="1355" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="1600" pageHeight="1200" math="0" shadow="0">
4 + <root>
5 + <mxCell id="0"/>
6 + <mxCell id="1" parent="0"/>
7 + <mxCell id="title" value="Manulife WeApp 项目架构图" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=32;fontStyle=1;fontFamily=Noto Sans JP;" parent="1" vertex="1">
8 + <mxGeometry x="560" y="20" width="480" height="40" as="geometry"/>
9 + </mxCell>
10 + <mxCell id="version" value="版本: 1.0.0 | 更新时间: 2026-02-15 | 作者: Claude Code" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=14;fontColor=#666666;fontFamily=Noto Sans JP;" parent="1" vertex="1">
11 + <mxGeometry x="560" y="60" width="480" height="30" as="geometry"/>
12 + </mxCell>
13 + <mxCell id="tech-stack-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;strokeWidth=2;dashed=1;" parent="1" vertex="1">
14 + <mxGeometry x="40" y="120" width="1520" height="160" as="geometry"/>
15 + </mxCell>
16 + <mxCell id="tech-stack-title" value="技术栈层 (Technology Stack)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Noto Sans JP;" parent="1" vertex="1">
17 + <mxGeometry x="60" y="130" width="400" height="30" as="geometry"/>
18 + </mxCell>
19 + <mxCell id="taro-box" value="&lt;b&gt;Taro 4.1.9&lt;/b&gt;&lt;br&gt;跨端框架" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
20 + <mxGeometry x="60" y="180" width="200" height="80" as="geometry"/>
21 + </mxCell>
22 + <mxCell id="vue-box" value="&lt;b&gt;Vue 3.3.0&lt;/b&gt;&lt;br&gt;Composition API" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
23 + <mxGeometry x="280" y="180" width="200" height="80" as="geometry"/>
24 + </mxCell>
25 + <mxCell id="nutui-box" value="&lt;b&gt;NutUI 4.3.13&lt;/b&gt;&lt;br&gt;UI 组件库" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
26 + <mxGeometry x="500" y="180" width="200" height="80" as="geometry"/>
27 + </mxCell>
28 + <mxCell id="pinia-box" value="&lt;b&gt;Pinia 3.0.3&lt;/b&gt;&lt;br&gt;状态管理" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
29 + <mxGeometry x="720" y="180" width="200" height="80" as="geometry"/>
30 + </mxCell>
31 + <mxCell id="axios-box" value="&lt;b&gt;axios-miniprogram&lt;/b&gt;&lt;br&gt;HTTP 客户端" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
32 + <mxGeometry x="940" y="180" width="200" height="80" as="geometry"/>
33 + </mxCell>
34 + <mxCell id="style-box" value="&lt;b&gt;Less + TailwindCSS&lt;/b&gt;&lt;br&gt;样式系统 (375px/750px)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
35 + <mxGeometry x="1160" y="180" width="200" height="80" as="geometry"/>
36 + </mxCell>
37 + <mxCell id="mock-box" value="&lt;b&gt;Mock Data System&lt;/b&gt;&lt;br&gt;开发测试工具" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e6e6e6;strokeColor=#999999;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;" parent="1" vertex="1">
38 + <mxGeometry x="1380" y="180" width="160" height="80" as="geometry"/>
39 + </mxCell>
40 + <mxCell id="core-arch-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e3f2fd;strokeColor=#1976d2;strokeWidth=2;" parent="1" vertex="1">
41 + <mxGeometry x="40" y="370" width="1520" height="320" as="geometry"/>
42 + </mxCell>
43 + <mxCell id="core-arch-title" value="核心架构层 (Core Architecture)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Noto Sans JP;" parent="1" vertex="1">
44 + <mxGeometry x="60" y="380" width="400" height="30" as="geometry"/>
45 + </mxCell>
46 + <mxCell id="auth-flow" value="&lt;b&gt;认证流程&lt;/b&gt;&lt;br&gt;1. miniProgramAuth()&lt;br&gt;2. 401 自动刷新&lt;br&gt;3. sessionid 管理" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbdefb;strokeColor=#1976d2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
47 + <mxGeometry x="60" y="430" width="280" height="100" as="geometry"/>
48 + </mxCell>
49 + <mxCell id="interceptor" value="&lt;b&gt;请求拦截器&lt;/b&gt;&lt;br&gt;• 自动注入 sessionid&lt;br&gt;• 统一错误处理&lt;br&gt;• 401 重试机制" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbdefb;strokeColor=#1976d2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
50 + <mxGeometry x="360" y="430" width="280" height="100" as="geometry"/>
51 + </mxCell>
52 + <mxCell id="state-mgmt" value="&lt;b&gt;状态管理 (Pinia)&lt;/b&gt;&lt;br&gt;• main.js - 全局状态&lt;br&gt;• user.js - 用户状态&lt;br&gt;• router.js - 路由状态" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbdefb;strokeColor=#1976d2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
53 + <mxGeometry x="660" y="430" width="280" height="100" as="geometry"/>
54 + </mxCell>
55 + <mxCell id="composables" value="&lt;b&gt;Composables 体系&lt;/b&gt;&lt;br&gt;• useSectionList - 分组列表&lt;br&gt;• useFileOperation - 文件操作&lt;br&gt;• useListItemClick - 列表点击&lt;br&gt;• useCollectOperation - 收藏&lt;br&gt;• usePermission - 权限" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbdefb;strokeColor=#1976d2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
56 + <mxGeometry x="960" y="420" width="280" height="120" as="geometry"/>
57 + </mxCell>
58 + <mxCell id="utils" value="&lt;b&gt;工具函数&lt;/b&gt;&lt;br&gt;• request.js - HTTP&lt;br&gt;• openid.js - 认证&lt;br&gt;• mockData.js - Mock&lt;br&gt;• documentIcons.js - 图标&lt;br&gt;• tools.js - 通用工具" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbdefb;strokeColor=#1976d2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
59 + <mxGeometry x="1260" y="420" width="280" height="120" as="geometry"/>
60 + </mxCell>
61 + <mxCell id="arch-features" value="&lt;b&gt;核心特性&lt;/b&gt;&lt;br&gt;• 双设计宽度: NutUI 375px / 其他 750px&lt;br&gt;• 样式策略: TailwindCSS 80% + Less 20%&lt;br&gt;• 组件抽取: &quot;第 3 次出现原则&quot;&lt;br&gt;• 路径别名: @/utils, @/components, @/api 等" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1f5fe;strokeColor=#0288d1;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
62 + <mxGeometry x="60" y="550" width="600" height="120" as="geometry"/>
63 + </mxCell>
64 + <mxCell id="api-layer" value="&lt;b&gt;API 层&lt;/b&gt;&lt;br&gt;• buildApiUrl() - 统一接口定义&lt;br&gt;• fn() - 请求包装器&lt;br&gt;• 统一返回结构: {code, data, msg}" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1f5fe;strokeColor=#0288d1;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
65 + <mxGeometry x="680" y="550" width="500" height="120" as="geometry"/>
66 + </mxCell>
67 + <mxCell id="hooks" value="&lt;b&gt;自定义 Hooks&lt;/b&gt;&lt;br&gt;• useGo - 增强导航&lt;br&gt;• 自动补全路径&lt;br&gt;• 统一跳转逻辑" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1f5fe;strokeColor=#0288d1;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
68 + <mxGeometry x="1200" y="550" width="340" height="120" as="geometry"/>
69 + </mxCell>
70 + <mxCell id="component-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3e5f5;strokeColor=#7b1fa2;strokeWidth=2;" parent="1" vertex="1">
71 + <mxGeometry x="40" y="780" width="760" height="280" as="geometry"/>
72 + </mxCell>
73 + <mxCell id="component-title" value="可复用组件体系 (Reusable Components)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Noto Sans JP;" parent="1" vertex="1">
74 + <mxGeometry x="40" y="730" width="400" height="30" as="geometry"/>
75 + </mxCell>
76 + <mxCell id="nav-components" value="&lt;b&gt;导航组件&lt;/b&gt;&lt;br&gt;• TabBar - 底部导航&lt;br&gt;• NavHeader - 导航头&lt;br&gt;• IconFont - 图标字体" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1bee7;strokeColor=#7b1fa2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
77 + <mxGeometry x="70" y="810" width="220" height="100" as="geometry"/>
78 + </mxCell>
79 + <mxCell id="list-components" value="&lt;b&gt;列表组件&lt;/b&gt;&lt;br&gt;• MaterialCard - 资料卡片&lt;br&gt;• ProductCard - 产品卡片&lt;br&gt;• SectionCard - 分组卡片" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1bee7;strokeColor=#7b1fa2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
80 + <mxGeometry x="300" y="810" width="220" height="100" as="geometry"/>
81 + </mxCell>
82 + <mxCell id="business-components" value="&lt;b&gt;业务组件&lt;/b&gt;&lt;br&gt;• PlanPopup - 计划书弹窗&lt;br&gt;• PlanFields - 表单字段集&lt;br&gt;• DocumentPreview - 文档预览" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1bee7;strokeColor=#7b1fa2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
83 + <mxGeometry x="530" y="810" width="240" height="100" as="geometry"/>
84 + </mxCell>
85 + <mxCell id="component-features" value="&lt;b&gt;组件设计原则&lt;/b&gt;&lt;br&gt;• 自包含业务逻辑(查看、收藏等)&lt;br&gt;• 通过事件与父组件通信&lt;br&gt;• Props 有类型定义和默认值&lt;br&gt;• &lt;script setup&gt; 语法" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3e5f5;strokeColor=#7b1fa2;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
86 + <mxGeometry x="60" y="950" width="720" height="100" as="geometry"/>
87 + </mxCell>
88 + <mxCell id="module-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff9c4;strokeColor=#f57c00;strokeWidth=2;" parent="1" vertex="1">
89 + <mxGeometry x="850" y="780" width="740" height="280" as="geometry"/>
90 + </mxCell>
91 + <mxCell id="module-title" value="业务模块层 (Business Modules)" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=20;fontStyle=1;fontFamily=Noto Sans JP;" parent="1" vertex="1">
92 + <mxGeometry x="870" y="790" width="400" height="30" as="geometry"/>
93 + </mxCell>
94 + <mxCell id="product-module" value="&lt;b&gt;产品展示模块&lt;/b&gt;&lt;br&gt;• 首页&lt;br&gt;• 产品中心&lt;br&gt;• 产品详情" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff59d;strokeColor=#f57c00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
95 + <mxGeometry x="870" y="840" width="160" height="100" as="geometry"/>
96 + </mxCell>
97 + <mxCell id="material-module" value="&lt;b&gt;资料库模块&lt;/b&gt;&lt;br&gt;• 资料列表&lt;br&gt;• 周热门资料&lt;br&gt;• 文档预览" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff59d;strokeColor=#f57c00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
98 + <mxGeometry x="1050" y="840" width="160" height="100" as="geometry"/>
99 + </mxCell>
100 + <mxCell id="plan-module" value="&lt;b&gt;计划书模块&lt;/b&gt;&lt;br&gt;• 计划书列表&lt;br&gt;• 计划书提交&lt;br&gt;• 计划书预览" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff59d;strokeColor=#f57c00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
101 + <mxGeometry x="1230" y="840" width="160" height="100" as="geometry"/>
102 + </mxCell>
103 + <mxCell id="message-module" value="&lt;b&gt;消息系统&lt;/b&gt;&lt;br&gt;• 消息列表&lt;br&gt;• 消息详情&lt;br&gt;• TabBar红点" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff59d;strokeColor=#f57c00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
104 + <mxGeometry x="1410" y="840" width="160" height="100" as="geometry"/>
105 + </mxCell>
106 + <mxCell id="other-modules" value="&lt;b&gt;其他模块&lt;/b&gt;&lt;br&gt;• 家办服务 • 签单流程 • 用户中心(个人资料、收藏、反馈、帮助中心)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff9c4;strokeColor=#f57c00;strokeWidth=2;fontSize=16;fontFamily=Noto Sans JP;align=left;spacingLeft=10;" parent="1" vertex="1">
107 + <mxGeometry x="870" y="980" width="700" height="50" as="geometry"/>
108 + </mxCell>
109 + <mxCell id="arrow1" value="" style="endArrow=classic;html=1;strokeWidth=3;strokeColor=#666666;entryX=0.5;entryY=0;exitX=0.5;exitY=1;" parent="1" source="tech-stack-bg" target="core-arch-bg" edge="1">
110 + <mxGeometry width="50" height="50" relative="1" as="geometry">
111 + <mxPoint x="800" y="280" as="sourcePoint"/>
112 + <mxPoint x="800" y="320" as="targetPoint"/>
113 + </mxGeometry>
114 + </mxCell>
115 + <mxCell id="flow-label1" value="依赖" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontStyle=1;fontFamily=Noto Sans JP;labelBackgroundColor=#ffffff;" parent="arrow1" vertex="1" connectable="0">
116 + <mxGeometry x="-0.2" y="2" relative="1" as="geometry">
117 + <mxPoint x="-10" y="-9" as="offset"/>
118 + </mxGeometry>
119 + </mxCell>
120 + <mxCell id="arrow2" value="" style="endArrow=classic;html=1;strokeWidth=3;strokeColor=#666666;entryX=0.5;entryY=0;exitX=0.5;exitY=1;" parent="1" source="core-arch-bg" target="component-bg" edge="1">
121 + <mxGeometry width="50" height="50" relative="1" as="geometry">
122 + <mxPoint x="420" y="600" as="sourcePoint"/>
123 + <mxPoint x="420" y="640" as="targetPoint"/>
124 + </mxGeometry>
125 + </mxCell>
126 + <mxCell id="flow-label2" value="提供基础能力" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontStyle=1;fontFamily=Noto Sans JP;labelBackgroundColor=#ffffff;" parent="arrow2" vertex="1" connectable="0">
127 + <mxGeometry x="-0.2" y="2" relative="1" as="geometry">
128 + <mxPoint x="-10" y="-9" as="offset"/>
129 + </mxGeometry>
130 + </mxCell>
131 + <mxCell id="arrow3" value="" style="endArrow=classic;html=1;strokeWidth=3;strokeColor=#666666;entryX=0.5;entryY=0;exitX=0.5;exitY=1;" parent="1" source="core-arch-bg" target="module-bg" edge="1">
132 + <mxGeometry width="50" height="50" relative="1" as="geometry">
133 + <mxPoint x="1190" y="600" as="sourcePoint"/>
134 + <mxPoint x="1190" y="640" as="targetPoint"/>
135 + </mxGeometry>
136 + </mxCell>
137 + <mxCell id="flow-label3" value="支撑业务" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontStyle=1;fontFamily=Noto Sans JP;labelBackgroundColor=#ffffff;" parent="arrow3" vertex="1" connectable="0">
138 + <mxGeometry x="-0.2" y="2" relative="1" as="geometry">
139 + <mxPoint x="-10" y="-9" as="offset"/>
140 + </mxGeometry>
141 + </mxCell>
142 + <mxCell id="arrow4" value="" style="endArrow=classic;startArrow=classic;html=1;strokeWidth=3;strokeColor=#999999;entryX=1;entryY=0.5;exitX=0;exitY=0.5;dashed=1;" parent="1" edge="1">
143 + <mxGeometry width="50" height="50" relative="1" as="geometry">
144 + <mxPoint x="80" y="1100" as="sourcePoint"/>
145 + <mxPoint x="1590" y="1110" as="targetPoint"/>
146 + </mxGeometry>
147 + </mxCell>
148 + <mxCell id="flow-label4" value="组件复用" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontStyle=1;fontFamily=Noto Sans JP;labelBackgroundColor=#ffffff;" parent="arrow4" vertex="1" connectable="0">
149 + <mxGeometry x="-0.2" y="2" relative="1" as="geometry">
150 + <mxPoint x="-10" y="-9" as="offset"/>
151 + </mxGeometry>
152 + </mxCell>
153 + </root>
154 + </mxGraphModel>
155 + </diagram>
156 +</mxfile>