乐于分享
好东西不私藏

如何利用 AI 从无到有搭建一套族谱小程序

如何利用 AI 从无到有搭建一套族谱小程序

一、为什么要做族谱小程序?

清明节回家祭祖,父亲突然问我:"咱们家的族谱你能帮忙整理一下吗?老的那本已经破旧不堪了。"

我翻出那本泛黄的族谱,上面密密麻麻记录着家族几代人的信息,但很多字迹已经模糊,有些页面还被虫蛀了。作为一个程序员,我第一反应就是:能不能做一个数字化的族谱系统?

需求很简单:

  • 能可视化展示家族树,像思维导图那样
  • 支持多人协作,家族成员可以自己补充信息
  • 最好有个小程序,方便长辈们使用
  • 除了基本的族谱,还能记录家族大事、人物传记、成就榜

但现实是:我平时工作很忙,这个项目只能用业余时间来做。如果按传统方式开发,光是写前端页面、搭后端、设计数据库,没有两三个月根本搞不定。

这时候我想到了 AI,于是就两天整理spec和技术方案,两天做出来。下面就是我的思路和经验。

二、技术选型:为什么选这些技术?

前端框架对比

方案
优点
缺点
最终选择
原生小程序
性能最好
开发效率低,无法跨平台
Taro + React
跨平台,React 生态
配置复杂,社区文档不够完善
UniApp + Vue 3
跨平台,上手快,文档完善
部分原生能力需要适配

最终选择 UniApp + Vue 3 + TypeScript,原因:

  1. 一套代码可以编译到微信小程序、H5、App 多端
  2. Vue 3 的 Composition API 写起来很舒服
  3. TypeScript 提供类型安全,AI 生成代码时不容易出错
  4. UniApp 生态成熟,遇到问题容易找到解决方案

后端方案对比

方案
优点
缺点
最终选择
自建服务器
完全可控
需要运维,成本高
Serverless 云函数
免运维,按量付费
冷启动问题
微信云开发
与小程序深度集成,免费额度充足
只能微信生态

对于族谱这种低频访问的应用,微信云开发是最优解:

  • 免费额度足够(每天 5 万次数据库读取)
  • 不用操心服务器运维
  • 云函数 + 云数据库 + 云存储一站式搞定
  • 天然支持微信登录

网页版技术栈

为了让家族成员在电脑上也能查看,我还做了一个网页版:

  • 前端
    :React 18 + TypeScript + ReactFlow(家族树可视化)+ Ant Design
  • 后端
    :Node.js + Express + SQLite
  • 部署
    :Docker 一键部署

三、架构设计:一个云函数搞定一切

传统方案 vs 我的方案

传统做法是每个功能模块一个云函数:getMemberscreatePostgetComments... 这样会导致:

  • 云函数数量爆炸,管理困难
  • 每个函数都有冷启动时间
  • 代码重复度高

我的方案是:单一云函数 + Action 路由代码// family-tree-db/index.js - 唯一的云函数入口exports.main = async (event, context) => {const action = event.actionconst data = event.dataswitch (action) {case'getMembers':returnawaitgetMembers(data)case'createPost':returnawaitcreatePost(data)case'getChronicleTimeline':returnawaitgetChronicleTimeline(data)// ... 50+ 个 action  }}

前端调用时只需要:const result = awaitcallCloud('getMembers', { clan_id'xxx' })

这样做的好处:

  1. 减少冷启动
    :只有一个云函数需要预热
  2. 统一权限校验
    :所有操作都走同一个鉴权逻辑
  3. 便于维护
    :所有后端代码在一个文件里,AI 修改起来也方便

分层架构┌─────────────────────────────────────┐│         小程序页面层 (20+ 页面)        │├─────────────────────────────────────┤│         组件层 (11 个公共组件)          │├─────────────────────────────────────┤│         API 层 (统一接口封装)           │├─────────────────────────────────────┤│         云函数层 (单一入口)             │├─────────────────────────────────────┤│         云数据库 (10+ 集合)            │└─────────────────────────────────────┘

多租户设计

一个小程序要服务多个家族,怎么隔离数据?

答案是:每个集合都有 clan_id 字段// API 层自动注入 clan_idasyncgetMembers(params) {const clan = getCurrentClan()const clan_id = clan?.id || user?.clan_idreturnawait memberDB.getAll({ ...params, clan_id })}

