119 lines
5.1 KiB
HTML
119 lines
5.1 KiB
HTML
<div class="mb-6">
|
||
<div class="flex items-center">
|
||
<a href="/admin/robots" class="text-indigo-600 hover:text-indigo-800 mr-4">
|
||
<i class="fas fa-arrow-left"></i>
|
||
</a>
|
||
<h1 class="text-2xl font-bold text-gray-800">新建机器人</h1>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="max-w-2xl">
|
||
<div class="bg-white rounded-lg shadow-md overflow-hidden">
|
||
<div class="p-6">
|
||
<form id="robot-form" action="/admin/robots" method="POST">
|
||
<div class="mb-6">
|
||
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">机器人名称</label>
|
||
<input type="text" id="name" name="name"
|
||
class="form-control"
|
||
placeholder="请输入机器人名称"
|
||
required>
|
||
<p class="mt-1 text-sm text-gray-500">给机器人起一个容易辨识的名称</p>
|
||
</div>
|
||
|
||
<div class="mb-6">
|
||
<label for="port" class="block text-sm font-medium text-gray-700 mb-1">端口映射 <span class="text-gray-500">(可选)</span></label>
|
||
<input type="number" id="port" name="port"
|
||
class="form-control"
|
||
placeholder="例如: 9001"
|
||
min="1024" max="65535">
|
||
<p class="mt-1 text-sm text-gray-500">可指定端口映射,留空则自动分配</p>
|
||
</div>
|
||
|
||
<div class="border-t border-gray-100 mt-6 pt-6">
|
||
<div class="flex justify-end space-x-3">
|
||
<a href="/admin/robots" class="btn-secondary">
|
||
取消
|
||
</a>
|
||
<button type="submit" class="btn-primary">
|
||
<i class="fas fa-plus mr-1"></i> 创建机器人
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-8 bg-blue-50 rounded-lg p-4 border border-blue-100">
|
||
<h3 class="text-md font-medium text-blue-800 mb-2 flex items-center">
|
||
<i class="fas fa-info-circle mr-2"></i> 提示信息
|
||
</h3>
|
||
<ul class="list-disc list-inside text-sm text-blue-700 ml-2 space-y-1">
|
||
<li>创建机器人会启动一个新的Docker容器</li>
|
||
<li>创建成功后需要扫码登录微信</li>
|
||
<li>每个机器人占用独立的容器资源</li>
|
||
<li>端口映射用于访问容器的HTTP服务,默认自动分配</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const form = document.getElementById('robot-form');
|
||
const nameInput = document.getElementById('name');
|
||
const portInput = document.getElementById('port');
|
||
|
||
form.addEventListener('submit', function(e) {
|
||
// 简单客户端验证
|
||
if (nameInput.value.trim() === '') {
|
||
e.preventDefault();
|
||
nameInput.classList.add('border-red-500');
|
||
|
||
const errorMsg = document.createElement('p');
|
||
errorMsg.className = 'mt-1 text-sm text-red-600';
|
||
errorMsg.textContent = '机器人名称不能为空';
|
||
|
||
if (!nameInput.nextElementSibling.classList.contains('text-red-600')) {
|
||
nameInput.parentNode.insertBefore(errorMsg, nameInput.nextElementSibling.nextSibling);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (portInput.value !== '' && (parseInt(portInput.value) < 1024 || parseInt(portInput.value) > 65535)) {
|
||
e.preventDefault();
|
||
portInput.classList.add('border-red-500');
|
||
|
||
const errorMsg = document.createElement('p');
|
||
errorMsg.className = 'mt-1 text-sm text-red-600';
|
||
errorMsg.textContent = '端口必须在1024-65535范围内';
|
||
|
||
if (!portInput.nextElementSibling.classList.contains('text-red-600')) {
|
||
portInput.parentNode.insertBefore(errorMsg, portInput.nextElementSibling.nextSibling);
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 添加提交中状态
|
||
const submitBtn = form.querySelector('button[type="submit"]');
|
||
submitBtn.disabled = true;
|
||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> 创建中...';
|
||
});
|
||
|
||
// 移除错误状态
|
||
nameInput.addEventListener('input', function() {
|
||
this.classList.remove('border-red-500');
|
||
const errorMsg = this.parentNode.querySelector('.text-red-600');
|
||
if (errorMsg) {
|
||
errorMsg.remove();
|
||
}
|
||
});
|
||
|
||
portInput.addEventListener('input', function() {
|
||
this.classList.remove('border-red-500');
|
||
const errorMsg = this.parentNode.querySelector('.text-red-600');
|
||
if (errorMsg) {
|
||
errorMsg.remove();
|
||
}
|
||
});
|
||
});
|
||
</script>
|