Files

136 lines
4.4 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ==========================================================================
api.js — 数据访问层(真实 REST)
所有页面只通过 window.API 访问后端。
========================================================================== */
(function () {
async function request(path, options) {
const res = await fetch(path, {
headers: { "Content-Type": "application/json" },
...options,
});
const text = await res.text();
let data = null;
if (text) {
try {
data = JSON.parse(text);
} catch (e) {
data = text;
}
}
if (!res.ok) {
let detail =
data && typeof data === "object"
? data.detail || data.message || JSON.stringify(data)
: String(data || res.statusText);
if (Array.isArray(detail)) {
detail = detail.map((item) => (item.loc || []).slice(1).join(".") + ": " + item.msg).join(";");
}
throw new Error(detail);
}
return data;
}
const get = (path) => request(path, { method: "GET" });
const post = (path, body) =>
request(path, { method: "POST", body: JSON.stringify(body || {}) });
const patch = (path, body) =>
request(path, { method: "PATCH", body: JSON.stringify(body || {}) });
const del = (path) => request(path, { method: "DELETE" });
window.API = {
/* ---------------------------------------------------------- 供应商 */
async listProviders() {
return get("/api/providers");
},
async saveProvider(payload) {
await post("/api/providers", payload);
return get("/api/providers");
},
async deleteProvider(id) {
await del("/api/providers/" + encodeURIComponent(id));
return get("/api/providers");
},
/* ------------------------------------- 上游模型发现(含 image 筛选) */
/* 按供应商 ID 拉取上游模型 */
async discoverProviderModels(providerId) {
return post("/api/providers/" + encodeURIComponent(providerId) + "/discover", {});
},
/* 保存勾选的模型 */
async saveProviderModels(providerId, modelIds, enabled, note) {
await post("/api/providers/" + encodeURIComponent(providerId) + "/models", {
model_ids: modelIds,
enabled: enabled !== false,
note: note || "自动发现",
});
return get("/api/models?provider_id=" + encodeURIComponent(providerId));
},
/* ---------------------------------------------------------- 模型 */
async listModels(providerId) {
const q = providerId ? "?provider_id=" + encodeURIComponent(providerId) : "";
return get("/api/models" + q);
},
async toggleModel(modelId, enabled) {
await patch("/api/models/" + encodeURIComponent(modelId), { enabled: !!enabled });
return get("/api/models");
},
async setModelsEnabled(modelIds, enabled) {
await post("/api/models/bulk", { ids: modelIds, enabled: !!enabled });
return get("/api/models");
},
/* ---------------------------------------------------------- 画廊 */
async listGalleries() {
return get("/api/galleries");
},
async listGallery(profileName) {
if (!profileName) return [];
return get("/api/galleries/" + encodeURIComponent(profileName));
},
async deleteGalleryImage(profileName, filename) {
return del("/api/galleries/" + encodeURIComponent(profileName) + "/" + encodeURIComponent(filename));
},
/* ------------------------------------------------------ 生成记录 */
async listGenerations() {
return get("/api/generations");
},
/* ---------------------------------------------------- 网页端出图 */
/* 网页端固定 profile_name = "user",落到 output/user/(不存在则自动创建) */
async generateImage(payload) {
const body = Object.assign({}, payload);
if (!body.profile_name) body.profile_name = "user";
const res = await post("/api/generate", body);
return {
generation: {
id: res.id,
provider_id: res.provider,
provider_name: res.provider_name,
model: res.model,
profile_name: res.profile_name,
size: res.size,
ratio: res.ratio,
created_at: res.created_at,
},
images: res.images || [],
output_dir: res.output_dir,
};
},
/* ---------------------------------------------------------- SKILL */
async getSkill() {
return get("/api/skills");
},
};
})();