1
zhang
3 天以前 07eafe2cff11f5795c60e05ff12d59db42781361
1
11个文件已添加
3960 ■■■■■ 已修改文件
open-rcs/components/content/content-interface-word.html 2532 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/content/content-platform-intro.html 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/content/content-platform-spec.html 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/header/header.html 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/rightsidebar/rightsidebar-interface-word.html 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/rightsidebar/rightsidebar-platform-intro.html 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/rightsidebar/rightsidebar-platform-spec.html 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/sidebar/sidebar-interface-word.html 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/sidebar/sidebar-platform-intro.html 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/sidebar/sidebar-platform-spec.html 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/pages/index-main.html 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
open-rcs/components/content/content-interface-word.html
New file
@@ -0,0 +1,2532 @@
<!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>
open-rcs/components/content/content-platform-intro.html
New file
@@ -0,0 +1,136 @@
<!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-color: #fff;
            padding: 30px;
            line-height: 1.8;
        }
        .breadcrumb {
            font-size: 14px;
            color: #999;
            margin-bottom: 20px;
        }
        .breadcrumb a {
            color: #999;
            text-decoration: none;
        }
        .update-time {
            float: right;
            color: #ccc;
            font-size: 12px;
        }
        h1 {
            font-size: 28px;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 1px solid #e0e0e0;
        }
        h2 {
            font-size: 20px;
            margin: 30px 0 20px;
            color: #333;
        }
        .content-text {
            line-height: 1.8;
            color: #666;
            margin-bottom: 20px;
        }
        .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;
        }
    </style>
</head>
<body>
<div class="breadcrumb">
    <a href="#">平台介绍</a> > 名词解释
    <span class="update-time">更新时间:2021-10-26 12:36:17</span>
</div>
<h1>名词解释</h1>
<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>
    // 监听来自父页面的滚动消息
    window.addEventListener('message', function (event) {
        if (event.data.type === 'scrollTo') {
            const targetElement = document.getElementById(event.data.sectionId);
            if (targetElement) {
                targetElement.scrollIntoView({
                    behavior: 'smooth',
                    block: 'start'
                });
            }
        }
    });
</script>
</body>
</html>
open-rcs/components/content/content-platform-spec.html
New file
@@ -0,0 +1,152 @@
<!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-color: #fff;
            padding: 30px;
            line-height: 1.8;
        }
        .breadcrumb {
            font-size: 14px;
            color: #999;
            margin-bottom: 20px;
        }
        .breadcrumb a {
            color: #999;
            text-decoration: none;
        }
        .update-time {
            float: right;
            color: #ccc;
            font-size: 12px;
        }
        h1 {
            font-size: 28px;
            margin-bottom: 30px;
            padding-bottom: 20px;
            border-bottom: 1px solid #e0e0e0;
        }
        h2 {
            font-size: 20px;
            margin: 30px 0 20px;
            color: #333;
        }
        .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;
        }
    </style>
</head>
<body>
<div class="breadcrumb">
    <a href="#">平台规范</a> > 开发规范
    <span class="update-time">更新时间:2021-12-15 10:30:00</span>
</div>
<h1>平台规范</h1>
<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>
    window.addEventListener('message', function (event) {
        if (event.data.type === 'scrollTo') {
            const targetElement = document.getElementById(event.data.sectionId);
            if (targetElement) {
                targetElement.scrollIntoView({behavior: 'smooth', block: 'start'});
            }
        }
    });
