资讯动态

TREK 打包清单(Packing Lists)完全指南:分类清单、成员分工、三级共享与行李重量追踪

发布时间:2026/9/15 11:08:08 来源:尧图企业网站定制
TREK 打包清单Packing Lists完全指南分类清单、成员分工、三级共享与行李重量追踪【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREKTREK 的打包清单Packing Lists是行程规划器内置的可分类、可协作的 checklist 模块你可以按分类组织物品、把清单分配给具体成员、为每个物品设置三级共享可见性并在管理员开启 Bag Tracking 后按行李Bag统计重量与限重。本文以官方文档 Packing-Lists.md 为骨架结合前端实现client/src/components/Packing与后端 APIserver/src/nest/packing/packing.controller.ts的源码细节完整讲解从开启插件、创建清单到模板复用的全流程读完后你既能熟练使用界面也能理解底层的数据模型与实时同步机制。在哪找到它入口与前置条件打包清单位于行程规划器Trip Planner内的Lists标签页选择Packing即可进入。该标签页只有在 Packing 插件启用时才可见。管理员注意需要在 Admin-Addons 中启用 Packing 插件并按需开启Bag Tracking行李追踪功能。从前端源码看该面板由PackingListPanel组件渲染client/src/components/Packing/PackingListPanel.tsx它组合了头部、视图/过滤器标签、分组列表与行李侧边栏四大部分行李追踪的全局开关通过 addon store 暴露给所有已登录用户而非仅管理员这样非管理员成员也能看到重量与行李信息见 usePackingListPanel.ts。进度条面板顶部有一条进度条实时显示已勾选已打包物品数 / 总物品数。它在小屏设备上隐藏仅在较大视口中展示当所有物品都被勾选后进度条会被一条完成提示文案替代。底层实现中进度由当前视图下的勾选比例计算得出const abgehakt viewItems.filter(i i.checked).length const fortschritt viewItems.length 0 ? Math.round((abgehakt / viewItems.length) * 100) : 0见 usePackingListPanel.ts。过滤器列表上方有三个过滤器按钮用于收窄物品视图All— 显示全部物品无论勾选状态Open— 只显示未勾选物品Done— 只显示已勾选物品。对应前端状态filter取值为alle/offen/erledigt分组渲染时按该状态过滤usePackingListPanel.ts按钮 UI 实现在 PackingListPanelViewTabs.tsx。分类Categories物品按分类分组展示每个分类头部有一个彩色圆点颜色取自一组 10 色调色板并循环分配。该调色板在源码中被定义为KAT_COLORS兼顾亮色与暗色主题packingListPanel.constants.tsexport const KAT_COLORS [ #3b82f6, // blue #a855f7, // purple #ec4899, // pink #22c55e, // green #f97316, // orange #06b6d4, // cyan #ef4444, // red #eab308, // yellow #8b5cf6, // violet #14b8a6, // teal ]颜色按分类在列表中的顺序稳定分配indexOf命中即取色未命中时回退为哈希取色见 packingListPanel.helpers.ts 中的katColor。因此只要分类的相对顺序不变颜色就不会跳动。新建清单时的建议物品创建一个新的打包清单时系统会自动预填充一批建议物品源码常量VORSCHLAEGE完整定义了这批预置数据packingListPanel.constants.ts分类建议物品DocumentsPassport、Travel Insurance、Visa Documents、Flight Tickets、Hotel Bookings、Vaccination CardClothingT-Shirts (5x)、Pants (2x)、Underwear (7x)、Socks (7x)、Jacket、Swimwear、Sport ShoesToiletriesToothbrush、Toothpaste、Shampoo、Sunscreen、Deodorant、RazorElectronicsPhone Charger、Travel Adapter、Headphones、Camera、Power BankHealthFirst Aid Kit、Prescription Medication、Pain Medication、Insect RepellentFinancesCash、Credit Card分类头部操作每个分类头部带有一个折叠/展开开关和一个溢出菜单菜单内提供Check all— 将该分类下所有物品标记为已打包Uncheck all— 取消该分类下所有物品的已打包状态Rename— 重命名分类前端会逐条更新该分类下所有物品的category字段见 usePackingListPanel.tsDelete— 删除该分类及其全部物品。一个值得注意的细节删除分类中最后一个物品时若该分类是用户自建的分类这一行会原地变成一个...占位符而不是被删除从而保住该分类的位置与颜色避免分类消失或跳到列表末尾源码注释标记为 #1289见 usePackingListPanel.ts。这个占位符也承担新分类占位职责——服务端会拒绝空名称因此每个分类首行用...占位packingListPanel.constants.ts。给分类分配成员分类头部有一个成员选择 chip 行people-picker可把行程成员指派到该分类。被指派的成员会收到一条打包通知详见 Notifications。后端通过PUT /api/trips/:tripId/packing/category-assignees/:categoryName保存指派关系成功后广播packing:assignees事件并调用notifyTagged触发通知packing.controller.ts。注意给分类指派成员只负责发送打包通知并不改变物品的可见性——可见性由下面介绍的物品级三级共享决定。物品Items每一行物品包含复选框— 标记该物品已打包可编辑的名称— 点击即可重命名当物品处于已勾选状态时重命名被禁用源码中仅当canEdit !item.checked时才允许进入编辑态见 PackingListPanelItemRow.tsx数量字段— 始终可见QuantityInput可即时保存当开启 Bag Tracking 后还会显示重量字段单位克和行李选择器bag picker。鼠标悬停物品行时会浮现一组操作分类选择器彩色圆点可将物品移动到其他分类、重命名按钮铅笔图标和删除按钮。新增物品则使用每个分类底部的内联 add item 行。物品级 API 支撑物品的创建、更新、删除、勾选切换、排序以及共享与协作动作在后端都有对应的 REST 端点server/src/nest/packing/packing.controller.tsPOST /api/trips/:tripId/packing— 创建物品名称必填否则 400PUT /api/trips/:tripId/packing/:id— 更新名称/勾选状态/分类/重量/行李/数量支持If-Matchx-base-updated-at头做离线冲突检测冲突时返回 409源码注释标记为 #1135DELETE /api/trips/:tripId/packing/:id— 删除物品PUT /api/trips/:tripId/packing/reorder— 批量重排物品顺序orderedIds。所有变更都会通过 WebSocket 以packing:created/packing:updated/packing:deleted等事件广播实现行程成员间的实时同步。共享打包物品Sharing packing items每个打包物品都有一个共享层级sharing tier控制谁能看到它、由谁带。默认情况下所有物品都位于共享的物品池中行为与旧版本完全一致——层级是按物品逐个选择的opt-in per item。两种视图列表顶部有两个胶囊按钮切换查看内容Shared— 群组物品池行程中所有人可见的物品My list— 你自己的清单你的个人物品、别人要求你带的物品、以及你与特定成员共享的物品。每个胶囊上会显示对应物品的数量。前端根据is_private字段拆分两种视图common视图只显示is_private 0的物品personal视图只显示is_private 1且已经由服务端过滤为属于我的物品usePackingListPanel.ts。视图与过滤器共用一行中间以竖线分隔PackingListPanelViewTabs.tsx。三个层级打开物品行的Sharing控件行上的分享图标即可在三个层级间切换Shared—在群组物品池中对所有人可见。这是每个物品的初始层级Personal—私人物品——只有你自己能看到。Shared with…— 在层级选项下方勾选指定的行程成员。此后该物品只出现在你的清单和对方的清单上。如果整个行程只有你一个人这一栏会显示No one else on this trip yet。新建物品继承当前视图的层级在My list视图中新增的物品自动成为 Personal私有在Shared视图中新增的则成为 Common。因此想把物品分享给特定的人请先添加物品再打开它的 Sharing 控件选择成员。谁在带什么Whos bringing what共享物品池中的每个物品都会显示由谁携带brought by 徽标。对于他人添加的物品其他成员看到的是两个快捷操作而非 Sharing 控件I can bring that too— 承诺一起携带co-bring。物品徽标会在原携带者旁边显示1。再次点击Im not bringing it即可撤回承诺Copy to my list— 把该物品克隆到你自己的个人清单中作为一份独立的私有副本共享池中的原物品不受影响。在该功能上线之前创建的物品没有携带者信息因此在有人编辑其共享设置之前不会显示 brought by 徽标。注意物品级共享与上面提到的给分类指派成员是两回事——分类指派只发送打包通知不改变物品可见性。权限模型与实现细节前端把这三个层级映射为visibility: common | personal | shared加一份recipient_ids列表调用PUT /api/trips/:tripId/packing/:id/sharingPackingShareControl.tsx。服务端规则packing.controller.ts只有**物品所有者携带者**可以修改共享层级非所有者修改会收到 403Only the owner can change sharing非所有者对 Common 物品只能承诺 co-bringPOST /:id/contributors或克隆到自己的清单POST /:id/clone返回 201与你共享的物品出现在你的My list上带有一个by {name}徽标你只能勾选它不能管理它被分享给谁。私密物品的实时广播也被精确限定list接口会按查看者过滤掉他人拥有的私有物品packing.controller.tsWebSocket 广播通过emitToViewers只投递给房间内所有人Common或所有者 接收者受限物品packing.controller.ts。broadcastUpdate则处理四种公/私状态切换时的广播路由确保私有化的物品不会被泄露给无关成员packing.controller.ts。所有这些能力依然由packing_edit权限统一管控不需要额外的插件开关或管理员开关。行李追踪Bag Tracking行李追踪只有在管理员启用后才可用。管理员注意在 Admin-Addons 中开启 Bag Tracking。启用后会多出一个Bags面板宽屏下显示为右侧栏窄屏下显示为模态抽屉点击头部Bags按钮打开。每个行李Bag展示名称与颜色圆点总重量以及若设置了限重重量限度的进度条分配给该行李的成员头像物品数量。侧边栏还包含一个unassigned未分配分区汇总所有没有行李的物品底部有一行total weight累加全部物品重量。行李的三种基础操作点击 Add bag创建一个带名称与颜色的行李用物品行上的行李选择器bag picker开启 Bag Tracking 后可见把物品分配进某个行李在行李卡片上用成员 chip 行把成员分配到该行李。重量计算与调色板每件物品对行李总重的贡献按单位重量 × 数量计算packingListPanel.helpers.tsexport const itemWeight (i: { weight_grams?: number | null; quantity?: number | null }): number (i.weight_grams || 0) * (i.quantity || 1)侧边栏据此累加每个行李的重量并计算限重进度百分比pct min(100, round(total / maxWeight * 100))重量 ≥1000g 时自动以 kg 显示PackingListPanelBagSidebar.tsx。新建行李时颜色从 16 色BAG_COLORS调色板按当前行李数量循环取用packingListPanel.constants.ts。行李的增删改与成员指派对应后端端点GET/POST /packing/bags、PUT/DELETE /packing/bags/:bagId、PUT /packing/bags/:bagId/members变更以packing:bag-created/packing:bag-updated/packing:bag-deleted/packing:bag-members-updated广播packing.controller.ts。此外行李选择器还支持在挑选时内联新建行李输入名称回车即创建并立即分配见 PackingListPanelItemRow.tsx。模板Templates打包清单可以跨行程保存与复用Save as Template— 当列表中有物品时头部会显示Save as Template按钮将当前清单的物品与分类保存为命名模板。该操作仅限管理员服务端校验user.role ! admin时返回 403且列表为空时返回 400No items to save见 packing.controller.tsApply Template— 若已存在模板头部会出现Apply Template下拉框。选择某个模板后其物品会追加到当前清单不会移除已有物品。应用模板时可以指定目标层级common或personal默认common见 packing.controller.ts。模板的集中管理在管理员后台完成详见 Admin-Packing-Templates。前端面板通过listTemplates/applyTemplate/saveAsTemplate三个 API 与后端交互usePackingListPanel.ts。权限Permissions所有写入操作新增/编辑/删除物品、重排、共享设置、行李管理、应用模板等都要求当前用户具备packing_edit权限只读的列表/行李/模板查询仅要求能访问该行程。后端每个 mutation handler 都会先执行requireEdit无权限时返回 403packing.controller.ts。前端则通过can(packing_edit, trip)判断是否渲染编辑控件usePackingListPanel.ts。值得一提的例外保存模板需要管理员角色而非普通成员权限这是与其余写操作不同的权限要求。关联阅读Packing-TemplatesAdmin-Packing-TemplatesAdmin-AddonsNotificationsTrip-Planner-Overview【免费下载链接】TREKA self-hosted travel/trip planner with real-time collaboration, interactive maps, PWA support, SSO, budgets, packing lists, and more.项目地址: https://gitcode.com/GitHub_Trending/nomad22/TREK创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价