feat: ele codegen use code editor
This commit is contained in:
@@ -1,34 +1,19 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { TabPaneName } from 'element-plus';
|
import type { TabPaneName } from 'element-plus';
|
||||||
|
|
||||||
// TODO @芋艿:待定,vben2.0 有 CodeEditor,不确定官方后续会不会迁移!!!
|
|
||||||
import type { InfraCodegenApi } from '#/api/infra/codegen';
|
import type { InfraCodegenApi } from '#/api/infra/codegen';
|
||||||
|
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
import { CodeEditor } from '@vben/plugins/code-editor';
|
||||||
|
|
||||||
import { useClipboard } from '@vueuse/core';
|
import { useClipboard } from '@vueuse/core';
|
||||||
import { ElMessage, ElTabPane, ElTabs, ElTree } from 'element-plus';
|
import { ElMessage, ElTabPane, ElTabs, ElTree } from 'element-plus';
|
||||||
import hljs from 'highlight.js/lib/core';
|
|
||||||
import java from 'highlight.js/lib/languages/java';
|
|
||||||
import javascript from 'highlight.js/lib/languages/javascript';
|
|
||||||
import sql from 'highlight.js/lib/languages/sql';
|
|
||||||
import typescript from 'highlight.js/lib/languages/typescript';
|
|
||||||
import xml from 'highlight.js/lib/languages/xml';
|
|
||||||
|
|
||||||
import { previewCodegen } from '#/api/infra/codegen';
|
import { previewCodegen } from '#/api/infra/codegen';
|
||||||
|
|
||||||
/** 注册代码高亮语言 */
|
|
||||||
hljs.registerLanguage('java', java);
|
|
||||||
hljs.registerLanguage('xml', xml);
|
|
||||||
hljs.registerLanguage('html', xml);
|
|
||||||
hljs.registerLanguage('vue', xml);
|
|
||||||
hljs.registerLanguage('javascript', javascript);
|
|
||||||
hljs.registerLanguage('sql', sql);
|
|
||||||
hljs.registerLanguage('typescript', typescript);
|
|
||||||
|
|
||||||
/** 文件树类型 */
|
/** 文件树类型 */
|
||||||
interface FileNode {
|
interface FileNode {
|
||||||
key: string;
|
key: string;
|
||||||
@@ -46,21 +31,14 @@ const activeKey = ref<string>('');
|
|||||||
|
|
||||||
/** 代码地图 */
|
/** 代码地图 */
|
||||||
const codeMap = ref<Map<string, string>>(new Map<string, string>());
|
const codeMap = ref<Map<string, string>>(new Map<string, string>());
|
||||||
function setCodeMap(key: string, lang: string, code: string) {
|
function setCodeMap(key: string, code: string) {
|
||||||
// 处理可能的缩进问题,特别是对Java文件
|
// 处理可能的缩进问题,特别是对Java文件
|
||||||
const trimmedCode = code.trimStart();
|
const trimmedCode = code.trimStart();
|
||||||
// 如果已有缓存则不重新构建
|
// 如果已有缓存则不重新构建
|
||||||
if (codeMap.value.has(key)) {
|
if (codeMap.value.has(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
codeMap.value.set(key, trimmedCode);
|
||||||
const highlightedCode = hljs.highlight(trimmedCode, {
|
|
||||||
language: lang,
|
|
||||||
}).value;
|
|
||||||
codeMap.value.set(key, highlightedCode);
|
|
||||||
} catch {
|
|
||||||
codeMap.value.set(key, trimmedCode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 删除代码地图 */
|
/** 删除代码地图 */
|
||||||
@@ -106,8 +84,7 @@ function handleNodeClick(node: FileNode) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lang = file.filePath.split('.').pop() || '';
|
setCodeMap(activeKey.value, file.code);
|
||||||
setCodeMap(activeKey.value, lang, file.code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 处理文件树 */
|
/** 处理文件树 */
|
||||||
@@ -240,9 +217,8 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
fileTree.value = handleFiles(data);
|
fileTree.value = handleFiles(data);
|
||||||
if (data.length > 0) {
|
if (data.length > 0) {
|
||||||
activeKey.value = data[0]?.filePath || '';
|
activeKey.value = data[0]?.filePath || '';
|
||||||
const lang = activeKey.value.split('.').pop() || '';
|
|
||||||
const code = data[0]?.code || '';
|
const code = data[0]?.code || '';
|
||||||
setCodeMap(activeKey.value, lang, code);
|
setCodeMap(activeKey.value, code);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -280,121 +256,24 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
:label="key.split('/').pop()"
|
:label="key.split('/').pop()"
|
||||||
:name="key"
|
:name="key"
|
||||||
>
|
>
|
||||||
<!-- TODO @puhui999:这里好像会有左右的滚动条?和 antd 不太一样 -->
|
|
||||||
<div
|
<div
|
||||||
class="h-full rounded-md bg-gray-50 !p-0 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
|
class="h-full rounded-md bg-gray-50 !p-0 text-gray-800 dark:bg-gray-800 dark:text-gray-200"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<CodeEditor
|
||||||
<code
|
class="max-h-200"
|
||||||
v-html="codeMap.get(activeKey)"
|
:value="codeMap.get(activeKey)"
|
||||||
class="code-highlight"
|
mode="application/json"
|
||||||
></code>
|
:readonly="true"
|
||||||
|
:bordered="true"
|
||||||
|
:auto-format="false"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ElTabPane>
|
</ElTabPane>
|
||||||
<template #add-icon>
|
<template #add-icon>
|
||||||
<!-- TODO @puhui999:这了有没办法加个复制按钮哈?和 antd 类似 -->
|
<IconifyIcon icon="lucide:copy" />
|
||||||
<IconifyIcon icon="ant-design:copy-twotone" />
|
|
||||||
</template>
|
</template>
|
||||||
</ElTabs>
|
</ElTabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
/* stylelint-disable selector-class-pattern */
|
|
||||||
|
|
||||||
/* 代码高亮样式 - 支持暗黑模式 */
|
|
||||||
:deep(.code-highlight) {
|
|
||||||
display: block;
|
|
||||||
white-space: pre;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 关键字 */
|
|
||||||
:deep(.hljs-keyword) {
|
|
||||||
@apply text-purple-600 dark:text-purple-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 字符串 */
|
|
||||||
:deep(.hljs-string) {
|
|
||||||
@apply text-green-600 dark:text-green-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 注释 */
|
|
||||||
:deep(.hljs-comment) {
|
|
||||||
@apply text-gray-500 dark:text-gray-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 函数 */
|
|
||||||
:deep(.hljs-function) {
|
|
||||||
@apply text-blue-600 dark:text-blue-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 数字 */
|
|
||||||
:deep(.hljs-number) {
|
|
||||||
@apply text-orange-600 dark:text-orange-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 类 */
|
|
||||||
:deep(.hljs-class) {
|
|
||||||
@apply text-yellow-600 dark:text-yellow-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 标题/函数名 */
|
|
||||||
:deep(.hljs-title) {
|
|
||||||
@apply font-bold text-blue-600 dark:text-blue-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 参数 */
|
|
||||||
:deep(.hljs-params) {
|
|
||||||
@apply text-gray-700 dark:text-gray-300;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 内置对象 */
|
|
||||||
:deep(.hljs-built_in) {
|
|
||||||
@apply text-teal-600 dark:text-teal-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* HTML标签 */
|
|
||||||
:deep(.hljs-tag) {
|
|
||||||
@apply text-blue-600 dark:text-blue-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 属性 */
|
|
||||||
:deep(.hljs-attribute),
|
|
||||||
:deep(.hljs-attr) {
|
|
||||||
@apply text-green-600 dark:text-green-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 字面量 */
|
|
||||||
:deep(.hljs-literal) {
|
|
||||||
@apply text-purple-600 dark:text-purple-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 元信息 */
|
|
||||||
:deep(.hljs-meta) {
|
|
||||||
@apply text-gray-500 dark:text-gray-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 选择器标签 */
|
|
||||||
:deep(.hljs-selector-tag) {
|
|
||||||
@apply text-blue-600 dark:text-blue-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XML/HTML名称 */
|
|
||||||
:deep(.hljs-name) {
|
|
||||||
@apply text-blue-600 dark:text-blue-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 变量 */
|
|
||||||
:deep(.hljs-variable) {
|
|
||||||
@apply text-orange-600 dark:text-orange-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 属性 */
|
|
||||||
:deep(.hljs-property) {
|
|
||||||
@apply text-red-600 dark:text-red-400;
|
|
||||||
}
|
|
||||||
/* stylelint-enable selector-class-pattern */
|
|
||||||
</style>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user