You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 14:06:04