fix(admin): reauthenticate model discovery
Staging Backend Quality Gate / validate (push) Successful in 12m14s
Staging Backend Quality Gate / publish (push) Successful in 25m47s

This commit is contained in:
Jesse_Chen
2026-08-07 22:19:15 +08:00
parent d1bea7611e
commit bf31193b60
2 changed files with 17 additions and 6 deletions
@@ -118,6 +118,7 @@ export default function ModelManagement() {
const [editingModel, setEditingModel] = useState<ModelVersion | null>(null);
const [saving, setSaving] = useState(false);
const [discovering, setDiscovering] = useState(false);
const [discoverProviderId, setDiscoverProviderId] = useState<string | null>(null);
const [discoveredModels, setDiscoveredModels] = useState<DiscoveredModel[]>([]);
const [actingId, setActingId] = useState<string | null>(null);
const [versionAction, setVersionAction] = useState<VersionAction | null>(null);
@@ -240,17 +241,16 @@ export default function ModelManagement() {
}
async function discoverModels() {
if (!selectedProviderId) return;
if (!discoverProviderId) return;
setDiscovering(true);
try {
const payload = await adminRequestJson<DiscoveredModelsPayload>("/api/admin/models/discover", {
method: "POST",
body: JSON.stringify({ providerId: selectedProviderId }),
body: JSON.stringify({ providerId: discoverProviderId }),
});
setDiscoveredModels(payload.data);
if (!payload.data.length) message.info("未发现可用模型,可继续手工输入");
} catch (error) {
message.error(error instanceof Error ? error.message : "获取模型列表失败");
setDiscoverProviderId(null);
} finally {
setDiscovering(false);
}
@@ -426,7 +426,7 @@ export default function ModelManagement() {
<Row gutter={16}>
<Col xs={24} md={8}><Form.Item name="modelId" label="模型 ID" rules={[{ required: true }, { pattern: /^[a-z0-9][a-z0-9._-]{0,63}$/ }]}><Input disabled={Boolean(editingModel)} /></Form.Item></Col>
<Col xs={24} md={8}><Form.Item name="label" label="显示名称" rules={[{ required: true }]}><Input /></Form.Item></Col>
<Col xs={24} md={8}><Form.Item label="供应商" required><Space.Compact block><Form.Item name="providerId" noStyle rules={[{ required: true, message: "请选择供应商" }]}><Select onChange={() => setDiscoveredModels([])} options={providers.map((item) => ({ value: item.id, label: `${item.name} (${item.code})` }))} /></Form.Item><Button loading={discovering} disabled={!selectedProviderId} onClick={() => void discoverModels()}></Button></Space.Compact></Form.Item></Col>
<Col xs={24} md={8}><Form.Item label="供应商" required><Space.Compact block><Form.Item name="providerId" noStyle rules={[{ required: true, message: "请选择供应商" }]}><Select onChange={() => setDiscoveredModels([])} options={providers.map((item) => ({ value: item.id, label: `${item.name} (${item.code})` }))} /></Form.Item><Button loading={discovering} disabled={!selectedProviderId} onClick={() => setDiscoverProviderId(selectedProviderId)}></Button></Space.Compact></Form.Item></Col>
</Row>
<Form.Item label="发现的模型" extra="选择后会填入供应商模型名;模型 ID 和显示名称仅在为空时自动补全。">
<Select
@@ -457,6 +457,15 @@ export default function ModelManagement() {
<Form.Item name="reason" label="修改原因" rules={[{ required: true }, { max: 500 }]}><Input.TextArea rows={2} /></Form.Item>
</Form>
</Modal>
<ReasonActionModal
open={Boolean(discoverProviderId)}
title="获取供应商模型列表"
okText="验证并获取"
confirmLoading={discovering}
reauthPermission="models.test"
onCancel={() => setDiscoverProviderId(null)}
onSubmit={discoverModels}
/>
<ReasonActionModal
open={Boolean(pendingProvider)}
title="保存模型供应商"
@@ -19,8 +19,10 @@ test("provider form keeps codes server-owned and API keys write-only", () => {
});
test("model discovery stays searchable with a manual provider model fallback", () => {
assert.match(component, /onClick=\{\(\) => setDiscoverProviderId\(selectedProviderId\)\}>获取模型列表<\/Button>/);
assert.match(component, /title="获取供应商模型列表"[\s\S]*reauthPermission="models\.test"[\s\S]*onSubmit=\{discoverModels\}/);
assert.match(component, /adminRequestJson<DiscoveredModelsPayload>\("\/api\/admin\/models\/discover"/);
assert.match(component, /body: JSON\.stringify\(\{ providerId: selectedProviderId \}\)/);
assert.match(component, /body: JSON\.stringify\(\{ providerId: discoverProviderId \}\)/);
assert.match(component, /获取模型列表/);
assert.match(component, /<Select[\s\S]*showSearch[\s\S]*optionFilterProp="label"[\s\S]*onSelect=\{selectDiscoveredModel\}/);
assert.match(component, /name="providerModel" label="供应商模型名(可手工输入)"/);