Skip to content

Commit ef5b408

Browse files
authored
feat: support Nacos displayServerUrl and improve HiClaw download UX (higress-group#222)
- Add displayServerUrl field to NacosInstance entity and admin console, allowing operators to configure a public-facing Nacos address for CLI download commands (falls back to serverUrl when not set) - Update SkillServiceImpl and WorkerServiceImpl to prefer displayServerUrl when building CLI download info - Redesign WorkerDetail HiClaw install section with platform tabs (Linux/Mac vs Windows) and one-liner curl/irm commands - Add Flyway migration V15 for the new column 🤖 Generated with [Qoder][https://qoder.com]
1 parent 714ed72 commit ef5b408

File tree

10 files changed

+79
-29
lines changed

10 files changed

+79
-29
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE nacos_instance ADD COLUMN display_server_url VARCHAR(256) DEFAULT NULL;

himarket-dal/src/main/java/com/alibaba/himarket/entity/NacosInstance.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public class NacosInstance extends BaseEntity {
6565
@Column(name = "secret_key", length = 256)
6666
private String secretKey;
6767

68+
@Column(name = "display_server_url", length = 256)
69+
private String displayServerUrl;
70+
6871
@Column(name = "description", length = 512)
6972
private String description;
7073

himarket-server/src/main/java/com/alibaba/himarket/dto/params/nacos/CreateNacosParam.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ public class CreateNacosParam implements InputConverter<NacosInstance> {
4747
private String secretKey;
4848

4949
private String description;
50+
51+
private String displayServerUrl;
5052
}

himarket-server/src/main/java/com/alibaba/himarket/dto/params/nacos/UpdateNacosParam.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,7 @@ public class UpdateNacosParam implements InputConverter<NacosInstance> {
5050

5151
@Size(max = 512, message = "Description cannot exceed 512 characters")
5252
private String description;
53+
54+
@Size(max = 256, message = "Display server URL cannot exceed 256 characters")
55+
private String displayServerUrl;
5356
}

himarket-server/src/main/java/com/alibaba/himarket/dto/result/nacos/NacosResult.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public class NacosResult implements OutputConverter<NacosResult, NacosInstance>
3333

3434
private String serverUrl;
3535

36+
private String displayServerUrl;
37+
3638
private Boolean isDefault;
3739

3840
private String defaultNamespace;

himarket-server/src/main/java/com/alibaba/himarket/service/impl/SkillServiceImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,12 @@ public CliDownloadInfo getCliDownloadInfo(String productId) {
512512
return null;
513513
}
514514
return CliDownloadInfo.builder()
515-
.nacosHost(URLUtil.url(nacos.getServerUrl()).getHost())
515+
.nacosHost(
516+
URLUtil.url(
517+
StrUtil.isNotBlank(nacos.getDisplayServerUrl())
518+
? nacos.getDisplayServerUrl()
519+
: nacos.getServerUrl())
520+
.getHost())
516521
.resourceName(config.getSkillName())
517522
.resourceType("skill")
518523
.build();

himarket-server/src/main/java/com/alibaba/himarket/service/impl/WorkerServiceImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,12 @@ public CliDownloadInfo getCliDownloadInfo(String productId) {
600600
return null;
601601
}
602602
return CliDownloadInfo.builder()
603-
.nacosHost(URLUtil.url(nacos.getServerUrl()).getHost())
603+
.nacosHost(
604+
URLUtil.url(
605+
StrUtil.isNotBlank(nacos.getDisplayServerUrl())
606+
? nacos.getDisplayServerUrl()
607+
: nacos.getServerUrl())
608+
.getHost())
604609
.resourceName(config.getAgentSpecName())
605610
.resourceType("worker")
606611
.build();

himarket-web/himarket-admin/src/pages/NacosConsoles.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export default function NacosConsoles() {
114114
form.setFieldsValue({
115115
nacosName: record.nacosName,
116116
serverUrl: record.serverUrl,
117+
displayServerUrl: record.displayServerUrl,
117118
username: record.username,
118119
password: record.password,
119120
accessKey: record.accessKey,
@@ -329,6 +330,10 @@ export default function NacosConsoles() {
329330
</Form.Item>
330331
{/* 命名空间字段已移除 */}
331332

333+
<Form.Item name="displayServerUrl" label="展示地址">
334+
<Input placeholder="可选,用于前台下载命令展示的公网地址,如 http://nacos.example.com:8848" />
335+
</Form.Item>
336+
332337
{/* 用户名/密码改为非必填 */}
333338
<Form.Item name="username" label="用户名" rules={[]}>
334339
<Input placeholder="请输入Nacos用户名(可选)" />

himarket-web/himarket-admin/src/types/gateway.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export interface NacosInstance {
4949
nacosId: string
5050
nacosName: string
5151
serverUrl: string
52+
displayServerUrl?: string
5253
username: string
5354
password?: string
5455
accessKey?: string

himarket-web/himarket-frontend/src/pages/WorkerDetail.tsx

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ function WorkerDetail() {
248248
const [copiedHttp, setCopiedHttp] = useState(false);
249249
const [cliInfo, setCliInfo] = useState<WorkerCliInfo | null>(null);
250250
const [mdRawMode, setMdRawMode] = useState(true);
251+
const [hiclawPlatform, setHiclawPlatform] = useState<'unix' | 'windows'>('unix');
251252

252253
const handleDownload = useCallback(() => {
253254
if (!workerProductId) return;
@@ -547,6 +548,55 @@ function WorkerDetail() {
547548
</Button>
548549
</div>
549550

551+
{/* HiClaw 安装 */}
552+
{cliInfo && (
553+
<div className="px-4 py-3" style={{ borderBottom: '1px solid #f0f0f0' }}>
554+
<div className="flex items-center justify-between mb-2">
555+
<div className="flex items-center gap-1.5">
556+
<CloudUploadOutlined className="text-gray-400 text-xs" />
557+
<span className="text-xs font-medium text-gray-500">安装到 HiClaw</span>
558+
</div>
559+
<div className="flex items-center gap-1">
560+
<button
561+
onClick={() => setHiclawPlatform('unix')}
562+
className={`text-xs px-1.5 py-0.5 rounded transition-colors ${hiclawPlatform === 'unix' ? 'bg-blue-50 text-blue-600 font-medium' : 'text-gray-400 hover:text-gray-600'}`}
563+
>
564+
Linux / Mac
565+
</button>
566+
<button
567+
onClick={() => setHiclawPlatform('windows')}
568+
className={`text-xs px-1.5 py-0.5 rounded transition-colors ${hiclawPlatform === 'windows' ? 'bg-blue-50 text-blue-600 font-medium' : 'text-gray-400 hover:text-gray-600'}`}
569+
>
570+
Windows
571+
</button>
572+
<button
573+
onClick={() => {
574+
const quotedName = cliInfo.resourceName.includes(' ') ? `"${cliInfo.resourceName}"` : cliInfo.resourceName;
575+
const cmd = hiclawPlatform === 'unix'
576+
? `curl -fsSL https://higress.ai/hiclaw/import.sh | bash -s -- --nacos --host ${cliInfo.nacosHost} --name ${quotedName}`
577+
: `irm https://higress.ai/hiclaw/import.ps1 -OutFile import.ps1; .\\import.ps1 --nacos --host ${cliInfo.nacosHost} --name ${quotedName}`;
578+
copyToClipboard(cmd).then(() => {
579+
setCopiedHiclaw(true);
580+
setTimeout(() => setCopiedHiclaw(false), 2000);
581+
});
582+
}}
583+
className="text-xs text-gray-400 hover:text-gray-600 transition-colors ml-1"
584+
>
585+
{copiedHiclaw ? <CheckOutlined className="text-green-500" /> : <CopyOutlined />}
586+
</button>
587+
</div>
588+
</div>
589+
<div className="rounded-md bg-gray-100 border border-gray-200 px-3 py-2">
590+
<code className="text-[12px] text-gray-700 break-all" style={{ fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace" }}>
591+
{hiclawPlatform === 'unix'
592+
? `curl -fsSL https://higress.ai/hiclaw/import.sh | bash -s -- --nacos --host ${cliInfo.nacosHost} --name ${cliInfo.resourceName.includes(' ') ? `"${cliInfo.resourceName}"` : cliInfo.resourceName}`
593+
: `irm https://higress.ai/hiclaw/import.ps1 -OutFile import.ps1; .\\import.ps1 --nacos --host ${cliInfo.nacosHost} --name ${cliInfo.resourceName.includes(' ') ? `"${cliInfo.resourceName}"` : cliInfo.resourceName}`
594+
}
595+
</code>
596+
</div>
597+
</div>
598+
)}
599+
550600
{/* HTTP 下载 */}
551601
{cliInfo && (
552602
<div className="px-4 py-3">
@@ -607,33 +657,6 @@ function WorkerDetail() {
607657
</code>
608658
</div>
609659
</div>
610-
611-
{/* HiClaw 安装命令 */}
612-
<div>
613-
<div className="flex items-center justify-between mb-2">
614-
<div className="flex items-center gap-1.5">
615-
<CloudUploadOutlined className="text-gray-400 text-xs" />
616-
<span className="text-xs font-medium text-gray-500">安装到 HiClaw</span>
617-
</div>
618-
<button
619-
onClick={() => {
620-
const cmd = `bash /opt/hiclaw/scripts/lib/hiclaw-import.sh --nacos --host ${cliInfo.nacosHost} --name ${cliInfo.resourceName}`;
621-
copyToClipboard(cmd).then(() => {
622-
setCopiedHiclaw(true);
623-
setTimeout(() => setCopiedHiclaw(false), 2000);
624-
});
625-
}}
626-
className="text-xs text-gray-400 hover:text-gray-600 transition-colors"
627-
>
628-
{copiedHiclaw ? <CheckOutlined className="text-green-500" /> : <CopyOutlined />}
629-
</button>
630-
</div>
631-
<div className="rounded-md bg-gray-100 border border-gray-200 px-3 py-2">
632-
<code className="text-[12px] text-gray-700 break-all" style={{ fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace" }}>
633-
{`bash /opt/hiclaw/scripts/lib/hiclaw-import.sh --nacos --host ${cliInfo.nacosHost} --name ${cliInfo.resourceName}`}
634-
</code>
635-
</div>
636-
</div>
637660
</div>
638661
)}
639662
</div>

0 commit comments

Comments
 (0)