喜程记小程序与婚启 App 源代码相似点取证分析

分析日期: 2026年4月30日
分析对象:

说明: 喜程记小程序代码已被混淆打包为JavaScript bundle(app-service.js),字段名大部分已保留,但代码逻辑经过压缩。以下相似点均基于可验证的代码证据,请审核人员参阅。

一、功能模块完全对应

相似点:两个应用的功能模块高度对应。常见婚礼筹备工具通常会覆盖任务、宾客、预算等基础能力,但“礼金账本 / 座位表 / 座位查询 / 回忆记录”组合在同一产品中并不属于纯通用配置;对方小程序将这些模块以相近入口和页面矩阵组织起来,适合作为整体产品形态相似的背景证据。

我方功能模块出处:mobile/lib/features/


    
    
    
  mobile/lib/features/
├── tasks/          # 任务清单
├── budget/         # 预算管理
├── family_friend/  # 宾客管理
├── gift_ledger/    # 礼金账本
├── anniversary/    # 纪念日
├── calendar/       # 日历
├── seating_chart/  # 座位表
├── memory/         # 回忆记录
└── home/           # 首页

对方页面路由出处:wx3f22282982586c02_unpacked/app-config.json:3


    
    
    
  "pages": [
  "pages/home/index"
,
  "pages/tasks/index"
,
  "pages/budget/index"
,
  "pages/guests/index"
,
  "pages/gifts/index"
,
  "pages/events/index"
,
  "pages/calendar/index"
,
  "pages/budgetRecords/index"
,
  "pages/seating/index"
,
  "pages/seatLookup/index"
,
  "pages/memories/index"
,
  "pages/memoriesEditor/index"

]

功能对应关系:

我方功能对方页面说明
任务清单pages/tasks/index基础筹备清单能力
预算管理pages/budget/indexpages/budgetRecords/index预算与支出记录拆分
宾客管理pages/guests/index宾客/亲友信息管理
礼金账本pages/gifts/index非纯通用工具,和亲友维度联动
纪念日pages/events/index婚期相关日期管理
日历pages/calendar/index聚合日期、任务等信息
座位表pages/seating/index排座与场地布局能力
座位查询pages/seatLookup/index排座后给亲友自助查座
回忆记录pages/memories/indexpages/memoriesEditor/index图文/视频素材记录

结论:功能矩阵整体高度对应,尤其是礼金账本、座位表、座位查询、回忆记录这几类非单一基础功能同时出现,能为后续代码逻辑和交互路径相似点提供产品形态背景。

二、代码逻辑高度相似

2.1 座位表桌型枚举与排座状态文案高度相似

相似点:双方都将座位表抽象为桌型枚举,并提供圆桌、方桌、长桌类桌型。我方包含圆桌、方桌、长桌、主位长桌、单边长桌;对方包含圆桌、方桌、单边长桌、双边长桌、端位长桌。对方还实现了“已满桌 / 暂无宾客 / 还可安排 N 位”这类与我方座位分配状态同类的容量交互文案。

