stream_app/templates/index.html
2025-04-18 13:20:01 +08:00

196 lines
9.2 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>装货方案计算</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<style>
body {
font-family: 'Inter', sans-serif;
}
</style>
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-4">
<h1 class="text-3xl font-bold text-center text-blue-600 mb-8">装货方案计算</h1>
<div class="bg-white p-6 rounded-md shadow-md">
<h2 class="text-xl font-bold mb-4">输入纸箱信息</h2>
<div id="cartons" class="mb-4">
<div class="flex mb-2">
<input type="number" placeholder="长" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="宽" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="高" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="重量" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<button onclick="addCartonInput()" class="bg-blue-500 text-white p-2 rounded-md hover:bg-blue-600">添加纸箱</button>
</div>
</div>
<h2 class="text-xl font-bold mb-4">输入集装箱信息</h2>
<div id="containers" class="mb-4">
<div class="flex mb-2">
<input type="number" placeholder="长" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="宽" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="高" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="最大载重" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<button onclick="addContainerInput()" class="bg-blue-500 text-white p-2 rounded-md hover:bg-blue-600">添加集装箱</button>
</div>
</div>
<button onclick="calculate()" class="bg-green-500 text-white p-2 rounded-md hover:bg-green-600">计算最优方案</button>
</div>
<div id="result" class="mt-8 bg-white p-6 rounded-md shadow-md"></div>
<div class="mt-8 bg-white p-6 rounded-md shadow-md">
<h3 class="text-xl font-bold mb-4">3D摆放视图</h3>
<div id="3d-view"></div>
</div>
</div>
<script>
function addCartonInput() {
const cartonsDiv = document.getElementById('cartons');
const newCarton = document.createElement('div');
newCarton.classList.add('flex', 'mb-2');
newCarton.innerHTML = `
<input type="number" placeholder="长" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="宽" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="高" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="重量" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
`;
cartonsDiv.appendChild(newCarton);
}
function addContainerInput() {
const containersDiv = document.getElementById('containers');
const newContainer = document.createElement('div');
newContainer.classList.add('flex', 'mb-2');
newContainer.innerHTML = `
<input type="number" placeholder="长" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="宽" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="高" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
<input type="number" placeholder="最大载重" class="border border-gray-300 p-2 mr-2 w-1/4 rounded-md">
`;
containersDiv.appendChild(newContainer);
}
function calculate() {
const cartonsInputs = document.querySelectorAll('#cartons input');
const containersInputs = document.querySelectorAll('#containers input');
let cartons = [];
for (let i = 0; i < cartonsInputs.length; i += 4) {
const length = parseFloat(cartonsInputs[i].value);
const width = parseFloat(cartonsInputs[i + 1].value);
const height = parseFloat(cartonsInputs[i + 2].value);
const weight = parseFloat(cartonsInputs[i + 3].value);
if (!isNaN(length) && !isNaN(width) && !isNaN(height) && !isNaN(weight)) {
cartons.push({ length, width, height, weight });
}
}
let containers = [];
for (let i = 0; i < containersInputs.length; i += 4) {
const length = parseFloat(containersInputs[i].value);
const width = parseFloat(containersInputs[i + 1].value);
const height = parseFloat(containersInputs[i + 2].value);
const maxWeight = parseFloat(containersInputs[i + 3].value);
if (!isNaN(length) && !isNaN(width) && !isNaN(height) && !isNaN(maxWeight)) {
containers.push({ length, width, height, maxWeight });
}
}
fetch('/calculate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ cartons, containers })
})
.then(response => response.json())
.then(data => {
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = '';
data.forEach((container, index) => {
const containerDiv = document.createElement('div');
containerDiv.classList.add('border', 'border-gray-300', 'p-4', 'mb-4', 'rounded-md');
containerDiv.innerHTML = `
<h3 class="text-lg font-bold">集装箱 ${index + 1}</h3>
<p>当前重量: ${container.currentWeight}</p>
<h4 class="text-md font-bold">装入的纸箱:</h4>
<ul>
${container.cartons.map(carton => `<li>长: ${carton.length}, 宽: ${carton.width}, 高: ${carton.height}, 重量: ${carton.weight}</li>`).join('')}
</ul>
`;
resultDiv.appendChild(containerDiv);
});
});
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
let scene, camera, renderer;
let containerGroup;
function initThree() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(800, 500);
document.getElementById('3d-view').appendChild(renderer.domElement);
// 灯光设置
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 10, 10);
scene.add(light);
scene.add(new THREE.AmbientLight(0x404040));
camera.position.z = 15;
camera.position.y = 10;
camera.lookAt(0, 0, 0);
}
function renderContainer(container) {
if(containerGroup) scene.remove(containerGroup);
containerGroup = new THREE.Group();
// 绘制集装箱
const geometry = new THREE.BoxGeometry(
container.length,
container.height,
container.width
);
const edges = new THREE.EdgesGeometry(geometry);
const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color: 0x000000 }));
containerGroup.add(line);
// 绘制纸箱
container.cartons.forEach(c => {
const box = new THREE.Mesh(
new THREE.BoxGeometry(c.length, c.height, c.width),
new THREE.MeshPhongMaterial({ color: 0x2194f3 })
);
box.position.set(c.position[0], c.position[1], c.position[2]);
containerGroup.add(box);
});
scene.add(containerGroup);
stopAnimation();
animate();
}
let animationId;
function animate() {
animationId = requestAnimationFrame(animate);
renderer.render(scene, camera);
containerGroup.rotation.y += 0.005;
}
function stopAnimation() {
if(animationId) cancelAnimationFrame(animationId);
}
// 初始化3D场景
window.addEventListener('load', initThree);
</script>
</body>
</html>