196 lines
9.2 KiB
HTML
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> |