<template>
  <div class="help-content">
    <div class="content-header">
      <h2>平台账号管理接口文档</h2>
      <el-button type="primary" size="small" plain @click="downloadDoc('/docs/account_management_api.md', 'Account_Management_API.md')">
        <el-icon style="margin-right: 5px"><Download /></el-icon>
        下载 开发文档
      </el-button>
    </div>
    <p class="intro">平台账号管理接口允许用户查询和管理自己在各个第三方应用中的账号映射关系，并支持通过 SSO 方式快速登录到目标应用。</p>

    <div class="section">
      <h3>1. 核心概念</h3>
      <ul>
        <li><strong>账号映射 (User Mapping)</strong>: 统一认证平台用户与第三方应用账号的关联关系</li>
        <li><strong>映射账号 (Mapped Key)</strong>: 用户在第三方系统中的唯一标识</li>
        <li><strong>映射邮箱 (Mapped Email)</strong>: 用户在第三方系统中的邮箱地址</li>
        <li><strong>SSO 登录</strong>: 单点登录，用户无需再次输入密码即可进入第三方应用</li>
      </ul>
    </div>

    <div class="section">
      <h3>1.1 接口权限说明</h3>
      <table class="param-table">
        <thead>
          <tr><th>接口</th><th>认证方式</th><th>说明</th></tr>
        </thead>
        <tbody>
          <tr>
            <td><code>GET /simple/me/launchpad-apps</code></td>
            <td>Bearer Token (用户认证)</td>
            <td>查询当前用户<strong>可访问</strong>的应用（已启用映射、协议为 <code>SIMPLE_API</code> / <code>OIDC</code> / <code>NONE</code>（导航）、应用未删除），用于快捷导航等</td>
          </tr>
          <tr>
            <td><code>GET /simple/me/mappings</code></td>
            <td>Bearer Token (用户认证)</td>
            <td>仅用户可查询自己的账号映射</td>
          </tr>
          <tr>
            <td><code>POST /simple/sso-login</code></td>
            <td>Bearer Token (可选) 或 用户名密码</td>
            <td>支持会话认证和凭据认证两种模式</td>
          </tr>
        </tbody>
      </table>
    </div>

    <div class="section">
      <h3>2. 认证方式</h3>
      
      <h4>2.1 用户认证 (Bearer Token)</h4>
      <p>适用于前端应用或已登录的用户。</p>
      <p><strong>请求头格式:</strong></p>
      <div class="code-block">
        <pre>Authorization: Bearer {access_token}</pre>
      </div>
      <p><strong>获取 Token:</strong></p>
      <ul>
        <li>通过 <code>POST /auth/login/json</code> 接口登录获取</li>
        <li>或通过 <code>POST /simple/login</code> 接口（不提供 app_id）获取平台 access_token</li>
      </ul>

      <h4>2.2 凭据认证 (用户名密码)</h4>
      <p>适用于用户未登录 UAP 平台的场景，直接使用用户名和密码进行认证。</p>
    </div>

    <div class="section">
      <h3>3. 接口定义</h3>

      <h4>3.1 查询当前可访问的应用列表</h4>
      <p>查询当前登录用户在哪些应用上拥有<strong>已启用</strong>的账号映射，且应用协议为 <code>SIMPLE_API</code>、<code>OIDC</code> 或 <code>NONE</code>（界面「无」：仅导航、未对接一键登录）、应用未删除。与 §3.2「映射列表」的区别：本接口<strong>无 Query 分页</strong>，且服务端已按「可跳转展示」过滤；若需分页或按应用名筛选的完整映射（含已停用等），请用 §3.2。更完整的字段说明与示例见帮助中心《客户端接口 API 指南》第 8 节。</p>
      <ul>
        <li><strong>接口地址</strong>: <code>GET /api/v1/simple/me/launchpad-apps</code></li>
        <li><strong>认证方式</strong>: Bearer Token</li>
        <li><strong>Query / Body</strong>: 无</li>
      </ul>
      <h5>3.1.1 成功响应字段摘要</h5>
      <table class="param-table">
        <thead>
          <tr><th>字段</th><th>说明</th></tr>
        </thead>
        <tbody>
          <tr><td><code>total</code> / <code>items</code></td><td>条数与列表；<code>total === items.length</code></td></tr>
          <tr><td><code>items[].app_id</code> / <code>app_name</code></td><td>业务应用 ID 与名称</td></tr>
          <tr><td><code>items[].protocol_type</code></td><td><code>SIMPLE_API</code>、<code>OIDC</code> 或 <code>NONE</code>（导航）</td></tr>
          <tr><td><code>items[].mapped_key</code> / <code>mapped_email</code></td><td>映射账号、邮箱（可空）</td></tr>
          <tr><td><code>items[].description</code></td><td>应用描述（可空）</td></tr>
          <tr><td><code>items[].category_id</code> / <code>category_name</code></td><td>分类（可空）</td></tr>
          <tr><td><code>items[].icon_url</code></td><td>Logo 展示 URL（可空；对象存储时为预签名短链）</td></tr>
          <tr><td><code>items[].icon_object_key</code></td><td>对象存储时的稳定对象路径（可空）；可与 <code>app_id</code> 作客户端缓存键，详见《客户端接口 API 指南》§8</td></tr>
        </tbody>
      </table>
      <h5>3.1.2 请求示例</h5>
      <div class="code-block">
        <pre>
