feat(rdp): 新增 RDP 远程桌面/SMB/账单同步能力 + 清理编译产物
主要变更: - RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、 backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API - Windows SMB 文件传输:backend/pkg/winsmb - 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情 - Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs - 服务器导入助手:server_import_helpers、ImportCredentialSettings - 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块) - 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-* - .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
777d9e4e71
commit
76ec9387f0
202 files changed
+16555
-2543
No files matched your search
@@ -6,7 +6,7 @@ import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { kubernetesApi } from '@/api';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getErrorMessage } from '@/lib/utils';
|
||||
|
||||
export interface CreateHPADialogProps {
|
||||
clusterCode: string;
|
||||
@@ -16,7 +16,6 @@ export interface CreateHPADialogProps {
|
||||
}
|
||||
|
||||
export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCreated }: CreateHPADialogProps) {
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -30,7 +29,7 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
||||
|
||||
const handleCreate = async () => {
|
||||
if (!form.name.trim()) {
|
||||
toast({ title: t('k8s.hpa.nameRequired'), variant: 'destructive' });
|
||||
toast({ title: '名称不能为空', variant: 'destructive' });
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
@@ -45,46 +44,46 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
||||
cpuPercent: form.cpuPercent,
|
||||
memPercent: form.memPercent,
|
||||
});
|
||||
toast({ title: t('k8s.hpa.createSuccess') });
|
||||
toast({ title: 'HPA 创建成功' });
|
||||
setOpen(false);
|
||||
onCreated();
|
||||
setForm({ name: '', minReplicas: 1, maxReplicas: 10, cpuPercent: 80, memPercent: 0 });
|
||||
} catch (e: any) {
|
||||
toast({ title: t('k8s.hpa.createFailed'), description: e?.message || String(e), variant: 'destructive' });
|
||||
} catch (e: unknown) {
|
||||
toast({ title: '创建失败', description: getErrorMessage(e), variant: 'destructive' });
|
||||
} finally { setLoading(false); }
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button variant="outline" size="sm" className="border-[var(--dg-border)] text-[var(--dg-text-secondary)]" onClick={() => setOpen(true)}>
|
||||
<Plus className="h-3.5 w-3.5 mr-1" />{t('k8s.hpa.create')}
|
||||
<Plus className="h-3.5 w-3.5 mr-1" />创建 HPA
|
||||
</Button>
|
||||
{open && (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4" onClick={() => setOpen(false)}>
|
||||
<div className="bg-[var(--dg-bg-secondary)] border border-[var(--dg-border)] rounded-xl w-[480px] max-w-[92vw] max-h-[85vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
|
||||
<h2 className="text-lg font-bold text-[var(--dg-text-primary)] px-6 pt-6 pb-4 shrink-0">{t('k8s.hpa.create')}</h2>
|
||||
<h2 className="text-lg font-bold text-[var(--dg-text-primary)] px-6 pt-6 pb-4 shrink-0">创建 HPA</h2>
|
||||
<div className="flex-1 min-h-0 overflow-y-auto px-6 space-y-3">
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('common.name')}</Label>
|
||||
<Label className="dg-text-secondary text-sm">名称</Label>
|
||||
<Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||||
placeholder={`hpa-${deploymentName}`}
|
||||
className="dg-input mt-1" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('k8s.hpa.target')}</Label>
|
||||
<p className="text-[var(--dg-text-secondary)] text-sm mt-1 bg-[var(--dg-bg-tertiary)] rounded px-3 py-2 truncate" title={t('k8s.hpa.targetSummary', { deployment: deploymentName, namespace })}>
|
||||
{t('k8s.hpa.targetSummary', { deployment: deploymentName, namespace })}
|
||||
<Label className="dg-text-secondary text-sm">目标</Label>
|
||||
<p className="text-[var(--dg-text-secondary)] text-sm mt-1 bg-[var(--dg-bg-tertiary)] rounded px-3 py-2 truncate" title={`Deployment: ${deploymentName} · 命名空间: ${namespace}`}>
|
||||
Deployment: {deploymentName} · 命名空间: {namespace}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('k8s.hpa.minReplicas')}</Label>
|
||||
<Label className="dg-text-secondary text-sm">最小副本数</Label>
|
||||
<Input type="number" value={form.minReplicas} min={1}
|
||||
onChange={(e) => setForm({ ...form, minReplicas: Number(e.target.value) })}
|
||||
className="dg-input mt-1" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('k8s.hpa.maxReplicas')}</Label>
|
||||
<Label className="dg-text-secondary text-sm">最大副本数</Label>
|
||||
<Input type="number" value={form.maxReplicas} min={1}
|
||||
onChange={(e) => setForm({ ...form, maxReplicas: Number(e.target.value) })}
|
||||
className="dg-input mt-1" />
|
||||
@@ -92,13 +91,13 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('k8s.hpa.cpuTarget')}</Label>
|
||||
<Label className="dg-text-secondary text-sm">CPU 目标 (%)</Label>
|
||||
<Input type="number" value={form.cpuPercent} min={0} max={100}
|
||||
onChange={(e) => setForm({ ...form, cpuPercent: Number(e.target.value) })}
|
||||
className="dg-input mt-1" />
|
||||
</div>
|
||||
<div>
|
||||
<Label className="dg-text-secondary text-sm">{t('k8s.hpa.memTarget')} <span className="dg-text-muted">{t('common.optional')}</span></Label>
|
||||
<Label className="dg-text-secondary text-sm">内存目标 (%) <span className="dg-text-muted">可选</span></Label>
|
||||
<Input type="number" value={form.memPercent} min={0} max={100}
|
||||
onChange={(e) => setForm({ ...form, memPercent: Number(e.target.value) })}
|
||||
className="dg-input mt-1" />
|
||||
@@ -106,9 +105,9 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 px-6 py-4 border-t border-[var(--dg-border)] shrink-0">
|
||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={() => setOpen(false)}>{t('common.cancel')}</Button>
|
||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={() => setOpen(false)}>取消</Button>
|
||||
<Button className="bg-blue-600 hover:bg-blue-700" disabled={loading} onClick={handleCreate}>
|
||||
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : t('common.create')}
|
||||
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : '创建'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,4 +115,4 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user