用户登录后选择自己的族群,之后所有操作都会自动带上 clan_id,确保数据隔离。

四、核心功能实现

1. 家族树可视化(最难的部分)

在小程序中实现树形图,最大的挑战是没有 DOM,不能像网页那样用 SVG 或 HTML 布局。

我的方案:绝对定位 + scroll-view// treeLayout.ts - 树布局算法interfaceLayoutBox {nodeFamilyTreeNodeDatacenterXnumber// 节点中心 X 坐标offsetLeftnumber// 左偏移量childrenLayoutBox[]  // 子节点}// 递归计算布局functionlayoutTree(node: FamilyTreeNodeData): LayoutBox {// 1. 先递归计算所有子树的布局const childBoxes = node.children.map(child =>layoutTree(child))// 2. 计算当前节点需要的宽度const totalWidth = childBoxes.reduce((sum, box) => sum + box.width0)// 3. 当前节点居中于子节点之上const centerX = totalWidth / 2return { node, centerX, children: childBoxes }}

渲染时:<scroll-view scroll-x scroll-y>  <view :style="{ width: canvasWidth + 'rpx', height: canvasHeight + 'rpx' }">    <!-- 节点卡片 -->    <view v-for="couple in layout.couples"      :style="{ left: couple.x + 'rpx', top: couple.y + 'rpx' }"    >      <FamilyTreeCoupleCard :node="couple.node" />    </view>    <!-- 连接线 -->    <view v-for="seg in layout.segments"      :style="{ left: seg.left + 'rpx', top: seg.top + 'rpx', width: seg.width + 'px' }"    />  </view></scroll-view>

还支持:

  • 展开/折叠子树
  • 导出为图片(Canvas 2D)
  • 左右滑动查看

2. 亲缘关系计算

"我和堂哥的曾孙是什么关系?" 这种问题,用算法就能回答。

实现方案:BFS 图搜索码// relationship.tsfunctionbuildRelationGraph(members: RelationMember[]) {const graph = newMap<stringRelationEdge[]>()for (const member of members) {// 父子关系if (member.father_idaddEdge(member.father_id, member.id'father')if (member.mother_idaddEdge(member.mother_id, member.id'mother')// 配偶关系if (member.spouse_idaddEdge(member.id, member.spouse_id'spouse')// 兄弟姐妹关系(同一父母)// ...  }return graph}functionfindRelationship(fromId: string, toId: string, graph) {// BFS 搜索最短路径const queue = [{ id: fromId, path: [] }]const visited = newSet()while (queue.length > 0) {const { id, path } = queue.shift()if (id === toId) return pathfor (const edge of graph.get(id)) {if (!visited.has(edge.to)) {        visited.add(edge.to)        queue.push({ id: edge.topath: [...path, edge] })      }    }  }}

最后把路径翻译成中文称谓:// 路径:A → 父亲 → 父亲的兄弟 → 兄弟的儿子// 翻译:堂兄弟

3. 大事记时间线

为了让家族历史更有仪式感,我做了两种视图:

列表视图:卡片式展示,适合快速浏览 时间线视图:按年月分组,带连接线,适合沉浸式阅读<!-- 时间线视图 --><view class="timeline">  <view v-for="group in timeline" class="timeline-group">    <view class="timeline-year-header">      <text>{{ group.year }}年{{ group.month }}月</text>      <text>{{ group.events.length }}件</text>    </view>    <view class="timeline-events">      <view v-for="event in group.events" class="timeline-event">        <view class="timeline-dot" :style="{ background: getTypeColor(event.event_type) }" />        <view class="timeline-content">          <text class="timeline-title">{{ event.title }}</text>          <text class="timeline-date">{{ formatDate(event.event_date) }}</text>          <text v-if="event.summary" class="timeline-summary">{{ event.summary }}</text>        </view>      </view>    </view>  </view></view>

五、AI 辅助开发:真实体验分享

1. 需求分析阶段

我的做法:把需求描述丢给 AI,让它帮我梳理技术方案。我:我想做一个族谱小程序,需要哪些功能模块?数据库怎么设计?AI:核心模块:1. 成员管理 - 存储家族成员信息2. 关系管理 - 父母、配偶、子女关系3. 族谱可视化 - 树形图展示4. 权限系统 - 多角色控制数据库设计:- family_members 集合:存储成员基本信息- users 集合:存储用户账号和角色- clans 集合:存储族群信息(支持多租户)

