Google表单编辑响应时同步表格与日历的自身预约冲突误判解决
改造方案
核心调整思路
现有冲突判定的核心问题是:拉取到重叠日历事件后未做归属过滤,将当前提交人自身创建的旧预约也计入冲突范围,需要从三个层面补全校验逻辑:
- 创建日历事件时,为每个事件绑定提交人邮箱、对应表格行号作为自定义标签,解决后续无法精准定位事件归属的问题。原有逻辑下所有预约事件的标题统一为“Booked”,未携带提交人关联信息,无法通过现有字段识别事件归属,必须通过自定义标签建立事件和提交人、表格行的绑定关系。
- 冲突检测阶段,对时间重叠的事件做二次过滤,排除属于当前提交人的事件后,再判定是否存在真实冲突
- 兼容表单响应编辑场景:用户修改原有提交时,先匹配并删除该用户关联的旧日历事件,再执行新的冲突校验、生成新预约
具体代码调整
1. 扩展Submission对象的属性
在原有构造函数中新增行ID字段,方便后续和日历事件做精准关联:
function Submission(){ var row = lastRow; this.rowId = row; // 新增行ID存储 this.timestamp = sheet.getRange(row, 1).getValue(); this.email = sheet.getRange(row, 2).getValue(); this.name = sheet.getRange(row, 3).getValue(); this.date = sheet.getRange(row, 4).getValue(); this.dateout = sheet.getRange(row, 5).getValue(); this.room = sheet.getRange(row, 6).getValue(); this.day = sheet.getRange(row,8).setFormula("=(R[0]C[-3]-R[0]C[-4])+1").getValue(); var fillDownRange = sheet.getRange(2, 8, lastRow-1); sheet.getRange(row,8).copyTo(fillDownRange); this.status; this.dateString = (this.date.getMonth() + 1) + '/' + this.date.getDate() + '/' + this.date.getYear(); this.dateOutString = (this.dateout.getMonth() + 1) + '/' + this.dateout.getDate() + '/' + this.dateout.getYear(); this.calendar = eval('cal' + String(this.room)); return this; }
2. 改造日历事件创建逻辑
创建事件时将提交人邮箱作为标签写入事件属性,为后续归属判断提供依据:
//update calendar (add) function updateCalendar(request){ var event = request.calendar.createEvent( "Booked", request.date, request.endTime ); // 新增:写入事件归属标签 event.setTag("submittedEmail", request.email); event.setTag("sourceRowId", String(request.rowId)); }
3. 重写冲突检测函数
在原有拉取重叠事件的逻辑基础上,过滤掉当前提交人自身的事件,再判定冲突:
function getEndTime(request){ request.endTime = new Date(request.dateout.getTime() + 24 * 60 * 60 * 1000); } // 改造后的冲突检测 function getConflicts(request){ const overlappingEvents = request.calendar.getEvents(request.date, request.endTime); // 过滤非当前提交人创建的重叠事件 const realConflicts = overlappingEvents.filter(event => { const eventOwner = event.getTag("submittedEmail"); return eventOwner !== request.email; }); request.status = realConflicts.length < 1 ? "Approve" : "Conflict"; }
4. 补充旧预约清理函数
针对表单编辑场景,先删除用户自己的旧关联事件,避免重复生成冗余预约:
// 清理当前提交人关联的旧日历事件 function cleanOldUserEvent(request){ const historyEvents = request.calendar.getEvents( new Date(0), new Date(), ); historyEvents.forEach(event => { if(event.getTag("submittedEmail") === request.email){ event.deleteEvent(); } }) }
最终流程执行顺序:
表单提交触发流程 → 初始化Submission对象 → 计算请求结束时间 → 调用cleanOldUserEvent清理该用户的旧预约 → 调用getConflicts做冲突校验 → 校验通过时调用updateCalendar创建新预约
内容的提问来源于stack exchange,提问作者Sarimu
相关产品推荐
相关产品推荐