GET /api/v1/simple/me/launchpad-apps HTTP/1.1
Authorization: Bearer &lt;JWT_TOKEN&gt;</pre>
      </div>
      <div class="code-block">
        <pre v-pre>
curl -sS -X GET "{{API_BASE_URL}}/simple/me/launchpad-apps" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        </pre>
      </div>
      <h5>3.1.3 响应示例</h5>
      <div class="code-block">
        <pre>
{
  "total": 3,
  "items": [
    {
      "app_name": "OA系统",
      "app_id": "oa_system",
      "protocol_type": "SIMPLE_API",
      "mapped_key": "zhangsan",
      "mapped_email": "zhangsan@corp.com",
      "is_active": true,
      "description": "办公自动化系统",
      "category_id": 1,
      "category_name": "办公协同",
      "icon_url": "https://files.example.com/presigned/app_icon/oa.png",
      "icon_object_key": "app_icon/42/a1b2c3d4-e5f6-7890-abcd-ef1234567890.png"
    },
    {
      "app_name": "CRM客户管理",
      "app_id": "crm_system",
      "protocol_type": "OIDC",
      "mapped_key": "zhangsan_crm",
      "mapped_email": null,
      "is_active": true,
      "description": null,
      "category_id": null,
      "category_name": null,
      "icon_url": null,
      "icon_object_key": null
    },
    {
      "app_name": "外部官网",
      "app_id": "nav_portal",
      "protocol_type": "NONE",
      "mapped_key": "zhangsan",
      "mapped_email": null,
      "is_active": true,
      "description": "仅导航入口",
      "category_id": null,
      "category_name": null,
      "icon_url": null,
      "icon_object_key": null
    }
  ]
}
        </pre>
      </div>

      <h4>3.2 获取我的账号映射列表</h4>
      <p>查询当前用户在所有第三方应用中的账号映射关系。</p>
      <ul>
        <li><strong>接口地址</strong>: <code>GET /api/v1/simple/me/mappings</code></li>
        <li><strong>认证方式</strong>: Bearer Token (用户认证)</li>
        <li><strong>Content-Type</strong>: <code>application/json</code></li>
      </ul>

      <h5>3.2.1 请求参数 (Query Parameters)</h5>
      <table class="param-table">
        <thead>
          <tr><th>字段</th><th>类型</th><th>必填</th><th>默认值</th><th>说明</th></tr>
        </thead>
        <tbody>
          <tr>
            <td><code>skip</code></td>
            <td>integer</td>
            <td><span class="tag-optional">否</span></td>
            <td>0</td>
            <td>跳过的记录数（用于分页）</td>
          </tr>
          <tr>
            <td><code>limit</code></td>
            <td>integer</td>
            <td><span class="tag-optional">否</span></td>
            <td>10</td>
            <td>每页返回的记录数</td>
          </tr>
          <tr>
            <td><code>app_name</code></td>
            <td>string</td>
            <td><span class="tag-optional">否</span></td>
            <td>-</td>
            <td>应用名称（支持模糊搜索）</td>
          </tr>
        </tbody>
      </table>

      <h5>3.2.2 响应格式</h5>
      <p><strong>成功响应 (200 OK):</strong></p>
      <div class="code-block">
        <pre>
{
  "total": 25,
  "items": [
    {
      "app_name": "OA办公系统",
      "app_id": "oa_system_001",
      "protocol_type": "SIMPLE_API",
      "mapped_key": "zhangsan_oa",
      "mapped_email": "zhangsan@company.com",
      "is_active": true
    }
  ]
}
        </pre>
      </div>

      <h5>3.2.3 请求示例</h5>
      <p><strong>cURL:</strong></p>
      <div class="code-block">
        <pre v-pre>
