Skip to content

Commit

Permalink
feat: support custom setting load by custom domain
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Nov 18, 2024
1 parent 51a3c9a commit 1e46763
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 21 deletions.
6 changes: 3 additions & 3 deletions components/static/Detail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import Sidebar from "~/components/static/Sidebar.vue"
import Outline from "~/components/static/Outline.vue"
import { Fold, Expand } from "@element-plus/icons-vue"
import AppConfig from "~/app.config"
import { useStaticSettingStore } from "~/stores/useStaticSettingStore"

// https://github.com/nuxt/nuxt/issues/15346
// 由于布局是个宏,静态构建情况下,不能动态设置,只能在前面的页面写死
Expand All @@ -95,7 +96,7 @@ const id = props.pageId ?? ((route.params.id ?? "") as string)
const { getFirstImageSrc } = useServerAssets()
const { fetchPostMeta } = useAuthModeFetch()
const { providerMode } = useProviderMode()
const { fetchConfig } = useAuthModeFetch()
const { getStaticSetting } = useStaticSettingStore()

// datas
const formData = reactive({
Expand All @@ -118,8 +119,7 @@ const getPostData = async () => {
formData.isExpires = checkExpires(attrs)
}
const getSetting = async () => {
const resText = await fetchConfig(`static.app.config.json`, providerMode)
const currentSetting = JsonUtil.safeParse<typeof AppConfig>(resText, {} as typeof AppConfig)
const currentSetting = await getStaticSetting()
logger.info("currentSetting=>", currentSetting)
formData.setting = currentSetting
}
Expand Down
11 changes: 3 additions & 8 deletions components/static/Footer.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
<script setup lang="ts">
import { JsonUtil } from "zhi-common"
import AppConfig from "~/app.config"
import { useAuthModeFetch } from "~/composables/useAuthModeFetch"
import { useProviderMode } from "~/composables/useProviderMode"
import { useStaticSettingStore } from "~/stores/useStaticSettingStore"
const { providerMode } = useProviderMode()
const { fetchConfig } = useAuthModeFetch()
const resText = await fetchConfig(`static.app.config.json`, providerMode)
const setting = JsonUtil.safeParse<typeof AppConfig>(resText, {} as typeof AppConfig)
const { getStaticSetting } = useStaticSettingStore()
const setting = await getStaticSetting()
await useStaticThemeMode()
const VNode = () =>
Expand Down
83 changes: 79 additions & 4 deletions composables/useAuthModeFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import { createAppLogger } from "~/common/appLogger"
import { useSiyuanApi } from "~/composables/api/useSiyuanApi"
import { JsonUtil } from "zhi-common"

export const useAuthModeFetch = () => {
const logger = createAppLogger("use-auth-mode-fetch")
Expand Down Expand Up @@ -99,10 +100,10 @@ export const useAuthModeFetch = () => {
/**
* 远程获取配置文本
*
* @param docId - 文档ID
* @param filename - 文件名
*/
const fetchProviderConfigForCurrentUser = async (filename: string): Promise<string> => {
const id = (route.params.id ?? "") as string
const fetchProviderConfigForCurrentUser = async (docId: string, filename: string): Promise<string> => {
const apiBase = env.public.providerUrl
const url = `/api/settings/share`
const reqUrl = `${apiBase}${url}`
Expand All @@ -115,7 +116,7 @@ export const useAuthModeFetch = () => {
},
body: JSON.stringify({
group: "GENERAL",
docId: id,
docId: docId,
key: filename,
}),
})
Expand All @@ -127,6 +128,54 @@ export const useAuthModeFetch = () => {
return resText
}

const fetchProviderConfigByAuthorForCurrentUser = async (author: string, filename: string): Promise<string> => {
const apiBase = env.public.providerUrl
const url = `/api/settings/byAuthor`
const reqUrl = `${apiBase}${url}`
let resText = ""
logger.info(`fetch config text ${filename} in provider mode, reqUrl=>${reqUrl}`)
const res = await fetch(reqUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
group: "GENERAL",
author: author,
key: filename,
}),
})
resText = await res.text()
logger.info("fetch config text in provider mode finish=>", { resText: resText })
if (!res.ok) {
throw new Error("fetch provider config error")
}
return resText
}

const fetchProviderConfigByResource = async (filename: string): Promise<string> => {
const apiBase = env.public.providerUrl
const url = `/api/settings/byResource`
const reqUrl = `${apiBase}${url}`
let resText = ""
logger.info(`fetch resource ${filename} in provider mode, reqUrl=>${reqUrl}`)
const res = await fetch(reqUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
key: filename,
}),
})
resText = await res.text()
logger.info("fetch resource in provider mode finish=>", { resText: resText })
if (!res.ok) {
throw new Error("fetch resource error")
}
return resText
}

