标签搜索

挤出逻辑

wehg489
2025-05-07 / 0 评论 / 2 阅读 / 正在检测是否收录...
<body>
  <div class="container">
    <h1>挤出排产</h1>
    <div class="input-group">
      <input type="file" id="excelFile" accept=".xlsx">
      <input type="date" id="startDate" required>
      <button onclick="startScheduling()">开始排产</button>
    </div>
    <div id="scheduleResult"></div>
  </div>

<script>
const PRODUCTION_PARAMS = {
  speed: {
    low: 5000,    // ≤16mm
    medium: 4000, // 17-30mm
    high: 3500    // >30mm
  },
  diameterGroups: [
    { max: 8, name: '0-8mm' },
    { max: 11, name: '9-11mm' },
    { max: Infinity, name: '12mm+' }
  ]
};

document.addEventListener('DOMContentLoaded', () => {
  if(typeof XLSX === 'undefined') {
    alert('错误:核心库加载失败,请检查网络连接');
    return;
  }
  document.getElementById('startDate').valueAsDate = new Date();
});

function startScheduling() {
  const fileInput = document.getElementById('excelFile');
  const startDate = document.getElementById('startDate').value;

  if(!fileInput.files.length) return alert("请选择Excel文件");
  if(!startDate) return alert("请选择排产开始日期");

  const reader = new FileReader();
  reader.onload = processExcelFile;
  reader.readAsArrayBuffer(fileInput.files[0]);
}

function processExcelFile(event) {
  try {
    const workbook = XLSX.read(event.target.result, {type: 'array'});
    const sheet = workbook.Sheets[workbook.SheetNames[0]];
    const rawData = XLSX.utils.sheet_to_json(sheet, {header:1});
    const orders = validateAndFormatData(rawData);
    const schedule = generateProductionSchedule(orders);
    renderScheduleTable(schedule);
  } catch (error) {
    handleError('文件处理失败', error);
  }
}

function validateAndFormatData(rawData) {
  return rawData.slice(1).map((row, index) => {
    const dateIndex = 2;
    if(row.length < 7) throw new Error(`第${index+2}行数据列数不足`);

    let demandDate;
    const excelDateValue = row[dateIndex];
    if(typeof excelDateValue === 'number') {
      const parsed = XLSX.SSF.parse_date_code(excelDateValue);
      demandDate = new Date(parsed.y, parsed.m - 1, parsed.d);
    } else {
      demandDate = new Date(excelDateValue);
    }

    if(isNaN(demandDate.getTime())) {
      throw new Error(`第${index+2}行需求日期格式错误,值:${excelDateValue}`);
    }

    return {
      订单号: String(row[0]).trim(),
      需求数量: Number(row[1]),
      需求日期: demandDate,
      产品口径: Number(row[3]),
      实际长度: parseFloat(Number(row[4]).toFixed(2)),
      胶料类型: String(row[5]).trim(),
      生产机台: String(row[6]).trim(),
      挤出基数: Math.ceil(row[1] * 1.1 / 10) * 10,
      剩余数量: Math.ceil(row[1] * 1.1 / 10) * 10
    };
  }).filter(order => order.需求数量 >= 10);
}

