多日历同步出现时间冲突时,Town 通常应先看优先级最高且更新时间最新的那本日历;但一旦参会人对某段冲突给出明确回复,参会人的实时回复应当覆盖日历里的旧忙碌状态。这个判断不是固定的,需要靠优先级配置、冲突日志和一轮人工确认流程来验证。先信哪份日历,取决于你把哪本日历定为主日历,以及它是否包含完整的忙碌状态。
处理多日历冲突,建议把“日历优先级”和“参会人回复”分成两层:第一层由配置决定平时信哪本日历,第二层由参会人明确回复兜底。当主日历与工作日历、个人日历打架,或日历更新明显滞后时,不要继续自动拍板,应暂停协调、标注冲突来源并转人工确认。验证方式通常是构造重叠事件、查协调日志、看它选了哪本日历或有没有发出询问。
列出所有已同步日历及来源
先确认冲突到底来自哪几份日历。很多“时间冲突”其实是漏看了隐藏日历、只读日历或只同步了忙碌状态、没同步标题的日历。建议逐份记录这几个字段:日历名称、接入方式或账号来源、读写权限、同步方向、更新频率,以及是否包含忙碌状态。只有忙碌状态没标题的那类日历,也照样会参与冲突判断,所以不能因为看不到详情就跳过。
- 名称:例如“工作主日历”“团队共享日历”“个人日历”“订阅日历”。
- 权限:只读、可写、仅忙碌,分别影响 Town 能不能回写和能不能改事件。
- 更新频率:手动同步、定时同步还是事件驱动同步;频率越低,越容易读到旧数据。
- 忙碌状态:确认该日历是否把“忙碌/空闲”写进同步数据,否则冲突可能被误判为不存在。
如果 Town 提供冲突日志或同步记录,可以先在页面或日志里找出这条冲突关联了哪几个日历 ID。字段名因部署而异,下面的排查方式按你的实际日志替换字段名后再用。
# 通用排查思路,字段名按实际环境替换
grep -i "conflict\|calendar_id\|busy" town.log
# 期望能看到:冲突时间段、参与判断的日历 ID、最终选中的日历
这一步的验证标准很简单:你能说清“这条冲突由哪几份日历组成”。如果列不全,后面配优先级就没有意义。
给多个日历定优先级与信任级别
Town 在冲突时需要一条明确的参照顺序,否则它可能按同步时间先后随便选一个。建议写一份通用配置骨架,只表达主日历、工作日历、个人日历的优先级和信任级别,不绑定任何官方接口。字段名和层级可按你的实际配置格式替换。
calendar_policy:
sources:
- name: "work-main" # 主日历
priority: 1
trust: "high"
require_busy_state: true
- name: "team-shared" # 工作日历
priority: 2
trust: "medium"
require_busy_state: true
- name: "personal" # 个人日历
priority: 3
trust: "low"
require_busy_state: false
conflict_rule: "higher_priority_wins" # 冲突时先按优先级
attendee_reply_override: true # 参会人明确回复可覆盖日历
这里有两个需要自己确认的边界。第一,priority 越小是否代表越优先,必须和 Town 实际读取逻辑一致,不能只看字段名猜。第二,attendee_reply_override 开启后,参会人回复应优先于日历,但“参会人回复”指明确确认还是模糊意向,需要结合你们的使用习惯定。
配置完成后不要直接依赖它。先用一条已知冲突验证 Town 是否按优先级选中主日历,再验证参会人回复能否把它拉回来。
构造同段冲突事件进行验证
要观察 Town 的行为,最直接的办法是在测试日历里放两段完全重叠的事件,再让它去协调。建议按下面步骤做:
- 在主日历放一段事件 A,时间设为 10:00–11:00。
- 在个人日历放一段事件 B,时间同样设为 10:00–11:00,制造真实冲突。
- 触发 Town 的协调动作,观察它读到几条冲突项、最终选了哪本日历、有没有向参会人发出询问。
- 对照冲突日志,确认选中的日历与你的 priority 配置是否一致。
验证点有三个:它是否读到了两本日历的冲突;它是直接按优先级选,还是转去问参会人;询问里是否带上了冲突时间段和可选的参会人。若它只读了一本日历,先回到第一步检查另一本日历的忙碌状态是否同步进来。若它按优先级选了却没有询问,说明当前规则偏向日历优先;反过来,如果它频繁询问,说明参会人回复的权重可能配得较高。这些都是配置行为,可以通过调整后再跑一遍确认。
模拟日历更新滞后的情况
同步频率低或外部日历更新慢时,Town 可能拿着旧数据去判断。要确认旧日历不会压过参会人的最新回复,可以按这个顺序模拟:
- 先让 Town 对某个时间段发出协调询问。
- 在参会人还没回复时,去日历里把该事件时间改掉,制造“日历已变、Town 可能还读旧值”的状态。
- 记录 Town 是否重新读取日历,是否更新了冲突结果。
- 如果参会人随后明确回复,再记录回复与日历哪个生效。
验证时重点看日志里的读取时间戳或事件版本标识,确认它用的是修改前还是修改后的数据。如果 Town 没有重新读取,需要检查同步频率、缓存或事件版本判断逻辑,而不是直接认定参会人回复没用。边界是:这一步只证明“它会不会重新读”,不证明协调结果一定正确,最终还要结合升级路径处理。
设置冲突无法判定时的升级路径
多日历互相矛盾、优先级也分不出高下时,继续自动协调容易产生误判。建议配置一条人工兜底路径:
- 暂停自动协调。在冲突策略里加入类似
auto_coordinate: false的开关,或只对当前冲突暂停,避免 Town 继续改时间。 - 标注冲突来源。把参与冲突的日历名称、事件 ID、冲突时间段和各自优先级写进待确认记录,方便确认人判断。
- 通知指定确认人。把这条记录发给一个明确的人或值班组,而不是发到群里等谁看见。通知内容至少包含冲突来源、建议选项和回复期限。
- 人工确认后再恢复。确认人给出结论后,再打开自动协调,并用一次重叠事件复测行为是否恢复。
这条路径的适用场景是:两本高优先级日历互相冲突、参会人回复与日历明显不一致、或者日历更新时间无法确认。风险边界是,暂停自动协调会增加人工介入,但它换来的是冲突来源可追溯;对于需要准确排期的团队,这通常比让 Town 硬选一本日历更稳妥。