我方出处:mobile/lib/features/seating_chart/models/seating_table_shape.dart:1


    
    
    
  enum SeatingTableShape {
  round('round', '圆桌'),
  square('square', '方桌'),
  long('long', '长桌'),
  headLong('head_long', '主位长桌'),
  singleSideLong('single_side_long', '单边长桌');
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:30423


    
    
    
  u = {
  round
: "圆桌",
  square
: "方桌",
  "long-single"
: "单边长桌",
  "long-double"
: "双边长桌",
  "long-end"
: "端位长桌"
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:30670


    
    
    
  r = a >= e.capacity ? "已满" : 0 === a ? "待安排" : "可继续安排",
l = a >= e.capacity ? "已满桌" : 0 === a ? "暂无宾客" : "还可安排 ".concat(o, " 位"),
tableTypeLabel
: u[h] || "圆桌",
seatText
: "".concat(a, "/").concat(e.capacity)

2.2 座位查询独立公开链路相似

相似点:我方将座位表分享为公开座位查询页面/接口,对方也有独立 seatLookup 页面,并从座位表页生成查座路径和二维码。该点不是普通座位编辑,而是“排座完成后给亲友自助查座”的完整链路。

我方出处:mobile/lib/core/config/env_config.dart:158


    
    
    
  // ===== 座位查询 Web 版本 =====
static
 const String seatingQueryWebUrl = String.fromEnvironment(
  'SEATING_QUERY_WEB_URL'
,
  defaultValue: 'https://wp-seating.fegotech.com:38443',
);

我方出处:backend/app/api/v2/endpoints/public_seating.py:35


    
    
    
  @router.get(
    "/{chart_id}"
,
    response_model=APIResponse[PublicSeatingResponse],
    summary="公开查询座位表数据(供亲友H5页面使用)",
)

async
 def get_public_seating(chart_id: str, db: AsyncSession = Depends(get_db)):
    ...

对方出处:wx3f22282982586c02_unpacked/app-config.json:11


    
    
    
  "pages/budgetRecords/index",
"pages/seating/index"
,
"pages/seatLookup/index"
,
"pages/memories/index"

对方出处:wx3f22282982586c02_unpacked/app-service.js:28944


    
    
    
  onShareAppMessage: function() {
  var
 e = this.data,
      t = e.eventId,
      n = e.title,
      a = t ? "/pages/seatLookup/index?eventId=".concat(encodeURIComponent(t)) : "/pages/seatLookup/index";
  return
 {
      title
: n ? "「".concat(n, "」查座位") : "查找我的座位",
      path
: a
  }
}

2.3 宾客关系分类体系高度一致

相似点:双方宾客关系分类的核心类目高度重合。我方枚举包含家人、亲戚、朋友、同事、同学、邻里、家长圈、合作伙伴/客户、其他等;对方数组包含家人、亲戚、朋友、同学、同事、邻里、父母好友、商务伙伴、其他。9 个对方类目中,7 个文案完全相同,2 个语义高度接近。

我方出处:mobile/lib/features/family_friend/models/family_relation_type.dart:33


    
    
    
  String get title {
  switch
 (this) {
    case
 FamilyRelationType.relative:
      return
 '亲戚';
    case
 FamilyRelationType.family:
      return
 '家人';
    case
 FamilyRelationType.friend:
      return
 '朋友';
    case
 FamilyRelationType.colleague:
      return
 '同事';
    case
 FamilyRelationType.classmate:
      return
 '同学';
    case
 FamilyRelationType.neighbor:
      return
 '邻里';
    case
 FamilyRelationType.parentCommunity:
      return
 '家长圈';
    case
 FamilyRelationType.business:
      return
 '合作伙伴/客户';
    case
 FamilyRelationType.other:
      return
 '其他';
  }
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:40007


    
    
    
  u = ["家人", "亲戚", "朋友", "同学", "同事", "邻里", "父母好友", "商务伙伴", "其他"]

2.4 礼金方向分类与筛选设计一致

相似点:双方礼金记录都采用“收/送”双向结构,并在列表侧提供“全部 / 收礼 / 送礼”筛选。相比单纯记录收到的礼金,这是一种更具体的账本产品设计。

我方出处:mobile/lib/features/gift_ledger/models/gift_direction.dart:5


    
    
    
  @HiveType(typeId: 23)
enum
 GiftDirection {
  @HiveField
(0)
  receive,
  @HiveField
(1)
  give,
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:40009


    
    
    
  f = ["收礼", "送礼"]

对方出处:wx3f22282982586c02_unpacked/app-service.js:40054


    
    
    
  typeFilter: "全部",
typeFilters
: ["全部", "收礼", "送礼"]

对方出处:wx3f22282982586c02_unpacked/app-service.js:40141


    
    
    
  l = a.sent, u = l.items.filter((function(t) {
  return
 "收礼" === t.type
})).reduce(...), d = l.items.filter((function(t) {
  return
 "送礼" === t.type
})).reduce(...)

2.5 座位表复用亲友名单的业务链路相似

相似点:我方明确设计“礼金簿和座位表共享亲友名单”,座位表初始化会加载亲友,并确保默认亲友组;对方在宾客、礼金、座位表之间也复用“宾客/亲友”数据,座位表逻辑中包含“出席宾客已排座”等文案。

我方出处:mobile/lib/features/seating_chart/views/seating_chart_screen.dart:33


    
    
    
  await ref.read(familyFriendControllerProvider.notifier).load();
// 确保默认的"新郎和新娘"亲友组存在(用于座位表功能)

await
 ref.read(familyFriendControllerProvider.notifier).ensureDefaultCoupleFamily();
await
 ref.read(seatingChartControllerProvider.notifier).load();

我方出处:mobile/lib/features/seating_chart/widgets/friend_list_panel.dart:357


    
    
    
  Text('可到场亲友'),
_SeatFilterToggle(label: '共 $totalMembers 位'),
_SeatFilterToggle(label: '已安排 $assignedCount'),
_SeatFilterToggle(label: '未安排 $unassignedCount'),
FilledButton(onPressed: () => context.push('/toolkit/family-friends'), child: Text('亲友管理')),

对方出处:wx3f22282982586c02_unpacked/app-service.js:32739


    
    
    
  content: "当前所有出席宾客已排座,无需重新安排。"

对方出处:wx3f22282982586c02_unpacked/app-service.js:32122


    
    
    
  i = r.guest.contactName || "该宾客",
o = Number(r.guest.plusOnes || 0) > 0,
l = o ? "移出 ".concat(i, " 及随行") : "移出 ".concat(i),
itemList
: [l, "换到其他桌"]

2.6 备婚任务阶段化设计高度相似

相似点:双方都将任务系统组织为备婚阶段,并在任务模型/页面中按阶段推进。对方阶段名称是“决策定档 / 资源筹备 / 流程设计 / 执行筹备 / 婚礼执行 / 收尾回顾”;我方任务模型是婚礼阶段枚举,包含“策划阶段 / 筹备阶段 / 确认阶段”等,并通过 TaskStage 驱动任务筛选、阶段进度和新增任务默认阶段。

我方出处:mobile/lib/features/tasks/models/task.dart:579


    
    
    
  enum TaskStage {
  dating(name: '恋爱阶段', value: 'dating', icon: '💕', description: '确定婚姻关系与家庭见面'),
  planning(name: '策划阶段', value: 'planning', icon: '📋', description: '确定婚礼日期、预算与场地'),
  preparation(name: '筹备阶段', value: 'preparation', icon: '🎊', description: '采购婚品、拍照、准备物料'),
  confirmation(name: '确认阶段', value: 'confirmation', icon: '✨', description: '最终确认与婚礼彩排');
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:34351


    
    
    
  d = require("../../utils/task"),
l = d.buildTimelineItems,
u = d.compareTaskByDeadline,
c = d.normalizeTaskItem,
p = ["决策定档", "资源筹备", "流程设计", "执行筹备", "婚礼执行", "收尾回顾"],
h = ["未开始", "进行中", "已完成"];

2.7 宾客按男方/女方归属分组相似

相似点:双方都对宾客设置了归属方。我方模型将亲友归属为 groom / bride / unknown,并提供“新郎 / 新娘”展示;对方在宾客和礼金相关表单中使用“男方 / 女方”数组和筛选 tab。

我方出处:mobile/lib/features/family_friend/models/family.dart:8


    
    
    
  enum FamilyReferrer {
  groom,
  bride,
  unknown,
}

extension
 FamilyReferrerX on FamilyReferrer {
  String
 get label => switch (this) {
        FamilyReferrer.groom => '新郎',
        FamilyReferrer.bride => '新娘',
        FamilyReferrer.unknown => '未设置关系人',
      };
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:40007


    
    
    
  d = ["男方", "女方"]

对方出处:wx3f22282982586c02_unpacked/app-service.js:40941


    
    
    
  d = ["家人", "亲戚", "朋友", "同学", "同事", "邻里", "父母好友", "商务伙伴", "其他"],
p = ["男方", "女方"];

2.8 礼金簿与亲友维度统计相似

相似点:我方礼金簿以亲友/成员为核心,支持收入支出记录、亲友管理入口和按亲友维度统计;对方小程序有独立“喜程礼金”页面,首页快捷入口描述为“人情往来与礼金收支记录”,与我方礼金簿定位基本一致。

我方出处:mobile/lib/features/gift_ledger/views/gift_ledger_screen.dart:46


    
    
    
  await ref.read(familyFriendControllerProvider.notifier).load();
await
 ref.read(familyFriendControllerProvider.notifier).ensureDefaultCoupleFamily();
await
 ref.read(giftLedgerControllerProvider.notifier).load();

我方出处:mobile/lib/features/gift_ledger/views/gift_ledger_screen.dart:152


    
    
    
  appBar: AppBar(
  title: const Text('礼金簿'),
  actions: [
    IconButton(tooltip: '亲友管理', icon: const Icon(Icons.group_outlined)),
    IconButton(tooltip: '添加记录', icon: const Icon(Icons.add)),
  ],
)

对方出处:wx3f22282982586c02_unpacked/app-config.json:49


    
    
    
  "pages/gifts/index.html": {
  "window"
: {
    "navigationBarTitleText"
: "喜程礼金",
    "navigationBarBackgroundColor"
: "#FFF7EB"
  }

}

对方出处:wx3f22282982586c02_unpacked/app-service.js:21500


    
    
    
  badge: "🧧",
desc
: "人情往来与礼金收支记录",
label
: "礼金",
path
: "/pages/gifts/index"

2.9 回忆/时光模块与婚礼素材分类相似

相似点:双方都有“回忆/时光”模块,并围绕婚礼筹备过程记录图文/视频素材。我方模型有婚纱照、求婚瞬间、订婚仪式、试衣试妆、场地考察、购物记录、聚会聚餐、筹备过程、特殊时刻、其他回忆;对方小程序暴露“时光小记 / 记录时光”页面和一组记忆分类,覆盖日常、约会、美食、旅行、求婚、领证、婚礼筹备、婚礼当天等。

我方出处:mobile/lib/features/memory/models/memory.dart:257


    
    
    
  enum MemoryType {
  weddingPhoto(name: '婚纱照', apiValue: 'weddingPhoto'),
  proposal(name: '求婚瞬间', apiValue: 'proposal'),
  engagement(name: '订婚仪式', apiValue: 'engagement'),
  fitting(name: '试衣试妆', apiValue: 'fitting'),
  venueVisit(name: '场地考察', apiValue: 'venueVisit'),
  shopping(name: '购物记录', apiValue: 'shopping'),
  gathering(name: '聚会聚餐', apiValue: 'gathering'),
  preparation(name: '筹备过程', apiValue: 'preparation'),
  specialMoment(name: '特殊时刻', apiValue: 'specialMoment'),
  other(name: '其他回忆', apiValue: 'other');
}

对方出处:wx3f22282982586c02_unpacked/app-config.json:120


    
    
    
  "pages/memories/index.html": {
  "window"
: { "navigationBarTitleText": "时光小记", "disableScroll": true }
}
,
"pages/memoriesEditor/index.html"
: {
  "window"
: { "navigationBarTitleText": "记录时光" }
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:2710


    
    
    
  MEMORY_CATEGORY_OPTIONS: [
  "日常碎片"
, "约会", "美食", "旅行", "节日纪念", "礼物惊喜",
  "家人朋友"
, "求婚", "领证", "婚礼筹备", "婚礼当天", "其他"
]

2.10 婚礼日历:倒计时、任务标记与当日详情相似

相似点:双方都把日历作为婚礼筹备的聚合视图:围绕婚期倒计时、当日任务、纪念日/回忆/支出等多维信息做日期标记和详情展开。该模块不只是普通日历,而是与备婚任务、花销、回忆联动的婚礼日历。

我方出处:mobile/lib/features/calendar/widgets/today_detail/countdown_section.dart:24


    
    
    
  if (weddingDate == null) {
  return
 _buildEmptyState(palette);
}
final
 daysRemaining = daysBetween(weddingDate!, currentDate);
if
 (daysRemaining < 0) return _buildPassedState(palette, daysRemaining.abs());
if
 (daysRemaining == 0) return _buildTodayState(palette, primary);
return
 _buildCountdown(palette, primary, daysRemaining);

我方出处:mobile/lib/features/calendar/widgets/today_detail/countdown_section.dart:119


    
    
    
  Text('距离大喜之日'),
RichText(
  text: TextSpan(children: [
    const
 TextSpan(text: '还有 '),
    TextSpan(text: '$days'),
    TextSpan(text: ' 天'),
  ]),
)

我方出处:mobile/lib/features/calendar/widgets/multi_dimension_marker.dart:46


    
    
    
  // 1. 添加任务标签
for
 (final task in [...activeTasks, ...completedTasks]) {
  markerItems.add(_MarkerItem(type: _MarkerType.task, text: task.displayTitle));
}
// 2. 添加回忆标签

for
 (final memory in data.memories) {
  markerItems.add(_MarkerItem(type: _MarkerType.memory, text: memory.displayTitle));
}
// 3. 添加支出标签

if
 (data.expenses.isNotEmpty) {
  final
 totalAmount = data.totalExpenseAmount;
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:21205


    
    
    
  if (!e) return "倒计时";
return
 Number.isNaN(a.getTime()) ? "倒计时" :
  new
 Date(a.getFullYear(), a.getMonth(), a.getDate()).getTime() < n.getTime()
    ? "我们已经结婚"
    : "距离婚礼还有"

对方出处:wx3f22282982586c02_unpacked/app-service.js:38498


    
    
    
  y.push({
  dateKey
: b,
  isAnniversary
: C.length > 0,
  isSelected
: b === t,
  isTaskDeadline
: M.length > 0,
  isToday
: b === o,
  isWeddingDate
: r === b,
  taskCount
: M.length
})

对方出处:wx3f22282982586c02_unpacked/app-service.js:38610


    
    
    
  this.setData({
  calendarDays
: M(i, d, t, c, u, p),
  selectedCalendarDate
: t,
  selectedDateAnniversaries
: x(t, u),
  selectedDateTasks
: p && p[t] || [],
  upcomingMarriageDates
: h.items
})

2.11 工具包能力组合:亲友、座位表、礼金、回忆

相似点:我方工具包明确包含“亲友管理 / 座位表 / 礼金簿”,首页快捷入口包含今日事项、记录回忆、记录支出、备婚工具包;对方首页快捷入口包含座位表、礼金、时光小记等,且描述都围绕亲友、座位、礼金往来、回忆记录。

我方出处:mobile/lib/features/home/views/toolkit_screen.dart:68


    
    
    
  _ToolkitCard(title: '亲友管理', description: '管理亲友信息和婚礼到场状态;礼金簿和座位表共享亲友名单,避免重复录入'),
_ToolkitCard(title: '座位表', description: '安排婚宴座位,拖拽分配宾客到各个桌子,设计宴会厅布局'),
_ToolkitCard(title: '礼金簿', description: '记录收到和送出的礼金,按亲友维度统计收支情况,清晰了解往来账目'),

对方出处:wx3f22282982586c02_unpacked/app-service.js:21491


    
    
    
  quickActions: [{
  badge
: "🪑",
  desc
: "排座扫码查座、场地规划",
  label
: "座位表",
  path
: "/pages/seating/index"
}, {
  badge
: "🧧",
  desc
: "人情往来与礼金收支记录",
  label
: "礼金",
  path
: "/pages/gifts/index"
}, {
  badge
: "📸",
  desc
: "记录我们的时光",
  label
: "时光小记",
  path
: "/pages/memories/index"
}]

2.12 礼金事项类型选项重叠

相似点:双方礼金表单都有事项类型字段。我方送礼方向包含“结婚 / 乔迁 / 其他”,对方事项数组包含“结婚 / 生育 / 学业 / 乔迁 / 寿庆 / 其他”,其中 3 个与我方完全重合。

我方出处:mobile/lib/features/gift_ledger/widgets/gift_record_form_sheet.dart:139


    
    
    
  List<String> get _giftEventOptions {
  if
 (_direction == GiftDirection.receive) {
    return
 [
      '本次婚礼'
,
      '其他'
,
    ];
  }
  return
 [
    '结婚'
,
    '乔迁'
,
    '其他'

  ];
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:40010


    
    
    
  p = ["结婚", "生育", "学业", "乔迁", "寿庆", "其他"];

2.13 预算分类体系与预算/支出页面相似

相似点:双方都有婚礼预算模块和支出记录模块。我方预算分类包含婚庆场地、交通住宿、婚纱摄影、婚宴酒水、婚礼执行、珠宝首饰、服饰道具、礼仪习俗、其他杂项等;对方也有“喜程预算”“支出记录”页面,并在首页、预算估算等场景使用婚礼预算语义。该相似点偏信息架构与业务域复刻。

我方出处:mobile/lib/features/budget/constants/budget_category_config.dart:25


    
    
    
  const List<BudgetCategoryInfo> budgetCategoryConfigs = [
  BudgetCategoryInfo(code: 'venue', displayName: '婚庆场地', description: '婚礼场地租赁及布置相关费用'),
  BudgetCategoryInfo(code: 'trans_accom', displayName: '交通住宿', description: '婚车、宾客接送及住宿费用'),
  BudgetCategoryInfo(code: 'photography', displayName: '婚纱摄影', description: '婚礼摄影摄像及婚纱照费用'),
  BudgetCategoryInfo(code: 'catering', displayName: '婚宴酒水', description: '婚宴餐饮及酒水费用'),
  BudgetCategoryInfo(code: 'wedding_service', displayName: '婚礼执行', description: '婚礼策划、主持、化妆及花艺等服务'),
];

我方出处:mobile/lib/features/budget/widgets/budget_overview_card.dart:68


    
    
    
  Text('预算总览'),
Text('剩余预算'),
Text('已支出'),

对方出处:wx3f22282982586c02_unpacked/app-config.json:35


    
    
    
  "pages/budget/index.html": {
  "window"
: { "navigationBarTitleText": "喜程预算" }
}
,
"pages/budgetRecords/index.html"
: {
  "window"
: { "navigationBarTitleText": "支出记录" }
}

对方出处:wx3f22282982586c02_unpacked/app-service.js:37911


    
    
    
  s = "".concat(wx.env.USER_DATA_PATH, "/支出明细_喜程记_").concat(c, ".xlsx")

2.14 底部导航与核心模块矩阵高度相似

相似点:对方小程序将主 Tab 配置为“首页 / 清单 / 预算 / 宾客”,并在页面矩阵中继续包含日历、礼金、座位表、回忆等模块;我方 App 主导航为“首页 / 日历 / 任务 / 回忆 / 预算”,工具包补充亲友、座位表、礼金簿。这不是单个通用功能相似,而是婚礼筹备产品的模块组合与入口组织高度接近。

我方出处:mobile/lib/shared/widgets/main_navigation.dart:96


    
    
    
  _NavigationItem(icon: Icons.home, label: '首页', onTap: () => context.go('/home')),
_NavigationItem(icon: Icons.calendar_today, label: '日历', onTap: () => context.go('/calendar')),
_NavigationItem(icon: Icons.task_alt, label: '任务', onTap: () => context.go('/tasks')),
_NavigationItem(icon: Icons.photo_library, label: '回忆', onTap: () => context.go('/memory')),
_NavigationItem(icon: Icons.account_balance_wallet, label: '预算', onTap: () => context.go('/budget')),

对方出处:wx3f22282982586c02_unpacked/app-config.json:3


    
    
    
  "pages": [
  "pages/home/index"
,
  "pages/tasks/index"
,
  "pages/budget/index"
,
  "pages/guests/index"
,
  "pages/gifts/index"
,
  "pages/events/index"
,
  "pages/calendar/index"
,
  "pages/seating/index"
,
  "pages/memories/index"

]

对方出处:wx3f22282982586c02_unpacked/app-config.json:149


    
    
    
  "tabBar": {
  "color"
: "#D0A0B0",
  "selectedColor"
: "#FF8FAD",
  "list"
: [
    {
 "pagePath": "pages/home/index.html", "text": "首页" },
    {
 "pagePath": "pages/tasks/index.html", "text": "清单" },
    {
 "pagePath": "pages/budget/index.html", "text": "预算" },
    {
 "pagePath": "pages/guests/index.html", "text": "宾客" }
  ]

}

2.15 首页快捷入口:今日事项、记录回忆、记录支出、工具入口相似

相似点:双方首页都把高频动作做成快捷入口。我方是“今日事项 / 记录回忆 / 记录支出 / 备婚工具包”;对方首页快捷入口包含“座位表 / 礼金 / 时光小记”等。交互目标都是从首页直接进入具体备婚工具,减少层级。

我方出处:mobile/lib/features/home/widgets/quick_actions.dart:28


    
    
    
  _buildActionItem(title: '今日事项', subtitle: '日程安排', onTap: () {
  context.push('/calendar?selectedDate=$today');
});
_buildActionItem(title: '记录回忆', subtitle: '拍照记录', onTap: () {
  context.push('/memory/add');
});
_buildActionItem(title: '记录支出', subtitle: '预算管理', onTap: () {
  context.push('/budget/add-expense');
});
_buildActionItem(title: '备婚工具包', subtitle: '礼金簿、座位表', onTap: () {
  context.go('/toolkit');
});

对方出处:wx3f22282982586c02_unpacked/app-service.js:21491


    
    
    
  quickActions: [{
  badge
: "🪑",
  desc
: "排座扫码查座、场地规划",
  label
: "座位表",
  path
: "/pages/seating/index"
}, {
  badge
: "🧧",
  desc
: "人情往来与礼金收支记录",
  label
: "礼金",
  path
: "/pages/gifts/index"
}, {
  badge
: "📸",
  desc
: "记录我们的时光",
  label
: "时光小记",
  path
: "/pages/memories/index"
}]

三、交互路径高度相似

3.1 座位表:创建/进入排座、选择亲友入座、进入布局、分享查座路径相似

交互路径:

我方路径证据 1:工具包入口与路由。出处:mobile/lib/features/home/views/toolkit_screen.dart:90


    
    
    
  _ToolkitCard(
  title: '座位表',
  description: '安排婚宴座位,拖拽分配宾客到各个桌子,设计宴会厅布局',
  onTap: () => context.push('/toolkit/seating-chart'),
)

出处:mobile/lib/core/routes/app_router.dart:727


    
    
    
  GoRoute(
  path: 'seating-chart',
  builder: (context, state) => const SeatingChartScreen(),
  routes: [
    GoRoute(path: 'assign', builder: (context, state) => SeatAssignmentView(fromLayout: fromLayout)),
    GoRoute(path: 'layout', builder: (context, state) => TableLayoutView(...)),
  ],
)

我方路径证据 2:座位表进入排座页,并提供亲友管理入口。出处:mobile/lib/features/seating_chart/views/seating_chart_screen.dart:62


    
    
    
  Future<void> _openAssignment(String chartId) async {
  await
 notifier.load(preferredChartId: chartId);
  await
 context.push('/toolkit/seating-chart/assign');
  await
 notifier.flushAllDirtyTables();
  await
 notifier.load();
}

出处:mobile/lib/features/seating_chart/views/seating_chart_screen.dart:160


    
    
    
  IconButton(
  tooltip: '亲友管理',
  onPressed: () async {
    await
 context.push('/toolkit/family-friends');
    ref.read(familyFriendControllerProvider.notifier).load();
  },
)

我方路径证据 3:排座页只取“可到场亲友”,点击/拖拽分配座位,下一步进入布局页。出处:mobile/lib/features/seating_chart/views/seat_assignment_view.dart:738


    
    
    
  final attendingFamilies = familyState.families.where((f) => f.canAttend).toList();
final
 attendingMembers = familyState.members
    .where((m) => attendingFamilyIds.contains(m.familyId))
    .toList();

出处:mobile/lib/features/seating_chart/views/seat_assignment_view.dart:300


    
    
    
  onAssignSeat: (chairId, memberId) async {
  final
 success = await ref.read(seatingChartControllerProvider.notifier).assignMemberToChair(
    chairId: chairId,
    friendMemberId: memberId,
  );
},
onSeatDragStart: () { setState(() { _isSeatDragging = true; }); },
onSeatDragEnd: () { setState(() { _isSeatDragging = false; }); },

出处:mobile/lib/features/seating_chart/views/seat_assignment_view.dart:683


    
    
    
  if (!hasAssigned) {
  context.showText('请先添加亲友入座');
  return
;
}
await
 context.push('/toolkit/seating-chart/layout', extra: const TableLayoutRouteArgs(fromAssignment: true));

我方路径证据 4:布局页导出/分享给亲友,支持链接和二维码。出处:mobile/lib/features/seating_chart/views/table_layout_view.dart:1350


    
    
    
  IconOption(
  title: '分享给亲友',
  subtitle: '分享链接、分享二维码',
  onTap: () async { await _showShareToFriendsSheet(); },
)

出处:mobile/lib/features/seating_chart/widgets/share_to_friends_bottom_sheet.dart:706


    
    
    
  PrimaryButton(text: '分享链接', onPressed: () async { await _handleShare(asQr: false); }),
PrimaryButton(text: '分享二维码', onPressed: () async { await _handleShare(asQr: true); }),

对方路径证据 1:座位表页可回到宾客页。出处:wx3f22282982586c02_unpacked/app-service.js:31524


    
    
    
  goToGuests: function() {
  wx.switchTab({ url: "/pages/guests/index" })
}

对方路径证据 2:拖拽/分配宾客到桌位,并调用云函数保存。出处:wx3f22282982586c02_unpacked/app-service.js:31829


    
    
    
  if (i.dragFromAssignment && o && t._pointInRect(o.clientX, o.clientY, t._pendingDropRect)) return l(), void t.doRemoveAssignment(i.dragFromAssignment);
l
(), t._completeGuestDragDrop(i)

出处:wx3f22282982586c02_unpacked/app-service.js:31838


    
    
    
  doAssign: function(n, i, o) {
  c = { tableId: i, guestId: n._id, contactName: n.contact ? n.contact.name : "未命名", plusOnes: Number(n.plusOnes || 0), seatPosition: ... }
  r.callCloud("seating", "assignGuest", {
    eventId
: g,
    tableId
: i,
    guestId
: n._id,
    seatPosition
: "number" == typeof o ? o : null
  });
}

对方路径证据 3:生成查座码,并进入查座页。出处:wx3f22282982586c02_unpacked/app-service.js:33056


    
    
    
  wx.navigateTo({
  url
: "/pages/seatLookup/index?eventId=".concat(s)
})

出处:wx3f22282982586c02_unpacked/app-service.js:33074


    
    
    
  generateSeatCode: function() {
  wx.showLoading({ title: "生成二维码…", mask: !0 })
  r.callCloud("seating", "generateSeatCode", { eventId: n, title: a.data.seatCodeTitle });
  a.setData({ seatCodeImageUrl: "data:image/png;base64,".concat(s.base64) })
}

3.2 礼金:亲友入口、添加记录、填写金额/事项/日期、保存路径相似

交互路径:

我方路径证据 1:工具包进入礼金簿。出处:mobile/lib/features/home/views/toolkit_screen.dart:101


    
    
    
  _ToolkitCard(
  title: '礼金簿',
  description: '记录收到和送出的礼金,按亲友维度统计收支情况,清晰了解往来账目',
  onTap: () => context.push('/toolkit/gift-ledger'),
)

我方路径证据 2:礼金簿页可进入亲友管理,也可新增记录。出处:mobile/lib/features/gift_ledger/views/gift_ledger_screen.dart:152


    
    
    
  IconButton(
  tooltip: '亲友管理',
  onPressed: () async {
    await
 context.push('/toolkit/family-friends');
    ref.read(giftLedgerControllerProvider.notifier).load();
  },
),
IconButton(
  tooltip: '添加记录',
  onPressed: () async {
    final
 saved = await GiftRecordFormSheet.show(context, mode: GiftRecordFormMode.create);
    if
 (saved == true) ref.read(giftLedgerControllerProvider.notifier).load();
  },
)

我方路径证据 3:礼金表单字段链路。出处:mobile/lib/features/gift_ledger/widgets/gift_record_form_sheet.dart:634


    
    
    
  _RadioItem(label: '收到', onTap: () => _setDirection(GiftDirection.receive)),
_RadioItem(label: '送出', onTap: () => _setDirection(GiftDirection.give)),
FamilyMemberSelector(onMemberSelected: (member) { unawaited(_handleMemberSelected(member)); }),
_SelectField<String>(items: _giftEventOptions, onChanged: (opt) => _setGiftEvent(opt)),
_InputField(prefixText: '¥', hintText: '0.00'),
_SelectField<GiftMethod>(items: GiftMethod.values, itemLabel: (m) => m.title),
_DateButton(date: _eventDate, onTap: _pickDate),

我方路径证据 4:保存按钮。出处:mobile/lib/features/gift_ledger/widgets/gift_record_form_sheet.dart:1251


    
    
    
  ElevatedButton(
  onPressed: canSave ? onSave : null,
)

对方路径证据 1:宾客页打开礼金页/座位页。出处:wx3f22282982586c02_unpacked/app-service.js:41837


    
    
    
  openGiftBook: function() {
  wx.navigateTo({ url: "/pages/gifts/index" })
},
openSeatEditor
: function() {
  wx.navigateTo({ url: "/pages/seating/index" })
}

对方路径证据 2:礼金页打开表单、选择类型/事项/日期/金额。出处:wx3f22282982586c02_unpacked/app-service.js:40211


    
    
    
  openGiftSheet: function() {
  this
.setData({ "giftSheet.visible": !0, giftForm: h(), selectedGiftOccasionLabel: p[0] })
},
onGiftTypeChange
: function(t) { this.setData({ "giftForm.typeIndex": Number(t.detail.value) }) },
onGiftOccasionPillChange
: function(t) { this.setData({ "giftForm.occasionIndex": a >= 0 ? a : 0 }) },
onGiftDateChange
: function(t) { this.setData({ "giftForm.date": t.detail.value }) },
onGiftInput
: function(t) { ... this.setData({ "giftForm.amount": e }) }

对方路径证据 3:校验联系人和金额后保存。出处:wx3f22282982586c02_unpacked/app-service.js:40401


    
    
    
  if (!t.data.giftForm.selectedContactId) return wx.showToast({ title: "请先选择联系人", icon: "none" })
if
 (n = Number(t.data.giftForm.amount)) { ... } else return wx.showToast({ title: "请输入金额", icon: "none" })
r.callCloud("contacts", "createGift", {
  amount
: n,
  contactId
: t.data.giftForm.selectedContactId,
  date
: t.data.giftForm.date || c(new Date),
  occasion
: p[t.data.giftForm.occasionIndex],
  remark
: t.data.giftForm.remark.trim(),
  type
: f[t.data.giftForm.typeIndex]
});

3.3 任务:阶段总览、添加/编辑任务、任务动作直达座位表路径相似

交互路径:

我方路径证据 1:任务页 Tab 和任务列表点击。出处:mobile/lib/features/tasks/views/tasks_screen.dart:235


    
    
    
  IconButton(onPressed: () => context.push('/tasks/add'), tooltip: '添加任务'),
TabBar(tabs: const [Tab(text: '总览'), Tab(text: '待开始'), Tab(text: '进行中'), Tab(text: '已完成')]),
TaskProgress(tasks: taskState.tasks, currentStage: ...),
StageProgress(tasks: taskState.tasks),
TaskListView(onTaskTap: (task) => context.push('/tasks/detail/${task.id}')),

我方路径证据 2:任务模板动作直达座位表能力。出处:mobile/lib/features/tasks/utils/task_actions.dart:101


    
    
    
  if (task.templateId == 'TPL_CONFIRMATION_14') {
  return
 TaskActionConfig(label: '安排座位', action: (ctx, r) async => ctx.push('/toolkit/seating-chart'));
}

对方路径证据 1:任务编辑弹层与阶段字段。出处:wx3f22282982586c02_unpacked/app-service.js:34480


    
    
    
  taskEditorSheet: {
  visible
: !1,
  stage
: "",
  taskId
: "",
  title
: "添加任务",
  submitText
: "添加",
  form
: { deadline: "", description: "", name: "" }
}

对方路径证据 2:添加/编辑任务弹层。出处:wx3f22282982586c02_unpacked/app-service.js:34756


    
    
    
  this.setData({
  taskEditorSheet
: {
    mode
: "create",
    visible
: !0,
    stage
: t,
    title
: "添加任务",
    submitText
: "添加",
    form
: { deadline: a && a.date ? r(a.date) : r(new Date), description: "", name: "" }
  }
})

出处:wx3f22282982586c02_unpacked/app-service.js:34772


    
    
    
  openEditTaskSheet: function(e) {
  a && this.setData({
    taskEditorSheet
: {
      mode
: "edit",
      visible
: !0,
      stage
: a.stage,
      taskId
: a._id,
      title
: "编辑任务",
      submitText
: "保存"
    }
  })
}

对方路径证据 3:从阶段时间线聚焦任务。出处:wx3f22282982586c02_unpacked/app-service.js:34808


    
    
    
  focusTaskFromTimeline: function(e) {
  var
 n = a.stage, s = a.taskId;
  if
 (s && n) {
    var
 i = f(n);
    this
.closeTimelineSheet();
    setTimeout
(function() {
      t.applyTaskViews(t.data.allTasks, { expandedState: i, onRendered: function() { return t.scrollToTask(s) } })
    }, 220)
  }
}

对方路径证据 4:提交任务时校验名称、日期和当前婚礼活动。出处:wx3f22282982586c02_unpacked/app-service.js:34836


    
    
    
  submitTaskEditor: function() {
  if
 (!(u && u.trim())) return wx.showToast({ title: "请输入任务名称", icon: "none" })
  if
 (!d) return wx.showToast({ title: "请选择截止日期", icon: "none" })
  if
 (p = getApp().globalData.currentEvent) { ... } else return wx.showToast({ title: "请先选择婚礼", icon: "none" })
}

3.4 预算/支出:预算页进入支出记录、添加/编辑支出、校验分类/日期路径相似

交互路径:

我方路径证据:mobile/lib/features/budget/views/budget_screen.dart:170


    
    
    
  if (_tabController.index == 1)
  IconButton(
    icon: Icon(Icons.add, size: 24),
    onPressed: () => context.push('/budget/add-expense'),
  ),
ExpenseListView(
  onExpenseTap: (control) => context.push('/budget/expense/${control.id}'),
  onExpenseEdit: (control) => context.push('/budget/edit-expense/${control.id}'),
)

我方路径证据:mobile/lib/features/budget/views/add_edit_expense_screen.dart:1086


    
    
    
  return ExpenseEventEditorSheet(
  title: item == null ? '新增支出记录' : '编辑支出记录',
  initialDate: item?.expenseDate ?? DateTime.now(),
)

对方路径证据:wx3f22282982586c02_unpacked/app-service.js:36307


    
    
    
  openRecords: function() {
  wx.navigateTo({ url: "/pages/budgetRecords/index" })
}

对方路径证据:wx3f22282982586c02_unpacked/app-service.js:37586


    
    
    
  return wx.showToast({ title: "请选择支出分类", icon: "none" })
return
 wx.showToast({ title: "请选择支出日期", icon: "none" })

对方路径证据:wx3f22282982586c02_unpacked/app-service.js:37830


    
    
    
  wx.showModal({
  title
: "删除记录",
  content
: "确定删除这条支出记录?",
  confirmText
: "删除",
  cancelText
: "取消"
});

3.5 日历:从首页进入今日详情、日期标记聚合、任务跳转路径相似

交互路径:

我方路径证据 1:首页“今日事项”直达日历指定日期。出处:mobile/lib/features/home/widgets/quick_actions.dart:28


    
    
    
  _buildActionItem(
  title: '今日事项',
  subtitle: '日程安排',
  onTap: () {
    final
 today = DateTime.now().millisecondsSinceEpoch;
    context.push('/calendar?selectedDate=$today');
  },
)

我方路径证据 2:日历日期下聚合任务、回忆、支出标记。出处:mobile/lib/features/calendar/widgets/multi_dimension_marker.dart:46


    
    
    
  for (final task in [...activeTasks, ...completedTasks]) {
  markerItems.add(_MarkerItem(type: _MarkerType.task, text: task.displayTitle));
}
for
 (final memory in data.memories) {
  markerItems.add(_MarkerItem(type: _MarkerType.memory, text: memory.displayTitle));
}
if
 (data.expenses.isNotEmpty) {
  final
 totalAmount = data.totalExpenseAmount;
}

我方路径证据 3:当日任务列表点击进入任务详情。出处:mobile/lib/features/calendar/widgets/today_detail/today_tasks_section.dart:91


    
    
    
  onTap: () {
  context.push('/tasks/detail/${task.id}');
}

对方路径证据 1:首页打开日历页。出处:wx3f22282982586c02_unpacked/app-service.js:22635


    
    
    
  openCalendarPage: function(e) {
  var
 t = "string" == typeof e ? e.trim() : "";
  wx.navigateTo({
    url
: t ? "/pages/calendar/index?date=".concat(t) : "/pages/calendar/index"
  })
}

对方路径证据 2:日历页构建日期格,包含婚期、纪念日、任务截止标记。出处:wx3f22282982586c02_unpacked/app-service.js:38498


    
    
    
  y.push({
  dateKey
: I,
  isAnniversary
: L.length > 0,
  isSelected
: I === t,
  isTaskDeadline
: N.length > 0,
  isToday
: I === o,
  isWeddingDate
: r === I,
  taskCount
: N.length
})

对方路径证据 3:点击日历任务跳转清单页并携带定位信息。出处:wx3f22282982586c02_unpacked/app-service.js:38753


    
    
    
  openTaskInTasks: function(e) {
  var
 a = e.currentTarget.dataset,
      t = a.stage,
      n = a.taskId,
      r = getApp(),
      s = r.globalData.currentEvent;
  s && s._id && n && (r.globalData.pendingTaskJump = {
    eventId
: s._id,
    stage
: t || "",
    taskId
: n
  }, wx.switchTab({ url: "/pages/tasks/index" }))
}