AI 帮我快速理清了思路,省去了大量调研时间。

2. 组件开发阶段

案例:FamilyTreeGraph 组件

这个组件有 300+ 行代码,如果手写至少需要半天。我用 AI 的方式是:

  1. 先描述需求:"我要在小程序里实现一个可滚动的家族树,支持夫妻卡片、父子连线、展开折叠"
  2. AI 生成基础代码
  3. 我调整细节,比如尺寸、颜色、交互逻辑
  4. 遇到问题再问 AI

整个过程大概 2 小时就完成了。

3. 算法实现阶段

案例:亲缘关系计算

BFS 算法我本来就会,但要处理各种边界情况(多重婚姻、过继、养子女等)很麻烦。我让 AI 帮我:

  1. 生成基础的 BFS 框架
  2. 处理各种关系类型的边构建
  3. 翻译路径为中文称谓

AI 生成的代码质量很高,我只需要微调就能用。

4. Bug 修复阶段

这是 AI 帮助最大的地方。

真实案例:头像不显示问题

前几天我遇到一个问题:成员详情页面的头像不显示了。

传统排查方式

  1. 检查图片 URL 是否正确 → 正确
  2. 检查网络请求 → 正常
  3. 检查 CSS 样式 → 发现问题了!

问题根因:Vue 的 scoped 样式无法穿透到子组件内部的 <image> 标签。因为微信小程序的 <image> 是组件而不是 HTML 元素。

AI 帮我想到的解决方案<!-- 方案 1:使用 :deep() 穿透 --><style scoped>.avatar-large :deep(image) {  width: 100%;  height: 100%;}</style><!-- 方案 2:使用全局样式(不推荐,会污染其他组件) --><style>.member-avatar-root image {  width: 100%;  height: 100%;}</style>

这种问题如果不是 AI 提醒,我可能要调试很久。

六、踩坑记录

坑 1:小程序的 image 是组件不是标签/* 错误写法 - 无法生效 */.avatar image { width100%; }/* 正确写法 - 需要 :deep() */.avatar :deep(image) { width100%; }

坑 2:云函数冷启动

第一次调用云函数会很慢(3-5 秒),解决方案:

  • 使用定时触发器预热
  • 前端加 loading 状态
  • 关键接口做缓存

坑 3:rpx 单位换算

小程序的 rpx 是响应式单位,但 Canvas 绘图时需要换算:const dpr = wx.getSystemInfoSync().pixelRatiocanvas.width = width * dprcanvas.height = height * dprctx.scale(dpr, dpr)

坑 4:隐私 API 合规

微信要求调用相册、定位等隐私 API 前必须先声明并获得用户授权:functionrunWithPrivacyAuthorize(action: () => void) {  wx.requirePrivacyAuthorize({success: action,fail() => {      uni.showToast({ title'需要授权才能使用此功能' })    }  })}

七、最终效果

功能清单

模块
功能点
状态
族谱核心
家族树可视化
成员 CRUD
亲缘关系计算
导出图片
家族论坛
文章发布
评论点赞
图片上传
大事记
时间线视图
列表视图
参与者管理
人物传记
生命时间线
图片画廊
成就榜
分类管理
证书上传
权限系统
4 种角色
多租户隔离

开发时间对比

功能
传统开发
AI 辅助开发
提升
数据库设计
2 天
0.5 天
4x
云函数开发
5 天
1.5 天
3x
前端页面
10 天
3 天
3x
核心组件
3 天
1 天
3x
调试修复
5 天
1 天
5x
总计25 天7 天3.5x

八、总结与建议

AI 辅助开发的正确姿势

  1. 不要完全依赖 AI
    :AI 生成的代码需要你理解并验证,不能直接 copy-paste
  2. 先想清楚再问 AI
    :需求描述越清晰,AI 生成的代码质量越高
  3. 分步骤迭代
    :不要一次性让 AI 生成整个项目,分模块、分功能来
  4. 保持学习
    :AI 是工具,核心能力还是你自己的技术功底

这个项目适合哪些场景

  • 家族族谱数字化
  • 家庭相册管理
  • 家族通讯录
  • 宗亲会管理

作者简介:后端开发工程师,8 年经验。欢迎关注我的公众号,分享更多 AI 辅助开发的实战经验。