hookehuyr

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

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
<mxfile host="65bd71144e">
<diagram id="b5dOQcsEGuaq2pC0fEqS" name="第 1 页">
<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">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<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">
<mxGeometry x="560" y="20" width="480" height="40" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="560" y="60" width="480" height="30" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="40" y="120" width="1520" height="160" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="130" width="400" height="30" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="280" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="500" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="720" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="940" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1160" y="180" width="200" height="80" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1380" y="180" width="160" height="80" as="geometry"/>
</mxCell>
<mxCell id="core-arch-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e3f2fd;strokeColor=#1976d2;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="40" y="370" width="1520" height="320" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="380" width="400" height="30" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="430" width="280" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="360" y="430" width="280" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="660" y="430" width="280" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="960" y="420" width="280" height="120" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1260" y="420" width="280" height="120" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="550" width="600" height="120" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="680" y="550" width="500" height="120" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1200" y="550" width="340" height="120" as="geometry"/>
</mxCell>
<mxCell id="component-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3e5f5;strokeColor=#7b1fa2;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="40" y="780" width="760" height="280" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="40" y="730" width="400" height="30" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="70" y="810" width="220" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="300" y="810" width="220" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="530" y="810" width="240" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="60" y="950" width="720" height="100" as="geometry"/>
</mxCell>
<mxCell id="module-bg" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff9c4;strokeColor=#f57c00;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="850" y="780" width="740" height="280" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="870" y="790" width="400" height="30" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="870" y="840" width="160" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1050" y="840" width="160" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1230" y="840" width="160" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="1410" y="840" width="160" height="100" as="geometry"/>
</mxCell>
<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">
<mxGeometry x="870" y="980" width="700" height="50" as="geometry"/>
</mxCell>
<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">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="800" y="280" as="sourcePoint"/>
<mxPoint x="800" y="320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry x="-0.2" y="2" relative="1" as="geometry">
<mxPoint x="-10" y="-9" as="offset"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="420" y="600" as="sourcePoint"/>
<mxPoint x="420" y="640" as="targetPoint"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry x="-0.2" y="2" relative="1" as="geometry">
<mxPoint x="-10" y="-9" as="offset"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="1190" y="600" as="sourcePoint"/>
<mxPoint x="1190" y="640" as="targetPoint"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry x="-0.2" y="2" relative="1" as="geometry">
<mxPoint x="-10" y="-9" as="offset"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="80" y="1100" as="sourcePoint"/>
<mxPoint x="1590" y="1110" as="targetPoint"/>
</mxGeometry>
</mxCell>
<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">
<mxGeometry x="-0.2" y="2" relative="1" as="geometry">
<mxPoint x="-10" y="-9" as="offset"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>