function generateProductionSchedule(orders) {
  const schedule = {};
  const startDate = new Date(document.getElementById('startDate').value);
  const grouped = groupOrders(orders);

  const sortedKeys = Object.keys(grouped).sort();

  sortedKeys.forEach(key => {
    const [machine, material, diameterGroup] = key.split('|');
    const orderList = grouped[key];
    let currentDate = new Date(startDate);

    const { maxQty: maxDailyQty } = calculateDailyCapacity(orderList[0].产品口径, orderList[0].实际长度);

    while (orderList.some(o => o.剩余数量 > 0)) {
      const dateKey = formatDate(currentDate);
      if (!schedule[machine]) schedule[machine] = {};
      if (!schedule[machine][dateKey]) {
        schedule[machine][dateKey] = {
          items: [],
          totalLength: 0,
          usedQty: 0,
          capacity: maxDailyQty
        };
      }

      const day = schedule[machine][dateKey];
      let capacityLeft = day.capacity - day.usedQty;

      for (let order of orderList) {
        if (order.剩余数量 <= 0 || capacityLeft <= 0) continue;
        const canAlloc = Math.min(order.剩余数量, capacityLeft);
        day.items.push({
          订单号: order.订单号,
          胶料类型: order.胶料类型,
          产品口径: order.产品口径,
          实际长度: order.实际长度,
          排产数量: canAlloc,
          排产长度: canAlloc * order.实际长度,
          需求日期: order.需求日期
        });
        day.totalLength += canAlloc * order.实际长度;
        day.usedQty += canAlloc;
        order.剩余数量 -= canAlloc;
        capacityLeft -= canAlloc;
      }

      currentDate = addDays(currentDate, 1);
    }
  });

  return schedule;
}

function groupOrders(orders) {
  const groups = {};
  orders.forEach(order => {
    const diameterGroup = PRODUCTION_PARAMS.diameterGroups.find(g => order.产品口径 <= g.max).name;
    const key = `${order.生产机台}|${order.胶料类型}|${diameterGroup}`;
    if (!groups[key]) groups[key] = [];
    groups[key].push(order);
  });
  return groups;
}

function calculateDailyCapacity(diameter, length) {
  let speed;
  if(diameter <= 16) speed = PRODUCTION_PARAMS.speed.low;
  else if(diameter <= 30) speed = PRODUCTION_PARAMS.speed.medium;
  else speed = PRODUCTION_PARAMS.speed.high;
  const maxQty = Math.floor(speed / length);
  return { value: speed, maxQty };
}

function formatDate(date) {
  return date.toISOString().split('T')[0];
}

function addDays(date, days) {
  const result = new Date(date);
  result.setDate(result.getDate() + days);
  return result;
}

function renderScheduleTable(schedule) {
  let html = '';

  Object.entries(schedule).forEach(([machine, dateMap]) => {
    html += `<div class="machine-header">
      <h3>${machine} 生产计划</h3>
      <div class="capacity-info">每日最大产能:${Object.values(dateMap)[0].capacity} 米</div>
    </div>`;

    html += `<table>
      <tr>
        <th>生产日期</th>
        <th>订单号</th>
        <th>口径(mm)</th>
        <th>长度(m)</th>
        <th>胶料类型</th>
        <th>排产数量</th>
        <th>总长度(m)</th>
        <th>需求日期</th>
        <th>状态</th>
        
      </tr>`;

    Object.entries(dateMap).forEach(([date, data]) => {
      data.items.forEach(item => {
        const isLate = new Date(date) > new Date(item.需求日期);
        html += `<tr${isLate ? ' class="warning"' : ''}>
          <td>${date}</td>
          <td>${item.订单号}</td>
          <td>${item.产品口径}</td>
          <td>${item.实际长度.toFixed(2)}</td>
          <td>${item.胶料类型}</td>
          <td>${item.排产数量}</td>
          <td>${item.排产长度.toFixed(1)}</td>
          <td>${item.需求日期.toISOString().split('T')[0]}</td>
          <td>${isLate ? '延迟' : '正常'}</td>
         
        </tr>`;
      });

      html += `<tr class="summary-row">
        <td colspan="5">当日汇总</td>
        <td>${data.usedQty}</td>
        <td>${data.totalLength.toFixed(1)}</td>
        <td colspan="3"> </td>
      </tr>`;
    });

    html += `</table>`;
  });

  document.getElementById('scheduleResult').innerHTML = html;
}

function handleError(message, error) {
  console.error(`${message}:`, error);
  alert(`${message},请检查控制台获取详细信息`);
}
</script>
</body>
0

评论 (0)

取消
歌曲封面
0:00