@melt-js/comps-bag-sys 0.0.0-stage → 2026.11.7-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -2
- package/dist/SysSetting--OmMlBRZ.js +461 -0
- package/dist/SysSettingAdvanced-A0T2UBb3.js +59 -0
- package/dist/SysSettingPlugins-CZQjv88J.js +282 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +96 -0
- package/dist/views/SysSetting.vue.d.ts +2 -0
- package/dist/views/SysSettingAdvanced.vue.d.ts +2 -0
- package/dist/views/SysSettingPlugins.vue.d.ts +2 -0
- package/package.json +42 -4
package/README.md
CHANGED
|
@@ -1,3 +1,73 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @melt-js/comps-bag-sys
|
|
2
|
+
|
|
3
|
+
`@melt-js/comps-bag-sys` 是官方提供的系统设置示例插件,放的是常规设置、高级设置、插件管理这类页面。
|
|
4
|
+
|
|
5
|
+
这个包真正想说明的是一条边界:宿主框架可以提供设置能力的壳,但具体的设置页面和配置流程,最好还是留在插件层。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @melt-js/libs-bag-entry @melt-js/comps-bag-sys
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
宿主项目需要自行提供 `vue`、`vue-router`,并通常会和 `@melt-js/libs-bag-host` 一起使用。
|
|
14
|
+
|
|
15
|
+
## 它带了什么
|
|
16
|
+
|
|
17
|
+
- `/sys-setting`: 常规设置页
|
|
18
|
+
- `/sys-setting/advanced`: 高级设置页
|
|
19
|
+
- `/sys-setting/plugins`: 插件管理页
|
|
20
|
+
- 一组对应的系统设置菜单
|
|
21
|
+
- `zh-CN` / `en` 多语言文案
|
|
22
|
+
|
|
23
|
+
## 怎么接进去
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { bootstrapPlugins } from '@melt-js/libs-bag-entry'
|
|
27
|
+
import sysSettingPlugin from '@melt-js/comps-bag-sys'
|
|
28
|
+
|
|
29
|
+
await bootstrapPlugins({
|
|
30
|
+
app,
|
|
31
|
+
router,
|
|
32
|
+
i18n,
|
|
33
|
+
plugins: [sysSettingPlugin]
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 一般拿它做什么
|
|
38
|
+
|
|
39
|
+
- 作为官方“系统设置业务插件”的参考实现
|
|
40
|
+
- 作为插件管理页的落点,配合 `@melt-js/libs-bag-entry` 暴露的运行时工具展示插件清单
|
|
41
|
+
- 作为你自己项目里设置中心的起步模板
|
|
42
|
+
|
|
43
|
+
## 这份示例的特点
|
|
44
|
+
|
|
45
|
+
- 插件 ID: `plugin-sys-setting`
|
|
46
|
+
- 默认排序: `100`
|
|
47
|
+
- 页面范围: 常规设置、高级设置、插件管理
|
|
48
|
+
- 菜单分组: `sys-setting-group`
|
|
49
|
+
- 多语言: 内置中文和英文文案
|
|
50
|
+
|
|
51
|
+
## 边界
|
|
52
|
+
|
|
53
|
+
- 它不是宿主框架本体,不应该整包并进 `@melt-js/libs-bag-host`。
|
|
54
|
+
- `@melt-js/libs-bag-host` 负责布局、权限、插件引导、缓存、主题这些框架层能力。
|
|
55
|
+
- `@melt-js/comps-bag-sys` 负责具体的系统设置业务页,包括插件管理这种偏运营、偏配置的页面。
|
|
56
|
+
- 这么拆的好处很直接:宿主层能保持通用,不会被某一个项目的设置中心绑死。
|
|
57
|
+
|
|
58
|
+
## 一般会搭什么
|
|
59
|
+
|
|
60
|
+
- `@melt-js/libs-bag-entry`:提供插件协议、运行时清单和基础后台组件
|
|
61
|
+
- `@melt-js/libs-bag-host`:把系统设置插件挂到宿主应用里
|
|
2
62
|
|
|
3
|
-
|
|
63
|
+
## 构建
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pnpm build # vite build(默认开启 javascript-obfuscator 混淆 + 注释清理)→ vue-tsc 生成 d.ts
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- 混淆参数与仓库内其它 `comps-*` 包一致:标识符重命名 + 字符串数组(30%),不开控制流平坦化 / 死代码注入 / 自保护 / 调试保护;
|
|
70
|
+
- `renameGlobals` / `renameProperties` 关闭:插件对象的 `id` / `name` / `routes` / `meta` 等字段名不变,宿主照常读取;
|
|
71
|
+
- 产物里的注释(`/*!`、`@license`、`@preserve`、`@__PURE__`)会被清空;
|
|
72
|
+
- 混淆后不再输出 source map;
|
|
73
|
+
- 排查产物:`HEL_OBFUSCATE=0 pnpm build`(关闭混淆并恢复 source map)。
|
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { defineComponent as V, ref as m, computed as T, openBlock as i, createElementBlock as n, createElementVNode as e, normalizeClass as o, createTextVNode as f, createStaticVNode as h, Fragment as k, renderList as j, unref as U, createCommentVNode as y, withDirectives as l, vModelText as u, vShow as v, vModelRadio as g } from "vue";
|
|
2
|
+
import { useAppConfigStore as B, themePresets as K } from "@melt-js/libs-bag-entry";
|
|
3
|
+
const z = { class: "p-6 bg-white dark:bg-[#0A1120] rounded-2xl shadow-sm min-h-[calc(100vh-120px)] border border-gray-100 dark:border-gray-800 max-w-5xl mx-auto" }, $ = { class: "flex flex-col md:flex-row gap-8" }, E = { class: "w-full md:w-64 shrink-0 space-y-1" }, F = { class: "flex-1 bg-slate-50 dark:bg-gray-800/30 rounded-2xl p-6 md:p-8 border border-gray-100 dark:border-gray-800" }, L = { key: 0 }, M = { class: "space-y-6" }, N = { class: "flex items-center gap-6" }, O = { class: "flex-1 flex gap-4" }, R = ["onClick", "title"], D = {
|
|
4
|
+
key: 0,
|
|
5
|
+
class: "w-4 h-4 text-white",
|
|
6
|
+
fill: "none",
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
stroke: "currentColor"
|
|
9
|
+
}, I = { key: 1 }, _ = { class: "space-y-6" }, P = { class: "flex items-start gap-6" }, H = { class: "flex-1" }, q = { class: "flex items-start gap-6" }, G = { class: "flex-1" }, J = { class: "flex items-start gap-6" }, Q = { class: "flex-1" }, W = { key: 2 }, X = { class: "space-y-6" }, Y = { class: "flex items-center gap-6" }, Z = { class: "flex-1 flex gap-4" }, ee = { class: "flex items-center gap-2 cursor-pointer group" }, te = { class: "w-2 h-2 rounded-full bg-primary-500" }, re = { class: "flex items-center gap-2 cursor-pointer group" }, ae = { class: "w-2 h-2 rounded-full bg-primary-500" }, se = { class: "flex items-start gap-6" }, le = { class: "flex-1" }, oe = { class: "flex items-center gap-2 max-w-md" }, de = { class: "flex items-start gap-6" }, ie = { class: "flex-1" }, ne = { class: "flex items-start gap-6" }, ue = { class: "flex-1 space-y-4 max-w-md" }, pe = { class: "flex gap-4" }, be = { key: 3 }, xe = { class: "space-y-6" }, ve = { class: "flex items-center gap-6" }, ge = { class: "flex-1" }, me = { class: "flex items-start gap-6" }, fe = { class: "flex-1" }, ye = { class: "flex items-start gap-6" }, ce = { class: "flex-1 flex gap-4" }, ke = { class: "flex items-center gap-2 cursor-pointer group" }, we = { class: "w-2 h-2 rounded-full bg-primary-500" }, he = { class: "flex items-center gap-2 cursor-pointer group" }, Ce = { class: "w-2 h-2 rounded-full bg-primary-500" }, Ae = { class: "flex items-center gap-2 cursor-pointer group" }, Se = { class: "w-2 h-2 rounded-full bg-primary-500" }, Ve = V({
|
|
10
|
+
__name: "SysSetting",
|
|
11
|
+
setup(c) {
|
|
12
|
+
const d = m("base"), b = B(), p = m({
|
|
13
|
+
title: "",
|
|
14
|
+
keywords: "",
|
|
15
|
+
description: ""
|
|
16
|
+
}), a = m({
|
|
17
|
+
storageType: "local",
|
|
18
|
+
maxSize: 10,
|
|
19
|
+
allowedTypes: "jpg,png,gif,jpeg,pdf,zip,rar,doc,docx,xls,xlsx",
|
|
20
|
+
ossBucket: "",
|
|
21
|
+
ossRegion: "",
|
|
22
|
+
ossAccessKey: "",
|
|
23
|
+
ossSecretKey: ""
|
|
24
|
+
}), s = m({
|
|
25
|
+
enabled: !1,
|
|
26
|
+
content: "",
|
|
27
|
+
type: "info"
|
|
28
|
+
}), C = K.map((x) => ({
|
|
29
|
+
name: x.name,
|
|
30
|
+
value: x.value,
|
|
31
|
+
bgClass: x.colorClass
|
|
32
|
+
})), w = T(() => b.themeColor), A = (x) => {
|
|
33
|
+
b.setThemeColor(x);
|
|
34
|
+
}, S = () => {
|
|
35
|
+
b.openSettingsDrawer();
|
|
36
|
+
};
|
|
37
|
+
return (x, t) => (i(), n("div", z, [
|
|
38
|
+
t[52] || (t[52] = e("div", { class: "flex justify-between items-center mb-8" }, [
|
|
39
|
+
e("h2", { class: "text-2xl font-bold text-slate-800 dark:text-slate-200" }, "系统常规设置"),
|
|
40
|
+
e("button", { class: "bag-sys-primary-action px-6 py-2.5 text-white rounded-lg transition-all font-bold" }, " 保存配置 ")
|
|
41
|
+
], -1)),
|
|
42
|
+
e("div", $, [
|
|
43
|
+
e("div", E, [
|
|
44
|
+
e("button", {
|
|
45
|
+
onClick: t[0] || (t[0] = (r) => d.value = "base"),
|
|
46
|
+
class: o([
|
|
47
|
+
"w-full text-left px-4 py-3 rounded-xl font-bold transition-colors",
|
|
48
|
+
d.value === "base" ? "bg-primary-500/10 text-primary-600 dark:text-primary-400" : "text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-gray-800"
|
|
49
|
+
])
|
|
50
|
+
}, " 基础配置 ", 2),
|
|
51
|
+
e("button", {
|
|
52
|
+
onClick: t[1] || (t[1] = (r) => d.value = "seo"),
|
|
53
|
+
class: o([
|
|
54
|
+
"w-full text-left px-4 py-3 rounded-xl font-medium transition-colors",
|
|
55
|
+
d.value === "seo" ? "bg-primary-500/10 text-primary-600 dark:text-primary-400" : "text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-gray-800"
|
|
56
|
+
])
|
|
57
|
+
}, " SEO 设置 ", 2),
|
|
58
|
+
e("button", {
|
|
59
|
+
onClick: t[2] || (t[2] = (r) => d.value = "upload"),
|
|
60
|
+
class: o([
|
|
61
|
+
"w-full text-left px-4 py-3 rounded-xl font-medium transition-colors",
|
|
62
|
+
d.value === "upload" ? "bg-primary-500/10 text-primary-600 dark:text-primary-400" : "text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-gray-800"
|
|
63
|
+
])
|
|
64
|
+
}, " 文件上传 ", 2),
|
|
65
|
+
e("button", {
|
|
66
|
+
onClick: t[3] || (t[3] = (r) => d.value = "notice"),
|
|
67
|
+
class: o([
|
|
68
|
+
"w-full text-left px-4 py-3 rounded-xl font-medium transition-colors",
|
|
69
|
+
d.value === "notice" ? "bg-primary-500/10 text-primary-600 dark:text-primary-400" : "text-slate-600 dark:text-slate-400 hover:bg-slate-50 dark:hover:bg-gray-800"
|
|
70
|
+
])
|
|
71
|
+
}, " 通知公告 ", 2)
|
|
72
|
+
]),
|
|
73
|
+
e("div", F, [
|
|
74
|
+
d.value === "base" ? (i(), n("div", L, [
|
|
75
|
+
t[24] || (t[24] = e("h3", { class: "text-lg font-bold flex items-center gap-2 text-slate-800 dark:text-slate-200 mb-6" }, [
|
|
76
|
+
e("div", { class: "w-1 h-4 bg-primary-500 rounded-full" }),
|
|
77
|
+
f(" 基础参数配置 ")
|
|
78
|
+
], -1)),
|
|
79
|
+
e("div", M, [
|
|
80
|
+
t[22] || (t[22] = h('<div class="flex flex-col sm:flex-row items-start gap-8" data-v-b3e0f555><div class="flex items-start gap-6" data-v-b3e0f555><div class="space-y-1 w-24 pt-2" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> 系统 Logo </label></div><div data-v-b3e0f555><div class="w-24 h-24 rounded-xl bg-white dark:bg-[#0A1120] border border-gray-200 dark:border-gray-700 flex items-center justify-center shadow-sm relative group cursor-pointer overflow-hidden" data-v-b3e0f555><img src="https://api.dicebear.com/7.x/shapes/svg?seed=sys&backgroundColor=ffedd5" class="w-full h-full object-cover" data-v-b3e0f555><div class="absolute inset-0 bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity" data-v-b3e0f555><span class="text-white text-xs font-bold" data-v-b3e0f555>更换</span></div></div></div></div><div class="flex items-start gap-6" data-v-b3e0f555><div class="space-y-1 w-24 pt-2" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> Favicon </label></div><div data-v-b3e0f555><div class="w-12 h-12 rounded-lg bg-white dark:bg-[#0A1120] border border-gray-200 dark:border-gray-700 flex items-center justify-center shadow-sm relative group cursor-pointer overflow-hidden" data-v-b3e0f555><span class="text-xl font-black text-primary-500" data-v-b3e0f555>B</span><div class="absolute inset-0 bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity" data-v-b3e0f555><svg class="w-4 h-4 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-b3e0f555><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" data-v-b3e0f555></path></svg></div></div></div></div></div><hr class="border-gray-200 dark:border-gray-700/50" data-v-b3e0f555><div class="flex items-start gap-6" data-v-b3e0f555><div class="space-y-1 w-24 pt-2" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> 网站名称 </label></div><div class="flex-1" data-v-b3e0f555><input type="text" value="Vue-Bag-Admin 中后台系统" class="w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200" data-v-b3e0f555></div></div><hr class="border-gray-200 dark:border-gray-700/50" data-v-b3e0f555><div class="flex items-start gap-6" data-v-b3e0f555><div class="space-y-1 w-24 pt-2" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> 版权信息 </label></div><div class="flex-1" data-v-b3e0f555><input type="text" value="Copyright © 2024 Vue Bag Admin All rights reserved." class="w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200" data-v-b3e0f555></div></div><hr class="border-gray-200 dark:border-gray-700/50" data-v-b3e0f555><div class="flex items-start gap-6" data-v-b3e0f555><div class="space-y-1 w-24 pt-2" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> 备案号 </label></div><div class="flex-1" data-v-b3e0f555><input type="text" placeholder="如:京ICP备00000000号-1" value="浙ICP备2023012345号" class="w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200" data-v-b3e0f555></div></div><hr class="border-gray-200 dark:border-gray-700/50" data-v-b3e0f555>', 8)),
|
|
81
|
+
e("div", N, [
|
|
82
|
+
t[21] || (t[21] = e("div", { class: "space-y-1 w-24" }, [
|
|
83
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 主题颜色 ")
|
|
84
|
+
], -1)),
|
|
85
|
+
e("div", O, [
|
|
86
|
+
(i(!0), n(k, null, j(U(C), (r) => (i(), n("button", {
|
|
87
|
+
key: r.value,
|
|
88
|
+
onClick: (je) => A(r.value),
|
|
89
|
+
class: o(["w-8 h-8 rounded-full border-2 transition-all flex items-center justify-center shadow-sm hover:scale-110", [
|
|
90
|
+
r.bgClass,
|
|
91
|
+
w.value === r.value ? "border-gray-800 dark:border-white" : "border-transparent"
|
|
92
|
+
]]),
|
|
93
|
+
title: r.name
|
|
94
|
+
}, [
|
|
95
|
+
w.value === r.value ? (i(), n("svg", D, [...t[20] || (t[20] = [
|
|
96
|
+
e("path", {
|
|
97
|
+
"stroke-linecap": "round",
|
|
98
|
+
"stroke-linejoin": "round",
|
|
99
|
+
"stroke-width": "2",
|
|
100
|
+
d: "M5 13l4 4L19 7"
|
|
101
|
+
}, null, -1)
|
|
102
|
+
])])) : y("", !0)
|
|
103
|
+
], 10, R))), 128))
|
|
104
|
+
]),
|
|
105
|
+
e("button", {
|
|
106
|
+
type: "button",
|
|
107
|
+
class: "px-3 py-2 text-sm rounded-lg border border-gray-200 dark:border-gray-700 text-slate-600 dark:text-slate-300 hover:border-primary-500 hover:text-primary-500 transition-colors",
|
|
108
|
+
onClick: S
|
|
109
|
+
}, " 打开配置中心 ")
|
|
110
|
+
]),
|
|
111
|
+
t[23] || (t[23] = h('<hr class="border-gray-200 dark:border-gray-700/50" data-v-b3e0f555><div class="flex items-center gap-6" data-v-b3e0f555><div class="space-y-1 w-24" data-v-b3e0f555><label class="block text-sm font-medium text-slate-700 dark:text-slate-300" data-v-b3e0f555> 系统状态 </label></div><div class="flex-1 flex gap-4" data-v-b3e0f555><label class="flex items-center gap-2 cursor-pointer group" data-v-b3e0f555><div class="w-4 h-4 rounded-full border-2 border-primary-500 flex items-center justify-center" data-v-b3e0f555><div class="w-2 h-2 rounded-full bg-primary-500" data-v-b3e0f555></div></div><span class="text-sm font-bold text-slate-700 dark:text-slate-200 group-hover:text-primary-500 transition-colors" data-v-b3e0f555> 正常运行 </span></label><label class="flex items-center gap-2 cursor-pointer group" data-v-b3e0f555><div class="w-4 h-4 rounded-full border-2 border-gray-300 dark:border-gray-600 flex items-center justify-center" data-v-b3e0f555></div><span class="text-sm font-medium text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300 transition-colors" data-v-b3e0f555> 维护中 </span></label></div></div>', 2))
|
|
112
|
+
])
|
|
113
|
+
])) : d.value === "seo" ? (i(), n("div", I, [
|
|
114
|
+
t[33] || (t[33] = e("h3", { class: "text-lg font-bold flex items-center gap-2 text-slate-800 dark:text-slate-200 mb-6" }, [
|
|
115
|
+
e("div", { class: "w-1 h-4 bg-primary-500 rounded-full" }),
|
|
116
|
+
f(" SEO 优化设置 ")
|
|
117
|
+
], -1)),
|
|
118
|
+
e("div", _, [
|
|
119
|
+
e("div", P, [
|
|
120
|
+
t[26] || (t[26] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
121
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 网页标题 (Title) ")
|
|
122
|
+
], -1)),
|
|
123
|
+
e("div", H, [
|
|
124
|
+
l(e("input", {
|
|
125
|
+
type: "text",
|
|
126
|
+
"onUpdate:modelValue": t[4] || (t[4] = (r) => p.value.title = r),
|
|
127
|
+
placeholder: "如:Vue Bag Admin - 现代化的中后台管理系统",
|
|
128
|
+
class: "w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
129
|
+
}, null, 512), [
|
|
130
|
+
[u, p.value.title]
|
|
131
|
+
]),
|
|
132
|
+
t[25] || (t[25] = e("p", { class: "text-xs text-slate-500 mt-2" }, " 一般不超过80个字符,用于显示在浏览器标签页及搜索引擎结果中。 ", -1))
|
|
133
|
+
])
|
|
134
|
+
]),
|
|
135
|
+
t[31] || (t[31] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
136
|
+
e("div", q, [
|
|
137
|
+
t[28] || (t[28] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
138
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 关键词 (Keywords) ")
|
|
139
|
+
], -1)),
|
|
140
|
+
e("div", G, [
|
|
141
|
+
l(e("input", {
|
|
142
|
+
type: "text",
|
|
143
|
+
"onUpdate:modelValue": t[5] || (t[5] = (r) => p.value.keywords = r),
|
|
144
|
+
placeholder: "多个关键词用英文逗号分隔",
|
|
145
|
+
class: "w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
146
|
+
}, null, 512), [
|
|
147
|
+
[u, p.value.keywords]
|
|
148
|
+
]),
|
|
149
|
+
t[27] || (t[27] = e("p", { class: "text-xs text-slate-500 mt-2" }, " 一般不超过100个字符,用于告诉搜索引擎网页的核心内容。 ", -1))
|
|
150
|
+
])
|
|
151
|
+
]),
|
|
152
|
+
t[32] || (t[32] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
153
|
+
e("div", J, [
|
|
154
|
+
t[30] || (t[30] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
155
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 描述 (Description) ")
|
|
156
|
+
], -1)),
|
|
157
|
+
e("div", Q, [
|
|
158
|
+
l(e("textarea", {
|
|
159
|
+
"onUpdate:modelValue": t[6] || (t[6] = (r) => p.value.description = r),
|
|
160
|
+
rows: "4",
|
|
161
|
+
placeholder: "网页的简要描述...",
|
|
162
|
+
class: "w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
163
|
+
}, null, 512), [
|
|
164
|
+
[u, p.value.description]
|
|
165
|
+
]),
|
|
166
|
+
t[29] || (t[29] = e("p", { class: "text-xs text-slate-500 mt-2" }, " 一般不超过200个字符,用于在搜索引擎结果中展示网页的摘要。 ", -1))
|
|
167
|
+
])
|
|
168
|
+
])
|
|
169
|
+
])
|
|
170
|
+
])) : d.value === "upload" ? (i(), n("div", W, [
|
|
171
|
+
t[44] || (t[44] = e("h3", { class: "text-lg font-bold flex items-center gap-2 text-slate-800 dark:text-slate-200 mb-6" }, [
|
|
172
|
+
e("div", { class: "w-1 h-4 bg-primary-500 rounded-full" }),
|
|
173
|
+
f(" 文件上传设置 ")
|
|
174
|
+
], -1)),
|
|
175
|
+
e("div", X, [
|
|
176
|
+
e("div", Y, [
|
|
177
|
+
t[34] || (t[34] = e("div", { class: "space-y-1 w-24" }, [
|
|
178
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 存储方式 ")
|
|
179
|
+
], -1)),
|
|
180
|
+
e("div", Z, [
|
|
181
|
+
e("label", ee, [
|
|
182
|
+
e("div", {
|
|
183
|
+
class: o([
|
|
184
|
+
"w-4 h-4 rounded-full border-2 transition-colors flex items-center justify-center",
|
|
185
|
+
a.value.storageType === "local" ? "border-primary-500" : "border-gray-300 dark:border-gray-600"
|
|
186
|
+
])
|
|
187
|
+
}, [
|
|
188
|
+
l(e("div", te, null, 512), [
|
|
189
|
+
[v, a.value.storageType === "local"]
|
|
190
|
+
])
|
|
191
|
+
], 2),
|
|
192
|
+
l(e("input", {
|
|
193
|
+
type: "radio",
|
|
194
|
+
"onUpdate:modelValue": t[7] || (t[7] = (r) => a.value.storageType = r),
|
|
195
|
+
value: "local",
|
|
196
|
+
class: "hidden"
|
|
197
|
+
}, null, 512), [
|
|
198
|
+
[g, a.value.storageType]
|
|
199
|
+
]),
|
|
200
|
+
e("span", {
|
|
201
|
+
class: o([
|
|
202
|
+
"text-sm font-medium transition-colors",
|
|
203
|
+
a.value.storageType === "local" ? "text-slate-800 dark:text-slate-200" : "text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300"
|
|
204
|
+
])
|
|
205
|
+
}, " 本地存储 ", 2)
|
|
206
|
+
]),
|
|
207
|
+
e("label", re, [
|
|
208
|
+
e("div", {
|
|
209
|
+
class: o([
|
|
210
|
+
"w-4 h-4 rounded-full border-2 transition-colors flex items-center justify-center",
|
|
211
|
+
a.value.storageType === "oss" ? "border-primary-500" : "border-gray-300 dark:border-gray-600"
|
|
212
|
+
])
|
|
213
|
+
}, [
|
|
214
|
+
l(e("div", ae, null, 512), [
|
|
215
|
+
[v, a.value.storageType === "oss"]
|
|
216
|
+
])
|
|
217
|
+
], 2),
|
|
218
|
+
l(e("input", {
|
|
219
|
+
type: "radio",
|
|
220
|
+
"onUpdate:modelValue": t[8] || (t[8] = (r) => a.value.storageType = r),
|
|
221
|
+
value: "oss",
|
|
222
|
+
class: "hidden"
|
|
223
|
+
}, null, 512), [
|
|
224
|
+
[g, a.value.storageType]
|
|
225
|
+
]),
|
|
226
|
+
e("span", {
|
|
227
|
+
class: o([
|
|
228
|
+
"text-sm font-medium transition-colors",
|
|
229
|
+
a.value.storageType === "oss" ? "text-slate-800 dark:text-slate-200" : "text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300"
|
|
230
|
+
])
|
|
231
|
+
}, " 阿里云 OSS ", 2)
|
|
232
|
+
])
|
|
233
|
+
])
|
|
234
|
+
]),
|
|
235
|
+
t[42] || (t[42] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
236
|
+
e("div", se, [
|
|
237
|
+
t[37] || (t[37] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
238
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 文件大小限制 ")
|
|
239
|
+
], -1)),
|
|
240
|
+
e("div", le, [
|
|
241
|
+
e("div", oe, [
|
|
242
|
+
l(e("input", {
|
|
243
|
+
type: "number",
|
|
244
|
+
"onUpdate:modelValue": t[9] || (t[9] = (r) => a.value.maxSize = r),
|
|
245
|
+
min: "1",
|
|
246
|
+
class: "w-32 px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
247
|
+
}, null, 512), [
|
|
248
|
+
[u, a.value.maxSize]
|
|
249
|
+
]),
|
|
250
|
+
t[35] || (t[35] = e("span", { class: "text-sm text-slate-600 dark:text-slate-400" }, "MB", -1))
|
|
251
|
+
]),
|
|
252
|
+
t[36] || (t[36] = e("p", { class: "text-xs text-slate-500 mt-2" }, "设置单个文件的最大上传限制。", -1))
|
|
253
|
+
])
|
|
254
|
+
]),
|
|
255
|
+
t[43] || (t[43] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
256
|
+
e("div", de, [
|
|
257
|
+
t[39] || (t[39] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
258
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 允许的文件类型 ")
|
|
259
|
+
], -1)),
|
|
260
|
+
e("div", ie, [
|
|
261
|
+
l(e("input", {
|
|
262
|
+
type: "text",
|
|
263
|
+
"onUpdate:modelValue": t[10] || (t[10] = (r) => a.value.allowedTypes = r),
|
|
264
|
+
placeholder: "如:jpg,png,gif,zip,pdf",
|
|
265
|
+
class: "w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
266
|
+
}, null, 512), [
|
|
267
|
+
[u, a.value.allowedTypes]
|
|
268
|
+
]),
|
|
269
|
+
t[38] || (t[38] = e("p", { class: "text-xs text-slate-500 mt-2" }, "多个后缀名用英文逗号分隔。", -1))
|
|
270
|
+
])
|
|
271
|
+
]),
|
|
272
|
+
a.value.storageType === "oss" ? (i(), n(k, { key: 0 }, [
|
|
273
|
+
t[41] || (t[41] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
274
|
+
e("div", ne, [
|
|
275
|
+
t[40] || (t[40] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
276
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " OSS 配置 ")
|
|
277
|
+
], -1)),
|
|
278
|
+
e("div", ue, [
|
|
279
|
+
e("div", null, [
|
|
280
|
+
l(e("input", {
|
|
281
|
+
type: "text",
|
|
282
|
+
"onUpdate:modelValue": t[11] || (t[11] = (r) => a.value.ossBucket = r),
|
|
283
|
+
placeholder: "Bucket Name",
|
|
284
|
+
class: "w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
285
|
+
}, null, 512), [
|
|
286
|
+
[u, a.value.ossBucket]
|
|
287
|
+
])
|
|
288
|
+
]),
|
|
289
|
+
e("div", null, [
|
|
290
|
+
l(e("input", {
|
|
291
|
+
type: "text",
|
|
292
|
+
"onUpdate:modelValue": t[12] || (t[12] = (r) => a.value.ossRegion = r),
|
|
293
|
+
placeholder: "Endpoint / Region",
|
|
294
|
+
class: "w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
295
|
+
}, null, 512), [
|
|
296
|
+
[u, a.value.ossRegion]
|
|
297
|
+
])
|
|
298
|
+
]),
|
|
299
|
+
e("div", pe, [
|
|
300
|
+
l(e("input", {
|
|
301
|
+
type: "password",
|
|
302
|
+
"onUpdate:modelValue": t[13] || (t[13] = (r) => a.value.ossAccessKey = r),
|
|
303
|
+
placeholder: "AccessKey ID",
|
|
304
|
+
class: "w-1/2 px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
305
|
+
}, null, 512), [
|
|
306
|
+
[u, a.value.ossAccessKey]
|
|
307
|
+
]),
|
|
308
|
+
l(e("input", {
|
|
309
|
+
type: "password",
|
|
310
|
+
"onUpdate:modelValue": t[14] || (t[14] = (r) => a.value.ossSecretKey = r),
|
|
311
|
+
placeholder: "AccessKey Secret",
|
|
312
|
+
class: "w-1/2 px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
313
|
+
}, null, 512), [
|
|
314
|
+
[u, a.value.ossSecretKey]
|
|
315
|
+
])
|
|
316
|
+
])
|
|
317
|
+
])
|
|
318
|
+
])
|
|
319
|
+
], 64)) : y("", !0)
|
|
320
|
+
])
|
|
321
|
+
])) : d.value === "notice" ? (i(), n("div", be, [
|
|
322
|
+
t[51] || (t[51] = e("h3", { class: "text-lg font-bold flex items-center gap-2 text-slate-800 dark:text-slate-200 mb-6" }, [
|
|
323
|
+
e("div", { class: "w-1 h-4 bg-primary-500 rounded-full" }),
|
|
324
|
+
f(" 通知公告设置 ")
|
|
325
|
+
], -1)),
|
|
326
|
+
e("div", xe, [
|
|
327
|
+
e("div", ve, [
|
|
328
|
+
t[46] || (t[46] = e("div", { class: "space-y-1 w-24" }, [
|
|
329
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 系统公告开关 ")
|
|
330
|
+
], -1)),
|
|
331
|
+
e("div", ge, [
|
|
332
|
+
e("div", {
|
|
333
|
+
class: o(["relative inline-flex h-6 w-11 items-center rounded-full transition-colors cursor-pointer", s.value.enabled ? "bg-primary-500" : "bg-gray-300 dark:bg-gray-600"]),
|
|
334
|
+
onClick: t[15] || (t[15] = (r) => s.value.enabled = !s.value.enabled)
|
|
335
|
+
}, [
|
|
336
|
+
e("span", {
|
|
337
|
+
class: o(["inline-block h-4 w-4 transform rounded-full bg-white transition-transform", s.value.enabled ? "translate-x-6" : "translate-x-1"])
|
|
338
|
+
}, null, 2)
|
|
339
|
+
], 2),
|
|
340
|
+
t[45] || (t[45] = e("p", { class: "text-xs text-slate-500 mt-2" }, "开启后,系统顶部将显示公告内容。", -1))
|
|
341
|
+
])
|
|
342
|
+
]),
|
|
343
|
+
s.value.enabled ? (i(), n(k, { key: 0 }, [
|
|
344
|
+
t[49] || (t[49] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
345
|
+
e("div", me, [
|
|
346
|
+
t[47] || (t[47] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
347
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 公告内容 ")
|
|
348
|
+
], -1)),
|
|
349
|
+
e("div", fe, [
|
|
350
|
+
l(e("textarea", {
|
|
351
|
+
"onUpdate:modelValue": t[16] || (t[16] = (r) => s.value.content = r),
|
|
352
|
+
rows: "3",
|
|
353
|
+
placeholder: "请输入公告内容...",
|
|
354
|
+
class: "w-full max-w-md px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-primary-500/20 focus:border-primary-500 outline-none transition-all dark:text-slate-200"
|
|
355
|
+
}, null, 512), [
|
|
356
|
+
[u, s.value.content]
|
|
357
|
+
])
|
|
358
|
+
])
|
|
359
|
+
]),
|
|
360
|
+
t[50] || (t[50] = e("hr", { class: "border-gray-200 dark:border-gray-700/50" }, null, -1)),
|
|
361
|
+
e("div", ye, [
|
|
362
|
+
t[48] || (t[48] = e("div", { class: "space-y-1 w-24 pt-2" }, [
|
|
363
|
+
e("label", { class: "block text-sm font-medium text-slate-700 dark:text-slate-300" }, " 展示样式 ")
|
|
364
|
+
], -1)),
|
|
365
|
+
e("div", ce, [
|
|
366
|
+
e("label", ke, [
|
|
367
|
+
e("div", {
|
|
368
|
+
class: o([
|
|
369
|
+
"w-4 h-4 rounded-full border-2 transition-colors flex items-center justify-center",
|
|
370
|
+
s.value.type === "info" ? "border-primary-500" : "border-gray-300 dark:border-gray-600"
|
|
371
|
+
])
|
|
372
|
+
}, [
|
|
373
|
+
l(e("div", we, null, 512), [
|
|
374
|
+
[v, s.value.type === "info"]
|
|
375
|
+
])
|
|
376
|
+
], 2),
|
|
377
|
+
l(e("input", {
|
|
378
|
+
type: "radio",
|
|
379
|
+
"onUpdate:modelValue": t[17] || (t[17] = (r) => s.value.type = r),
|
|
380
|
+
value: "info",
|
|
381
|
+
class: "hidden"
|
|
382
|
+
}, null, 512), [
|
|
383
|
+
[g, s.value.type]
|
|
384
|
+
]),
|
|
385
|
+
e("span", {
|
|
386
|
+
class: o([
|
|
387
|
+
"text-sm font-medium transition-colors",
|
|
388
|
+
s.value.type === "info" ? "text-slate-800 dark:text-slate-200" : "text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300"
|
|
389
|
+
])
|
|
390
|
+
}, " 普通信息 (蓝) ", 2)
|
|
391
|
+
]),
|
|
392
|
+
e("label", he, [
|
|
393
|
+
e("div", {
|
|
394
|
+
class: o([
|
|
395
|
+
"w-4 h-4 rounded-full border-2 transition-colors flex items-center justify-center",
|
|
396
|
+
s.value.type === "warning" ? "border-primary-500" : "border-gray-300 dark:border-gray-600"
|
|
397
|
+
])
|
|
398
|
+
}, [
|
|
399
|
+
l(e("div", Ce, null, 512), [
|
|
400
|
+
[v, s.value.type === "warning"]
|
|
401
|
+
])
|
|
402
|
+
], 2),
|
|
403
|
+
l(e("input", {
|
|
404
|
+
type: "radio",
|
|
405
|
+
"onUpdate:modelValue": t[18] || (t[18] = (r) => s.value.type = r),
|
|
406
|
+
value: "warning",
|
|
407
|
+
class: "hidden"
|
|
408
|
+
}, null, 512), [
|
|
409
|
+
[g, s.value.type]
|
|
410
|
+
]),
|
|
411
|
+
e("span", {
|
|
412
|
+
class: o([
|
|
413
|
+
"text-sm font-medium transition-colors",
|
|
414
|
+
s.value.type === "warning" ? "text-slate-800 dark:text-slate-200" : "text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300"
|
|
415
|
+
])
|
|
416
|
+
}, " 警告预警 (黄) ", 2)
|
|
417
|
+
]),
|
|
418
|
+
e("label", Ae, [
|
|
419
|
+
e("div", {
|
|
420
|
+
class: o([
|
|
421
|
+
"w-4 h-4 rounded-full border-2 transition-colors flex items-center justify-center",
|
|
422
|
+
s.value.type === "error" ? "border-primary-500" : "border-gray-300 dark:border-gray-600"
|
|
423
|
+
])
|
|
424
|
+
}, [
|
|
425
|
+
l(e("div", Se, null, 512), [
|
|
426
|
+
[v, s.value.type === "error"]
|
|
427
|
+
])
|
|
428
|
+
], 2),
|
|
429
|
+
l(e("input", {
|
|
430
|
+
type: "radio",
|
|
431
|
+
"onUpdate:modelValue": t[19] || (t[19] = (r) => s.value.type = r),
|
|
432
|
+
value: "error",
|
|
433
|
+
class: "hidden"
|
|
434
|
+
}, null, 512), [
|
|
435
|
+
[g, s.value.type]
|
|
436
|
+
]),
|
|
437
|
+
e("span", {
|
|
438
|
+
class: o([
|
|
439
|
+
"text-sm font-medium transition-colors",
|
|
440
|
+
s.value.type === "error" ? "text-slate-800 dark:text-slate-200" : "text-slate-500 group-hover:text-slate-800 dark:group-hover:text-slate-300"
|
|
441
|
+
])
|
|
442
|
+
}, " 重要通知 (红) ", 2)
|
|
443
|
+
])
|
|
444
|
+
])
|
|
445
|
+
])
|
|
446
|
+
], 64)) : y("", !0)
|
|
447
|
+
])
|
|
448
|
+
])) : y("", !0)
|
|
449
|
+
])
|
|
450
|
+
])
|
|
451
|
+
]));
|
|
452
|
+
}
|
|
453
|
+
}), Te = (c, d) => {
|
|
454
|
+
const b = c.__vccOpts || c;
|
|
455
|
+
for (const [p, a] of d)
|
|
456
|
+
b[p] = a;
|
|
457
|
+
return b;
|
|
458
|
+
}, Ke = Te(Ve, [["__scopeId", "data-v-b3e0f555"]]);
|
|
459
|
+
export {
|
|
460
|
+
Ke as default
|
|
461
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { defineComponent as b, openBlock as g, createElementBlock as c, createStaticVNode as l, createElementVNode as e, createTextVNode as u, normalizeClass as s, unref as d } from "vue";
|
|
2
|
+
import { useLocalStorage as o } from "@vueuse/core";
|
|
3
|
+
const v = { class: "p-6 bg-white dark:bg-[#0A1120] rounded-2xl shadow-sm min-h-[calc(100vh-120px)] border border-gray-100 dark:border-gray-800 max-w-5xl mx-auto" }, x = { class: "space-y-8" }, f = { class: "border border-gray-100 dark:border-gray-800 rounded-xl overflow-hidden bg-white dark:bg-[#0A1120]" }, p = { class: "p-6 space-y-6" }, y = { class: "space-y-4" }, m = { class: "flex justify-between items-center" }, k = { class: "flex justify-between items-center" }, T = b({
|
|
4
|
+
__name: "SysSettingAdvanced",
|
|
5
|
+
setup(h) {
|
|
6
|
+
const r = o("bag.admin.enableTabCache", !0), a = o("bag.admin.enableTabPersist", !0), i = () => {
|
|
7
|
+
r.value = !r.value;
|
|
8
|
+
}, n = () => {
|
|
9
|
+
a.value = !a.value;
|
|
10
|
+
};
|
|
11
|
+
return (w, t) => (g(), c("div", v, [
|
|
12
|
+
t[4] || (t[4] = l('<div class="flex justify-between items-center mb-8"><h2 class="text-2xl font-bold text-slate-800 dark:text-slate-200">高级设置</h2><button class="px-6 py-2.5 bg-gradient-to-r from-orange-500 to-rose-500 text-white rounded-lg hover:shadow-lg hover:shadow-orange-500/30 transition-all font-bold"> 保存配置 </button></div><div class="mb-8 p-4 bg-rose-50 dark:bg-rose-500/10 border border-rose-200 dark:border-rose-500/20 rounded-xl flex gap-3 items-start"><svg class="w-5 h-5 text-rose-500 shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg><div><h4 class="font-bold text-rose-600 dark:text-rose-400">高危操作提醒</h4><p class="text-sm text-rose-500/80 dark:text-rose-400/80 mt-1">此页面的配置项可能会直接影响系统的正常运行,请在修改前确保您了解这些配置的具体作用。</p></div></div>', 2)),
|
|
13
|
+
e("div", x, [
|
|
14
|
+
t[3] || (t[3] = l('<div class="border border-gray-100 dark:border-gray-800 rounded-xl overflow-hidden bg-white dark:bg-[#0A1120]"><div class="px-6 py-4 border-b border-gray-100 dark:border-gray-800 bg-slate-50/50 dark:bg-gray-800/30 font-bold text-slate-800 dark:text-slate-200 flex items-center gap-2"><div class="w-1 h-4 bg-blue-500 rounded-full"></div>存储与缓存 </div><div class="p-6 space-y-6"><div class="flex flex-col md:flex-row gap-6"><div class="flex-1 space-y-2"><label class="block text-sm font-medium text-slate-700 dark:text-slate-300">Redis 缓存前缀</label><input type="text" value="bag_admin:" class="w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all dark:text-slate-200"></div><div class="flex-1 space-y-2"><label class="block text-sm font-medium text-slate-700 dark:text-slate-300">数据库自动备份周期</label><select class="w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all dark:text-slate-200"><option value="daily">每天凌晨 02:00</option><option value="weekly">每周日凌晨 03:00</option><option value="monthly">每月 1 号凌晨 04:00</option></select></div></div><div class="flex items-center justify-between p-4 bg-slate-50 dark:bg-gray-800/30 rounded-lg border border-gray-100 dark:border-gray-800"><div><div class="font-bold text-slate-800 dark:text-slate-200">清理系统缓存</div><div class="text-xs text-slate-500 mt-1">清理包括字典数据、系统配置、权限规则在内的所有 Redis 缓存</div></div><button class="px-4 py-2 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 text-slate-700 dark:text-slate-200 rounded-lg hover:text-rose-500 hover:border-rose-500 transition-colors font-medium text-sm">立即清理</button></div></div></div><div class="border border-gray-100 dark:border-gray-800 rounded-xl overflow-hidden bg-white dark:bg-[#0A1120]"><div class="px-6 py-4 border-b border-gray-100 dark:border-gray-800 bg-slate-50/50 dark:bg-gray-800/30 font-bold text-slate-800 dark:text-slate-200 flex items-center gap-2"><div class="w-1 h-4 bg-emerald-500 rounded-full"></div>安全策略 </div><div class="p-6 space-y-6"><div class="flex flex-col md:flex-row gap-6"><div class="flex-1 space-y-2"><label class="block text-sm font-medium text-slate-700 dark:text-slate-300">登录失败锁定次数</label><input type="number" value="5" class="w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all dark:text-slate-200"></div><div class="flex-1 space-y-2"><label class="block text-sm font-medium text-slate-700 dark:text-slate-300">登录失败锁定时长 (分钟)</label><input type="number" value="30" class="w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all dark:text-slate-200"></div><div class="flex-1 space-y-2"><label class="block text-sm font-medium text-slate-700 dark:text-slate-300">Token 有效期 (小时)</label><input type="number" value="24" class="w-full px-4 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-[#0A1120] focus:ring-2 focus:ring-orange-500/20 focus:border-orange-500 outline-none transition-all dark:text-slate-200"></div></div><hr class="border-gray-100 dark:border-gray-800"><div class="space-y-4"><div class="flex justify-between items-center"><div><div class="font-bold text-slate-800 dark:text-slate-200 text-sm">单设备登录限制</div><div class="text-xs text-slate-500 mt-1">开启后,同一账号在同一时间只能在一台设备上登录</div></div><div class="w-12 h-6 bg-orange-500 rounded-full relative cursor-pointer shadow-inner"><div class="absolute right-1 top-1 w-4 h-4 bg-white rounded-full shadow-sm"></div></div></div><div class="flex justify-between items-center"><div><div class="font-bold text-slate-800 dark:text-slate-200 text-sm">强制验证码登录</div><div class="text-xs text-slate-500 mt-1">开启后,所有用户登录必须输入图形验证码</div></div><div class="w-12 h-6 bg-gray-200 dark:bg-gray-700 rounded-full relative cursor-pointer shadow-inner transition-colors"><div class="absolute left-1 top-1 w-4 h-4 bg-white rounded-full shadow-sm"></div></div></div></div></div></div>', 2)),
|
|
15
|
+
e("div", f, [
|
|
16
|
+
t[2] || (t[2] = e("div", { class: "px-6 py-4 border-b border-gray-100 dark:border-gray-800 bg-slate-50/50 dark:bg-gray-800/30 font-bold text-slate-800 dark:text-slate-200 flex items-center gap-2" }, [
|
|
17
|
+
e("div", { class: "w-1 h-4 bg-purple-500 rounded-full" }),
|
|
18
|
+
u("界面与交互设置 ")
|
|
19
|
+
], -1)),
|
|
20
|
+
e("div", p, [
|
|
21
|
+
e("div", y, [
|
|
22
|
+
e("div", m, [
|
|
23
|
+
t[0] || (t[0] = e("div", null, [
|
|
24
|
+
e("div", { class: "font-bold text-slate-800 dark:text-slate-200 text-sm" }, "TabBar 页面缓存 (KeepAlive)"),
|
|
25
|
+
e("div", { class: "text-xs text-slate-500 mt-1" }, "开启后,切换标签页时将缓存页面状态,避免重新加载")
|
|
26
|
+
], -1)),
|
|
27
|
+
e("div", {
|
|
28
|
+
class: s(["w-12 h-6 rounded-full relative cursor-pointer shadow-inner transition-colors", d(r) ? "bg-orange-500" : "bg-gray-200 dark:bg-gray-700"]),
|
|
29
|
+
onClick: i
|
|
30
|
+
}, [
|
|
31
|
+
e("div", {
|
|
32
|
+
class: s(["absolute top-1 w-4 h-4 bg-white rounded-full shadow-sm transition-all", d(r) ? "right-1" : "left-1"])
|
|
33
|
+
}, null, 2)
|
|
34
|
+
], 2)
|
|
35
|
+
]),
|
|
36
|
+
e("div", k, [
|
|
37
|
+
t[1] || (t[1] = e("div", null, [
|
|
38
|
+
e("div", { class: "font-bold text-slate-800 dark:text-slate-200 text-sm" }, "记住上一次打开的 TabBar"),
|
|
39
|
+
e("div", { class: "text-xs text-slate-500 mt-1" }, "刷新页面或重新打开浏览器时,恢复之前打开的标签页列表")
|
|
40
|
+
], -1)),
|
|
41
|
+
e("div", {
|
|
42
|
+
class: s(["w-12 h-6 rounded-full relative cursor-pointer shadow-inner transition-colors", d(a) ? "bg-orange-500" : "bg-gray-200 dark:bg-gray-700"]),
|
|
43
|
+
onClick: n
|
|
44
|
+
}, [
|
|
45
|
+
e("div", {
|
|
46
|
+
class: s(["absolute top-1 w-4 h-4 bg-white rounded-full shadow-sm transition-all", d(a) ? "right-1" : "left-1"])
|
|
47
|
+
}, null, 2)
|
|
48
|
+
], 2)
|
|
49
|
+
])
|
|
50
|
+
])
|
|
51
|
+
])
|
|
52
|
+
])
|
|
53
|
+
])
|
|
54
|
+
]));
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
export {
|
|
58
|
+
T as default
|
|
59
|
+
};
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { defineComponent as N, ref as h, computed as c, openBlock as l, createElementBlock as d, createElementVNode as t, createTextVNode as V, Fragment as f, renderList as k, toDisplayString as s, normalizeClass as b, createCommentVNode as u } from "vue";
|
|
2
|
+
import { useRouter as z } from "vue-router";
|
|
3
|
+
import { listRuntimePlugins as F, setPluginEnabledState as H } from "@melt-js/libs-bag-entry";
|
|
4
|
+
const G = { class: "mx-auto min-h-[calc(100vh-120px)] max-w-7xl space-y-6" }, q = { class: "relative overflow-hidden rounded-[32px] border border-orange-100/80 bg-[linear-gradient(135deg,#fff8f1_0%,#fff4fb_38%,#ffffff_100%)] p-6 shadow-[0_24px_80px_rgba(249,115,22,0.10)] dark:border-slate-800/80 dark:bg-[radial-gradient(circle_at_top_left,_rgba(251,146,60,0.16),_transparent_30%),radial-gradient(circle_at_top_right,_rgba(168,85,247,0.14),_transparent_28%),linear-gradient(135deg,_rgba(15,23,42,0.98),_rgba(10,17,32,0.96))] dark:shadow-none" }, J = { class: "relative rounded-[28px] border border-white/70 bg-white/80 p-5 shadow-[0_18px_45px_rgba(15,23,42,0.06)] backdrop-blur-xl dark:border-slate-800/80 dark:bg-white/[0.05] dark:shadow-none" }, K = { class: "flex flex-col gap-5 md:flex-row md:items-start md:justify-between" }, Q = { class: "max-w-3xl" }, U = { class: "mt-4 flex flex-wrap gap-2" }, W = { class: "w-full max-w-[320px] rounded-[24px] bg-slate-50/90 p-4 dark:bg-slate-900/70" }, X = { class: "flex items-center justify-between gap-4" }, Y = { class: "mt-1 text-sm text-slate-500 dark:text-slate-400" }, Z = { class: "mt-4 text-sm leading-6 text-slate-500 dark:text-slate-400" }, ee = {
|
|
5
|
+
key: 0,
|
|
6
|
+
class: "flex flex-col gap-4 rounded-[28px] border border-amber-200/80 bg-amber-50/90 p-5 shadow-[0_18px_45px_rgba(245,158,11,0.10)] dark:border-amber-400/20 dark:bg-amber-500/10 dark:shadow-none md:flex-row md:items-center md:justify-between"
|
|
7
|
+
}, te = { class: "rounded-[28px] border border-slate-200/70 bg-white/80 p-5 shadow-[0_18px_45px_rgba(15,23,42,0.05)] backdrop-blur-xl dark:border-slate-800/80 dark:bg-white/[0.04] dark:shadow-none" }, re = { class: "flex flex-col gap-4 md:flex-row md:items-center md:justify-between" }, ae = { class: "flex flex-wrap gap-2" }, se = ["onClick"], le = { class: "mt-5 grid gap-4 lg:grid-cols-2" }, de = { class: "relative flex h-full flex-col gap-5" }, ne = { class: "flex items-start justify-between gap-4" }, oe = { class: "flex min-w-0 items-start gap-4" }, ie = {
|
|
8
|
+
key: 0,
|
|
9
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
10
|
+
class: "h-6 w-6",
|
|
11
|
+
fill: "none",
|
|
12
|
+
viewBox: "0 0 24 24",
|
|
13
|
+
stroke: "currentColor"
|
|
14
|
+
}, be = {
|
|
15
|
+
key: 1,
|
|
16
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17
|
+
class: "h-6 w-6",
|
|
18
|
+
fill: "none",
|
|
19
|
+
viewBox: "0 0 24 24",
|
|
20
|
+
stroke: "currentColor"
|
|
21
|
+
}, ge = {
|
|
22
|
+
key: 2,
|
|
23
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
24
|
+
class: "h-6 w-6",
|
|
25
|
+
fill: "none",
|
|
26
|
+
viewBox: "0 0 24 24",
|
|
27
|
+
stroke: "currentColor"
|
|
28
|
+
}, xe = { class: "min-w-0" }, ce = { class: "flex flex-wrap items-center gap-2" }, ue = { class: "text-lg font-bold text-slate-900 dark:text-white" }, fe = { class: "mt-2 truncate text-xs font-medium tracking-[0.16em] text-slate-400 dark:text-slate-500" }, ke = { class: "mt-2 text-sm leading-6 text-slate-500 dark:text-slate-400" }, me = { class: "rounded-full bg-white/80 px-3 py-1 text-xs font-semibold text-slate-500 ring-1 ring-slate-200/70 dark:bg-white/[0.04] dark:text-slate-300 dark:ring-slate-800/80" }, he = { class: "grid grid-cols-3 gap-3" }, ve = { class: "rounded-[20px] bg-white/80 px-4 py-3 ring-1 ring-slate-200/70 dark:bg-white/[0.04] dark:ring-slate-800/80" }, pe = { class: "mt-2 text-lg font-black text-slate-900 dark:text-white" }, we = { class: "rounded-[20px] bg-white/80 px-4 py-3 ring-1 ring-slate-200/70 dark:bg-white/[0.04] dark:ring-slate-800/80" }, _e = { class: "mt-2 text-lg font-black text-slate-900 dark:text-white" }, ye = { class: "rounded-[20px] bg-white/80 px-4 py-3 ring-1 ring-slate-200/70 dark:bg-white/[0.04] dark:ring-slate-800/80" }, Ce = { class: "mt-2 text-lg font-black text-slate-900 dark:text-white" }, Pe = { class: "space-y-2" }, Be = { class: "flex flex-wrap gap-2" }, je = {
|
|
29
|
+
key: 0,
|
|
30
|
+
class: "rounded-full border border-dashed border-slate-200 px-3 py-1 text-xs text-slate-400 dark:border-slate-700"
|
|
31
|
+
}, Se = { class: "rounded-[22px] bg-slate-50/90 p-4 text-sm leading-6 text-slate-500 dark:bg-slate-900/70 dark:text-slate-400" }, Te = {
|
|
32
|
+
key: 0,
|
|
33
|
+
class: "mt-2 text-amber-700 dark:text-amber-300"
|
|
34
|
+
}, De = {
|
|
35
|
+
key: 1,
|
|
36
|
+
class: "mt-2 text-rose-600 dark:text-rose-300"
|
|
37
|
+
}, Le = { class: "mt-auto flex flex-col gap-3 sm:flex-row" }, Me = ["disabled", "onClick"], Re = ["onClick"], $e = {
|
|
38
|
+
key: 0,
|
|
39
|
+
class: "mt-5 rounded-[24px] border border-dashed border-slate-200 bg-slate-50/80 px-6 py-10 text-center text-sm text-slate-500 dark:border-slate-800/80 dark:bg-slate-900/40 dark:text-slate-400"
|
|
40
|
+
}, Ne = N({
|
|
41
|
+
__name: "SysSettingPlugins",
|
|
42
|
+
setup(Ee) {
|
|
43
|
+
const P = z(), v = h(0), g = h(!1), m = h("all"), n = c(() => (v.value, F())), B = c(
|
|
44
|
+
() => new Set(n.value.filter((e) => e.enabled).map((e) => e.id))
|
|
45
|
+
), j = ["启停状态先写入本地存储", "依赖冲突会被阻止", "刷新后才会重新注册路由和菜单"], S = c(
|
|
46
|
+
() => n.value.filter((e) => y(e))
|
|
47
|
+
), T = c(() => [
|
|
48
|
+
{
|
|
49
|
+
key: "all",
|
|
50
|
+
label: "全部插件",
|
|
51
|
+
count: n.value.length
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: "enabled",
|
|
55
|
+
label: "启用中",
|
|
56
|
+
count: n.value.filter((e) => e.enabled).length
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
key: "attention",
|
|
60
|
+
label: "需要关注",
|
|
61
|
+
count: S.value.length
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "disabled",
|
|
65
|
+
label: "已禁用",
|
|
66
|
+
count: n.value.filter((e) => !e.enabled).length
|
|
67
|
+
}
|
|
68
|
+
]), p = c(() => {
|
|
69
|
+
switch (m.value) {
|
|
70
|
+
case "enabled":
|
|
71
|
+
return n.value.filter((e) => e.enabled);
|
|
72
|
+
case "attention":
|
|
73
|
+
return n.value.filter((e) => y(e));
|
|
74
|
+
case "disabled":
|
|
75
|
+
return n.value.filter((e) => !e.enabled);
|
|
76
|
+
default:
|
|
77
|
+
return n.value;
|
|
78
|
+
}
|
|
79
|
+
}), w = () => {
|
|
80
|
+
v.value += 1;
|
|
81
|
+
}, _ = () => {
|
|
82
|
+
window.location.reload();
|
|
83
|
+
}, o = (e) => e.dependsOn.filter((r) => !B.value.has(r)), i = (e) => n.value.filter((r) => r.enabled && r.dependsOn.includes(e.id)).map((r) => r.name), y = (e) => !e.enabledByConfig || o(e).length > 0 || i(e).length > 0, C = (e) => !(!e.enabledByConfig || !e.enabled && o(e).length > 0 || e.enabled && i(e).length > 0), D = (e) => e.enabledByConfig ? o(e).length > 0 ? "缺少依赖" : e.enabled && i(e).length > 0 ? "被依赖中" : e.enabled ? "启用中" : "已禁用" : "代码锁定", L = (e) => e.enabledByConfig ? o(e).length > 0 ? "bg-amber-100 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" : e.enabled && i(e).length > 0 ? "bg-rose-100 text-rose-700 dark:bg-rose-500/10 dark:text-rose-300" : e.enabled ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-300" : "bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-300" : "bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-300", M = (e) => e.enabledByConfig ? o(e).length > 0 ? "border-amber-200/80 bg-[linear-gradient(180deg,rgba(255,251,235,0.94),rgba(255,255,255,0.92))] dark:border-amber-400/20 dark:bg-[linear-gradient(180deg,rgba(120,53,15,0.18),rgba(15,23,42,0.92))]" : e.enabled ? "border-emerald-200/70 bg-[linear-gradient(180deg,rgba(236,253,245,0.90),rgba(255,255,255,0.92))] dark:border-emerald-400/20 dark:bg-[linear-gradient(180deg,rgba(6,78,59,0.16),rgba(15,23,42,0.92))]" : "border-slate-200/80 bg-[linear-gradient(180deg,rgba(255,255,255,0.92),rgba(248,250,252,0.92))] dark:border-slate-800/80 dark:bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(15,23,42,0.88))]" : "border-slate-200/80 bg-[linear-gradient(180deg,rgba(255,255,255,0.92),rgba(248,250,252,0.92))] dark:border-slate-800/80 dark:bg-[linear-gradient(180deg,rgba(15,23,42,0.96),rgba(15,23,42,0.88))]", R = (e) => e.enabledByConfig ? o(e).length > 0 ? "bg-amber-200/50 dark:bg-amber-500/10" : e.enabled ? "bg-emerald-200/40 dark:bg-emerald-500/10" : "bg-slate-200/30 dark:bg-slate-500/10" : "bg-slate-200/30 dark:bg-slate-500/10", $ = (e) => e.enabledByConfig ? o(e).length > 0 ? "bg-[linear-gradient(135deg,#f59e0b,#f97316)] shadow-orange-500/20" : e.enabled ? "bg-[linear-gradient(135deg,#10b981,#14b8a6)] shadow-emerald-500/20" : "bg-[linear-gradient(135deg,#64748b,#334155)] shadow-slate-900/15" : "bg-[linear-gradient(135deg,#475569,#0f172a)] shadow-slate-900/15", E = (e) => e.enabledByConfig ? o(e).length > 0 ? "依赖链还没准备好,先补齐前置插件,再决定是否把它带回运行集合。" : e.enabled && i(e).length > 0 ? "它是其他插件正在使用的基础能力,禁用前需要先处理依赖方。" : e.enabled ? "插件已经进入当前运行集合,刷新后会继续承担对应的页面和菜单能力。" : "插件当前处于停用状态,适合在确认影响范围后再决定是否重新启用。" : "代码层面已锁定为默认关闭,当前页面只负责展示它的运行位置信息。", I = (e) => e.enabledByConfig ? !e.enabled && o(e).length > 0 ? "当前插件依赖的前置能力还未启用,先处理依赖关系再刷新应用会更安全。" : e.enabled && i(e).length > 0 ? "它正被其他启用中的插件依赖。为了避免刷新后引导失败,当前不允许直接禁用。" : e.enabled ? "插件目前已经处于启用集合中。若你禁用它,刷新后相关路由、菜单与语言包会一起移除。" : "插件目前已从启用集合中排除。启用后刷新应用,相关页面入口与能力会重新接入。" : "这个插件在代码层被标记为默认关闭,运行时只读展示,不能直接通过管理中心启用。", O = async (e) => {
|
|
84
|
+
try {
|
|
85
|
+
await navigator.clipboard.writeText(e);
|
|
86
|
+
} catch {
|
|
87
|
+
window.prompt("复制插件 ID", e);
|
|
88
|
+
}
|
|
89
|
+
}, A = async (e) => {
|
|
90
|
+
if (!C(e)) return;
|
|
91
|
+
const r = !e.enabled;
|
|
92
|
+
window.confirm(
|
|
93
|
+
r ? `确认启用插件“${e.name}”吗?刷新后会重新注册它的路由和菜单。` : `确认禁用插件“${e.name}”吗?刷新后它的路由和菜单会被移除。`
|
|
94
|
+
) && (H(e.id, r), g.value = !0, w(), !r && e.id === "plugin-sys-setting" && await P.replace("/dashboard"));
|
|
95
|
+
};
|
|
96
|
+
return (e, r) => (l(), d("div", G, [
|
|
97
|
+
t("section", q, [
|
|
98
|
+
r[4] || (r[4] = t("div", { class: "pointer-events-none absolute inset-0" }, [
|
|
99
|
+
t("div", { class: "absolute -left-16 top-10 h-36 w-36 rounded-full bg-orange-200/30 blur-3xl dark:bg-orange-400/10" }),
|
|
100
|
+
t("div", { class: "absolute right-0 top-0 h-48 w-48 rounded-full bg-fuchsia-200/30 blur-3xl dark:bg-fuchsia-500/10" })
|
|
101
|
+
], -1)),
|
|
102
|
+
t("div", J, [
|
|
103
|
+
t("div", K, [
|
|
104
|
+
t("div", Q, [
|
|
105
|
+
r[0] || (r[0] = t("div", { class: "inline-flex items-center gap-2 rounded-full bg-white/80 px-3 py-1 text-xs font-semibold text-orange-500 ring-1 ring-orange-100 dark:bg-white/5 dark:text-orange-300 dark:ring-slate-800/80" }, [
|
|
106
|
+
t("span", { class: "h-2 w-2 rounded-full bg-emerald-400" }),
|
|
107
|
+
V(" Plugin Runtime Console ")
|
|
108
|
+
], -1)),
|
|
109
|
+
r[1] || (r[1] = t("h2", { class: "mt-4 text-3xl font-black tracking-tight text-slate-900 dark:text-white" }, " 运行总控 ", -1)),
|
|
110
|
+
r[2] || (r[2] = t("p", { class: "mt-3 text-sm leading-7 text-slate-600 dark:text-slate-400" }, " 这里专门负责插件状态同步与应用重载。启停结果会先写入本地存储,等你确认完本轮调整后,再统一刷新应用让路由、菜单和语言包真正生效。 ", -1)),
|
|
111
|
+
t("div", U, [
|
|
112
|
+
(l(), d(f, null, k(j, (a) => t("span", {
|
|
113
|
+
key: a,
|
|
114
|
+
class: "rounded-full bg-white/80 px-3 py-1.5 text-xs font-medium text-slate-500 ring-1 ring-slate-200/70 backdrop-blur-sm dark:bg-white/[0.04] dark:text-slate-300 dark:ring-slate-800/80"
|
|
115
|
+
}, s(a), 1)), 64))
|
|
116
|
+
])
|
|
117
|
+
]),
|
|
118
|
+
t("div", W, [
|
|
119
|
+
t("div", X, [
|
|
120
|
+
t("div", null, [
|
|
121
|
+
r[3] || (r[3] = t("div", { class: "text-sm font-bold text-slate-900 dark:text-white" }, "当前状态", -1)),
|
|
122
|
+
t("div", Y, " 已识别 " + s(n.value.length) + " 个插件 ", 1)
|
|
123
|
+
]),
|
|
124
|
+
t("div", {
|
|
125
|
+
class: b([
|
|
126
|
+
"rounded-full px-3 py-1 text-xs font-semibold",
|
|
127
|
+
g.value ? "bg-amber-100 text-amber-700 dark:bg-amber-500/10 dark:text-amber-300" : "bg-emerald-100 text-emerald-700 dark:bg-emerald-500/10 dark:text-emerald-300"
|
|
128
|
+
])
|
|
129
|
+
}, s(g.value ? "待刷新" : "已同步"), 3)
|
|
130
|
+
]),
|
|
131
|
+
t("div", { class: "mt-4 grid gap-3" }, [
|
|
132
|
+
t("button", {
|
|
133
|
+
type: "button",
|
|
134
|
+
class: "rounded-2xl border border-slate-200/80 bg-white px-4 py-3 text-sm font-semibold text-slate-700 transition-all hover:-translate-y-0.5 hover:border-orange-200 hover:text-orange-500 dark:border-slate-700/80 dark:bg-slate-950/30 dark:text-slate-200 dark:hover:border-orange-400/30 dark:hover:text-orange-300",
|
|
135
|
+
onClick: w
|
|
136
|
+
}, " 刷新运行时状态 "),
|
|
137
|
+
t("button", {
|
|
138
|
+
type: "button",
|
|
139
|
+
class: "rounded-2xl bg-[linear-gradient(135deg,#f97316,#ec4899)] px-4 py-3 text-sm font-semibold text-white shadow-[0_18px_40px_rgba(249,115,22,0.25)] transition-transform hover:-translate-y-0.5",
|
|
140
|
+
onClick: _
|
|
141
|
+
}, " 重新引导应用 ")
|
|
142
|
+
]),
|
|
143
|
+
t("div", Z, s(g.value ? "已有变更待生效,建议现在刷新应用完成本轮切换。" : "当前运行视图与本地配置一致,可以继续调整。"), 1)
|
|
144
|
+
])
|
|
145
|
+
])
|
|
146
|
+
])
|
|
147
|
+
]),
|
|
148
|
+
g.value ? (l(), d("section", ee, [
|
|
149
|
+
r[5] || (r[5] = t("div", { class: "space-y-1" }, [
|
|
150
|
+
t("div", { class: "text-sm font-bold text-amber-700 dark:text-amber-300" }, "检测到插件状态已更新"),
|
|
151
|
+
t("p", { class: "text-sm leading-6 text-amber-700/90 dark:text-amber-100/80" }, " 当前页面已经保存启停选择,但新的路由、菜单和依赖关系要在应用重新引导后才会真正生效。 ")
|
|
152
|
+
], -1)),
|
|
153
|
+
t("button", {
|
|
154
|
+
type: "button",
|
|
155
|
+
class: "rounded-2xl bg-amber-500 px-4 py-3 text-sm font-semibold text-white transition-colors hover:bg-amber-600",
|
|
156
|
+
onClick: _
|
|
157
|
+
}, " 立即刷新生效 ")
|
|
158
|
+
])) : u("", !0),
|
|
159
|
+
t("section", te, [
|
|
160
|
+
t("div", re, [
|
|
161
|
+
r[6] || (r[6] = t("div", null, [
|
|
162
|
+
t("div", { class: "text-lg font-bold text-slate-900 dark:text-white" }, "插件视图"),
|
|
163
|
+
t("p", { class: "mt-1 text-sm leading-6 text-slate-500 dark:text-slate-400" }, " 按运行状态快速筛选插件,专注处理启停决策和依赖关系。 ")
|
|
164
|
+
], -1)),
|
|
165
|
+
t("div", ae, [
|
|
166
|
+
(l(!0), d(f, null, k(T.value, (a) => (l(), d("button", {
|
|
167
|
+
key: a.key,
|
|
168
|
+
type: "button",
|
|
169
|
+
class: b([
|
|
170
|
+
"rounded-full px-4 py-2 text-sm font-medium transition-all",
|
|
171
|
+
m.value === a.key ? "bg-slate-900 text-white shadow-lg dark:bg-white dark:text-slate-900" : "bg-slate-100 text-slate-500 hover:bg-slate-200 dark:bg-slate-900/80 dark:text-slate-300 dark:hover:bg-slate-800"
|
|
172
|
+
]),
|
|
173
|
+
onClick: (x) => m.value = a.key
|
|
174
|
+
}, s(a.label) + " · " + s(a.count), 11, se))), 128))
|
|
175
|
+
])
|
|
176
|
+
]),
|
|
177
|
+
t("div", le, [
|
|
178
|
+
(l(!0), d(f, null, k(p.value, (a) => (l(), d("article", {
|
|
179
|
+
key: a.id,
|
|
180
|
+
class: b(["group relative overflow-hidden rounded-[28px] border p-5 transition-all duration-300 hover:-translate-y-1 hover:shadow-[0_24px_60px_rgba(15,23,42,0.08)] dark:hover:shadow-none", M(a)])
|
|
181
|
+
}, [
|
|
182
|
+
t("div", {
|
|
183
|
+
class: b(["pointer-events-none absolute inset-x-0 top-0 h-24 opacity-80 blur-3xl", R(a)])
|
|
184
|
+
}, null, 2),
|
|
185
|
+
t("div", de, [
|
|
186
|
+
t("div", ne, [
|
|
187
|
+
t("div", oe, [
|
|
188
|
+
t("div", {
|
|
189
|
+
class: b(["flex h-14 w-14 shrink-0 items-center justify-center rounded-[20px] text-white shadow-lg", $(a)])
|
|
190
|
+
}, [
|
|
191
|
+
a.enabled ? (l(), d("svg", ie, [...r[7] || (r[7] = [
|
|
192
|
+
t("path", {
|
|
193
|
+
"stroke-linecap": "round",
|
|
194
|
+
"stroke-linejoin": "round",
|
|
195
|
+
"stroke-width": "1.8",
|
|
196
|
+
d: "M5 13l4 4L19 7"
|
|
197
|
+
}, null, -1)
|
|
198
|
+
])])) : a.enabledByConfig ? (l(), d("svg", ge, [...r[9] || (r[9] = [
|
|
199
|
+
t("path", {
|
|
200
|
+
"stroke-linecap": "round",
|
|
201
|
+
"stroke-linejoin": "round",
|
|
202
|
+
"stroke-width": "1.8",
|
|
203
|
+
d: "M18.364 5.636L5.636 18.364M5.636 5.636l12.728 12.728"
|
|
204
|
+
}, null, -1)
|
|
205
|
+
])])) : (l(), d("svg", be, [...r[8] || (r[8] = [
|
|
206
|
+
t("path", {
|
|
207
|
+
"stroke-linecap": "round",
|
|
208
|
+
"stroke-linejoin": "round",
|
|
209
|
+
"stroke-width": "1.8",
|
|
210
|
+
d: "M12 15v2m0-8v2m7 1a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
211
|
+
}, null, -1)
|
|
212
|
+
])]))
|
|
213
|
+
], 2),
|
|
214
|
+
t("div", xe, [
|
|
215
|
+
t("div", ce, [
|
|
216
|
+
t("h3", ue, s(a.name), 1),
|
|
217
|
+
t("span", {
|
|
218
|
+
class: b(["rounded-full px-2.5 py-1 text-xs font-semibold", L(a)])
|
|
219
|
+
}, s(D(a)), 3)
|
|
220
|
+
]),
|
|
221
|
+
t("p", fe, s(a.id), 1),
|
|
222
|
+
t("p", ke, s(E(a)), 1)
|
|
223
|
+
])
|
|
224
|
+
]),
|
|
225
|
+
t("div", me, " v" + s(a.version), 1)
|
|
226
|
+
]),
|
|
227
|
+
t("div", he, [
|
|
228
|
+
t("div", ve, [
|
|
229
|
+
r[10] || (r[10] = t("div", { class: "text-[11px] uppercase tracking-[0.18em] text-slate-400 dark:text-slate-500" }, " 顺序 ", -1)),
|
|
230
|
+
t("div", pe, s(a.order), 1)
|
|
231
|
+
]),
|
|
232
|
+
t("div", we, [
|
|
233
|
+
r[11] || (r[11] = t("div", { class: "text-[11px] uppercase tracking-[0.18em] text-slate-400 dark:text-slate-500" }, " 路由 ", -1)),
|
|
234
|
+
t("div", _e, s(a.routeCount), 1)
|
|
235
|
+
]),
|
|
236
|
+
t("div", ye, [
|
|
237
|
+
r[12] || (r[12] = t("div", { class: "text-[11px] uppercase tracking-[0.18em] text-slate-400 dark:text-slate-500" }, " 菜单 ", -1)),
|
|
238
|
+
t("div", Ce, s(a.menuCount), 1)
|
|
239
|
+
])
|
|
240
|
+
]),
|
|
241
|
+
t("div", Pe, [
|
|
242
|
+
r[13] || (r[13] = t("div", { class: "text-[11px] font-semibold uppercase tracking-[0.22em] text-slate-400 dark:text-slate-500" }, " 依赖关系 ", -1)),
|
|
243
|
+
t("div", Be, [
|
|
244
|
+
a.dependsOn.length === 0 ? (l(), d("span", je, " 无依赖 ")) : u("", !0),
|
|
245
|
+
(l(!0), d(f, null, k(a.dependsOn, (x) => (l(), d("span", {
|
|
246
|
+
key: x,
|
|
247
|
+
class: "rounded-full bg-white/80 px-3 py-1 text-xs font-medium text-slate-600 ring-1 ring-slate-200/70 dark:bg-white/[0.04] dark:text-slate-300 dark:ring-slate-800/80"
|
|
248
|
+
}, s(x), 1))), 128))
|
|
249
|
+
])
|
|
250
|
+
]),
|
|
251
|
+
t("div", Se, [
|
|
252
|
+
t("p", null, s(I(a)), 1),
|
|
253
|
+
o(a).length > 0 ? (l(), d("p", Te, " 缺失依赖:" + s(o(a).join("、")) + "。请先启用依赖插件,再刷新应用。 ", 1)) : u("", !0),
|
|
254
|
+
i(a).length > 0 ? (l(), d("p", De, " 当前有插件依赖它:" + s(i(a).join("、")) + "。 ", 1)) : u("", !0)
|
|
255
|
+
]),
|
|
256
|
+
t("div", Le, [
|
|
257
|
+
t("button", {
|
|
258
|
+
type: "button",
|
|
259
|
+
class: b([
|
|
260
|
+
"flex-1 rounded-2xl px-4 py-3 text-sm font-semibold text-white transition-colors disabled:cursor-not-allowed disabled:opacity-50",
|
|
261
|
+
a.enabled ? "bg-rose-500 hover:bg-rose-600" : "bg-emerald-500 hover:bg-emerald-600"
|
|
262
|
+
]),
|
|
263
|
+
disabled: !C(a),
|
|
264
|
+
onClick: (x) => A(a)
|
|
265
|
+
}, s(a.enabled ? "禁用插件" : "启用插件"), 11, Me),
|
|
266
|
+
t("button", {
|
|
267
|
+
type: "button",
|
|
268
|
+
class: "rounded-2xl border border-slate-200/80 bg-white px-4 py-3 text-sm font-medium text-slate-600 transition-colors hover:border-violet-300 hover:text-violet-600 dark:border-slate-700/80 dark:bg-slate-950/30 dark:text-slate-300 dark:hover:border-violet-400/40 dark:hover:text-violet-300",
|
|
269
|
+
onClick: (x) => O(a.id)
|
|
270
|
+
}, " 复制插件 ID ", 8, Re)
|
|
271
|
+
])
|
|
272
|
+
])
|
|
273
|
+
], 2))), 128))
|
|
274
|
+
]),
|
|
275
|
+
p.value.length === 0 ? (l(), d("div", $e, " 当前筛选条件下没有匹配的插件。 ")) : u("", !0)
|
|
276
|
+
])
|
|
277
|
+
]));
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
export {
|
|
281
|
+
Ne as default
|
|
282
|
+
};
|
package/dist/index.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.bag-sys-primary-action[data-v-b3e0f555]{background:linear-gradient(90deg,var(--bag-color-primary) 0%,var(--bag-color-accent) 100%)}.bag-sys-primary-action[data-v-b3e0f555]:hover{box-shadow:0 10px 24px var(--bag-color-primary-soft)}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const t = {
|
|
2
|
+
id: "plugin-sys-setting",
|
|
3
|
+
name: "系统设置插件",
|
|
4
|
+
version: "1.0.0",
|
|
5
|
+
order: 100,
|
|
6
|
+
routes: [
|
|
7
|
+
{
|
|
8
|
+
path: "/sys-setting",
|
|
9
|
+
name: "SysSetting",
|
|
10
|
+
component: () => import("./SysSetting--OmMlBRZ.js"),
|
|
11
|
+
meta: {
|
|
12
|
+
title: "sysSetting.title",
|
|
13
|
+
layout: "default",
|
|
14
|
+
roles: ["authenticated"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
path: "/sys-setting/advanced",
|
|
19
|
+
name: "SysSettingAdvanced",
|
|
20
|
+
component: () => import("./SysSettingAdvanced-A0T2UBb3.js"),
|
|
21
|
+
meta: {
|
|
22
|
+
title: "sysSetting.advanced",
|
|
23
|
+
layout: "default",
|
|
24
|
+
roles: ["authenticated"]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
path: "/sys-setting/plugins",
|
|
29
|
+
name: "SysSettingPlugins",
|
|
30
|
+
component: () => import("./SysSettingPlugins-CZQjv88J.js"),
|
|
31
|
+
meta: {
|
|
32
|
+
title: "sysSetting.plugins",
|
|
33
|
+
layout: "default",
|
|
34
|
+
roles: ["authenticated"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
menus: [
|
|
39
|
+
{
|
|
40
|
+
path: "/sys-setting-group",
|
|
41
|
+
title: "sysSetting.title",
|
|
42
|
+
icon: "settings",
|
|
43
|
+
sort: 100,
|
|
44
|
+
roles: ["authenticated"],
|
|
45
|
+
children: [
|
|
46
|
+
{
|
|
47
|
+
path: "/sys-setting",
|
|
48
|
+
title: "sysSetting.base",
|
|
49
|
+
sort: 1,
|
|
50
|
+
roles: ["authenticated"]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
path: "/sys-setting/advanced",
|
|
54
|
+
title: "sysSetting.advanced",
|
|
55
|
+
sort: 10,
|
|
56
|
+
roles: ["authenticated"]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
path: "/sys-setting/plugins",
|
|
60
|
+
title: "sysSetting.plugins",
|
|
61
|
+
sort: 20,
|
|
62
|
+
roles: ["authenticated"]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
locales: {
|
|
68
|
+
"zh-CN": {
|
|
69
|
+
sysSetting: {
|
|
70
|
+
title: "系统设置",
|
|
71
|
+
base: "常规设置",
|
|
72
|
+
advanced: "高级设置",
|
|
73
|
+
plugins: "插件管理",
|
|
74
|
+
welcome: "欢迎来到系统设置模块",
|
|
75
|
+
buttonSave: "保存配置",
|
|
76
|
+
logout: "退出登录"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
en: {
|
|
80
|
+
sysSetting: {
|
|
81
|
+
title: "System Settings",
|
|
82
|
+
base: "General Settings",
|
|
83
|
+
advanced: "Advanced",
|
|
84
|
+
plugins: "Plugins",
|
|
85
|
+
welcome: "Welcome to System Settings",
|
|
86
|
+
buttonSave: "Save Config",
|
|
87
|
+
logout: "Logout"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
install() {
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
export {
|
|
95
|
+
t as default
|
|
96
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@melt-js/comps-bag-sys",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "2026.11.7-2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist"
|
|
7
|
+
],
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json",
|
|
20
|
+
"check-types": "vue-tsc -p tsconfig.build.json --noEmit",
|
|
21
|
+
"publish:stage": "pnpm run build && npx -y npm@11 stage publish"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@vueuse/core": "11.3.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"vue": "^3.5.0",
|
|
28
|
+
"@melt-js/libs-bag-entry": "^2026.11.7",
|
|
29
|
+
"vue-router": "^4.4.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@vitejs/plugin-vue": "6.0.10",
|
|
33
|
+
"javascript-obfuscator": "4.2.2",
|
|
34
|
+
"vite": "6.4.5",
|
|
35
|
+
"vite-plugin-bundle-obfuscator": "1.10.0",
|
|
36
|
+
"@melt-js/libs-bag-entry": "workspace:*",
|
|
37
|
+
"vue-tsc": "2.2.12"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public",
|
|
41
|
+
"registry": "https://registry.npmjs.org",
|
|
42
|
+
"tag": "latest"
|
|
43
|
+
}
|
|
44
|
+
}
|