</script>
</body>
</html>
open-rcs/components/header/header.html
New file
@@ -0,0 +1,135 @@
<!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-color: #fff;
        }
        /* 头部 */
        header {
            background-color: #fff;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        .top-bar {
            max-width: 1400px;
            margin: 0 auto;
            padding: 10px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .logo {
            font-size: 20px;
            font-weight: bold;
            color: #333;
        }
        .top-nav {
            display: flex;
            gap: 30px;
            align-items: center;
        }
        .top-nav a {
            text-decoration: none;
            color: #666;
            font-size: 14px;
        }
        .top-nav a:hover {
            color: #0066cc;
        }
        .doc-link {
            color: #0066cc !important;
        }
        /* 主导航 */
        .main-nav {
            max-width: 1400px;
            margin: 0 auto;
            padding: 0 20px;
            display: flex;
            gap: 40px;
            border-bottom: 1px solid #e0e0e0;
        }
        .main-nav a {
            display: block;
            padding: 15px 0;
            text-decoration: none;
            color: #333;
            font-size: 15px;
            border-bottom: 2px solid transparent;
        }
        .main-nav a:hover,
        .main-nav a.active {
            color: #0066cc;
            border-bottom-color: #0066cc;
        }
    </style>
</head>
<body>
<header>
    <div class="top-bar">
        <div class="logo">中扬RCS开放平台</div>
        <!--            <div class="top-nav">-->
        <!--                <a href="#">首页</a>-->
        <!--                <a href="#" class="doc-link">文档中心</a>-->
        <!--                <a href="#">🔍</a>-->
        <!--                <a href="#">控制台</a>-->
        <!--                <a href="#">免费注册</a>-->
        <!--            </div>-->
    </div>
    <nav class="main-nav">
        <!--            <a href="javascript:void(0);" class="tab-link active" data-tab="platform-intro" onclick="sendMessage('platform-intro'); return false;">平台介绍</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="platform-spec" onclick="sendMessage('platform-spec'); return false;">平台规范</a>-->
        <a href="javascript:void(0);" class="tab-link active" data-tab="interface-word"
           onclick="sendMessage('interface-word'); return false;">接口文档</a>
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="app-guide" onclick="sendMessage('app-guide'); return false;">应用接入引导</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="device-dev" onclick="sendMessage('device-dev'); return false;">设备开发</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="app-dev" onclick="sendMessage('app-dev'); return false;">应用开发</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="cloud-old" onclick="sendMessage('cloud-old'); return false;">云服务开发(旧)</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="cloud-new" onclick="sendMessage('cloud-new'); return false;">云服务开发(新)</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="dev-tools" onclick="sendMessage('dev-tools'); return false;">开发者工具</a>-->
        <!--            <a href="javascript:void(0);" class="tab-link" data-tab="data-center" onclick="sendMessage('data-center'); return false;">数据中心</a>-->
    </nav>
</header>
<script>
    // 发送消息到父页面
    function sendMessage(tabName) {
        console.log('发送消息:', tabName);
        window.parent.postMessage({
            type: 'switchTab',
            tab: tabName
        }, '*');
    }
    // 监听父页面发来的消息,更新active状态
    window.addEventListener('message', function (e) {
        if (e.data.type === 'updateTab') {
            document.querySelectorAll('.tab-link').forEach(link => {
                link.classList.remove('active');
                if (link.getAttribute('data-tab') === e.data.tab) {
                    link.classList.add('active');
                }
            });
        }
    });
</script>
</body>
</html>
open-rcs/components/rightsidebar/rightsidebar-interface-word.html
New file
@@ -0,0 +1,134 @@
<!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, #ffffff, #f8f9fa);
            padding: 20px;
        }
        h3 {
            font-size: 16px;
            margin-bottom: 20px;
            padding-bottom: 15px;
            border-bottom: 2px solid #e0e0e0;
            color: #333;
            font-weight: 700;
            position: relative;
        }
        h3::before {
            content: '📝';
            margin-right: 8px;
        }
        h3::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 30px;
            height: 2px;
            background: linear-gradient(90deg, #667eea, #764ba2);
        }
        ul {
            list-style: none;
        }
        ul li {
            padding: 10px 12px;
            cursor: pointer;
            color: #555;
            font-size: 14px;
            border-radius: 6px;
            margin-bottom: 4px;
            transition: all 0.3s ease;
            position: relative;
            padding-left: 25px;
        }
        ul li::before {
            content: '▸';
            position: absolute;
            left: 10px;
            color: #0066cc;
            font-size: 10px;
            transition: all 0.3s ease;
        }
        ul li:hover {
            background: linear-gradient(135deg, #f0f4ff, #e8f0fe);
            padding-left: 30px;
            box-shadow: 0 2px 6px rgba(102, 126, 234, 0.1);
        }
        ul li:hover::before {
            left: 12px;
            color: #667eea;
        }
        ul li a {
            color: #555;
            text-decoration: none;
            display: block;
            font-weight: 500;
            transition: color 0.3s ease;
        }
        ul li a:hover {
            color: #667eea;
            font-weight: 600;
        }
        /* 滚动条美化 */
        ::-webkit-scrollbar {
            width: 6px;
        }
        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb {
            background: linear-gradient(135deg, #667eea, #764ba2);
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb:hover {
            background: linear-gradient(135deg, #764ba2, #667eea);
        }
    </style>
</head>
<body>
<h3>本页内容</h3>
<ul>
    <li><a href="javascript:void(0);" onclick="scrollToSection('api-overview'); return false;">接口概览</a></li>
    <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-create'); return false;">生成任务单*</a></li>
    <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-cancel'); return false;">取消任务单*</a></li>
    <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-notice'); return false;">任务执行通知*</a></li>
    <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-priority'); return false;">申请入库任务*</a></li>
    <!-- <li><a href="javascript:void(0);" onclick="scrollToSection('api-loc-status'); return false;">库位状态修改</a></li> -->
    <li><a href="javascript:void(0);" onclick="scrollToSection('error-codes'); return false;">错误码说明</a></li>
</ul>
<script>
    function scrollToSection(sectionId) {
        window.parent.postMessage({
            type: 'scrollToSection',
            sectionId: sectionId
        }, '*');
    }
</script>
</body>
</html>
open-rcs/components/rightsidebar/rightsidebar-platform-intro.html
New file
@@ -0,0 +1,76 @@
<!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-color: #fff;
            padding: 20px;
        }
        h3 {
            font-size: 16px;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #e0e0e0;
        }
        ul {
            list-style: none;
        }
        ul li {
            padding: 8px 0;
            cursor: pointer;
            color: #666;
            font-size: 14px;
        }
        ul li a {
            color: #666;
            text-decoration: none;
            display: block;
        }
        ul li a:hover {
            color: #0066cc;
        }
    </style>
</head>
<body>
<h3>本页内容</h3>
<ul>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('enterprise-admin'); return false;">企业管理员</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('enterprise-member'); return false;">企业成员</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('device'); return false;">设备</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('product'); return false;">产品</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('user-id'); return false;">开发者获取User ID</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('iot-enable'); return false;">物联使能</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('dev-board'); return false;">海尔设备开发板</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('dev-kit'); return false;">联家开发者套件</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('firmware'); return false;">固件</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('hw-direct'); return false;">硬件直连接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('hw-cloud'); return false;">硬件云对云接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('app-access'); return false;">应用&应用接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('sw-modeling'); return false;">软件建模</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('typeid'); return false;">TYPEID</a></li>
</ul>
<script>
    function sendScrollMessage(sectionId) {
        window.parent.postMessage({
            type: 'scrollToSection',
            sectionId: sectionId
        }, '*');
    }
</script>
</body>
</html>
open-rcs/components/rightsidebar/rightsidebar-platform-spec.html
New file
@@ -0,0 +1,57 @@
<!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-color: #fff;
            padding: 20px;
        }
        h3 {
            font-size: 16px;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #e0e0e0;
        }
        ul {
            list-style: none;
        }
        ul li {
            padding: 8px 0;
            cursor: pointer;
            color: #666;
            font-size: 14px;
        }
        ul li a {
            color: #666;
            text-decoration: none;
            display: block;
        }
        ul li a:hover {
            color: #0066cc;
        }
    </style>
</head>
<body>
<h3>本页内容</h3>
<ul>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('dev-spec'); return false;">开发规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('security-spec'); return false;">安全规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('data-spec'); return false;">数据规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('api-spec'); return false;">接口规范</a></li>
</ul>
</body>
</html>
open-rcs/components/sidebar/sidebar-interface-word.html
New file
@@ -0,0 +1,223 @@
<!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, #ffffff, #f8f9fa);
            padding: 20px;
        }
        h3 {
            font-size: 18px;
            background: linear-gradient(135deg, #0066cc, #00c6ff);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
            margin-bottom: 20px;
            cursor: pointer;
            font-weight: 700;
            padding-bottom: 15px;
            border-bottom: 2px solid #e0e0e0;
            position: relative;
        }
        h3::after {
            content: '';
            position: absolute;
            bottom: -2px;
            left: 0;
            width: 40px;
            height: 2px;
            background: linear-gradient(90deg, #0066cc, #00c6ff);
        }
        .sidebar-menu {
            list-style: none;
        }
        /* 一级菜单项 */
        .sidebar-menu > li {
            padding: 12px 15px;
            cursor: pointer;
            color: #555;
            font-size: 14px;
            border-radius: 8px;
            margin-bottom: 5px;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
            font-weight: 600;
        }
        .sidebar-menu > li::before {
            content: '';
            position: absolute;
            left: 0;
            top: 0;
            height: 100%;
            width: 3px;
            background: linear-gradient(180deg, #0066cc, #00c6ff);
            transform: scaleY(0);
            transition: transform 0.3s ease;
        }
        .sidebar-menu > li:hover {
            background: linear-gradient(135deg, #e8f4ff, #d4e9ff);
            box-shadow: 0 2px 8px rgba(0, 102, 204, 0.1);
        }
        .sidebar-menu > li:hover::before {
            transform: scaleY(1);
        }
        .sidebar-menu > li.active {
            background: linear-gradient(135deg, #0066cc, #0052a3);
            color: #fff;
            box-shadow: 0 4px 12px rgba(0, 102, 204, 0.3);
        }
        /* 二级菜单容器 */
        .submenu {
            list-style: none;
            margin-top: 5px;
            margin-left: 10px;
            margin-bottom: 10px;
            display: none;
        }
        /* 展开的二级菜单 */
        .submenu.expanded {
            display: block;
        }
        /* 二级菜单项 */
        .submenu li {
            padding: 8px 15px;
            cursor: pointer;
            color: #666;
            font-size: 13px;
            border-radius: 6px;
            margin-bottom: 3px;
            transition: all 0.3s ease;
            position: relative;
        }
        .submenu li:hover {
            background: rgba(0, 102, 204, 0.08);
            padding-left: 20px;
        }
        .submenu li.active {
            background: rgba(0, 102, 204, 0.15);
            color: #0066cc;
            font-weight: 500;
        }
        /* 菜单链接 */
        .sidebar-menu a {
            color: inherit;
            text-decoration: none;
            display: block;
            transition: color 0.3s ease;
        }
        /* 展开/折叠图标 */
        .menu-toggle {
            float: right;
            font-size: 12px;
            transition: transform 0.3s ease;
        }
        .menu-toggle.expanded {
            transform: rotate(90deg);
        }
        /* 滚动条美化 */
        ::-webkit-scrollbar {
            width: 6px;
        }
        ::-webkit-scrollbar-track {
            background: #f1f1f1;
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb {
            background: linear-gradient(135deg, #667eea, #764ba2);
            border-radius: 3px;
        }
        ::-webkit-scrollbar-thumb:hover {
            background: linear-gradient(135deg, #764ba2, #667eea);
        }
    </style>
</head>
<body>
<h3>RCS接口文档</h3>
<ul class="sidebar-menu">
    <!-- 概览类 -->
    <li onclick="toggleSubmenu(this)">
        概览
        <span class="menu-toggle expanded">▶</span>
        <ul class="submenu expanded">
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-overview'); event.stopPropagation(); return false;">接口概览</a></li>
            <li><a href="javascript:void(0);" onclick="scrollToSection('error-codes'); event.stopPropagation(); return false;">错误码说明</a></li>
        </ul>
    </li>
    <!-- 任务管理类 -->
    <li onclick="toggleSubmenu(this)">
        任务管理
        <span class="menu-toggle">▶</span>
        <ul class="submenu expanded">
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-create'); event.stopPropagation(); return false;">生成任务单*</a></li>
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-cancel'); event.stopPropagation(); return false;">取消任务*</a></li>
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-notice'); event.stopPropagation(); return false;">任务执行通知*</a></li>
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-task-priority'); event.stopPropagation(); return false;">申请入库任务*</a></li>
        </ul>
    </li>
    <!-- 设备管理类 -->
    <!-- <li onclick="toggleSubmenu(this)">
        设备管理
        <span class="menu-toggle">▶</span>
        <ul class="submenu expanded">
            <li><a href="javascript:void(0);" onclick="scrollToSection('api-loc-status'); event.stopPropagation(); return false;">库位状态修改</a></li>
        </ul>
    </li> -->
</ul>
<script>
    // 切换二级菜单展开/折叠
    function toggleSubmenu(element) {
        const submenu = element.querySelector('.submenu');
        const menuToggle = element.querySelector('.menu-toggle');
        if (submenu) {
            submenu.classList.toggle('expanded');
        }
        if (menuToggle) {
            menuToggle.classList.toggle('expanded');
        }
    }
    // 滚动到指定章节
    function scrollToSection(sectionId) {
        window.parent.postMessage({
            type: 'scrollToSection',
            sectionId: sectionId
        }, '*');
    }
</script>
</body>
</html>
open-rcs/components/sidebar/sidebar-platform-intro.html
New file
@@ -0,0 +1,76 @@
<!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-color: #fff;
            padding: 20px;
        }
        h3 {
            font-size: 16px;
            color: #0066cc;
            margin-bottom: 20px;
            cursor: pointer;
        }
        .sidebar-menu {
            list-style: none;
        }
        .sidebar-menu li {
            padding: 10px 0;
            cursor: pointer;
            color: #666;
            font-size: 14px;
        }
        .sidebar-menu li a {
            color: #666;
            text-decoration: none;
            display: block;
        }
        .sidebar-menu li a:hover {
            color: #0066cc;
        }
    </style>
</head>
<body>
<h3>名词解释</h3>
<ul class="sidebar-menu">
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('enterprise-admin'); return false;">企业管理员</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('enterprise-member'); return false;">企业成员</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('device'); return false;">设备</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('product'); return false;">产品</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('user-id'); return false;">开发者获取User ID</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('iot-enable'); return false;">物联使能</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('dev-board'); return false;">海尔设备开发板</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('dev-kit'); return false;">联家开发者套件</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('firmware'); return false;">固件</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('hw-direct'); return false;">硬件直连接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('hw-cloud'); return false;">硬件云对云接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('app-access'); return false;">应用&应用接入</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('sw-modeling'); return false;">软件建模</a></li>
    <li><a href="javascript:void(0);" onclick="sendScrollMessage('typeid'); return false;">TYPEID</a></li>
</ul>
<script>
    function sendScrollMessage(sectionId) {
        window.parent.postMessage({
            type: 'scrollToSection',
            sectionId: sectionId
        }, '*');
    }
</script>
</body>
</html>
open-rcs/components/sidebar/sidebar-platform-spec.html
New file
@@ -0,0 +1,57 @@
<!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-color: #fff;
            padding: 20px;
        }
        h3 {
            font-size: 16px;
            color: #0066cc;
            margin-bottom: 20px;
            cursor: pointer;
        }
        .sidebar-menu {
            list-style: none;
        }
        .sidebar-menu li {
            padding: 10px 0;
            cursor: pointer;
            color: #666;
            font-size: 14px;
        }
        .sidebar-menu li a {
            color: #666;
            text-decoration: none;
            display: block;
        }
        .sidebar-menu li a:hover {
            color: #0066cc;
        }
    </style>
</head>
<body>
<h3>平台规范</h3>
<ul class="sidebar-menu">
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('dev-spec'); return false;">开发规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('security-spec'); return false;">安全规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('data-spec'); return false;">数据规范</a></li>
    <li><a href="javascript:void(0);" onclick="parent.scrollToSection('api-spec'); return false;">接口规范</a></li>
</ul>
</body>
</html>
open-rcs/pages/index-main.html
New file
@@ -0,0 +1,382 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>中扬RCS开放平台</title>
    <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-color: #f5f5f5;
            overflow-x: hidden;
        }
        /* Header区域 */
        #header-container {
            width: 100%;
            position: sticky;
            top: 0;
            z-index: 1000;
            background-color: #fff;
        }
        #header-frame {
            width: 100%;
            height: 120px;
            border: none;
            display: block;
        }
        /* 主体内容区域 */
        .main-container {
            max-width: 1400px;
            margin: 20px auto;
            padding: 0 20px;
            display: flex;
            gap: 20px;
        }
        /* 左侧边栏 */
        .sidebar-left {
            width: 220px;
            background-color: #fff;
            height: fit-content;
            position: sticky;
            top: 140px;
        }
        #sidebar-frame {
            width: 100%;
            height: 600px;
            border: none;
            display: block;
        }
        /* 主内容区 */
        .content-area {
            flex: 1;
            background-color: #fff;
            min-height: 800px;
        }
        #content-frame {
            width: 100%;
            height: 100%;
            min-height: 800px;
            border: none;
            display: block;
        }
        /* 右侧边栏 */
        .sidebar-right {
            width: 220px;
            background-color: #fff;
            height: fit-content;
            position: sticky;
            top: 140px;
        }
        #right-sidebar-frame {
            width: 100%;
            height: 600px;
            border: none;
            display: block;
        }
        /* 底部 */
        footer {
            background-color: #003366;
            color: #fff;
            margin-top: 60px;
        }
        .footer-content {
            max-width: 1400px;
            margin: 0 auto;
            padding: 60px 20px 40px;
            display: flex;
            justify-content: space-between;
        }
        .footer-section {
            flex: 1;
        }
        .footer-section h3 {
            font-size: 16px;
            margin-bottom: 20px;
            font-weight: normal;
        }
        .footer-section ul {
            list-style: none;
        }
        .footer-section ul li {
            margin-bottom: 12px;
        }
        .footer-section a {
            color: rgba(255, 255, 255, 0.7);
            text-decoration: none;
            font-size: 14px;
        }
        .footer-section a:hover {
            color: #fff;
        }
        .qr-codes {
            display: flex;
            gap: 30px;
        }
        .qr-code-item {
            text-align: center;
        }
        .qr-code-placeholder {
            width: 100px;
            height: 100px;
            background-color: #fff;
            margin-bottom: 10px;
        }
        .qr-code-item p {
            font-size: 12px;
            color: rgba(255, 255, 255, 0.7);
        }
        .footer-contact {
            text-align: center;
            margin-top: 30px;
        }
        .contact-button {
            display: inline-block;
            padding: 12px 40px;
            background-color: #0099ff;
            color: #fff;
            text-decoration: none;
            border-radius: 25px;
            font-size: 14px;
            margin-top: 20px;
        }
        .contact-button:hover {
            background-color: #0088ee;
        }
        .footer-bottom {
            text-align: center;
            padding: 20px;
            background-color: #002244;
            font-size: 12px;
            color: rgba(255, 255, 255, 0.5);
        }
        /* 固定导航 */
        .fixed-nav {
            position: fixed;
            right: 20px;
            bottom: 50%;
            transform: translateY(50%);
            background-color: #fff;
            padding: 10px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            border-radius: 4px;
            z-index: 999;
        }
        .fixed-nav div {
            padding: 10px;
            cursor: pointer;
            color: #666;
            font-size: 14px;
            text-align: center;
        }
        .fixed-nav div:hover {
            color: #0066cc;
        }
    </style>
</head>
<body>
<!-- 头部区域 -->
<div id="header-container">
    <iframe id="header-frame" src="../components/header/header.html"></iframe>
</div>
<!-- 主体内容区域 -->
<div class="main-container">
    <!-- 左侧边栏 -->
    <div class="sidebar-left">
        <iframe id="sidebar-frame" src="../components/sidebar/sidebar-interface-word.html"></iframe>
    </div>
    <!-- 主内容区 -->
    <div class="content-area">
        <iframe id="content-frame" src="../components/content/content-interface-word.html"></iframe>
    </div>
    <!-- 右侧边栏 -->
    <div class="sidebar-right">
        <iframe id="right-sidebar-frame" src="../components/rightsidebar/rightsidebar-interface-word.html"></iframe>
    </div>
</div>
<!-- 底部 -->
<footer>
    <div class="footer-content">
        <div class="footer-section">
            <h3>开发者支持</h3>
            <ul>
                <li><a href="#">帮助中心</a></li>
                <li><a href="#">技术支持</a></li>
                <li><a href="#">开发者文档</a></li>
                <li><a href="#">价格政策</a></li>
            </ul>
        </div>
        <div class="footer-section">
            <h3>关于我们</h3>
            <ul>
                <li><a href="#">平台介绍</a></li>
                <li><a href="#">服务声明</a></li>
                <li><a href="#">隐私与信息化政策</a></li>
                <li><a href="#">合作备案</a></li>
            </ul>
        </div>
        <div class="footer-section">
            <h3>更多推荐</h3>
            <ul>
                <li><a href="#">中扬</a></li>
            </ul>
        </div>
        <div class="footer-section">
            <h3>扫码关注</h3>
            <div class="qr-codes">
                <div class="qr-code-item">
                    <div class="qr-code-placeholder"></div>
                    <p>中扬RCS</p>
                </div>
                <div class="qr-code-item">
                    <div class="qr-code-placeholder"></div>
                    <p>开发者公众号</p>
                </div>
            </div>
            <div class="footer-contact">
                <a href="#" class="contact-button">合作咨询</a>
            </div>
        </div>
    </div>
    <div class="footer-bottom">
        CopyRight © 2024 All Right Reserved 浙江中扬立库技术有限公司 版权所有
    </div>
</footer>
<!-- 固定导航 -->
<div class="fixed-nav">
    <div>⊕<br>合作</div>
    <div>📧<br>咨询</div>
    <div onclick="scrollToTop()">↑</div>
</div>
<script>
    // 标签页配置映射
    const tabConfig = {
        'platform-intro': {
            sidebar: '../components/sidebar/sidebar-platform-intro.html',
            content: '../components/content/content-platform-intro.html',
            rightSidebar: '../components/rightsidebar/rightsidebar-platform-intro.html'
        },
        'platform-spec': {
            sidebar: '../components/sidebar/sidebar-platform-spec.html',
            content: '../components/content/content-platform-spec.html',
            rightSidebar: '../components/rightsidebar/rightsidebar-platform-spec.html'
        },
        'interface-word': {
            sidebar: '../components/sidebar/sidebar-interface-word.html',
            content: '../components/content/content-interface-word.html',
            rightSidebar: '../components/rightsidebar/rightsidebar-interface-word.html'
        }
    };
    // 监听来自iframe的消息
    window.addEventListener('message', function (event) {
        console.log('收到消息:', event.data);
        if (event.data.type === 'switchTab') {
            switchTab(event.data.tab);
        } else if (event.data.type === 'scrollToSection') {
            scrollToSection(event.data.sectionId);
        }
    });
    // 切换标签页
    function switchTab(tabName) {
        console.log('切换标签页:', tabName);
        const config = tabConfig[tabName];
        if (config) {
            // 更新iframe内容
            document.getElementById('sidebar-frame').src = config.sidebar;
            document.getElementById('content-frame').src = config.content;
            document.getElementById('right-sidebar-frame').src = config.rightSidebar;
            // 通知header更新active状态
            const headerFrame = document.getElementById('header-frame');
            if (headerFrame && headerFrame.contentWindow) {
                headerFrame.contentWindow.postMessage({
                    type: 'updateTab',
                    tab: tabName
                }, '*');
            }
        } else {
            console.log('未找到配置:', tabName);
        }
    }
    // 滚动到指定章节
    function scrollToSection(sectionId) {
        console.log('滚动到章节:', sectionId);
        const contentFrame = document.getElementById('content-frame');
        if (contentFrame && contentFrame.contentWindow) {
            // 向content iframe发送滚动消息
            contentFrame.contentWindow.postMessage({
                type: 'scrollToSection',
                sectionId: sectionId
            }, '*');
        }
    }
    // 回到顶部
    function scrollToTop() {
        window.scrollTo({
            top: 0,
            behavior: 'smooth'
        });
    }
    // 监听iframe加载完成
    window.addEventListener('load', function () {
        console.log('页面加载完成');
        // 调整content-frame高度以适应内容
        const contentFrame = document.getElementById('content-frame');
        contentFrame.addEventListener('load', function () {
            try {
                const contentHeight = contentFrame.contentDocument.body.scrollHeight;
                contentFrame.style.height = contentHeight + 'px';
                console.log('调整iframe高度:', contentHeight);
            } catch (e) {
                console.log('无法调整iframe高度', e);
            }
        });
    });
</script>
</body>
</html>