diff --git a/web/src/views/Sites.vue b/web/src/views/Sites.vue
index 49bbac5..d1689ff 100644
--- a/web/src/views/Sites.vue
+++ b/web/src/views/Sites.vue
@@ -15,9 +15,10 @@
-
+
编辑
+ 配置
@@ -49,6 +50,17 @@
保存
+
+
+
+ 加载中...
+ {{ configError }}
+ 暂无配置
+
+
+ 关闭
+
+
@@ -71,6 +83,68 @@ const siteTypes = [
{ value: 'unknown', label: '未知' },
]
+// 配置查看
+const configVisible = ref(false)
+const configLoading = ref(false)
+const configError = ref('')
+const configContent = ref('')
+const configSiteId = ref('')
+
+const highlightedJson = computed(() => {
+ try {
+ const obj = JSON.parse(configContent.value)
+ return syntaxHighlight(JSON.stringify(obj, null, 2))
+ } catch {
+ return escapeHtml(configContent.value)
+ }
+})
+
+const handleViewConfig = async (row) => {
+ configVisible.value = true
+ configSiteId.value = row.siteId
+ configLoading.value = true
+ configError.value = ''
+ configContent.value = ''
+ try {
+ const res = await api.configs.bySite(row.siteId)
+ const configs = res.data || []
+ if (configs.length === 0) {
+ configContent.value = ''
+ } else {
+ const latest = configs[0] // already sorted by created_at desc
+ const resp = await api.configs.content(latest.siteId, latest.version)
+ const content = resp.data
+ configContent.value = typeof content === 'string' ? content : JSON.stringify(content, null, 2)
+ }
+ } catch (e) {
+ configError.value = e.response?.data?.message || '获取配置失败'
+ } finally {
+ configLoading.value = false
+ }
+}
+
+// syntax highlighting (reused from Configs.vue)
+const syntaxHighlight = (json) => {
+ return escapeHtml(json).replace(
+ /("(\\u[a-fA-F0-9]{4}|\\[^u]|[^"\\])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
+ (match) => {
+ let cls = 'number'
+ if (/^"/.test(match)) {
+ cls = /:$/.test(match) ? 'key' : 'string'
+ } else if (/true|false/.test(match)) {
+ cls = 'boolean'
+ } else if (/null/.test(match)) {
+ cls = 'null'
+ }
+ return `${match}`
+ }
+ )
+}
+
+const escapeHtml = (str) => {
+ return str.replace(/&/g, '&').replace(//g, '>')
+}
+
const fetchSites = async () => {
loading.value = true
try {
@@ -120,3 +194,24 @@ const handleSave = async () => {
onMounted(fetchSites)
+
+