19 changed files with 319 additions and 238 deletions
Binary file not shown.
Binary file not shown.
@ -0,0 +1,7 @@ |
|||||
|
https://pkmer.cn/Pkmer-Docs/10-obsidian/obsidian%E7%A4%BE%E5%8C%BA%E6%8F%92%E4%BB%B6/readme/obsidian-local-rest-api_readme/ |
||||
|
|
||||
|
https://trix-editor.org/js/attachments.js |
||||
|
|
||||
|
https://github.com/basecamp/trix/tree/main |
||||
|
|
||||
|
https://icon-sets.iconify.design/?query=info |
||||
@ -0,0 +1,58 @@ |
|||||
|
import { formatResponse } from "utils/helper.js" |
||||
|
import Router from "utils/router.js" |
||||
|
|
||||
|
class AuthController { |
||||
|
constructor() {} |
||||
|
|
||||
|
/** |
||||
|
* 通用请求函数:依次请求网址数组,返回第一个成功的响应及其类型 |
||||
|
* @param {string[]} urls |
||||
|
* @returns {Promise<{type: string, data: any}>} |
||||
|
*/ |
||||
|
async fetchFirstSuccess(urls) { |
||||
|
for (const url of urls) { |
||||
|
try { |
||||
|
const res = await fetch(url, { method: "get", mode: "cors", redirect: "follow" }) |
||||
|
if (!res.ok) continue |
||||
|
const contentType = res.headers.get("content-type") || "" |
||||
|
let data, type |
||||
|
if (contentType.includes("application/json")) { |
||||
|
data = await res.json() |
||||
|
type = "json" |
||||
|
} else if (contentType.includes("text/")) { |
||||
|
data = await res.text() |
||||
|
type = "text" |
||||
|
} else { |
||||
|
data = await res.blob() |
||||
|
type = "blob" |
||||
|
} |
||||
|
return { type, data } |
||||
|
} catch (e) { |
||||
|
// ignore and try next url
|
||||
|
} |
||||
|
} |
||||
|
throw new Error("All requests failed") |
||||
|
} |
||||
|
|
||||
|
async random(ctx) { |
||||
|
const { type, data } = await this.fetchFirstSuccess(["https://api.miaomc.cn/image/get"]) |
||||
|
if (type === "blob") { |
||||
|
ctx.set("Content-Type", "image/jpeg") |
||||
|
ctx.body = data |
||||
|
} else { |
||||
|
ctx.body = formatResponse(false, "Failed to fetch image") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 路由注册 |
||||
|
*/ |
||||
|
static createRoutes() { |
||||
|
const controller = new AuthController() |
||||
|
const router = new Router({ prefix: "/api/pics" }) |
||||
|
router.get("/random", controller.random.bind(controller), { auth: false }) |
||||
|
return router |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default AuthController |
||||
@ -1,7 +1,6 @@ |
|||||
extends /layouts/empty.pug |
extends /layouts/empty.pug |
||||
|
|
||||
block pageHead |
block pageHead |
||||
+css('css/page/index.css') |
|
||||
|
|
||||
block pageContent |
block pageContent |
||||
.faq.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
.faq.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
||||
@ -1,8 +1,5 @@ |
|||||
extends /layouts/empty.pug |
extends /layouts/empty.pug |
||||
|
|
||||
block pageHead |
|
||||
+css('css/page/index.css') |
|
||||
|
|
||||
block pageContent |
block pageContent |
||||
.privacy.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
.privacy.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
||||
h1(class="text-2xl font-bold mb-4") 隐私政策 |
h1(class="text-2xl font-bold mb-4") 隐私政策 |
||||
@ -1,8 +1,5 @@ |
|||||
extends /layouts/empty.pug |
extends /layouts/empty.pug |
||||
|
|
||||
block pageHead |
|
||||
+css('css/page/index.css') |
|
||||
|
|
||||
block pageContent |
block pageContent |
||||
.terms.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
.terms.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100") |
||||
h1(class="text-2xl font-bold mb-4") 服务条款 |
h1(class="text-2xl font-bold mb-4") 服务条款 |
||||
@ -0,0 +1,7 @@ |
|||||
|
extends /layouts/empty.pug |
||||
|
|
||||
|
block pageHead |
||||
|
|
||||
|
|
||||
|
block pageContent |
||||
|
div sad |
||||
Loading…
Reference in new issue