const fetchPostMeta = async (id: string, providerMode: boolean): Promise<string> => {
let resText: string
if (providerMode) {
Expand All @@ -140,13 +189,39 @@ export const useAuthModeFetch = () => {
return resText
}

const getAuthorByDomainWhiteList = async (): Promise<string> => {
// 先查找 domain 白名单
const domainsText = await fetchProviderConfigByResource("domains.json")
const domainsJson = JsonUtil.safeParse<any>(domainsText, {})
const domains = domainsJson.domains ?? []
// 获取当前页面的 origin
const currentOrigin = window.location.origin
// 查找匹配的 domain 并获取 author
const matchedDomain = domains.find((domain: any) => domain.domain === currentOrigin)
return matchedDomain ? matchedDomain.author : null
}

const fetchConfig = async (filename: string, providerMode: boolean): Promise<string> => {
console.log("providerMode=>", providerMode)
let resText: string
if (providerMode) {
logger.info(`fetch config text ${filename} in provider mode`)
try {
resText = await fetchProviderConfigForCurrentUser(filename)
const docId = (route.params.id ?? "") as string
if (docId == "") {
// 首页
const whiteListAuthor = await getAuthorByDomainWhiteList()
if (whiteListAuthor) {
logger.info("use author from domain white list for home page")
resText = await fetchProviderConfigByAuthorForCurrentUser(whiteListAuthor, filename)
} else {
logger.info("use default author for home page")
resText = await fetchProviderConfigForCurrentUser(docId, filename)
}
} else {
resText = await fetchProviderConfigForCurrentUser(docId, filename)
}

logger.info("success fetch config in provider mode")
} catch (e) {
logger.warn("cannot find setting for current user, use default")
Expand Down
9 changes: 3 additions & 6 deletions composables/useStaticThemeMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ import { BrowserUtil } from "zhi-device"
import { createAppLogger } from "~/common/appLogger"
import { CONSTANTS } from "~/utils/constants"
import { useRoute } from "vue-router"
import { useAuthModeFetch } from "~/composables/useAuthModeFetch"
import { JsonUtil } from "zhi-common"
import AppConfig from "~/app.config"
import { useProviderMode } from "~/composables/useProviderMode"
import { useStaticSettingStore } from "~/stores/useStaticSettingStore"

// 创建日志记录器
const logger = createAppLogger("use-theme-mode")
Expand All @@ -44,7 +42,7 @@ export const useStaticThemeMode = async () => {
const { query } = useRoute()
const { providerMode } = useProviderMode()
const appBase = process.env.APP_BASE
const { fetchConfig } = useAuthModeFetch()
const { getStaticSetting } = useStaticSettingStore()

// 在 mounted 生命周期中处理加载后逻辑
onMounted(() => {})
Expand All @@ -67,8 +65,7 @@ export const useStaticThemeMode = async () => {
switchMode()
}

const resText = await fetchConfig(`static.app.config.json`, providerMode)
const setting = JsonUtil.safeParse<typeof AppConfig>(resText, {} as typeof AppConfig)
const setting = await getStaticSetting()
const siyuanV = CONSTANTS.SIYUAN_VERSION
const hljsV = CONSTANTS.HLJS_VERSION
const siyuanLightTheme = (query.lightTheme ?? setting.theme?.lightTheme ?? "Zhihu") as string
Expand Down

0 comments on commit 1e46763

Please sign in to comment.