<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="UTF-8">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<style>
|
* {
|
margin: 0;
|
padding: 0;
|
box-sizing: border-box;
|
}
|
|
body {
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
padding: 30px;
|
line-height: 1.8;
|
}
|
|
.breadcrumb {
|
font-size: 14px;
|
color: #999;
|
margin-bottom: 25px;
|
padding: 12px 20px;
|
background: linear-gradient(145deg, #ffffff, #f5f5f5);
|
border-radius: 8px;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
}
|
|
.breadcrumb a {
|
color: #999;
|
text-decoration: none;
|
}
|
|
.update-time {
|
float: right;
|
color: #ccc;
|
font-size: 12px;
|
}
|
|
.intro {
|
line-height: 2;
|
margin-bottom: 40px;
|
color: #555;
|
font-size: 16px;
|
padding: 25px;
|
background: linear-gradient(145deg, #ffffff, #f8f9fa);
|
border-radius: 12px;
|
border-left: 4px solid #0066cc;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
}
|
|
h1 {
|
font-size: 32px;
|
margin-bottom: 30px;
|
padding-bottom: 20px;
|
border-bottom: 3px solid transparent;
|
border-image: linear-gradient(90deg, #0066cc, #00c6ff);
|
border-image-slice: 1;
|
color: #1a1a2e;
|
font-weight: 700;
|
}
|
|
h2 {
|
font-size: 22px;
|
margin: 40px 0 25px;
|
color: #1a1a2e;
|
font-weight: 700;
|
}
|
|
.content-text {
|
line-height: 1.8;
|
color: #666;
|
margin-bottom: 20px;
|
}
|
|
ul.feature-list {
|
list-style: none;
|
padding-left: 20px;
|
}
|
|
ul.feature-list li {
|
position: relative;
|
padding-left: 20px;
|
margin-bottom: 10px;
|
line-height: 1.8;
|
color: #666;
|
}
|
|
ul.feature-list li:before {
|
content: "■";
|
position: absolute;
|
left: 0;
|
color: #333;
|
}
|
|
.feedback-section {
|
margin: 40px 0;
|
text-align: center;
|
}
|
|
.stars {
|
margin: 20px 0;
|
}
|
|
.stars span {
|
font-size: 30px;
|
margin: 0 10px;
|
color: #ddd;
|
cursor: pointer;
|
}
|
|
.pagination {
|
display: flex;
|
justify-content: space-between;
|
margin-top: 60px;
|
padding-top: 30px;
|
border-top: 1px solid #e0e0e0;
|
}
|
|
.pagination > div {
|
cursor: pointer;
|
max-width: 45%;
|
}
|
|
.pagination > div:hover {
|
color: #0066cc;
|
}
|
|
.api-section {
|
margin: 40px 0;
|
padding: 30px;
|
background: linear-gradient(145deg, #ffffff, #f0f0f0);
|
border-radius: 16px;
|
box-shadow: 0 8px 32px rgba(0, 102, 204, 0.1);
|
transition: all 0.3s ease;
|
}
|
|
.api-section:hover {
|
box-shadow: 0 12px 48px rgba(0, 102, 204, 0.15);
|
transform: translateY(-2px);
|
}
|
|
.api-section h2 {
|
margin-top: 0;
|
background: linear-gradient(135deg, #0066cc, #00c6ff);
|
-webkit-background-clip: text;
|
-webkit-text-fill-color: transparent;
|
background-clip: text;
|
font-size: 24px;
|
font-weight: 700;
|
position: relative;
|
padding-left: 20px;
|
}
|
|
.api-section h2::before {
|
content: '';
|
position: absolute;
|
left: 0;
|
top: 50%;
|
transform: translateY(-50%);
|
width: 6px;
|
height: 24px;
|
background: linear-gradient(135deg, #0066cc, #00c6ff);
|
border-radius: 3px;
|
}
|
|
.api-info {
|
background-color: #fff;
|
padding: 25px;
|
margin: 20px 0;
|
border-radius: 12px;
|
border-left: 5px solid #0066cc;
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
|
transition: all 0.3s ease;
|
}
|
|
.api-info:hover {
|
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
|
}
|
|
.api-method {
|
display: inline-block;
|
padding: 6px 16px;
|
border-radius: 20px;
|
font-weight: 700;
|
margin-right: 12px;
|
font-size: 13px;
|
text-transform: uppercase;
|
letter-spacing: 0.5px;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
transition: all 0.3s ease;
|
}
|
|
.api-method:hover {
|
transform: translateY(-1px);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
}
|
|
.method-post {
|
background: linear-gradient(135deg, #49cc90, #38b57d);
|
color: #fff;
|
}
|
|
.method-get {
|
background: linear-gradient(135deg, #61affe, #4e98eb);
|
color: #fff;
|
}
|
|
.method-put {
|
background: linear-gradient(135deg, #fca130, #e89020);
|
color: #fff;
|
}
|
|
.method-delete {
|
background: linear-gradient(135deg, #f93e3e, #e62e2e);
|
color: #fff;
|
}
|
|
.api-url {
|
font-family: 'Courier New', 'Consolas', monospace;
|
background: linear-gradient(135deg, #2d3748, #1a202c);
|
color: #48bb78;
|
padding: 14px 18px;
|
margin: 15px 0;
|
border-radius: 8px;
|
font-size: 14px;
|
word-break: break-all;
|
border: 1px solid #4a5568;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
position: relative;
|
overflow: hidden;
|
}
|
|
.api-url::before {
|
content: '';
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 4px;
|
height: 100%;
|
background: linear-gradient(180deg, #48bb78, #38a169);
|
}
|
|
table {
|
width: 100%;
|
border-collapse: collapse;
|
margin: 15px 0;
|
background-color: #fff;
|
}
|
|
table th,
|
table td {
|
padding: 12px;
|
text-align: left;
|
border: 1px solid #e0e0e0;
|
font-size: 14px;
|
}
|
|
table th {
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
font-weight: 700;
|
color: #fff;
|
text-transform: uppercase;
|
font-size: 12px;
|
letter-spacing: 0.5px;
|
}
|
|
table tr:hover {
|
background-color: #f8f9fa;
|
transition: background-color 0.2s ease;
|
}
|
|
pre {
|
background: linear-gradient(135deg, #1e1e1e, #2d2d30);
|
color: #d4d4d4;
|
padding: 24px;
|
border-radius: 12px;
|
overflow-x: auto;
|
margin: 20px 0;
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
border: 1px solid #3e3e42;
|
position: relative;
|
}
|
|
pre::before {
|
content: '{ }';
|
position: absolute;
|
top: 10px;
|
right: 15px;
|
color: #858585;
|
font-size: 12px;
|
font-weight: bold;
|
}
|
|
code {
|
font-family: 'Courier New', monospace;
|
font-size: 13px;
|
line-height: 1.6;
|
}
|
|
.mock-container {
|
background: linear-gradient(145deg, #ffffff, #f8f9fa);
|
padding: 25px;
|
margin: 25px 0;
|
border-radius: 16px;
|
box-shadow: 0 8px 24px rgba(0, 102, 204, 0.12);
|
border: 2px solid #e3e8ef;
|
transition: all 0.3s ease;
|
}
|
|
.mock-container:hover {
|
box-shadow: 0 12px 32px rgba(0, 102, 204, 0.18);
|
border-color: #0066cc;
|
}
|
|
.mock-btn {
|
background: linear-gradient(135deg, #0066cc, #0052a3);
|
color: #fff;
|
border: none;
|
padding: 12px 28px;
|
border-radius: 25px;
|
cursor: pointer;
|
font-size: 14px;
|
font-weight: 600;
|
margin: 5px;
|
height: 44px;
|
line-height: 20px;
|
box-shadow: 0 4px 15px rgba(0, 102, 204, 0.3);
|
transition: all 0.3s ease;
|
position: relative;
|
overflow: hidden;
|
box-sizing: border-box;
|
}
|
|
.mock-btn::before {
|
content: '';
|
position: absolute;
|
top: 50%;
|
left: 50%;
|
width: 0;
|
height: 0;
|
border-radius: 50%;
|
background: rgba(255, 255, 255, 0.3);
|
transform: translate(-50%, -50%);
|
transition: width 0.6s, height 0.6s;
|
}
|
|
.mock-btn:hover {
|
background: linear-gradient(135deg, #0052a3, #003d7a);
|
box-shadow: 0 6px 20px rgba(0, 102, 204, 0.4);
|
transform: translateY(-2px);
|
}
|
|
.mock-btn:hover::before {
|
width: 300px;
|
height: 300px;
|
}
|
|
.mock-btn:active {
|
transform: translateY(0);
|
box-shadow: 0 2px 10px rgba(0, 102, 204, 0.3);
|
}
|
|
.reset-btn {
|
background: linear-gradient(135deg, #f5f5f5, #e0e0e0);
|
color: #666;
|
border: 1px solid #d0d0d0;
|
padding: 12px 28px;
|
border-radius: 25px;
|
cursor: pointer;
|
font-size: 14px;
|
font-weight: 600;
|
margin: 5px;
|
height: 44px;
|
line-height: 20px;
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
|
transition: all 0.3s ease;
|
box-sizing: border-box;
|
}
|
|
.reset-btn:hover {
|
background: linear-gradient(135deg, #e0e0e0, #d0d0d0);
|
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
transform: translateY(-2px);
|
color: #444;
|
}
|
|
.reset-btn:active {
|
transform: translateY(0);
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
}
|
|
.mode-switch {
|
display: flex;
|
gap: 10px;
|
margin-bottom: 20px;
|
padding: 5px;
|
background: #f0f2f5;
|
border-radius: 25px;
|
width: fit-content;
|
}
|
|
.mode-switch button {
|
padding: 8px 20px;
|
border: none;
|
border-radius: 20px;
|
cursor: pointer;
|
font-size: 13px;
|
font-weight: 600;
|
transition: all 0.3s ease;
|
background: transparent;
|
color: #666;
|
}
|
|
.mode-switch button.active {
|
background: linear-gradient(135deg, #0066cc, #0052a3);
|
color: #fff;
|
box-shadow: 0 2px 10px rgba(0, 102, 204, 0.3);
|
}
|
|
.mode-switch button:hover:not(.active) {
|
background: #e0e0e0;
|
}
|
|
.json-input-container {
|
display: none;
|
}
|
|
.json-input-container.active {
|
display: block;
|
}
|
|
.form-input-container {
|
display: block;
|
}
|
|
.form-input-container.hidden {
|
display: none;
|
}
|
|
.json-textarea {
|
width: 100%;
|
min-height: 200px;
|
padding: 15px;
|
border: 2px solid #e3e8ef;
|
border-radius: 12px;
|
font-family: 'Courier New', monospace;
|
font-size: 13px;
|
line-height: 1.6;
|
resize: vertical;
|
transition: all 0.3s ease;
|
background: #fafbfc;
|
}
|
|
.json-textarea:focus {
|
outline: none;
|
border-color: #0066cc;
|
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
|
background: #fff;
|
}
|
|
.json-textarea.error {
|
border-color: #f93e3e;
|
background: #fff5f5;
|
}
|
|
.mock-result {
|
background: linear-gradient(145deg, #f8f9fa, #e9ecef);
|
padding: 20px;
|
margin-top: 20px;
|
border-radius: 12px;
|
max-height: 500px;
|
overflow-y: auto;
|
display: none;
|
border: 2px solid #dee2e6;
|
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05);
|
animation: slideDown 0.3s ease;
|
}
|
|
.mock-result.show {
|
display: block;
|
}
|
|
@keyframes slideDown {
|
from {
|
opacity: 0;
|
transform: translateY(-10px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
|
.mock-form {
|
background: linear-gradient(145deg, #ffffff, #f8f9fa);
|
padding: 20px;
|
margin-top: 15px;
|
border-radius: 12px;
|
border: 1px solid #e3e8ef;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
}
|
|
.mock-form h5 {
|
color: #333;
|
margin-bottom: 15px;
|
font-size: 14px;
|
font-weight: 600;
|
}
|
|
.form-group {
|
margin-bottom: 15px;
|
}
|
|
.form-group label {
|
display: block;
|
margin-bottom: 6px;
|
color: #555;
|
font-size: 13px;
|
font-weight: 500;
|
}
|
|
.form-group label .required {
|
color: #f93e3e;
|
margin-left: 3px;
|
}
|
|
.form-group input,
|
.form-group select {
|
width: 100%;
|
padding: 10px 12px;
|
border: 1px solid #d1d5db;
|
border-radius: 6px;
|
font-size: 13px;
|
color: #333;
|
background: #fff;
|
transition: all 0.2s ease;
|
}
|
|
.form-group input:focus,
|
.form-group select:focus {
|
outline: none;
|
border-color: #0066cc;
|
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.1);
|
}
|
|
.form-group input.error,
|
.form-group select.error {
|
border-color: #f93e3e;
|
background: #fff5f5;
|
}
|
|
.form-group .error-msg {
|
color: #f93e3e;
|
font-size: 12px;
|
margin-top: 5px;
|
display: none;
|
}
|
|
.form-group .error-msg.show {
|
display: block;
|
}
|
|
.error-msg {
|
color: #f93e3e;
|
font-size: 12px;
|
margin-top: 5px;
|
display: none;
|
}
|
|
.error-msg.show {
|
display: block;
|
}
|
|
.error-message {
|
color: #f93e3e;
|
font-size: 12px;
|
margin-top: 5px;
|
display: none;
|
}
|
|
.error-message.show {
|
display: block;
|
}
|
|
.form-group .hint {
|
color: #999;
|
font-size: 12px;
|
margin-top: 4px;
|
}
|
|
.mock-form-actions {
|
display: flex;
|
gap: 10px;
|
margin-top: 20px;
|
}
|
|
.mock-btn-secondary {
|
background: linear-gradient(135deg, #6c757d, #5a6268);
|
color: #fff;
|
border: none;
|
padding: 12px 28px;
|
border-radius: 25px;
|
cursor: pointer;
|
font-size: 14px;
|
font-weight: 600;
|
box-shadow: 0 4px 15px rgba(108, 117, 125, 0.3);
|
transition: all 0.3s ease;
|
}
|
|
.mock-btn-secondary:hover {
|
background: linear-gradient(135deg, #5a6268, #495057);
|
transform: translateY(-2px);
|
}
|
|
.mock-btn-secondary:active {
|
transform: translateY(0);
|
}
|
|
.tag {
|
display: inline-block;
|
padding: 5px 14px;
|
color: #0b0b0b;
|
border-radius: 12px;
|
font-size: 14px;
|
font-weight: 700;
|
margin-left: 10px;
|
text-transform: uppercase;
|
letter-spacing: 0.5px;
|
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
|
}
|
|
.note {
|
background: linear-gradient(135deg, #fff9e6, #fff3cd);
|
border-left: 5px solid #ffc107;
|
padding: 20px;
|
margin: 20px 0;
|
border-radius: 12px;
|
box-shadow: 0 4px 12px rgba(255, 193, 7, 0.15);
|
position: relative;
|
overflow: hidden;
|
}
|
|
.note::before {
|
content: '⚠';
|
position: absolute;
|
top: 15px;
|
right: 15px;
|
font-size: 24px;
|
opacity: 0.2;
|
}
|
|
.note-title {
|
font-weight: 700;
|
color: #856404;
|
margin-bottom: 10px;
|
font-size: 16px;
|
display: flex;
|
align-items: center;
|
}
|
|
.note-title::before {
|
content: '💡';
|
margin-right: 8px;
|
}
|
|
h3 {
|
font-size: 18px;
|
color: #2c3e50;
|
margin: 20px 0 15px;
|
font-weight: 600;
|
}
|
|
h4 {
|
font-size: 16px;
|
color: #34495e;
|
margin: 18px 0 12px;
|
font-weight: 600;
|
padding-left: 12px;
|
border-left: 3px solid #0066cc;
|
}
|
|
/* 滚动条美化 */
|
::-webkit-scrollbar {
|
width: 8px;
|
height: 8px;
|
}
|
|
::-webkit-scrollbar-track {
|
background: #f1f1f1;
|
border-radius: 4px;
|
}
|
|
::-webkit-scrollbar-thumb {
|
background: linear-gradient(135deg, #667eea, #764ba2);
|
border-radius: 4px;
|
}
|
|
::-webkit-scrollbar-thumb:hover {
|
background: linear-gradient(135deg, #764ba2, #667eea);
|
}
|
|
/* Mock测试折叠功能 */
|
.mock-container {
|
position: relative;
|
}
|
|
.mock-container .mock-toggle-btn {
|
position: absolute;
|
top: 0;
|
right: 0;
|
background: linear-gradient(135deg, #f5f5f5, #e0e0e0);
|
border: 1px solid #d0d0d0;
|
border-radius: 6px;
|
padding: 6px 12px;
|
cursor: pointer;
|
font-size: 12px;
|
font-weight: 600;
|
color: #666;
|
transition: all 0.3s ease;
|
z-index: 10;
|
}
|
|
.mock-container .mock-toggle-btn:hover {
|
background: linear-gradient(135deg, #e0e0e0, #d0d0d0);
|
color: #444;
|
}
|
|
.mock-container .mock-content {
|
transition: all 0.3s ease;
|
overflow: hidden;
|
}
|
|
.mock-container .mock-content.collapsed {
|
max-height: 0;
|
opacity: 0;
|
margin-top: 0;
|
padding-top: 0;
|
padding-bottom: 0;
|
}
|
|
.mock-container .mock-content.expanded {
|
max-height: 2000px;
|
opacity: 1;
|
}
|
|
/* 加载动画 */
|
@keyframes pulse {
|
0%, 100% {
|
opacity: 1;
|
}
|
50% {
|
opacity: 0.5;
|
}
|
}
|
|
.loading {
|
animation: pulse 1.5s ease-in-out infinite;
|
}
|
|
/* 渐入动画 */
|
@keyframes fadeIn {
|
from {
|
opacity: 0;
|
transform: translateY(20px);
|
}
|
to {
|
opacity: 1;
|
transform: translateY(0);
|
}
|
}
|
|
.api-section {
|
animation: fadeIn 0.6s ease-out;
|
}
|
|
/* 代码复制按钮 */
|
.code-wrapper {
|
position: relative;
|
}
|
|
.copy-btn {
|
position: absolute;
|
top: 10px;
|
right: 10px;
|
background: rgba(255, 255, 255, 0.1);
|
color: #d4d4d4;
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
padding: 6px 12px;
|
border-radius: 6px;
|
cursor: pointer;
|
font-size: 12px;
|
transition: all 0.3s ease;
|
opacity: 0;
|
}
|
|
.code-wrapper:hover .copy-btn {
|
opacity: 1;
|
}
|
|
.copy-btn:hover {
|
background: rgba(255, 255, 255, 0.2);
|
border-color: rgba(255, 255, 255, 0.4);
|
}
|
|
/* 成功提示 */
|
.success-icon {
|
color: #49cc90;
|
font-weight: bold;
|
animation: scaleIn 0.3s ease;
|
}
|
|
@keyframes scaleIn {
|
from {
|
transform: scale(0);
|
}
|
to {
|
transform: scale(1);
|
}
|
}
|
</style>
|
</head>
|
<body>
|
<div class="breadcrumb">
|
<a href="#">RCS接口文档</a> > 接口详情
|
<span class="update-time">更新时间:2025-12-29 14:20:00</span>
|
</div>
|
|
<h1>RCS接口文档</h1>
|
|
<div class="intro">
|
<p style="font-size: 16px; margin-bottom: 20px;">欢迎使用中扬RCS开放平台
|
API。本文档提供了完整的接口说明,包含请求参数、返回结果以及示例代码。每个接口都提供了 Mock
|
功能,方便您快速测试和集成。</p>
|
</div>
|
|
<div class="note" style="margin-bottom: 30px;">
|
<div class="note-title">📌 快速对接指南</div>
|
<p style="margin-bottom: 12px;"><strong>接口中标 * 的为常用接口</strong>,初步对接时,只需要调通以下接口:</p>
|
<ul style="list-style: none; padding-left: 0; margin-bottom: 15px;">
|
<li style="padding: 6px 0; padding-left: 25px; position: relative;">
|
<span style="position: absolute; left: 0; color: #0066cc; font-weight: bold;">1.</span>生成任务单
|
</li>
|
<li style="padding: 6px 0; padding-left: 25px; position: relative;">
|
<span style="position: absolute; left: 0; color: #0066cc; font-weight: bold;">2.</span>取消任务单
|
</li>
|
</ul>
|
<p style="margin-bottom: 12px;"><strong>如果上层系统需要接收任务的执行状态</strong>,需要提供以下接口,供调度系统回调:
|
</p>
|
<ul style="list-style: none; padding-left: 0; margin-bottom: 15px;">
|
<li style="padding: 6px 0; padding-left: 25px; position: relative;">
|
<span style="position: absolute; left: 0; color: #0066cc; font-weight: bold;">•</span>任务执行通知接口
|
</li>
|
</ul>
|
<p style="background: #fff3cd; padding: 10px 15px; border-radius: 6px; margin-top: 15px; border-left: 4px solid #ffc107;">
|
⚠️ <strong>超时设置:</strong>中扬调度系统调用上层系统的接口,获取连接超时时间默认为 <strong>30秒</strong>,数据返回超时时间默认为
|
<strong>60秒</strong>,超时情况下,调度系统会返回连接失败。
|
</p>
|
</div>
|
|
<div class="api-info" style="margin-bottom: 30px;">
|
<h3 style="color: #2c3e50; font-size: 18px; margin-bottom: 15px; padding-left: 0; border-left: none;">📋
|
对接约定</h3>
|
<ul style="list-style: none; padding-left: 0;">
|
<li style="padding: 10px 15px; margin-bottom: 8px; background: #f8f9fa; border-radius: 6px; border-left: 3px solid #667eea;">
|
<strong style="color: #667eea;">统一格式:</strong>为接口统一并兼容,所有的参数都为字符串格式。
|
</li>
|
<li style="padding: 10px 15px; margin-bottom: 8px; background: #f8f9fa; border-radius: 6px; border-left: 3px solid #667eea;">
|
<strong style="color: #667eea;">术语约定:</strong>文本涉及到的 AGV、robot、机器人术语、CTU为同一术语,不要混淆。
|
</li>
|
<li style="padding: 10px 15px; margin-bottom: 8px; background: #f8f9fa; border-radius: 6px; border-left: 3px solid #667eea;">
|
<strong style="color: #667eea;">版本兼容:</strong>为兼容以前版本,消息上报字段会比列出的字段要多,上层平台根据业务截取需要的字段。
|
</li>
|
<li style="padding: 10px 15px; margin-bottom: 8px; background: #f8f9fa; border-radius: 6px; border-left: 3px solid #667eea;">
|
<strong style="color: #667eea;">容器定义:</strong>应用于叉车、CTU等项目中,料箱、托盘、载具都可称为容器。
|
</li>
|
</ul>
|
</div>
|
|
<!-- 接口概览 -->
|
<section id="api-overview" class="api-section">
|
<h2>接口概览</h2>
|
<div class="api-info">
|
<h3>🔗 基础信息</h3>
|
<table style="margin-top: 15px;">
|
<tbody>
|
<tr>
|
<td style="width: 30%; font-weight: bold; background: #f8f9fa;">基础 URL</td>
|
<td><code style="background: #282c34; color: #48bb78; padding: 4px 8px; border-radius: 4px;">http://IP:PORT</code>
|
</td>
|
</tr>
|
<tr>
|
<td style="font-weight: bold; background: #f8f9fa;">请求格式</td>
|
<td><code>application/json</code></td>
|
</tr>
|
<tr>
|
<td style="font-weight: bold; background: #f8f9fa;">返回格式</td>
|
<td><code>application/json</code></td>
|
</tr>
|
<tr>
|
<td style="font-weight: bold; background: #f8f9fa;">字符编码</td>
|
<td><code>UTF-8</code></td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<div class="api-info">
|
<h3>📋 通用请求参数</h3>
|
<p style="margin-bottom: 15px; color: #666;">以下参数为所有接口的通用参数,每次调用时需要携带:</p>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">是否必填</th>
|
<th>描述</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr>
|
<td><code>reqTime</code></td>
|
<td><span style="color: #999;">选填</span></td>
|
<td>请求时间戳,格式: <code>yyyy-MM-dd HH:mm:ss</code>。由上层系统设定。</td>
|
</tr>
|
<!-- <tr>-->
|
<!-- <td><code>clientCode</code></td>-->
|
<!-- <td><span style="color: #999;">选填</span></td>-->
|
<!-- <td>客户端编号,如 PDA、HCWMS 等。如果填写,需先在 RCS-2000 系统配置,上层系统调用时进行填写,当多系统调用时,调度系统可以进行调用方区分。</td>-->
|
<!-- </tr>-->
|
<tr>
|
<td><code>tokenCode</code></td>
|
<td><span style="color: #999;">选填</span></td>
|
<td>令牌号,由调度系统颁发。如果填写,需先在 RCS-2000 系统配置,上层系统调用时进行填写。</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<div class="api-info">
|
<h3>📤 通用返回值定义</h3>
|
<p style="margin-bottom: 15px; color: #666;">所有接口的响应都遵循以下统一格式:</p>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">是否必填</th>
|
<th>描述</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr>
|
<td><code>code</code></td>
|
<td><span style="color: #f93e3e; font-weight: bold;">必填</span></td>
|
<td>返回编号,<code>200</code> 表示成功,<code>1~N</code> 表示失败</td>
|
</tr>
|
<tr>
|
<td><code>message</code></td>
|
<td><span style="color: #f93e3e; font-weight: bold;">必填</span></td>
|
<td>返回消息,<code>请求成功</code> 表示成功,内容为详细的错误描述</td>
|
</tr>
|
<tr>
|
<td><code>data</code></td>
|
<td><span style="color: #999;">选填</span></td>
|
<td>返回的数据结构,具体内容根据接口而定</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
</section>
|
|
<!-- 生成任务单 -->
|
<section id="api-task-create" class="api-section">
|
<h2>生成任务单* <span class="tag">常用</span></h2>
|
<div class="api-info">
|
<h3>
|
<span class="api-method method-post">POST</span>
|
<span>创建搬运任务</span>
|
</h3>
|
<div class="api-url">/api/open/bus/submit</div>
|
|
<h4>请求参数</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
|
<tr>
|
<td><code>batchNo</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>批次编号(上层系统生成,唯一标识)</td>
|
</tr>
|
<tr>
|
<td><code>tasks</code></td>
|
<td>array</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>任务数组,包含具体的任务详情</td>
|
</tr>
|
</tbody>
|
</table>
|
|
<h4>任务数组元素参数</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr>
|
<td><code>taskNo</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>任务编号(上层系统生成,唯一标识)</td>
|
</tr>
|
<tr>
|
<td><code>oriSta</code></td>
|
<td>string</td>
|
<td><span style="color: #999;">否</span></td>
|
<td>起点站点编号</td>
|
</tr>
|
<tr>
|
<td><code>destSta</code></td>
|
<td>string</td>
|
<td><span style="color: #999;">否</span></td>
|
<td>终点站点编号</td>
|
</tr>
|
<tr>
|
<td><code>oriLoc</code></td>
|
<td>string</td>
|
<td><span style="color: #999;">否</span></td>
|
<td>起点库位编号</td>
|
</tr>
|
<tr>
|
<td><code>destLoc</code></td>
|
<td>string</td>
|
<td><span style="color: #999;">否</span></td>
|
<td>终点库位编号</td>
|
</tr>
|
<tr>
|
<td><code>priority</code></td>
|
<td>int</td>
|
<td><span style="color: #999;">否</span></td>
|
<td>优先级:1-300,默认为1</td>
|
</tr>
|
|
</tbody>
|
</table>
|
|
<h4>请求示例</h4>
|
<pre><code>{
|
|
"batchNo": "122334",
|
"tasks": [
|
{
|
"taskNo": "TASK20231220001",
|
"oriLoc": "A100100101",
|
"destSta": "STA001",
|
"priority": 1
|
},
|
{
|
"taskNo": "TASK20231220001",
|
"oriSta": "STA002",
|
"destLoc": "B02-03-05",
|
"priority": 2
|
}
|
]
|
}</code></pre>
|
|
<h4>返回示例</h4>
|
<pre><code>{
|
"code": 200,
|
"message": "任务创建成功",
|
"data": {
|
"taskNo": "TASK20231220001",
|
"taskId": "T1234567890",
|
"status": "ASSIGN"
|
},
|
"timestamp": 1671526800000
|
}</code></pre>
|
</div>
|
|
<div class="mock-container">
|
<h4>Mock 测试</h4>
|
<button class="mock-toggle-btn" onclick="toggleMockContent(this)">展开</button>
|
<div class="mock-content collapsed">
|
<div class="mode-switch">
|
<button class="active" onclick="switchInputMode('task-create', 'form')" id="task-create-form-btn">
|
表单输入
|
</button>
|
<button onclick="switchInputMode('task-create', 'json')" id="task-create-json-btn">JSON输入</button>
|
</div>
|
<div class="mock-form">
|
<div class="form-input-container" id="task-create-form-container">
|
<h5>请求参数</h5>
|
<div class="form-group">
|
<label>taskNo <span class="required">*</span></label>
|
<input type="text" id="task-create-taskNo" placeholder="TASK20231220001"
|
value="TASK20231220001">
|
<div class="error-msg" id="task-create-taskNo-error">请输入任务编号</div>
|
</div>
|
<div class="form-group">
|
<label>batchNo <span class="required">*</span></label>
|
<input type="text" id="task-create-batchNo" placeholder="122334"
|
value="122334">
|
<div class="error-msg" id="task-create-batchNo-error">请输入批次编号</div>
|
</div>
|
<div class="form-group">
|
<label>taskType <span class="required">*</span></label>
|
<select id="task-create-taskType">
|
<option value="1" selected>1 - 出库(oriLoc和destSta必填)</option>
|
<option value="2">2 - 入库(oriSta和destLoc必填)</option>
|
<option value="3">3 - 库位间移库(oriLoc和destLoc必填)</option>
|
<option value="4">4 - 站点间搬运(oriSta和destSta必填)</option>
|
</select>
|
<div class="error-msg" id="task-create-taskType-error">请选择任务类型</div>
|
</div>
|
<div class="form-group">
|
<label>oriSta</label>
|
<input type="text" id="task-create-oriSta" placeholder="STA001" value="">
|
<div class="hint">起点站点编号</div>
|
</div>
|
<div class="form-group">
|
<label>destSta</label>
|
<input type="text" id="task-create-destSta" placeholder="STA002" value="STA001">
|
<div class="hint">终点站点编号</div>
|
</div>
|
<div class="form-group">
|
<label>oriLoc</label>
|
<input type="text" id="task-create-oriLoc" placeholder="A100100101" value="A100100101">
|
<div class="hint">起点库位编号</div>
|
</div>
|
<div class="form-group">
|
<label>destLoc</label>
|
<input type="text" id="task-create-destLoc" placeholder="B02-03-05" value="">
|
<div class="hint">终点库位编号</div>
|
</div>
|
<div class="form-group">
|
<label>priority</label>
|
<input type="text" id="task-create-priority" placeholder="1" value="1">
|
<div class="hint">优先级:1-300,默认为1</div>
|
</div>
|
|
</div>
|
<div class="json-input-container" id="task-create-json-container">
|
<h5>JSON输入</h5>
|
<textarea class="json-textarea" id="task-create-json">{
|
"taskNo": "TASK20231220001",
|
"batchNo": "122334",
|
"tasks": [
|
{
|
"oriLoc": "A100100101",
|
"destSta": "STA001",
|
"priority": 1
|
|
}
|
]
|
}</textarea>
|
<div class="error-msg" id="task-create-json-error">请输入有效的JSON格式</div>
|
</div>
|
<div class="mock-form-actions">
|
<button class="mock-btn" onclick="mockTaskCreate()">执行 Mock 请求</button>
|
<button class="reset-btn" onclick="resetTaskCreateForm()">重置</button>
|
</div>
|
</div>
|
<div id="mock-task-create-result" class="mock-result"></div>
|
</div>
|
</div>
|
</section>
|
|
<!-- 取消任务 -->
|
<section id="api-task-cancel" class="api-section">
|
<h2>取消任务单* <span class="tag">常用</span></h2>
|
<div class="api-info">
|
<h3>
|
<span class="api-method method-post">POST</span>
|
<span>取消已创建的任务</span>
|
</h3>
|
<div class="api-url">/api/open/task/cancel</div>
|
|
<h4>请求参数</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
|
<tr>
|
<td><code>tasks</code></td>
|
<td>array</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>要取消的任务编号数组</td>
|
</tr>
|
<tr>
|
<td><code>batchNo</code></td>
|
<td>string</td>
|
<td><span style="color: RED;">是</span></td>
|
<td>任务批次编号</td>
|
</tr>
|
</tbody>
|
</table>
|
|
<h4>请求示例</h4>
|
<pre><code>{
|
“batchNo”: “12345”,
|
“tasks”: [“123”, “456”]
|
}</code></pre>
|
|
<h4>返回示例</h4>
|
<pre><code>{
|
code: 200,
|
msg: ‘…’,
|
data: [
|
{
|
“taskNo”: “123”,
|
“success”: true,
|
“msg”: null
|
},
|
{
|
“taskNo”: “456”,
|
“success”: false,
|
“msg”: “456 is not exist”
|
}
|
]
|
}</code></pre>
|
|
<div class="note">
|
<div class="note-title">注意事项</div>
|
<p>• 已经在执行中的任务无法取消,会返回相应错误码</p>
|
<p>• 取消任务后,AGV会停止执行并返回待命状态</p>
|
</div>
|
</div>
|
|
<div class="mock-container">
|
<h4>Mock 测试</h4>
|
<button class="mock-toggle-btn" onclick="toggleMockContent(this)">展开</button>
|
<div class="mock-content collapsed">
|
<div class="mode-switch">
|
<button class="active" onclick="switchInputMode('task-cancel', 'form')" id="task-cancel-form-btn">
|
表单输入
|
</button>
|
<button onclick="switchInputMode('task-cancel', 'json')" id="task-cancel-json-btn">JSON输入</button>
|
</div>
|
<div class="mock-form">
|
<div class="form-input-container" id="task-cancel-form-container">
|
<h5>请求参数</h5>
|
<div class="form-group">
|
<label>tasks <span class="required">*</span></label>
|
<input type="text" id="task-cancel-tasks" placeholder="TASK20231220001,TASK20231220002"
|
value="TASK20231220001,TASK20231220002">
|
<div class="error-msg" id="task-cancel-tasks-error">请输入要取消的任务编号</div>
|
<div class="hint">多个任务编号请用逗号分隔</div>
|
</div>
|
<div class="form-group">
|
<label>batchNo</label>
|
<input type="text" id="task-cancel-batchNo" placeholder="12345"
|
value="12345">
|
<div class="hint">任务批次编号(选填)</div>
|
</div>
|
</div>
|
<div class="json-input-container" id="task-cancel-json-container">
|
<h5>JSON输入</h5>
|
<textarea class="json-textarea" id="task-cancel-json">{
|
"batchNo": "12345",
|
"tasks": ["TASK20231220001", "TASK20231220002"]
|
}</textarea>
|
<div class="error-msg" id="task-cancel-json-error">请输入有效的JSON格式</div>
|
</div>
|
<div class="mock-form-actions">
|
<button class="mock-btn" onclick="mockTaskCancel()">执行 Mock 请求</button>
|
<button class="reset-btn" onclick="resetTaskCancelForm()">重置</button>
|
</div>
|
</div>
|
<div id="mock-task-cancel-result" class="mock-result"></div>
|
</div>
|
</div>
|
</section>
|
|
<!-- 任务执行通知 -->
|
<section id="api-task-notice" class="api-section">
|
<h2>任务执行通知* <span class="tag">回调接口</span></h2>
|
<div class="api-info">
|
<h3>
|
<span class="api-method method-post">POST</span>
|
<span>RCS回调上层系统接口</span>
|
</h3>
|
<div class="api-url">/api/open/task/report</div>
|
|
<div class="note" style="background: linear-gradient(135deg, #e3f2fd, #bbdefb); border-left-color: #2196f3;">
|
<div class="note-title" style="color: #1565c0;">📢 接口说明</div>
|
<p style="color: #1976d2;">此接口由<strong>上层系统提供</strong>,RCS系统在任务状态发生变化时主动回调。上层系统需要实现此接口并配置回调地址到RCS系统中。
|
</p>
|
</div>
|
|
<h4>请求参数(RCS推送)</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr>
|
<td><code>batchNo</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>任务批次</td>
|
</tr>
|
<tr>
|
<td><code>taskNo</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>任务编号</td>
|
</tr>
|
<tr>
|
<td><code>timestamp</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>时间戳</td>
|
</tr>
|
</tbody>
|
</table>
|
|
<h4>推送示例(RCS → 上层系统)</h4>
|
<pre><code>{
|
"taskNo": "TASK20231220001",
|
"batchNo": "2345",
|
"timestamp": "2023-12-20 14:30:25"
|
}</code></pre>
|
|
<h4>返回示例(上层系统需返回)</h4>
|
<pre><code>{
|
"code": 200,
|
"message": "接收成功"
|
}</code></pre>
|
|
|
</div>
|
|
<div class="mock-container">
|
<h4>Mock 测试(模拟RCS推送)</h4>
|
<button class="mock-toggle-btn" onclick="toggleMockContent(this)">展开</button>
|
<div class="mock-content collapsed">
|
<div class="form-group">
|
<label>回调地址 <span class="required">*</span></label>
|
<input type="text" id="task-notice-callback-url" placeholder="http://localhost:8080/api/callback" value="http://localhost:8080/api/callback">
|
<span class="error-message" id="task-notice-callback-url-error">请输入回调地址</span>
|
</div>
|
<div class="form-actions">
|
<button class="mock-btn" onclick="mockTaskNotice()">发送请求</button>
|
<button class="reset-btn" onclick="resetTaskNoticeForm()">重置</button>
|
</div>
|
<div id="mock-task-notice-result" class="mock-result"></div>
|
</div>
|
</div>
|
</section>
|
|
<!-- 申请入库任务 -->
|
<section id="api-task-priority" class="api-section">
|
<h2>申请入库任务* <span class="tag">常用</span></h2>
|
<div class="api-info">
|
<h3>
|
<span class="api-method method-post">POST</span>
|
<span>申请入库任务</span>
|
</h3>
|
<div class="api-url">/api/open/location/allocate</div>
|
<div class="note" style="background: linear-gradient(135deg, #e3f2fd, #bbdefb); border-left-color: #2196f3;">
|
<div class="note-title" style="color: #1565c0;">📢 接口说明</div>
|
<p style="color: #1976d2;">此接口由<strong>上层系统提供</strong>,RCS系统在任务状态发生变化时主动回调。上层系统需要实现此接口并配置回调地址到RCS系统中。
|
</p>
|
</div>
|
<h4>请求参数</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
|
<tr>
|
<td><code>barcode</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>料箱码</td>
|
</tr>
|
<tr>
|
<td><code>staNo</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>入库站点</td>
|
</tr>
|
</tbody>
|
</table>
|
|
<h4>请求示例</h4>
|
<pre><code>{
|
"barcode": "8000001",
|
"staNo": "1005"
|
}</code></pre>
|
|
<h4>返回示例</h4>
|
<pre><code>{
|
"code": 200,
|
"message": "success",
|
"data": {
|
"locNo": "A100100101"
|
}
|
}</code></pre>
|
</div>
|
|
<div class="mock-container">
|
<h4>Mock 测试</h4>
|
<button class="mock-toggle-btn" onclick="toggleMockContent(this)">展开</button>
|
<div class="mock-content collapsed">
|
<div class="mode-switch">
|
<button class="active" onclick="switchInputMode('task-priority', 'form')" id="task-priority-form-btn">
|
表单输入
|
</button>
|
<button onclick="switchInputMode('task-priority', 'json')" id="task-priority-json-btn">JSON输入</button>
|
</div>
|
<div class="mock-form">
|
<div class="form-input-container" id="task-priority-form-container">
|
<h5>请求参数</h5>
|
<div class="form-group">
|
<label>taskNo <span class="required">*</span></label>
|
<input type="text" id="task-priority-taskNo" placeholder="TASK20231220001"
|
value="TASK20231220001">
|
<div class="error-msg" id="task-priority-taskNo-error">请输入任务编号</div>
|
</div>
|
<div class="form-group">
|
<label>priority <span class="required">*</span></label>
|
<input type="text" id="task-priority-priority" placeholder="1-300" value="3">
|
<div class="hint">优先级范围:1-300</div>
|
<div class="error-msg" id="task-priority-priority-error">请输入优先级(1-300)</div>
|
</div>
|
</div>
|
<div class="json-input-container" id="task-priority-json-container">
|
<h5>JSON输入</h5>
|
<textarea class="json-textarea" id="task-priority-json">{
|
"taskNo": "TASK20231220001",
|
"priority": "3"
|
}</textarea>
|
<div class="error-msg" id="task-priority-json-error">请输入有效的JSON格式</div>
|
</div>
|
<div class="mock-form-actions">
|
<button class="mock-btn" onclick="mockTaskPriority()">执行 Mock 请求</button>
|
<button class="reset-btn" onclick="resetTaskPriorityForm()">重置</button>
|
</div>
|
</div>
|
<div id="mock-task-priority-result" class="mock-result"></div>
|
</div>
|
</div>
|
</section>
|
|
<!-- 库位状态修改 -->
|
<!-- <section id="api-loc-status" class="api-section">
|
<h2>库位状态修改</h2>
|
<div class="api-info">
|
<h3>
|
<span class="api-method method-post">POST</span>
|
<span>修改库位状态</span>
|
</h3>
|
<div class="api-url">/api/open/loc/status/update</div>
|
|
<h4>请求参数</h4>
|
<table>
|
<thead>
|
<tr>
|
<th style="width: 20%;">参数名</th>
|
<th style="width: 15%;">类型</th>
|
<th style="width: 15%;">必填</th>
|
<th>说明</th>
|
</tr>
|
</thead>
|
<tbody>
|
|
<tr>
|
<td><code>locCode</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>库位编号</td>
|
</tr>
|
<tr>
|
<td><code>status</code></td>
|
<td>string</td>
|
<td><span style="color: #f93e3e; font-weight: bold;">是</span></td>
|
<td>库位状态:0-禁用、1-启用、2-在库、3-空库位</td>
|
</tr>
|
</tbody>
|
</table>
|
|
<h4>请求示例</h4>
|
<pre><code>{
|
"locCode": "A100100101",
|
"status": "0"
|
}</code></pre>
|
|
<h4>返回示例</h4>
|
<pre><code>{
|
"code": 200,
|
"message": "库位状态修改成功"
|
}</code></pre>
|
|
<div class="note">
|
<div class="note-title">使用场景</div>
|
<p>• 临时封闭某个库位(维护、检修等)</p>
|
<p>• 库位异常时禁用</p>
|
<p>• 维护完成后重新启用库位</p>
|
</div>
|
</div>
|
|
<div class="mock-container">
|
<h4>Mock 测试</h4>
|
<button class="mock-toggle-btn" onclick="toggleMockContent(this)">展开</button>
|
<div class="mock-content collapsed">
|
<div class="mode-switch">
|
<button id="loc-status-form-btn" class="mode-btn active"
|
onclick="switchInputMode('loc-status', 'form')">表单输入
|
</button>
|
<button id="loc-status-json-btn" class="mode-btn" onclick="switchInputMode('loc-status', 'json')">
|
JSON输入
|
</button>
|
</div>
|
<div class="form-input-container" id="loc-status-form-container">
|
<h5>请求参数</h5>
|
<div class="form-group">
|
<label>库位编码 <span class="required">*</span></label>
|
<input type="text" id="loc-status-locCode" placeholder="A100100101" value="A100100101">
|
<span class="error-message" id="loc-status-locCode-error">请输入库位编码</span>
|
</div>
|
<div class="form-group">
|
<label>状态 <span class="required">*</span></label>
|
<select id="loc-status-status">
|
<option value="">请选择状态</option>
|
<option value="0">0 - 禁用</option>
|
<option value="1" selected>1 - 启用</option>
|
<option value="2">2 - 在库</option>
|
<option value="3">3 - 空库位</option>
|
</select>
|
<span class="error-message" id="loc-status-status-error">请选择状态</span>
|
</div>
|
<div class="form-actions">
|
<button class="mock-btn" onclick="mockLocStatus()">执行 Mock 请求</button>
|
<button class="reset-btn" onclick="resetLocStatusForm()">重置</button>
|
</div>
|
</div>
|
<div class="json-input-container" id="loc-status-json-container">
|
<h5>JSON输入</h5>
|
<textarea class="json-textarea" id="loc-status-json" rows="8">{
|
"locCode": "A100100101",
|
"status": "1"
|
}</textarea>
|
<span class="error-message" id="loc-status-json-error">请输入有效的JSON参数</span>
|
<div class="form-actions">
|
<button class="mock-btn" onclick="mockLocStatus()">执行 Mock 请求</button>
|
<button class="reset-btn" onclick="resetLocStatusForm()">重置</button>
|
</div>
|
</div>
|
<div id="mock-loc-status-result" class="mock-result"></div>
|
</div>
|
</div>
|
</section> -->
|
|
|
|
<!-- 错误码说明 -->
|
<section id="error-codes" class="api-section">
|
<h2>错误码说明</h2>
|
<div class="api-info">
|
<h3>通用错误码</h3>
|
<table>
|
<thead>
|
<tr>
|
<th>错误码</th>
|
<th>说明</th>
|
<th>解决方案</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr>
|
<td>200</td>
|
<td>成功</td>
|
<td>-</td>
|
</tr>
|
<tr>
|
<td>500</td>
|
<td>参数错误</td>
|
<td>检查请求参数是否完整和正确</td>
|
</tr>
|
|
</tbody>
|
</table>
|
</div>
|
</section>
|
|
|
<div class="feedback-section">
|
<p style="color: #999;">以上内容对您有帮助吗?</p>
|
<div class="stars">
|
<span>☆</span>
|
<span>☆</span>
|
<span>☆</span>
|
<span>☆</span>
|
<span>☆</span>
|
</div>
|
</div>
|
|
<div class="pagination">
|
<div class="prev-page">
|
<div style="color: #999; font-size: 14px; margin-bottom: 10px;">上一篇</div>
|
<div style="color: #333; font-size: 16px;">平台规范</div>
|
</div>
|
<div class="next-page">
|
<div style="color: #999; font-size: 14px; margin-bottom: 10px; text-align: right;">下一篇</div>
|
<div style="color: #333; font-size: 16px; text-align: right;">应用接入引导</div>
|
</div>
|
</div>
|
|
<script>
|
// 验证任务创建参数
|
function validateTaskCreate() {
|
let isValid = true;
|
|
const taskNo = document.getElementById('task-create-taskNo');
|
const taskType = document.getElementById('task-create-taskType');
|
const oriSta = document.getElementById('task-create-oriSta');
|
const destSta = document.getElementById('task-create-destSta');
|
const oriLoc = document.getElementById('task-create-oriLoc');
|
const destLoc = document.getElementById('task-create-destLoc');
|
|
const taskNoError = document.getElementById('task-create-taskNo-error');
|
const taskTypeError = document.getElementById('task-create-taskType-error');
|
|
taskNo.classList.remove('error');
|
taskType.classList.remove('error');
|
oriSta.classList.remove('error');
|
destSta.classList.remove('error');
|
oriLoc.classList.remove('error');
|
destLoc.classList.remove('error');
|
|
taskNoError.classList.remove('show');
|
taskTypeError.classList.remove('show');
|
|
if (!taskNo.value.trim()) {
|
taskNo.classList.add('error');
|
taskNoError.classList.add('show');
|
isValid = false;
|
}
|
|
if (!taskType.value) {
|
taskType.classList.add('error');
|
taskTypeError.classList.add('show');
|
isValid = false;
|
}
|
|
const taskTypeValue = parseInt(taskType.value);
|
if (taskTypeValue === 1 || taskTypeValue === 3) {
|
if (!oriLoc.value.trim()) {
|
oriLoc.classList.add('error');
|
isValid = false;
|
}
|
}
|
if (taskTypeValue === 2 || taskTypeValue === 4) {
|
if (!oriSta.value.trim()) {
|
oriSta.classList.add('error');
|
isValid = false;
|
}
|
}
|
if (taskTypeValue === 1 || taskTypeValue === 4) {
|
if (!destSta.value.trim()) {
|
destSta.classList.add('error');
|
isValid = false;
|
}
|
}
|
if (taskTypeValue === 2 || taskTypeValue === 3) {
|
if (!destLoc.value.trim()) {
|
destLoc.classList.add('error');
|
isValid = false;
|
}
|
}
|
|
if (oriLoc.value.trim() && destLoc.value.trim() && oriLoc.value.trim() === destLoc.value.trim()) {
|
oriLoc.classList.add('error');
|
destLoc.classList.add('error');
|
isValid = false;
|
}
|
|
return isValid;
|
}
|
|
// 重置任务创建表单
|
function resetTaskCreateForm() {
|
document.getElementById('task-create-taskNo').value = 'TASK20231220001';
|
document.getElementById('task-create-batchNo').value = '122334';
|
document.getElementById('task-create-taskType').value = '1';
|
document.getElementById('task-create-oriSta').value = '';
|
document.getElementById('task-create-destSta').value = 'STA001';
|
document.getElementById('task-create-oriLoc').value = 'A100100101';
|
document.getElementById('task-create-destLoc').value = '';
|
document.getElementById('task-create-priority').value = '1';
|
|
syncFormToJson('task-create');
|
|
const inputs = document.querySelectorAll('#task-create-taskNo, #task-create-batchNo, #task-create-taskType, #task-create-oriSta, #task-create-destSta, #task-create-oriLoc, #task-create-destLoc');
|
inputs.forEach(input => input.classList.remove('error'));
|
|
const errors = document.querySelectorAll('[id^="task-create-"][id$="-error"]');
|
errors.forEach(error => {
|
error.classList.remove('show');
|
if (error.id === 'task-create-taskNo-error') error.textContent = '请输入任务编号';
|
if (error.id === 'task-create-taskType-error') error.textContent = '请选择任务类型';
|
});
|
|
document.getElementById('mock-task-create-result').classList.remove('show');
|
document.getElementById('mock-task-create-result').innerHTML = '';
|
|
const jsonError = document.getElementById('task-create-json-error');
|
if (jsonError) jsonError.classList.remove('show');
|
|
|
const resultDiv = document.getElementById('mock-task-create-result');
|
resultDiv.classList.remove('show');
|
resultDiv.innerHTML = '';
|
}
|
|
// 切换输入模式
|
function switchInputMode(formId, mode) {
|
const formBtn = document.getElementById(`${formId}-form-btn`);
|
const jsonBtn = document.getElementById(`${formId}-json-btn`);
|
const formContainer = document.getElementById(`${formId}-form-container`);
|
const jsonContainer = document.getElementById(`${formId}-json-container`);
|
|
if (mode === 'form') {
|
syncJsonToForm(formId);
|
formBtn.classList.add('active');
|
jsonBtn.classList.remove('active');
|
formContainer.classList.remove('hidden');
|
jsonContainer.classList.remove('active');
|
} else {
|
syncFormToJson(formId);
|
formBtn.classList.remove('active');
|
jsonBtn.classList.add('active');
|
formContainer.classList.add('hidden');
|
jsonContainer.classList.add('active');
|
}
|
}
|
|
function syncFormToJson(formId) {
|
let params;
|
if (formId === 'task-create') {
|
// 对于任务创建表单,使用新的数组格式
|
const formParams = getParamsFromForm(formId);
|
params = {
|
taskNo: formParams.taskNo,
|
batchNo: formParams.batchNo || '122334',
|
tasks: [{
|
taskType: formParams.taskType,
|
oriSta: formParams.oriSta,
|
destSta: formParams.destSta,
|
oriLoc: formParams.oriLoc,
|
destLoc: formParams.destLoc,
|
priority: formParams.priority ? parseInt(formParams.priority) : 1
|
}]
|
};
|
} else if (formId === 'task-cancel') {
|
// 对于任务取消表单,使用tasks数组格式
|
const formParams = getParamsFromForm(formId);
|
params = {
|
batchNo: formParams.batchNo || '12345',
|
tasks: formParams.tasks.split(',').map(task => task.trim())
|
};
|
} else {
|
// 对于其他表单,使用原有的格式
|
params = getParamsFromForm(formId);
|
}
|
const textarea = document.getElementById(`${formId}-json`);
|
if (textarea) {
|
textarea.value = JSON.stringify(params, null, 2);
|
}
|
}
|
|
function syncJsonToForm(formId) {
|
const textarea = document.getElementById(`${formId}-json`);
|
if (!textarea) return;
|
|
try {
|
const params = JSON.parse(textarea.value);
|
const inputs = document.querySelectorAll(`#${formId}-form-container input, #${formId}-form-container select`);
|
|
if (formId === 'task-create' && params.tasks && Array.isArray(params.tasks) && params.tasks.length > 0) {
|
// 对于任务创建表单,从tasks数组中获取第一个任务的数据
|
const task = params.tasks[0];
|
inputs.forEach(input => {
|
const key = input.id.replace(`${formId}-`, '');
|
if (params[key] !== undefined) {
|
input.value = params[key];
|
} else if (task[key] !== undefined) {
|
input.value = task[key];
|
}
|
});
|
} else if (formId === 'task-cancel' && params.tasks && Array.isArray(params.tasks)) {
|
// 对于任务取消表单,将tasks数组转换为逗号分隔的字符串
|
inputs.forEach(input => {
|
const key = input.id.replace(`${formId}-`, '');
|
if (key === 'tasks') {
|
input.value = params.tasks.join(', ');
|
} else if (params[key] !== undefined) {
|
input.value = params[key];
|
}
|
});
|
} else {
|
// 对于其他表单,使用原有的逻辑
|
inputs.forEach(input => {
|
const key = input.id.replace(`${formId}-`, '');
|
if (params[key] !== undefined) {
|
input.value = params[key];
|
}
|
});
|
}
|
} catch (e) {
|
console.error('JSON解析失败,无法同步到表单', e);
|
}
|
}
|
|
// 从表单获取参数
|
function getParamsFromForm(formId) {
|
const params = {};
|
const inputs = document.querySelectorAll(`#${formId}-form-container input, #${formId}-form-container select`);
|
inputs.forEach(input => {
|
const key = input.id.replace(`${formId}-`, '');
|
params[key] = input.value.trim();
|
});
|
return params;
|
}
|
|
// 从JSON获取参数
|
function getParamsFromJson(jsonId) {
|
const textarea = document.getElementById(jsonId);
|
const errorDiv = document.getElementById(`${jsonId}-error`);
|
|
try {
|
const json = JSON.parse(textarea.value);
|
textarea.classList.remove('error');
|
errorDiv.classList.remove('show');
|
return json;
|
} catch (e) {
|
textarea.classList.add('error');
|
errorDiv.classList.add('show');
|
return null;
|
}
|
}
|
|
// 验证任务创建JSON参数
|
function validateTaskCreateJson(params) {
|
const errorDiv = document.getElementById('task-create-json-error');
|
|
if (!params || typeof params !== 'object') {
|
errorDiv.textContent = '请输入有效的JSON格式';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.taskNo || !params.taskNo.trim()) {
|
errorDiv.textContent = 'taskNo不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.batchNo || !params.batchNo.trim()) {
|
errorDiv.textContent = 'batchNo不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.tasks || !Array.isArray(params.tasks)) {
|
errorDiv.textContent = 'tasks必须是数组格式';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (params.tasks.length === 0) {
|
errorDiv.textContent = 'tasks数组不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
// 验证tasks数组中的每个任务
|
for (let i = 0; i < params.tasks.length; i++) {
|
const task = params.tasks[i];
|
if (!task || typeof task !== 'object') {
|
errorDiv.textContent = `tasks数组第${i+1}个元素必须是对象`;
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
// 验证起点和终点
|
if (task.oriLoc && task.destLoc && task.oriLoc.trim() === task.destLoc.trim()) {
|
errorDiv.textContent = `tasks数组第${i+1}个元素的起点库位和终点库位不能相同`;
|
errorDiv.classList.add('show');
|
return false;
|
}
|
}
|
|
errorDiv.classList.remove('show');
|
return true;
|
}
|
|
// Mock 生成任务单
|
function mockTaskCreate() {
|
let params;
|
const isJsonMode = document.getElementById('task-create-json-container').classList.contains('active');
|
|
if (isJsonMode) {
|
params = getParamsFromJson('task-create-json');
|
if (!params) return;
|
if (!validateTaskCreateJson(params)) return;
|
} else {
|
// 从表单获取参数并转换为新的数组格式
|
const formParams = getParamsFromForm('task-create');
|
params = {
|
taskNo: formParams.taskNo,
|
batchNo: formParams.batchNo || '122334',
|
tasks: [{
|
taskType: formParams.taskType,
|
oriSta: formParams.oriSta,
|
destSta: formParams.destSta,
|
oriLoc: formParams.oriLoc,
|
destLoc: formParams.destLoc,
|
priority: formParams.priority ? parseInt(formParams.priority) : 1
|
}]
|
};
|
}
|
|
const resultDiv = document.getElementById('mock-task-create-result');
|
resultDiv.classList.add('show');
|
resultDiv.innerHTML = '<p style="color: #999;" class="loading">⏳ 正在发送请求...</p>';
|
|
setTimeout(() => {
|
const response = {
|
code: 200,
|
message: "任务创建成功",
|
data: {
|
taskNo: params.taskNo,
|
batchNo: params.batchNo,
|
taskId: "T" + Math.random().toString(36).substr(2, 10),
|
status: "ASSIGN",
|
taskCount: params.tasks.length
|
},
|
timestamp: new Date().getTime()
|
};
|
resultDiv.innerHTML = `
|
<p style="color: #49cc90; font-weight: bold;" class="success-icon">✔ 请求成功</p>
|
<div style="margin-bottom: 20px; padding: 15px; background: #e3f2fd; border-radius: 8px; border-left: 4px solid #2196f3;">
|
<p style="font-weight: bold; color: #1976d2; margin-bottom: 10px;">📤 发送数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(params, null, 2)}</code></pre>
|
</div>
|
</div>
|
<div style="padding: 15px; background: #e8f5e9; border-radius: 8px; border-left: 4px solid #49cc90;">
|
<p style="font-weight: bold; color: #2e7d32; margin-bottom: 10px;">📥 返回数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(response, null, 2)}</code></pre>
|
</div>
|
</div>
|
<p style="margin-top: 15px; color: #666; padding: 10px; background: #fff; border-radius: 8px; border: 2px solid #49cc90;">🎯 成功创建 ${params.tasks.length} 个搬运任务,等待分配机器人执行</p>
|
`;
|
}, 800);
|
}
|
|
// 验证任务取消参数
|
function validateTaskCancel() {
|
let isValid = true;
|
|
const tasks = document.getElementById('task-cancel-tasks');
|
|
const tasksError = document.getElementById('task-cancel-tasks-error');
|
|
tasks.classList.remove('error');
|
|
tasksError.classList.remove('show');
|
|
if (!tasks.value.trim()) {
|
tasks.classList.add('error');
|
tasksError.classList.add('show');
|
isValid = false;
|
}
|
|
return isValid;
|
}
|
|
// 重置任务取消表单
|
function resetTaskCancelForm() {
|
document.getElementById('task-cancel-tasks').value = 'TASK20231220001,TASK20231220002';
|
document.getElementById('task-cancel-batchNo').value = '12345';
|
|
syncFormToJson('task-cancel');
|
|
const inputs = document.querySelectorAll('#task-cancel-tasks');
|
inputs.forEach(input => input.classList.remove('error'));
|
|
const errors = document.querySelectorAll('[id^="task-cancel-"][id$="-error"]');
|
errors.forEach(error => {
|
error.classList.remove('show');
|
if (error.id === 'task-cancel-tasks-error') error.textContent = '请输入要取消的任务编号';
|
});
|
|
const resultDiv = document.getElementById('mock-task-cancel-result');
|
resultDiv.classList.remove('show');
|
resultDiv.innerHTML = '';
|
}
|
|
// 验证任务取消JSON参数
|
function validateTaskCancelJson(params) {
|
const errorDiv = document.getElementById('task-cancel-json-error');
|
|
if (!params || typeof params !== 'object') {
|
errorDiv.textContent = '请输入有效的JSON格式';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.tasks || !Array.isArray(params.tasks) || params.tasks.length === 0) {
|
errorDiv.textContent = 'tasks必须是非空数组';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
errorDiv.classList.remove('show');
|
return true;
|
}
|
|
// Mock 取消任务
|
function mockTaskCancel() {
|
let params;
|
const isJsonMode = document.getElementById('task-cancel-json-container').classList.contains('active');
|
|
if (isJsonMode) {
|
params = getParamsFromJson('task-cancel-json');
|
if (!params) return;
|
if (!validateTaskCancelJson(params)) return;
|
} else {
|
if (!validateTaskCancel()) return;
|
const formParams = getParamsFromForm('task-cancel');
|
// 将逗号分隔的任务编号字符串转换为数组
|
params = {
|
tasks: formParams.tasks.split(',').map(task => task.trim()),
|
batchNo: formParams.batchNo
|
};
|
}
|
|
const resultDiv = document.getElementById('mock-task-cancel-result');
|
resultDiv.classList.add('show');
|
resultDiv.innerHTML = '<p style="color: #999;" class="loading">⏳ 正在发送请求...</p>';
|
|
setTimeout(() => {
|
// 生成每个任务的取消结果
|
const data = params.tasks.map(taskNo => {
|
// 模拟随机的取消结果
|
const success = Math.random() > 0.2; // 80%的概率成功
|
return {
|
taskNo: taskNo,
|
success: success,
|
msg: success ? null : `${taskNo} 不存在或无法取消`
|
};
|
});
|
|
const response = {
|
code: 200,
|
msg: "任务取消成功",
|
data: data,
|
timestamp: new Date().getTime()
|
};
|
|
resultDiv.innerHTML = `
|
<p style="color: #49cc90; font-weight: bold;" class="success-icon">✔ 请求成功</p>
|
<div style="margin-bottom: 20px; padding: 15px; background: #e3f2fd; border-radius: 8px; border-left: 4px solid #2196f3;">
|
<p style="font-weight: bold; color: #1976d2; margin-bottom: 10px;">📤 发送数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(params, null, 2)}</code></pre>
|
</div>
|
</div>
|
<div style="padding: 15px; background: #e8f5e9; border-radius: 8px; border-left: 4px solid #49cc90;">
|
<p style="font-weight: bold; color: #2e7d32; margin-bottom: 10px;">📥 返回数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(response, null, 2)}</code></pre>
|
</div>
|
</div>
|
<p style="margin-top: 15px; color: #666; padding: 10px; background: #e8f5e9; border-radius: 8px; border-left: 4px solid #4caf50;">✅ 任务取消请求已处理,共取消 ${params.tasks.length} 个任务</p>
|
`;
|
}, 1000);
|
}
|
|
// Mock 任务执行通知
|
function mockTaskNotice() {
|
const callbackUrl = document.getElementById('task-notice-callback-url');
|
|
if (!callbackUrl.value.trim()) {
|
callbackUrl.classList.add('error');
|
document.getElementById('task-notice-callback-url-error').classList.add('show');
|
return;
|
} else {
|
callbackUrl.classList.remove('error');
|
document.getElementById('task-notice-callback-url-error').classList.remove('show');
|
}
|
|
const resultDiv = document.getElementById('mock-task-notice-result');
|
resultDiv.classList.add('show');
|
resultDiv.innerHTML = '<p style="color: #999;" class="loading">⏳ 正在发送请求...</p>';
|
|
const pushData = {
|
taskNo: "TASK20231220001",
|
robotCode: "AGV" + Math.floor(Math.random() * 10 + 1).toString().padStart(3, '0'),
|
finishTime: new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }).replace(/\//g, '-')
|
};
|
|
fetch(callbackUrl.value.trim(), {
|
method: 'POST',
|
headers: {
|
'Content-Type': 'application/json'
|
},
|
body: JSON.stringify(pushData)
|
})
|
.then(response => {
|
if (!response.ok) {
|
throw new Error(`HTTP error! status: ${response.status}`);
|
}
|
return response.json();
|
})
|
.then(data => {
|
resultDiv.innerHTML = `
|
<p style="color: #49cc90; font-weight: bold;" class="success-icon">✔ 请求成功</p>
|
<div style="margin-bottom: 20px; padding: 15px; background: #e3f2fd; border-radius: 8px; border-left: 4px solid #2196f3;">
|
<p style="font-weight: bold; color: #1976d2; margin-bottom: 10px;">📤 发送数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(pushData, null, 2)}</code></pre>
|
</div>
|
</div>
|
<div style="padding: 15px; background: #e8f5e9; border-radius: 8px; border-left: 4px solid #49cc90;">
|
<p style="font-weight: bold; color: #2e7d32; margin-bottom: 10px;">📥 返回数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(data, null, 2)}</code></pre>
|
</div>
|
</div>
|
<p style="margin-top: 15px; color: #666; padding: 10px; background: #e8f5e9; border-radius: 8px; border-left: 4px solid #49cc90;">🎯 任务执行通知已成功发送</p>
|
`;
|
})
|
.catch(error => {
|
resultDiv.innerHTML = `
|
<p style="color: #f44336; font-weight: bold;" class="error-icon">✖ 请求失败</p>
|
<div style="margin-bottom: 20px; padding: 15px; background: #e3f2fd; border-radius: 8px; border-left: 4px solid #2196f3;">
|
<p style="font-weight: bold; color: #1976d2; margin-bottom: 10px;">📤 发送数据</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(pushData, null, 2)}</code></pre>
|
</div>
|
</div>
|
<p style="margin-top: 15px; color: #f44336; padding: 10px; background: #ffebee; border-radius: 8px; border-left: 4px solid #f44336;">
|
❌ 错误信息:<strong>${error.message}</strong>
|
</p>
|
<p style="margin-top: 10px; color: #999; font-size: 12px;">提示:请确保回调地址可访问,且服务器已启动并支持CORS跨域请求</p>
|
`;
|
});
|
}
|
|
function resetTaskNoticeForm() {
|
document.getElementById('task-notice-callback-url').value = 'http://localhost:8080/api/callback';
|
|
document.getElementById('mock-task-notice-result').classList.remove('show');
|
document.getElementById('mock-task-notice-result').innerHTML = '';
|
|
const inputs = document.querySelectorAll('#api-task-notice input');
|
inputs.forEach(input => input.classList.remove('error'));
|
const errors = document.querySelectorAll('#api-task-notice .error-message');
|
errors.forEach(error => error.classList.remove('show'));
|
}
|
|
// 验证库位状态修改参数
|
function validateLocStatus() {
|
let isValid = true;
|
const locCode = document.getElementById('loc-status-locCode');
|
const status = document.getElementById('loc-status-status');
|
|
if (!locCode.value.trim()) {
|
locCode.classList.add('error');
|
document.getElementById('loc-status-locCode-error').classList.add('show');
|
isValid = false;
|
} else {
|
locCode.classList.remove('error');
|
document.getElementById('loc-status-locCode-error').classList.remove('show');
|
}
|
|
if (!status.value) {
|
status.classList.add('error');
|
document.getElementById('loc-status-status-error').classList.add('show');
|
isValid = false;
|
} else {
|
status.classList.remove('error');
|
document.getElementById('loc-status-status-error').classList.remove('show');
|
}
|
|
return isValid;
|
}
|
|
function validateLocStatusJson(params) {
|
const errorDiv = document.getElementById('loc-status-json-error');
|
|
if (!params || typeof params !== 'object') {
|
errorDiv.textContent = '请输入有效的JSON格式';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.locCode || !params.locCode.trim()) {
|
errorDiv.textContent = 'locCode不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.status || !params.status.toString().trim()) {
|
errorDiv.textContent = 'status不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
} else {
|
const statusValue = params.status.toString().trim();
|
if (!['0', '1', '2', '3'].includes(statusValue)) {
|
errorDiv.textContent = 'status必须是0-3之间的数字(0-禁用、1-启用、2-在库、3-空库位)';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
}
|
|
errorDiv.classList.remove('show');
|
return true;
|
}
|
|
// 重置库位状态修改表单
|
function resetLocStatusForm() {
|
document.getElementById('loc-status-locCode').value = 'A100100101';
|
document.getElementById('loc-status-status').value = '1';
|
|
syncFormToJson('loc-status');
|
|
document.getElementById('mock-loc-status-result').classList.remove('show');
|
document.getElementById('mock-loc-status-result').innerHTML = '';
|
|
const inputs = document.querySelectorAll('#loc-status-form-container input, #loc-status-form-container select');
|
inputs.forEach(input => input.classList.remove('error'));
|
const errors = document.querySelectorAll('#loc-status-form-container .error-message');
|
errors.forEach(error => error.classList.remove('show'));
|
|
const jsonError = document.getElementById('loc-status-json-error');
|
if (jsonError) jsonError.classList.remove('show');
|
}
|
|
// 验证任务优先级参数
|
function validateTaskPriority() {
|
let isValid = true;
|
|
const taskNo = document.getElementById('task-priority-taskNo');
|
const priority = document.getElementById('task-priority-priority');
|
|
const taskNoError = document.getElementById('task-priority-taskNo-error');
|
const priorityError = document.getElementById('task-priority-priority-error');
|
|
taskNo.classList.remove('error');
|
priority.classList.remove('error');
|
|
taskNoError.classList.remove('show');
|
priorityError.classList.remove('show');
|
|
if (!taskNo.value.trim()) {
|
taskNo.classList.add('error');
|
taskNoError.classList.add('show');
|
isValid = false;
|
}
|
|
if (!priority.value.trim()) {
|
priority.classList.add('error');
|
priorityError.classList.add('show');
|
isValid = false;
|
} else {
|
const priorityNum = parseInt(priority.value.trim());
|
if (isNaN(priorityNum) || priorityNum < 1 || priorityNum > 300) {
|
priority.classList.add('error');
|
priorityError.textContent = '优先级必须是1-300的数字';
|
priorityError.classList.add('show');
|
isValid = false;
|
}
|
}
|
|
return isValid;
|
}
|
|
// 重置任务优先级表单
|
function resetTaskPriorityForm() {
|
document.getElementById('task-priority-taskNo').value = 'TASK20231220001';
|
document.getElementById('task-priority-priority').value = '2';
|
|
syncFormToJson('task-priority');
|
|
const inputs = document.querySelectorAll('#task-priority-taskNo, #task-priority-priority');
|
inputs.forEach(input => input.classList.remove('error'));
|
|
const errors = document.querySelectorAll('[id^="task-priority-"][id$="-error"]');
|
errors.forEach(error => {
|
error.classList.remove('show');
|
if (error.id === 'task-priority-taskNo-error') error.textContent = '请输入任务编号';
|
if (error.id === 'task-priority-priority-error') error.textContent = '请输入优先级(1-300)';
|
});
|
|
const resultDiv = document.getElementById('mock-task-priority-result');
|
resultDiv.classList.remove('show');
|
resultDiv.innerHTML = '';
|
}
|
|
// 验证任务优先级JSON参数
|
function validateTaskPriorityJson(params) {
|
const errorDiv = document.getElementById('task-priority-json-error');
|
|
if (!params || typeof params !== 'object') {
|
errorDiv.textContent = '请输入有效的JSON格式';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.taskNo || !params.taskNo.trim()) {
|
errorDiv.textContent = 'taskNo不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
|
if (!params.priority || !params.priority.toString().trim()) {
|
errorDiv.textContent = 'priority不能为空';
|
errorDiv.classList.add('show');
|
return false;
|
} else {
|
const priorityNum = parseInt(params.priority.toString().trim());
|
if (isNaN(priorityNum) || priorityNum < 1 || priorityNum > 300) {
|
errorDiv.textContent = 'priority必须是1-300的数字';
|
errorDiv.classList.add('show');
|
return false;
|
}
|
}
|
|
errorDiv.classList.remove('show');
|
return true;
|
}
|
|
// Mock 任务优先级设置
|
function mockTaskPriority() {
|
let params;
|
const isJsonMode = document.getElementById('task-priority-json-container').classList.contains('active');
|
|
if (isJsonMode) {
|
params = getParamsFromJson('task-priority-json');
|
if (!params) return;
|
if (!validateTaskPriorityJson(params)) return;
|
} else {
|
if (!validateTaskPriority()) return;
|
params = getParamsFromForm('task-priority');
|
}
|
|
const taskNo = params.taskNo;
|
const priority = params.priority;
|
|
const resultDiv = document.getElementById('mock-task-priority-result');
|
resultDiv.classList.add('show');
|
resultDiv.innerHTML = '<p style="color: #999;" class="loading">⏳ 正在发送请求...</p>';
|
|
setTimeout(() => {
|
const response = {
|
code: 200,
|
message: "请求成功",
|
data: {
|
taskNo: taskNo,
|
priority: priority
|
},
|
timestamp: new Date().getTime()
|
};
|
|
const priorityNum = parseInt(priority);
|
let priorityInfo;
|
if (priorityNum <= 100) {
|
priorityInfo = {text: '低', color: '#9e9e9e', icon: '⬇️'};
|
} else if (priorityNum <= 200) {
|
priorityInfo = {text: '中', color: '#2196f3', icon: '➡️'};
|
} else {
|
priorityInfo = {text: '高', color: '#f44336', icon: '⬆️'};
|
}
|
|
resultDiv.innerHTML = `
|
<p style="color: #49cc90; font-weight: bold;" class="success-icon">✔ 请求成功</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(response, null, 2)}</code></pre>
|
</div>
|
<p style="margin-top: 15px; color: #666; padding: 10px; background: #f5f5f5; border-radius: 8px; border-left: 4px solid ${priorityInfo.color};">
|
${priorityInfo.icon} 任务优先级已设置为:<strong style="color: ${priorityInfo.color};">${priorityInfo.text}</strong>
|
</p>
|
`;
|
}, 600);
|
}
|
|
// Mock 库位状态修改
|
function mockLocStatus() {
|
let params;
|
const isJsonMode = document.getElementById('loc-status-json-container').classList.contains('active');
|
|
if (isJsonMode) {
|
params = getParamsFromJson('loc-status-json');
|
if (!params) return;
|
if (!validateLocStatusJson(params)) return;
|
} else {
|
if (!validateLocStatus()) return;
|
params = getParamsFromForm('loc-status');
|
}
|
|
const resultDiv = document.getElementById('mock-loc-status-result');
|
resultDiv.classList.add('show');
|
resultDiv.innerHTML = '<p style="color: #999;" class="loading">⏳ 正在发送请求...</p>';
|
|
setTimeout(() => {
|
const locCode = params.locCode;
|
const status = params.status;
|
|
const response = {
|
code: 200,
|
message: "库位状态修改成功",
|
timestamp: new Date().getTime()
|
};
|
|
const statusMap = {
|
'0': {text: '禁用', color: '#f44336', icon: '🚫'},
|
'1': {text: '启用', color: '#4caf50', icon: '✅'},
|
'2': {text: '在库', color: '#ff9800', icon: '📦'},
|
'3': {text: '空库位', color: '#2196f3', icon: '⬜'}
|
};
|
|
const statusInfo = statusMap[status];
|
|
resultDiv.innerHTML = `
|
<p style="color: #49cc90; font-weight: bold;" class="success-icon">✔ 请求成功</p>
|
<div class="code-wrapper">
|
<button class="copy-btn" onclick="copyCode(this)">📋 复制</button>
|
<pre><code>${JSON.stringify(response, null, 2)}</code></pre>
|
</div>
|
<p style="margin-top: 15px; color: #666; padding: 10px; background: #f5f5f5; border-radius: 8px; border-left: 4px solid ${statusInfo.color};">
|
${statusInfo.icon} 库位 <strong>${locCode}</strong> 状态:<strong style="color: ${statusInfo.color};">${statusInfo.text}</strong>
|
</p>
|
`;
|
}, 700);
|
}
|
|
|
|
// 复制代码功能
|
function copyCode(button) {
|
const codeBlock = button.nextElementSibling.querySelector('code');
|
const text = codeBlock.textContent;
|
|
navigator.clipboard.writeText(text).then(() => {
|
const originalText = button.innerHTML;
|
button.innerHTML = '✓ 已复制';
|
button.style.background = 'rgba(73, 204, 144, 0.2)';
|
button.style.borderColor = 'rgba(73, 204, 144, 0.4)';
|
button.style.color = '#49cc90';
|
|
setTimeout(() => {
|
button.innerHTML = originalText;
|
button.style.background = 'rgba(255, 255, 255, 0.1)';
|
button.style.borderColor = 'rgba(255, 255, 255, 0.2)';
|
button.style.color = '#d4d4d4';
|
}, 2000);
|
}).catch(err => {
|
console.error('复制失败:', err);
|
});
|
}
|
|
function toggleMockContent(button) {
|
const content = button.nextElementSibling;
|
if (content.classList.contains('expanded')) {
|
content.classList.remove('expanded');
|
content.classList.add('collapsed');
|
button.textContent = '展开';
|
} else {
|
content.classList.remove('collapsed');
|
content.classList.add('expanded');
|
button.textContent = '折叠';
|
}
|
}
|
|
// 监听滚动消息
|
window.addEventListener('message', function (event) {
|
if (event.data.type === 'scrollToSection') {
|
const targetElement = document.getElementById(event.data.sectionId);
|
if (targetElement) {
|
targetElement.scrollIntoView({behavior: 'smooth', block: 'start'});
|
}
|
}
|
});
|
</script>
|
</body>
|
</html>
|