@liujitcn/kratos-admin-core 0.0.97 → 0.0.99
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/dist/package/declarations/src/components/CodeEditor/index.vue.d.ts +22 -0
- package/dist/package/declarations/src/views/demo/demo-data.d.ts +13 -0
- package/dist/package/src/components/CodeEditor/index.vue +92 -0
- package/dist/package/src/components/WangEditor/index.vue +15 -4
- package/dist/package/src/utils/request.ts +3 -2
- package/dist/package/src/views/demo/demo-data.ts +21 -0
- package/dist/package/src/views/demo/table/index.vue +2 -2
- package/package.json +6 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** 代码编辑器属性。 */
|
|
2
|
+
interface CodeEditorProps {
|
|
3
|
+
/** 编辑器源码。 */
|
|
4
|
+
modelValue: string;
|
|
5
|
+
/** Monaco 语言标识。 */
|
|
6
|
+
language?: string;
|
|
7
|
+
/** 编辑器高度。 */
|
|
8
|
+
height?: string;
|
|
9
|
+
/** 是否只读。 */
|
|
10
|
+
readonly?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const __VLS_export: import("vue").DefineComponent<CodeEditorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
|
+
"update:modelValue": (value: string) => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<CodeEditorProps> & Readonly<{
|
|
15
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
16
|
+
}>, {
|
|
17
|
+
readonly: boolean;
|
|
18
|
+
height: string;
|
|
19
|
+
language: string;
|
|
20
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
@@ -139,6 +139,19 @@ export declare const demoRegionTree: {
|
|
|
139
139
|
label: string;
|
|
140
140
|
}[];
|
|
141
141
|
}[];
|
|
142
|
+
/** 团队树静态数据:与城市级联数据分离,供纯表格团队筛选使用。 */
|
|
143
|
+
export declare const demoOwnerGroupTree: ({
|
|
144
|
+
value: string;
|
|
145
|
+
label: string;
|
|
146
|
+
children: {
|
|
147
|
+
value: string;
|
|
148
|
+
label: string;
|
|
149
|
+
}[];
|
|
150
|
+
} | {
|
|
151
|
+
value: string;
|
|
152
|
+
label: string;
|
|
153
|
+
children?: undefined;
|
|
154
|
+
})[];
|
|
142
155
|
/** 项目静态数据:25 条覆盖分页、多级表头、进度条、标签列等展示场景。 */
|
|
143
156
|
export declare const demoProjects: DemoProject[];
|
|
144
157
|
/** 目录树静态数据:三层嵌套演示树形表格的展开、折叠与子级操作。 */
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div ref="editorHost" class="code-editor" :style="{ height }" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
7
|
+
import * as monaco from "monaco-editor";
|
|
8
|
+
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
|
|
9
|
+
|
|
10
|
+
/** 代码编辑器属性。 */
|
|
11
|
+
interface CodeEditorProps {
|
|
12
|
+
/** 编辑器源码。 */
|
|
13
|
+
modelValue: string;
|
|
14
|
+
/** Monaco 语言标识。 */
|
|
15
|
+
language?: string;
|
|
16
|
+
/** 编辑器高度。 */
|
|
17
|
+
height?: string;
|
|
18
|
+
/** 是否只读。 */
|
|
19
|
+
readonly?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const props = withDefaults(defineProps<CodeEditorProps>(), {
|
|
23
|
+
language: "javascript",
|
|
24
|
+
height: "360px",
|
|
25
|
+
readonly: false
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const emit = defineEmits<{ "update:modelValue": [value: string] }>();
|
|
29
|
+
const editorHost = ref<HTMLElement>();
|
|
30
|
+
let editor: monaco.editor.IStandaloneCodeEditor | undefined;
|
|
31
|
+
let model: monaco.editor.ITextModel | undefined;
|
|
32
|
+
|
|
33
|
+
function createEditor() {
|
|
34
|
+
if (!editorHost.value) return;
|
|
35
|
+
self.MonacoEnvironment = {
|
|
36
|
+
getWorker() {
|
|
37
|
+
return new editorWorker();
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
model = monaco.editor.createModel(props.modelValue, props.language);
|
|
41
|
+
editor = monaco.editor.create(editorHost.value, {
|
|
42
|
+
model,
|
|
43
|
+
automaticLayout: true,
|
|
44
|
+
minimap: { enabled: false },
|
|
45
|
+
fontSize: 13,
|
|
46
|
+
tabSize: 2,
|
|
47
|
+
scrollBeyondLastLine: false,
|
|
48
|
+
wordWrap: "on",
|
|
49
|
+
readOnly: props.readonly,
|
|
50
|
+
padding: { top: 12, bottom: 12 }
|
|
51
|
+
});
|
|
52
|
+
editor.onDidChangeModelContent(() => {
|
|
53
|
+
emit("update:modelValue", editor?.getValue() ?? "");
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function disposeEditor() {
|
|
58
|
+
editor?.dispose();
|
|
59
|
+
model?.dispose();
|
|
60
|
+
editor = undefined;
|
|
61
|
+
model = undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
onMounted(createEditor);
|
|
65
|
+
onBeforeUnmount(disposeEditor);
|
|
66
|
+
|
|
67
|
+
watch(
|
|
68
|
+
() => props.modelValue,
|
|
69
|
+
value => {
|
|
70
|
+
if (!editor || value === editor.getValue()) return;
|
|
71
|
+
editor.setValue(value);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
watch(
|
|
76
|
+
() => props.language,
|
|
77
|
+
value => {
|
|
78
|
+
if (!model) return;
|
|
79
|
+
monaco.editor.setModelLanguage(model, value);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<style scoped>
|
|
85
|
+
.code-editor {
|
|
86
|
+
width: 100%;
|
|
87
|
+
min-height: 240px;
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
border: 1px solid var(--el-border-color);
|
|
90
|
+
border-radius: var(--admin-page-radius);
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
@@ -86,14 +86,24 @@ const emit = defineEmits<{
|
|
|
86
86
|
"update:value": [value: string];
|
|
87
87
|
"check-validate": [];
|
|
88
88
|
}>();
|
|
89
|
+
|
|
90
|
+
/** 判断富文本 HTML 是否只包含空白节点。 */
|
|
91
|
+
const normalizeEditorValue = (value: string) => {
|
|
92
|
+
if (!value) return "";
|
|
93
|
+
if (/<(?:img|video|iframe)\b/i.test(value)) return value;
|
|
94
|
+
const text = value
|
|
95
|
+
.replace(/<[^>]*>/g, "")
|
|
96
|
+
.replace(/ | |​/gi, "")
|
|
97
|
+
.trim();
|
|
98
|
+
return text ? value : "";
|
|
99
|
+
};
|
|
89
100
|
const valueHtml = computed({
|
|
90
101
|
get() {
|
|
91
102
|
return normalizeRichTextMediaPaths(props.value);
|
|
92
103
|
},
|
|
93
104
|
set(val: string) {
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
emit("update:value", val);
|
|
105
|
+
// 以编辑器回写的 HTML 为准,避免 isEmpty() 在回写时序中误清空有效内容。
|
|
106
|
+
emit("update:value", normalizeEditorValue(val));
|
|
97
107
|
}
|
|
98
108
|
});
|
|
99
109
|
|
|
@@ -180,7 +190,8 @@ editorMenuConfig["uploadVideo"] = {
|
|
|
180
190
|
};
|
|
181
191
|
|
|
182
192
|
// 编辑框失去焦点时触发
|
|
183
|
-
const handleBlur = () => {
|
|
193
|
+
const handleBlur = async () => {
|
|
194
|
+
await nextTick();
|
|
184
195
|
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
|
|
185
196
|
};
|
|
186
197
|
|
|
@@ -121,14 +121,15 @@ const service = axios.create({
|
|
|
121
121
|
baseURL: requestBaseURL,
|
|
122
122
|
timeout: 50000,
|
|
123
123
|
headers: { "Content-Type": "application/json;charset=utf-8" },
|
|
124
|
-
paramsSerializer: params => qs.stringify(compactTenantProjectQueryParams(params)),
|
|
124
|
+
paramsSerializer: params => qs.stringify(compactTenantProjectQueryParams(params), { arrayFormat: "repeat" }),
|
|
125
125
|
withCredentials: true
|
|
126
126
|
});
|
|
127
127
|
|
|
128
128
|
// 刷新令牌请求使用独立实例,避免与主请求拦截器互相递归。
|
|
129
129
|
const refreshService = axios.create({
|
|
130
130
|
baseURL: requestBaseURL,
|
|
131
|
-
|
|
131
|
+
// 路由守卫会同步等待刷新结果:超时过长时后端重启窗口内整站黑屏挂起,收敛到 8 秒。
|
|
132
|
+
timeout: 8000,
|
|
132
133
|
headers: { "Content-Type": "application/json;charset=utf-8" },
|
|
133
134
|
withCredentials: true
|
|
134
135
|
});
|
|
@@ -220,6 +220,27 @@ export const demoRegionTree = [
|
|
|
220
220
|
}
|
|
221
221
|
];
|
|
222
222
|
|
|
223
|
+
/** 团队树静态数据:与城市级联数据分离,供纯表格团队筛选使用。 */
|
|
224
|
+
export const demoOwnerGroupTree = [
|
|
225
|
+
{
|
|
226
|
+
value: "engineering",
|
|
227
|
+
label: "研发团队",
|
|
228
|
+
children: [
|
|
229
|
+
{ value: "frontend", label: "前端组" },
|
|
230
|
+
{ value: "backend", label: "后端组" }
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
value: "product",
|
|
235
|
+
label: "产品团队",
|
|
236
|
+
children: [
|
|
237
|
+
{ value: "design", label: "设计组" },
|
|
238
|
+
{ value: "research", label: "研究组" }
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
{ value: "operations", label: "运营团队" }
|
|
242
|
+
];
|
|
243
|
+
|
|
223
244
|
/** 项目静态数据:25 条覆盖分页、多级表头、进度条、标签列等展示场景。 */
|
|
224
245
|
export const demoProjects: DemoProject[] = [
|
|
225
246
|
{ id: 1, name: "星尘数据平台", level: "S", owner: "陈默", status: STATUS_ENABLE, budget: 128000000, task_total: 46, progress: 82, region: ["zhejiang", "hangzhou"], created_at: "2025-01-06 09:30:00" },
|
|
@@ -46,7 +46,7 @@ import { t } from "../../../locales";
|
|
|
46
46
|
import DemoFormDialog from "../components/DemoFormDialog.vue";
|
|
47
47
|
import DemoDetailDrawer from "../components/DemoDetailDrawer.vue";
|
|
48
48
|
import type { DemoDetailModel, DemoProject } from "../demo-data";
|
|
49
|
-
import { STATUS_DISABLE, STATUS_ENABLE, demoLevelOptions, demoProjects, demoRegionTree } from "../demo-data";
|
|
49
|
+
import { STATUS_DISABLE, STATUS_ENABLE, demoLevelOptions, demoOwnerGroupTree, demoProjects, demoRegionTree } from "../demo-data";
|
|
50
50
|
|
|
51
51
|
defineOptions({
|
|
52
52
|
name: "DemoTable",
|
|
@@ -71,7 +71,7 @@ const statusTagOptions = [
|
|
|
71
71
|
const tagSearchOptions = Array.from({ length: 50 }, (_, index) => ({ label: t("core.demo.table.tag_item", { index: index + 1 }), value: `tag-${index + 1}` }));
|
|
72
72
|
|
|
73
73
|
/** tree-select 搜索项的静态团队树(isShow: false,仅出现在搜索区)。 */
|
|
74
|
-
const ownerGroupOptions =
|
|
74
|
+
const ownerGroupOptions = demoOwnerGroupTree;
|
|
75
75
|
|
|
76
76
|
/** 把级联编码翻译成“省 / 市”文本,用于 region 列单元格展示。 */
|
|
77
77
|
function formatRegion(region: string[]): string {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liujitcn/kratos-admin-core",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.99",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "kratos-admin frontend runtime and base modules",
|
|
7
7
|
"author": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"md-editor-v3": "^6.5.5",
|
|
46
46
|
"md5": "^2.3.0",
|
|
47
47
|
"mitt": "^3.0.1",
|
|
48
|
+
"monaco-editor": "^0.52.2",
|
|
48
49
|
"nprogress": "^0.2.0",
|
|
49
50
|
"pinia": "^4.0.3",
|
|
50
51
|
"pinia-plugin-persistedstate": "^4.7.1",
|
|
@@ -150,6 +151,10 @@
|
|
|
150
151
|
"types": "./dist/package/declarations/src/components/YamlEditor/index.vue.d.ts",
|
|
151
152
|
"default": "./dist/package/src/components/YamlEditor/index.vue"
|
|
152
153
|
},
|
|
154
|
+
"./components/CodeEditor/index.vue": {
|
|
155
|
+
"types": "./dist/package/declarations/src/components/CodeEditor/index.vue.d.ts",
|
|
156
|
+
"default": "./dist/package/src/components/CodeEditor/index.vue"
|
|
157
|
+
},
|
|
153
158
|
"./components/ProForm/index.vue": {
|
|
154
159
|
"types": "./dist/package/declarations/src/components/ProForm/index.vue.d.ts",
|
|
155
160
|
"default": "./dist/package/src/components/ProForm/index.vue"
|