393 行
21 KiB
HTML
393 行
21 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>供应商详情资源信息分页 API 接口规范 · v1.0</title>
|
||
<style>
|
||
:root {
|
||
--ink: #172033;
|
||
--muted: #667085;
|
||
--line: #dfe5ef;
|
||
--soft: #f6f8fb;
|
||
--blue: #1677ff;
|
||
--blue-soft: #eaf3ff;
|
||
--green: #15803d;
|
||
--green-soft: #eaf8ef;
|
||
--amber: #a15c00;
|
||
--amber-soft: #fff7e6;
|
||
--red: #b42318;
|
||
--code: #101828;
|
||
}
|
||
* { box-sizing: border-box; }
|
||
html { scroll-behavior: smooth; }
|
||
body {
|
||
margin: 0;
|
||
color: var(--ink);
|
||
background: #eef2f7;
|
||
font: 14px/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||
}
|
||
.page {
|
||
width: min(1180px, calc(100% - 40px));
|
||
margin: 28px auto 64px;
|
||
background: #fff;
|
||
border: 1px solid var(--line);
|
||
border-radius: 16px;
|
||
box-shadow: 0 18px 48px rgba(16, 24, 40, .08);
|
||
overflow: hidden;
|
||
}
|
||
header {
|
||
padding: 42px 48px 34px;
|
||
color: #fff;
|
||
background: linear-gradient(135deg, #123d78, #1677ff 68%, #39a0ff);
|
||
}
|
||
header h1 { margin: 10px 0 8px; font-size: 30px; line-height: 1.3; }
|
||
header p { margin: 0; opacity: .9; }
|
||
.eyebrow { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; opacity: .78; }
|
||
.badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
|
||
.badge {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
min-height: 28px;
|
||
padding: 3px 10px;
|
||
border: 1px solid rgba(255,255,255,.35);
|
||
border-radius: 999px;
|
||
background: rgba(255,255,255,.14);
|
||
font-size: 12px;
|
||
}
|
||
main { padding: 12px 48px 54px; }
|
||
nav {
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 2;
|
||
display: flex;
|
||
gap: 20px;
|
||
margin: 0 -48px 24px;
|
||
padding: 13px 48px;
|
||
overflow-x: auto;
|
||
background: rgba(255,255,255,.96);
|
||
border-bottom: 1px solid var(--line);
|
||
backdrop-filter: blur(8px);
|
||
}
|
||
nav a { color: #344054; text-decoration: none; white-space: nowrap; font-size: 13px; }
|
||
nav a:hover { color: var(--blue); }
|
||
section { scroll-margin-top: 62px; padding-top: 22px; }
|
||
h2 { margin: 0 0 14px; font-size: 22px; }
|
||
h3 { margin: 24px 0 10px; font-size: 16px; }
|
||
p { margin: 8px 0; }
|
||
code {
|
||
padding: 2px 5px;
|
||
border-radius: 4px;
|
||
background: var(--soft);
|
||
color: #175cd3;
|
||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||
font-size: .93em;
|
||
}
|
||
pre {
|
||
margin: 12px 0;
|
||
padding: 18px 20px;
|
||
overflow: auto;
|
||
border-radius: 10px;
|
||
background: var(--code);
|
||
color: #d1e9ff;
|
||
font: 12px/1.65 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||
}
|
||
pre code { padding: 0; color: inherit; background: transparent; }
|
||
table { width: 100%; border-collapse: collapse; margin: 12px 0 18px; }
|
||
th, td { padding: 10px 12px; border: 1px solid var(--line); text-align: left; vertical-align: top; }
|
||
th { background: var(--soft); color: #344054; font-weight: 600; }
|
||
td:first-child code { white-space: nowrap; }
|
||
.endpoint {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin: 12px 0 16px;
|
||
padding: 14px 16px;
|
||
border: 1px solid #b9d8ff;
|
||
border-radius: 10px;
|
||
background: var(--blue-soft);
|
||
overflow-x: auto;
|
||
}
|
||
.method { padding: 4px 9px; border-radius: 6px; color: #fff; background: var(--blue); font-weight: 700; }
|
||
.path { font: 600 14px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; white-space: nowrap; }
|
||
.callout {
|
||
margin: 14px 0;
|
||
padding: 13px 15px;
|
||
border-left: 4px solid var(--blue);
|
||
border-radius: 6px;
|
||
background: var(--blue-soft);
|
||
}
|
||
.callout.ok { border-color: var(--green); background: var(--green-soft); }
|
||
.callout.warn { border-color: #f59e0b; background: var(--amber-soft); }
|
||
.callout strong { display: block; margin-bottom: 2px; }
|
||
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 16px 0; }
|
||
.card { padding: 15px; border: 1px solid var(--line); border-radius: 10px; background: #fff; }
|
||
.card b { display: block; margin-bottom: 4px; color: #344054; }
|
||
.card span { color: var(--muted); }
|
||
.status-ok { color: var(--green); font-weight: 700; }
|
||
.status-pending { color: var(--amber); font-weight: 700; }
|
||
ul, ol { padding-left: 22px; }
|
||
li + li { margin-top: 5px; }
|
||
footer { padding: 24px 48px; border-top: 1px solid var(--line); background: var(--soft); color: var(--muted); }
|
||
@media (max-width: 760px) {
|
||
.page { width: 100%; margin: 0; border: 0; border-radius: 0; }
|
||
header, main, footer { padding-left: 20px; padding-right: 20px; }
|
||
nav { margin-left: -20px; margin-right: -20px; padding-left: 20px; padding-right: 20px; }
|
||
.grid { grid-template-columns: 1fr; }
|
||
table { display: block; overflow-x: auto; white-space: nowrap; }
|
||
}
|
||
@media print {
|
||
@page { size: A4; margin: 14mm; }
|
||
body { background: #fff; }
|
||
.page { width: 100%; margin: 0; border: 0; box-shadow: none; }
|
||
header { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
|
||
nav { display: none; }
|
||
main { padding: 10px 0 20px; }
|
||
footer { padding: 16px 0 0; }
|
||
section { break-inside: avoid-page; }
|
||
pre { white-space: pre-wrap; word-break: break-word; }
|
||
a { color: inherit; text-decoration: none; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<article class="page">
|
||
<header>
|
||
<div class="eyebrow">HL Supplier API · Admin</div>
|
||
<h1>供应商详情资源信息分页 API 接口规范</h1>
|
||
<p>v1.0 · Issue #6316 · 2026-08-25</p>
|
||
<div class="badges">
|
||
<span class="badge">已实现 · 可联调</span>
|
||
<span class="badge">后端 deployed</span>
|
||
<span class="badge">Gateway verified</span>
|
||
<span class="badge">前端 pending</span>
|
||
<span class="badge">只读接口</span>
|
||
</div>
|
||
</header>
|
||
<main>
|
||
<nav aria-label="文档目录">
|
||
<a href="#overview">概览</a>
|
||
<a href="#request">请求</a>
|
||
<a href="#response">响应</a>
|
||
<a href="#fields">字段</a>
|
||
<a href="#semantics">业务口径</a>
|
||
<a href="#errors">错误码</a>
|
||
<a href="#frontend">前端接入</a>
|
||
<a href="#verification">验证</a>
|
||
<a href="#rollback">撤回</a>
|
||
</nav>
|
||
|
||
<section id="overview">
|
||
<h2>1. 接口概览</h2>
|
||
<div class="endpoint"><span class="method">GET</span><span class="path">/admin/supplier/items/{supplierId}/resource-info/page</span></div>
|
||
<p>用于供应商管理详情页“资源信息”页签,分页展示该供应商当前有效关系对应的资源权威信息。关系来源为本系统 <code>supplier_resource_rel</code>;Resource 提供九类本地资源,Fleet 提供车辆资源。</p>
|
||
<div class="grid">
|
||
<div class="card"><b>实现状态</b><span class="status-ok">已实现 · 可联调</span></div>
|
||
<div class="card"><b>调用方</b><span>管理后台;前端接入待完成</span></div>
|
||
<div class="card"><b>数据副作用</b><span>无写库、Redis、MQ、配置或审计副作用</span></div>
|
||
</div>
|
||
<div class="callout ok"><strong>契约真相</strong>本文以合并提交 <code>4f032cd6f</code> 的 Controller、请求/响应 VO、Service 权限门禁及 TEST Gateway 验收为准。</div>
|
||
</section>
|
||
|
||
<section id="request">
|
||
<h2>2. 请求契约</h2>
|
||
<h3>2.1 路径与查询参数</h3>
|
||
<table>
|
||
<thead><tr><th>参数</th><th>位置</th><th>类型</th><th>必填</th><th>约束与默认值</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>supplierId</code></td><td>path</td><td>string</td><td>是</td><td>正整数;Snowflake ID 必须按字符串传递</td></tr>
|
||
<tr><td><code>page</code></td><td>query</td><td>integer</td><td>否</td><td>默认 1,最小 1;公共分页兼容 <code>pageNo</code></td></tr>
|
||
<tr><td><code>pageSize</code></td><td>query</td><td>integer</td><td>否</td><td>默认 20,范围 1..100</td></tr>
|
||
<tr><td><code>resourceModule</code></td><td>query</td><td>string</td><td>否</td><td>为空查询全部;非空按关系冻结模块精确筛选</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<h3>2.2 支持的资源模块</h3>
|
||
<table>
|
||
<thead><tr><th>编码</th><th>moduleName</th><th>数据归属</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>SCENIC</code></td><td>景区管理</td><td>Resource</td></tr>
|
||
<tr><td><code>RESTAURANT</code></td><td>餐厅管理</td><td>Resource</td></tr>
|
||
<tr><td><code>SUPPLIES</code></td><td>备品管理</td><td>Resource</td></tr>
|
||
<tr><td><code>SUPPLIES_COMBO</code></td><td>组合配品</td><td>Resource</td></tr>
|
||
<tr><td><code>ACTIVITY</code></td><td>游玩项目管理</td><td>Resource</td></tr>
|
||
<tr><td><code>HOTEL</code></td><td>酒店管理</td><td>Resource</td></tr>
|
||
<tr><td><code>SERVICE</code></td><td>服务管理</td><td>Resource</td></tr>
|
||
<tr><td><code>COST_ITEM</code></td><td>额外成本</td><td>Resource</td></tr>
|
||
<tr><td><code>STAFF</code></td><td>服务人员管理</td><td>Resource</td></tr>
|
||
<tr><td><code>VEHICLE</code></td><td>车队管理-车队管理</td><td>Fleet(内部批量聚合)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<h3>2.3 调用示例</h3>
|
||
<pre><code>GET /admin/supplier/items/2091715622923657217/resource-info/page?page=1&pageSize=20&resourceModule=SCENIC
|
||
Authorization: Bearer <有效管理端访问令牌></code></pre>
|
||
<div class="callout warn"><strong>权限是双门禁</strong>服务端仅允许 ADMIN、FINANCE、SUPER_ADMIN,并同时要求 <code>supplier:view</code> 与 <code>supplier:resource:view</code>。不能只通过隐藏页签代替服务端授权。</div>
|
||
</section>
|
||
|
||
<section id="response">
|
||
<h2>3. 响应结构</h2>
|
||
<p>统一返回 <code>Result<PageResult<SupplierResourceInfoRespVO>></code>。业务失败通常仍是 HTTP 200,调用方必须检查 <code>code</code>、<code>success</code> 与 <code>message</code>。</p>
|
||
<pre><code>{
|
||
"code": 200,
|
||
"message": "success",
|
||
"success": true,
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"relationId": "2091715622923657218",
|
||
"resourceModule": "SCENIC",
|
||
"moduleName": "景区管理",
|
||
"resourceId": "2091715622923657001",
|
||
"resourceName": "示例景区",
|
||
"coverUrl": null,
|
||
"city": "海拉尔",
|
||
"isCharged": true,
|
||
"isChargedName": "是",
|
||
"settleTypeCode": "CASH",
|
||
"settleTypeName": "现付",
|
||
"tags": [
|
||
{ "tagId": "2084636804090089473", "tagName": "自然风光", "tagColor": "#52C41A" }
|
||
],
|
||
"seasons": [
|
||
{ "seasonCode": "spring", "seasonName": "春" }
|
||
],
|
||
"statusCode": "ENABLED",
|
||
"statusName": "启用",
|
||
"enabled": true,
|
||
"resourceAvailable": true,
|
||
"updateTime": "2026-08-25 10:00:00"
|
||
}
|
||
],
|
||
"total": 1,
|
||
"page": 1,
|
||
"pageSize": 20
|
||
}
|
||
}</code></pre>
|
||
</section>
|
||
|
||
<section id="fields">
|
||
<h2>4. records[] 字段</h2>
|
||
<table>
|
||
<thead><tr><th>字段</th><th>类型</th><th>可空</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>relationId</code></td><td>string</td><td>否</td><td>供应商资源关系 ID</td></tr>
|
||
<tr><td><code>resourceModule</code></td><td>string</td><td>否</td><td>关系冻结的资源模块编码</td></tr>
|
||
<tr><td><code>moduleName</code></td><td>string</td><td>否</td><td>模块中文名</td></tr>
|
||
<tr><td><code>resourceId</code></td><td>string</td><td>否</td><td>资源 ID;资源缺失仍保留关系原值</td></tr>
|
||
<tr><td><code>resourceName</code></td><td>string</td><td>是</td><td>当前资源名称</td></tr>
|
||
<tr><td><code>coverUrl</code></td><td>string</td><td>是</td><td>当前有效封面 URL</td></tr>
|
||
<tr><td><code>city</code></td><td>string</td><td>是</td><td>城市展示值</td></tr>
|
||
<tr><td><code>isCharged</code></td><td>boolean</td><td>是</td><td>是否收费;不适用/未知为 null</td></tr>
|
||
<tr><td><code>isChargedName</code></td><td>string</td><td>是</td><td>是否收费中文名</td></tr>
|
||
<tr><td><code>settleTypeCode</code></td><td>string</td><td>是</td><td>结算方式编码</td></tr>
|
||
<tr><td><code>settleTypeName</code></td><td>string</td><td>是</td><td>结算方式中文名</td></tr>
|
||
<tr><td><code>tags</code></td><td>array</td><td>否</td><td>标签列表;无数据为 []</td></tr>
|
||
<tr><td><code>seasons</code></td><td>array</td><td>否</td><td>标准季节列表;无数据为 []</td></tr>
|
||
<tr><td><code>statusCode</code></td><td>string</td><td>是</td><td>资源当前权威状态编码</td></tr>
|
||
<tr><td><code>statusName</code></td><td>string</td><td>是</td><td>归一化状态中文名</td></tr>
|
||
<tr><td><code>enabled</code></td><td>boolean</td><td>是</td><td>归一化启用标记</td></tr>
|
||
<tr><td><code>resourceAvailable</code></td><td>boolean</td><td>否</td><td>false 表示关系保留但资源已删除/缺失</td></tr>
|
||
<tr><td><code>updateTime</code></td><td>string</td><td>是</td><td>资源本身更新时间;yyyy-MM-dd HH:mm:ss</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<h3>4.1 子结构</h3>
|
||
<table>
|
||
<thead><tr><th>数组</th><th>字段</th><th>说明</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>tags[]</code></td><td><code>tagId</code>、<code>tagName</code>、<code>tagColor</code></td><td>标签 ID 沿用各资源模块的字符串表达</td></tr>
|
||
<tr><td><code>seasons[]</code></td><td><code>seasonCode</code>、<code>seasonName</code></td><td>标准季节编码与中文名</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section id="semantics">
|
||
<h2>5. 业务口径</h2>
|
||
<ul>
|
||
<li>只读取当前有效的供应商资源关系,按关系 <code>update_time DESC, rel_id DESC</code> 稳定排序。</li>
|
||
<li>响应中的 <code>updateTime</code> 是资源主数据更新时间,不是关系更新时间。</li>
|
||
<li>标量字段不适用、未知或资源缺失时返回 <code>null</code>;<code>tags</code> 与 <code>seasons</code> 永远返回数组。</li>
|
||
<li>资源被软删除或不存在时不丢弃关系行:<code>resourceAvailable=false</code>,名称、状态、更新时间等当前资源字段为 null。</li>
|
||
<li>十类资源以本系统权威数据为准;展示形式可参考现有资源列表,但不要从参考图硬编码字段值或状态。</li>
|
||
<li>供应商处于草稿、审批中、合作中、暂停、黑名单、归档等任意生命周期状态时均可只读查询。</li>
|
||
<li>Fleet/字典依赖出现空响应、非成功、重复、缺失、额外或非法数据时返回 395039,不降级为部分成功。</li>
|
||
</ul>
|
||
<div class="callout"><strong>内部依赖说明</strong>Resource 通过内部 Token 调用 <code>POST /internal/fleet/vehicles/supplier-resource-info/batch</code> 聚合车辆信息。该路径不面向管理端,前端不得调用、转发或持有内部 Token。</div>
|
||
</section>
|
||
|
||
<section id="errors">
|
||
<h2>6. 错误码</h2>
|
||
<table>
|
||
<thead><tr><th>业务码</th><th>场景</th><th>管理端建议</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>401</code></td><td>未认证或登录态失效</td><td>按统一登录续期/退出逻辑处理</td></tr>
|
||
<tr><td><code>400</code></td><td>supplierId、page 或 pageSize 等参数不合法</td><td>修正请求,不自动重试</td></tr>
|
||
<tr><td><code>395001</code></td><td>供应商不存在</td><td>关闭失效详情或刷新列表</td></tr>
|
||
<tr><td><code>395034</code></td><td>resourceModule 不受支持</td><td>仅使用本文十个稳定编码</td></tr>
|
||
<tr><td><code>395039</code></td><td>Fleet、字典或资源必要依赖不可用/响应不完整</td><td>提示稍后重试,不展示旧数据冒充成功</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<pre><code>{
|
||
"code": 395034,
|
||
"message": "不支持的资源模块",
|
||
"data": null,
|
||
"success": false
|
||
}</code></pre>
|
||
</section>
|
||
|
||
<section id="frontend">
|
||
<h2>7. 管理端接入清单</h2>
|
||
<ol>
|
||
<li>在供应商详情“账号信息”页签后新增“资源信息”页签;仅在页签打开时加载数据。</li>
|
||
<li>建议列:资源名称(封面 + 名称)、资源模块、城市、是否收费、结算方式、标签、季节、状态、更新时间。</li>
|
||
<li>所有 ID 按字符串保存、传参和比较,禁止转换为 JavaScript number。</li>
|
||
<li>优先展示服务端中文字段;未知字段显示“—”,不得前端猜测状态或字典名称。</li>
|
||
<li><code>resourceAvailable=false</code> 时保留行并明确显示“资源已删除/不可用”。</li>
|
||
<li>模块筛选或页容量改变时回到第 1 页;pageSize 最大 100。</li>
|
||
<li>按 <code>code/success</code> 判断业务结果;不要仅依据 HTTP 200。</li>
|
||
<li>页签为只读展示,不增加绑定、改绑、解绑、启停或删除按钮。</li>
|
||
</ol>
|
||
<h3>7.1 建议验收场景</h3>
|
||
<table>
|
||
<thead><tr><th>场景</th><th>预期</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>有资源关系</td><td>按分页显示,中文字段、数组、字符串 ID 正常</td></tr>
|
||
<tr><td>无资源关系</td><td>records=[]、total=0,不显示错误空态</td></tr>
|
||
<tr><td>按模块筛选</td><td>返回行的 resourceModule 全部等于筛选值</td></tr>
|
||
<tr><td>关系存在但资源缺失</td><td>保留关系行,resourceAvailable=false</td></tr>
|
||
<tr><td>无双权限/未登录</td><td>服务端拒绝,页面不泄露数据</td></tr>
|
||
<tr><td>依赖暂不可用</td><td>展示 395039 对应提示,不展示不完整成功页</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section id="verification">
|
||
<h2>8. 实现与验收状态</h2>
|
||
<ul>
|
||
<li><strong>代码:</strong>PR #6330 已合并 <code>dev-v3</code>,合并提交 <code>4f032cd6f6698607a2f1524437533d595975fc9a</code>。</li>
|
||
<li><strong>自动化:</strong>Resource 全量 2043 项零失败;Fleet 可运行全量 3853 项零失败;GatewayRouteAuditTest 3 项零失败;独立审计套件再次通过。</li>
|
||
<li><strong>TEST:</strong>任务 <code>cc1fe248</code>、<code>2697d374</code> 精确部署同一合并提交,Resource/Fleet 双实例与 Nacos 各 2 实例健康。</li>
|
||
<li><strong>真实 Gateway:</strong>有效管理端会话只读查询 3 个供应商,实际取得 1 条 SCENIC 关系;18 字段、字符串 ID、数组、时间和模块筛选均通过。</li>
|
||
<li><strong>负向:</strong>395001、395034、page/pageSize 参数 400 与未认证 401 均实测通过。</li>
|
||
<li><strong>车辆样本:</strong>TEST 当时无 VEHICLE 供应商关系;未伪造数据,跨服务路径由双服务真实部署健康与内部契约/批量/失败关闭测试覆盖。</li>
|
||
<li><strong>环境恢复:</strong>任务 <code>45e843e5</code>、<code>c05eda6e</code> 已回切包含本次合并的 <code>dev-v3</code>;Resource 8082/8182、Fleet 8087/8187 及 Nacos 各 2 个实例健康,临时部署分支已删除。</li>
|
||
</ul>
|
||
<div class="callout ok"><strong>数据清理</strong>TEST 验收全部为 GET 只读请求,没有创建或修改供应商、资源、数据库、Redis、MQ 或配置数据。</div>
|
||
</section>
|
||
|
||
<section id="rollback">
|
||
<h2>9. 撤回方案</h2>
|
||
<ol>
|
||
<li>从最新 <code>dev-v3</code> 创建回退分支,执行 <code>git revert -m 1 --no-edit 4f032cd6f6698607a2f1524437533d595975fc9a</code>,经独立 PR 合入。</li>
|
||
<li>依次重新构建并滚动部署 Resource、Fleet,分别保持双实例可用。</li>
|
||
<li>本次无数据库、Redis、MQ、Nacos 或其他配置变更,无需 DDL、DML、缓存清理、消息补偿或配置恢复,也无不可逆影响。</li>
|
||
<li>管理端停止调用新增 GET 和读取本次字段;既有供应商详情、账号和资源管理接口不受影响。</li>
|
||
<li>经 Gateway 复测新增路径撤回、既有供应商详情正常,并确认两服务双实例和 Nacos 健康。</li>
|
||
</ol>
|
||
</section>
|
||
</main>
|
||
<footer>
|
||
关联:Issue #6316 · PR #6330 · 后端负责人 @lc · 本文件为可离线、可打印单页接口规范。
|
||
</footer>
|
||
</article>
|
||
</body>
|
||
</html>
|