curl -X GET "{{API_BASE_URL}}/simple/me/mappings?skip=0&limit=10&app_name=OA" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        </pre>
      </div>

      <p><strong>JavaScript (Fetch API):</strong></p>
      <div class="code-block">
        <pre v-pre>
const response = await fetch('{{API_BASE_URL}}/simple/me/mappings?skip=0&limit=10&app_name=OA', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
});

const data = await response.json();
console.log('总记录数:', data.total);
console.log('映射列表:', data.items);
        </pre>
      </div>
    </div>

    <div class="section">
      <h3>3.3 SSO 单点登录</h3>
      <p>通过 SSO 方式登录到目标应用，支持两种认证模式：</p>
      <ol>
        <li><strong>会话认证模式</strong>: 用户已登录 UAP 平台，使用 Bearer Token</li>
        <li><strong>凭据认证模式</strong>: 用户未登录，使用用户名和密码</li>
      </ol>
      <ul>
        <li><strong>接口地址</strong>: <code>POST /api/v1/simple/sso-login</code></li>
        <li><strong>认证方式</strong>: Bearer Token (会话认证，推荐) 或 用户名密码 (凭据认证)</li>
        <li><strong>Content-Type</strong>: <code>application/json</code></li>
        <li><strong>支持的应用协议</strong>：<code>SIMPLE_API</code>（<code>redirect_url</code> 含一次性 <code>ticket</code>）、<code>OIDC</code>（<code>redirect_url</code> 为 <code>scheme://host</code>，用于已登录场景下的跳转入口）、<code>NONE</code>（导航：<code>redirect_url</code> 为应用配置的导航 URL 原文，<strong>无 ticket</strong>）。不支持其它协议值。</li>
      </ul>

      <h5>3.3.1 请求参数 (Request Body)</h5>
      <table class="param-table">
        <thead>
          <tr><th>字段</th><th>类型</th><th>必填</th><th>说明</th></tr>
        </thead>
        <tbody>
          <tr>
            <td><code>app_id</code></td>
            <td>string</td>
            <td><span class="tag-required">是</span></td>
            <td>目标应用的ID</td>
          </tr>
          <tr>
            <td><code>username</code></td>
            <td>string</td>
            <td><span class="tag-conditional">条件必填</span></td>
            <td>用户名（手机号、映射key或映射email）。如果已登录UAP平台，可不提供</td>
          </tr>
          <tr>
            <td><code>password</code></td>
            <td>string</td>
            <td><span class="tag-conditional">条件必填</span></td>
            <td>用户密码。如果已登录UAP平台，可不提供</td>
          </tr>
        </tbody>
      </table>

      <p><strong>注意:</strong> 如果用户已登录 UAP 平台（请求头包含有效的 Bearer Token），则 <code>username</code> 和 <code>password</code> 可以省略。</p>

      <h5>3.3.2 响应格式</h5>
      <p><strong>成功响应 (200 OK):</strong> <code>redirect_url</code> 含义随协议而异：<code>SIMPLE_API</code> 一般为回调地址附加 <code>ticket</code>；<code>OIDC</code> 为授权的 <code>scheme://host</code>；<code>NONE</code> 为导航目标 URL，不含 <code>ticket</code>。</p>
      <div class="code-block">
        <pre>
{
  "redirect_url": "https://oa.company.com/login?ticket=TICKET-7f8e9d0a-1234-5678-9abc-def012345678"
}
        </pre>
      </div>

      <h5>3.3.3 请求示例</h5>
      <p><strong>场景1: 用户已登录 UAP 平台（会话认证）</strong></p>
      <div class="code-block">
        <pre v-pre>
// JavaScript (Fetch API)
const response = await fetch('{{API_BASE_URL}}/simple/sso-login', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    app_id: 'oa_system_001'
  })
});

const data = await response.json();
if (data.redirect_url) {
  // 在新标签页中打开
  window.open(data.redirect_url, '_blank');
}
        </pre>
      </div>

      <p><strong>场景2: 用户未登录（凭据认证）</strong></p>
      <div class="code-block">
        <pre v-pre>
