feat: 平台凭证动态表单(按SDK类型渲染凭证字段,替代手写JSON)
This commit is contained in:
+30
-3
@@ -661,10 +661,14 @@ const ProviderModal = {
|
|||||||
<label class="block"><span class="text-xs text-slate-500">标识 slug *</span><input v-model="f.slug" required placeholder="aliyun" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
<label class="block"><span class="text-xs text-slate-500">标识 slug *</span><input v-model="f.slug" required placeholder="aliyun" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
||||||
<label class="block"><span class="text-xs text-slate-500">名称 *</span><input v-model="f.name" required class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
<label class="block"><span class="text-xs text-slate-500">名称 *</span><input v-model="f.name" required class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
||||||
<label class="block"><span class="text-xs text-slate-500">分类</span><select v-model="f.category" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option v-for="(l,k) in Fmt.CATEGORY_LABELS" :key="k" :value="k">{{ l }}</option></select></label>
|
<label class="block"><span class="text-xs text-slate-500">分类</span><select v-model="f.category" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option v-for="(l,k) in Fmt.CATEGORY_LABELS" :key="k" :value="k">{{ l }}</option></select></label>
|
||||||
<label class="block"><span class="text-xs text-slate-500">SDK类型</span><input v-model="f.sdk_type" placeholder="aliyun-sdk" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
<label class="block"><span class="text-xs text-slate-500">SDK类型</span><select v-model="f.sdk_type" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"><option value="">未指定</option><option v-for="o in sdkOptions" :key="o.type" :value="o.type">{{ o.type }}</option></select></label>
|
||||||
<label class="col-span-2 block"><span class="text-xs text-slate-500">官网</span><input v-model="f.website" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
<label class="col-span-2 block"><span class="text-xs text-slate-500">官网</span><input v-model="f.website" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
||||||
<label class="col-span-2 block"><span class="text-xs text-slate-500">管理面板URL</span><input v-model="f.console_url" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
<label class="col-span-2 block"><span class="text-xs text-slate-500">管理面板URL</span><input v-model="f.console_url" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
||||||
<label class="col-span-2 block"><span class="text-xs text-slate-500">API配置(JSON)</span><textarea v-model="f.api_config" rows="2" :placeholder="store.providerModal.editing ? '留空不修改' : '{"access_key":"","secret":""}'" class="mt-1 w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></textarea></label>
|
<div v-if="currentFields.length" class="col-span-2 border border-slate-200 dark:border-slate-700 rounded-lg p-3 space-y-2">
|
||||||
|
<div class="text-xs font-medium text-slate-600 dark:text-slate-300">API 凭证(加密存储)</div>
|
||||||
|
<label v-for="field in currentFields" :key="field" class="block"><span class="text-xs text-slate-400">{{ field }}</span><input v-model="apiFields[field]" type="password" :placeholder="store.providerModal.editing ? '留空不修改' : '填写 ' + field" class="mt-1 w-full px-2 py-1.5 rounded border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 text-sm"></label>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="f.sdk_type" class="col-span-2 text-xs text-amber-600 dark:text-amber-400">该 SDK 类型暂无预设凭证字段(可后续扩展)</div>
|
||||||
<label class="col-span-2 flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300"><input type="checkbox" v-model="f.enabled"> 启用</label>
|
<label class="col-span-2 flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300"><input type="checkbox" v-model="f.enabled"> 启用</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-end gap-2">
|
<div class="flex justify-end gap-2">
|
||||||
@@ -674,7 +678,30 @@ const ProviderModal = {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>`,
|
</div>`,
|
||||||
setup() { return { store, Fmt, f: computed(() => store.providerModal.form), save: saveProvider }; },
|
setup() {
|
||||||
|
const f = computed(() => store.providerModal.form);
|
||||||
|
const adapterMeta = ref([]);
|
||||||
|
const apiFields = reactive({});
|
||||||
|
onMounted(async () => {
|
||||||
|
try { const r = await Api.get('/providers/adapters'); adapterMeta.value = r.adapters || []; } catch (e) { /* ignore */ }
|
||||||
|
});
|
||||||
|
const sdkOptions = computed(() => {
|
||||||
|
const opts = [];
|
||||||
|
for (const m of adapterMeta.value) for (const t of (m.sdk_types || [])) opts.push({ type: t, fields: m.required_config || [] });
|
||||||
|
return opts;
|
||||||
|
});
|
||||||
|
const currentFields = computed(() => {
|
||||||
|
const opt = sdkOptions.value.find(o => o.type === (f.value && f.value.sdk_type));
|
||||||
|
return opt ? opt.fields : [];
|
||||||
|
});
|
||||||
|
function save() {
|
||||||
|
const cfg = {};
|
||||||
|
for (const field of currentFields.value) if (apiFields[field]) cfg[field] = apiFields[field];
|
||||||
|
if (Object.keys(cfg).length) f.value.api_config = JSON.stringify(cfg);
|
||||||
|
saveProvider();
|
||||||
|
}
|
||||||
|
return { store, Fmt, f, sdkOptions, currentFields, apiFields, save };
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ================= 根组件 ================= */
|
/* ================= 根组件 ================= */
|
||||||
|
|||||||
Reference in New Issue
Block a user