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

如何用JavaScript开发日期调度应用及飞机跑道调度程序

一、如何使用JavaScript开发一款日期调度应用

作为开发过不少日程调度工具的人,我来给你拆解下核心步骤——不管是纯JS还是结合React,思路都是相通的:

  • 第一步:明确核心需求与数据结构
    先搞清楚你的调度应用要支持什么:是个人日程?团队协作?还是资源类调度?先定义好基础的数据结构,比如:

    // 基础日程项结构(可根据需求扩展)
    const scheduleItem = {
      id: "unique-id",
      title: "会议名称",
      startTime: 1718901600000, // 用时间戳存储,方便后续计算
      endTime: 1718905200000,
      isAllDay: false // 可选:标记是否为全天日程
    };
    
  • 第二步:实现核心调度逻辑
    最关键的是冲突检测——这几乎是所有调度应用的核心。比如判断新添加的日程是否和已有日程重叠:

    function checkConflict(newItem, existingItems) {
      return existingItems.some(item => {
        // 重叠逻辑:新日程的开始时间在已有日程的时间范围内,或者结束时间在范围内
        return (newItem.startTime < item.endTime && newItem.endTime > item.startTime);
      });
    }
    

    在此基础上,封装添加、删除、编辑日程的方法,每次操作前先做冲突检测,确保调度合法。

  • 第三步:UI层实现(结合React更高效)
    如果用React开发,可通过useState或状态管理库维护日程列表,再渲染对应的视图。比如做一个简单的时间线视图:

    function ScheduleTimeline({ items }) {
      const dayStart = new Date().setHours(0, 0, 0, 0);
      const dayDuration = 24 * 60 * 60 * 1000;
    
      return (
        <div className="timeline">
          {items.map(item => (
            <div
              key={item.id}
              className="timeline-item"
              style={{
                left: `${(item.startTime - dayStart) / dayDuration * 100}%`,
                width: `${(item.endTime - item.startTime) / dayDuration * 100}%`
              }}
            >
              {item.title}
            </div>
          ))}
        </div>
      );
    }
    
  • 第四步:优化用户体验
    比如添加日程时实时提示冲突、支持拖拽调整时间、用localStorage保存数据避免刷新丢失等,这些小细节能大幅提升应用质感。


二、新手向:实现飞机跑道起降调度的Scheduler类(React可用)

针对你说的飞机跑道调度场景,核心规则是每次起降需要在计划时间的前10分钟到后10分钟独占跑道,咱们一步步来拆解实现:

1. 核心逻辑梳理

每个航班的“独占时间区间”是 [计划时间 - 10分钟, 计划时间 + 10分钟],新航班添加时,必须检查这个区间是否和已有的任何航班区间重叠。

2. 实现Scheduler类

我给你写个极简但可用的版本,你可以根据需求扩展:

class RunwayScheduler {
  constructor() {
    // 存储已调度的航班,每个航班包含唯一ID和计划起降时间(时间戳)
    this.scheduledFlights = [];
  }

  // 辅助函数:计算航班的独占时间区间(单位:毫秒)
  #getExclusiveInterval(planTime) {
    const tenMinutes = 10 * 60 * 1000;
    return {
      start: planTime - tenMinutes,
      end: planTime + tenMinutes
    };
  }

  // 检查新航班是否存在调度冲突
  hasConflict(newPlanTime) {
    const newInterval = this.#getExclusiveInterval(newPlanTime);
    return this.scheduledFlights.some(flight => {
      const existingInterval = this.#getExclusiveInterval(flight.planTime);
      // 区间重叠判断:新区间的start < 已有区间的end,且新区间的end > 已有区间的start
      return newInterval.start < existingInterval.end && newInterval.end > existingInterval.start;
    });
  }

  // 添加航班调度,成功返回true,冲突返回false
  addFlight(flightId, planTime) {
    if (this.hasConflict(planTime)) {
      console.error(`航班${flightId}调度冲突,无法添加`);
      return false;
    }
    this.scheduledFlights.push({ id: flightId, planTime });
    return true;
  }

  // 删除指定航班的调度
  removeFlight(flightId) {
    this.scheduledFlights = this.scheduledFlights.filter(flight => flight.id !== flightId);
  }

  // 获取所有已调度的航班(返回副本,避免外部修改内部数据)
  getFlights() {
    return [...this.scheduledFlights];
  }
}

3. 在React中使用Scheduler

React组件中可以用useRef保存Scheduler实例,避免组件重渲染时丢失已调度数据:

import { useState, useRef } from 'react';

function RunwayApp() {
  const scheduler = useRef(new RunwayScheduler());
  const [flights, setFlights] = useState([]);
  const [planTime, setPlanTime] = useState('');

  const handleAddFlight = () => {
    const timestamp = new Date(planTime).getTime();
    if (!timestamp) {
      alert('请输入有效的起降时间');
      return;
    }
    const flightId = `FL-${Date.now()}`; // 生成唯一ID
    const success = scheduler.current.addFlight(flightId, timestamp);
    if (success) {
      setFlights(scheduler.current.getFlights());
      setPlanTime('');
    } else {
      alert('该时间前后10分钟已有航班调度,请重新选择');
    }
  };

  const handleRemove = (id) => {
    scheduler.current.removeFlight(id);
    setFlights(scheduler.current.getFlights());
  };

  return (
    <div className="app">
      <h2>飞机跑道调度系统</h2>
      <div className="input-group">
        <input
          type="datetime-local"
          value={planTime}
          onChange={(e) => setPlanTime(e.target.value)}
        />
        <button onClick={handleAddFlight}>添加调度</button>
      </div>
      <div className="flights-list">
        <h3>已调度航班</h3>
        {flights.length === 0 ? (
          <p>暂无调度记录</p>
        ) : (
          <ul>
            {flights.map(flight => (
              <li key={flight.id}>
                航班{flight.id}:{new Date(flight.planTime).toLocaleString()}
                <button onClick={() => handleRemove(flight.id)}>删除</button>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

export default RunwayApp;

4. 新手注意事项

  • 用时间戳处理时间计算,能避免时区、字符串格式等坑;
  • Scheduler类中用#标记私有方法,避免外部误调用;
  • 如果要支持多跑道,只需要给Scheduler添加跑道ID参数,每个跑道维护独立的航班列表即可。

内容的提问来源于stack exchange,提问作者Francis Batista

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:56:20