// JavaScript (Fetch API)
const response = await fetch('{{API_BASE_URL}}/simple/sso-login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    app_id: 'oa_system_001',
    username: '13800138000',
    password: 'user_password_123'
  })
});

const data = await response.json();
if (data.redirect_url) {
  window.open(data.redirect_url, '_blank');
}
        </pre>
      </div>
    </div>

    <div class="section">
      <h3>4. 注意事项</h3>
      
      <div class="feature-card">
        <h4>⚠️ 协议类型限制</h4>
        <ul>
          <li><code>GET /simple/me/launchpad-apps</code> 返回 <code>SIMPLE_API</code>、<code>OIDC</code> 与 <code>NONE</code> 且映射已启用、应用未删除的应用，用于「当前可访问应用」展示</li>
          <li><code>GET /simple/me/mappings</code> 返回映射列表（支持分页与按应用名筛选），协议类型与映射状态以实际数据为准</li>
          <li><code>POST /simple/sso-login</code> 支持 <code>SIMPLE_API</code>、<code>OIDC</code> 与 <code>NONE</code>，返回的 <code>redirect_url</code> 规则见 §3.3.2</li>
          <li><code>POST /simple/login</code> 在<strong>提供 <code>app_id</code></strong>时仅向 <code>SIMPLE_API</code> 与 <code>OIDC</code> 应用返回 <code>ticket</code>；<code>NONE</code> 应用不支持票据登录，请使用 <code>sso-login</code></li>
          <li>需要完整 OIDC 授权码、ID Token 等标准能力时，请使用 Hydra 标准 OIDC 流程</li>
        </ul>
      </div>

      <div class="feature-card">
        <h4>🔒 安全建议</h4>
        <ul>
          <li><strong>Token 安全</strong>: Bearer Token 应妥善保管，避免泄露</li>
          <li><strong>HTTPS</strong>: 生产环境必须使用 HTTPS 协议</li>
          <li><strong>Token 过期</strong>: 注意处理 Token 过期的情况，及时刷新或重新登录</li>
          <li><strong>错误处理</strong>: 建议实现完善的错误处理和重试机制</li>
        </ul>
      </div>
    </div>

    <div class="section">
      <h3>5. 常见问题 (FAQ)</h3>
      
      <div class="faq-item">
        <h4>Q1: 为什么 SSO 登录返回 400 错误，提示「协议不支持」？</h4>
        <p><strong>A:</strong> <code>POST /simple/sso-login</code> 仅支持 <code>SIMPLE_API</code>、<code>OIDC</code> 与 <code>NONE</code>。若应用协议为其它值或未识别的枚举，将返回该错误。若需完整 OIDC 授权码流程，请走 Hydra 标准端点。</p>
      </div>

      <div class="faq-item">
        <h4>Q2: 如何判断用户是否已登录 UAP 平台？</h4>
        <p><strong>A:</strong> 如果您的应用中有有效的 <code>access_token</code>，可以在请求头中携带 <code>Authorization: Bearer {token}</code>。如果 Token 有效，则无需提供 <code>username</code> 和 <code>password</code>。</p>
      </div>

      <div class="faq-item">
        <h4>Q3: 账号映射列表中的 <code>mapped_email</code> 为什么可能为空？</h4>
        <p><strong>A:</strong> 不是所有第三方应用都要求或提供邮箱信息，因此 <code>mapped_email</code> 字段可能为 <code>null</code>。这是正常情况。</p>
      </div>

      <div class="faq-item">
        <h4>Q4: SSO 登录后，Ticket 的有效期是多久？</h4>
        <p><strong>A:</strong> 仅 <code>SIMPLE_API</code> 的 <code>redirect_url</code> 含一次性 Ticket，有效期由平台配置决定（常见为数分钟）。<code>NONE</code> 导航应用无 Ticket；<code>OIDC</code> 经 <code>sso-login</code> 返回的是入口 URL，完整会话仍以 OIDC Token 为准。获取 <code>redirect_url</code> 后建议尽快跳转。</p>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Download } from '@element-plus/icons-vue'
import { useHelpDocs } from '../../composables/useHelpDocs'

const { downloadDoc } = useHelpDocs()
</script>

<style scoped>
@import './help.css';
</style>
