feat(projects): 使用 highlight.js 替换 monaco-editor
This commit is contained in:
@@ -7,7 +7,6 @@ import { setupUnocss } from './unocss';
|
||||
import { setupUnplugin } from './unplugin';
|
||||
import { setupHtmlPlugin } from './html';
|
||||
import { setupDevtoolsPlugin } from './devtools';
|
||||
import { setupMonacoEditorPlugin } from './monaco-editor';
|
||||
|
||||
export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) {
|
||||
const plugins: PluginOption = [
|
||||
@@ -18,8 +17,7 @@ export function setupVitePlugins(viteEnv: Env.ImportMeta, buildTime: string) {
|
||||
setupUnocss(viteEnv),
|
||||
...setupUnplugin(viteEnv),
|
||||
progress(),
|
||||
setupHtmlPlugin(buildTime),
|
||||
setupMonacoEditorPlugin()
|
||||
setupHtmlPlugin(buildTime)
|
||||
];
|
||||
|
||||
return plugins;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import monacoEditorPlugin from 'vite-plugin-monaco-editor';
|
||||
|
||||
export function setupMonacoEditorPlugin() {
|
||||
return (monacoEditorPlugin as any).default({
|
||||
languageWorkers: ['editorWorkerService', 'css', 'html', 'json', 'typescript']
|
||||
});
|
||||
}
|
||||
+22
-388
@@ -1,389 +1,23 @@
|
||||
package org.dromara.generator.util;
|
||||
//引入依赖和语言
|
||||
import 'highlight.js/styles/stackoverflow-light.css'
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import hljsVuePlugin from "@highlightjs/vue-plugin";
|
||||
//import "highlight.js/lib/common"; //单一加载
|
||||
//按需引入语言
|
||||
import javascript from "highlight.js/lib/languages/javascript";
|
||||
import java from "highlight.js/lib/languages/java";
|
||||
import sql from "highlight.js/lib/languages/sql";
|
||||
import xml from "highlight.js/lib/languages/xml";
|
||||
import html from "highlight.js/lib/languages/vbscript-html";
|
||||
import json from "highlight.js/lib/languages/json";
|
||||
import yaml from "highlight.js/lib/languages/json";
|
||||
hljs.registerLanguage("javascript", javascript);
|
||||
hljs.registerLanguage("java", java);
|
||||
hljs.registerLanguage("yaml", yaml);
|
||||
hljs.registerLanguage("json", json);
|
||||
hljs.registerLanguage("sql", sql);
|
||||
hljs.registerLanguage("xml", xml);
|
||||
hljs.registerLanguage("html", html);
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mybatis.enums.DataBaseType;
|
||||
import org.dromara.common.mybatis.helper.DataBaseHelper;
|
||||
import org.dromara.generator.constant.GenConstants;
|
||||
import org.dromara.generator.domain.GenTable;
|
||||
import org.dromara.generator.domain.GenTableColumn;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 模板处理工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class VelocityUtils {
|
||||
|
||||
/**
|
||||
* 项目空间路径
|
||||
*/
|
||||
private static final String PROJECT_PATH = "main/java";
|
||||
|
||||
/**
|
||||
* mybatis空间路径
|
||||
*/
|
||||
private static final String MYBATIS_PATH = "main/resources/mapper";
|
||||
|
||||
/**
|
||||
* 默认上级菜单,系统工具
|
||||
*/
|
||||
private static final String DEFAULT_PARENT_MENU_ID = "3";
|
||||
|
||||
/**
|
||||
* 设置模板变量信息
|
||||
*
|
||||
* @return 模板列表
|
||||
*/
|
||||
public static VelocityContext prepareContext(GenTable genTable) {
|
||||
String moduleName = genTable.getModuleName();
|
||||
String businessName = genTable.getBusinessName();
|
||||
String packageName = genTable.getPackageName();
|
||||
String tplCategory = genTable.getTplCategory();
|
||||
String functionName = genTable.getFunctionName();
|
||||
|
||||
VelocityContext velocityContext = new VelocityContext();
|
||||
velocityContext.put("tplCategory", genTable.getTplCategory());
|
||||
velocityContext.put("tableName", genTable.getTableName());
|
||||
velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
|
||||
velocityContext.put("ClassName", genTable.getClassName());
|
||||
velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
|
||||
velocityContext.put("moduleName", StrUtil.toSymbolCase(genTable.getModuleName(), '-'));
|
||||
velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
|
||||
velocityContext.put("businessName", genTable.getBusinessName());
|
||||
velocityContext.put("business_name", StrUtil.toUnderlineCase(genTable.getBusinessName()));
|
||||
velocityContext.put("business__name", StrUtil.toSymbolCase(genTable.getBusinessName(), '-'));
|
||||
velocityContext.put("businessname", StrUtil.toSymbolCase(genTable.getBusinessName(), ' '));
|
||||
velocityContext.put("basePackage", getPackagePrefix(packageName));
|
||||
velocityContext.put("packageName", packageName);
|
||||
velocityContext.put("author", genTable.getFunctionAuthor());
|
||||
velocityContext.put("datetime", DateUtils.getDate());
|
||||
velocityContext.put("pkColumn", genTable.getPkColumn());
|
||||
velocityContext.put("importList", getImportList(genTable));
|
||||
velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
|
||||
velocityContext.put("dicts", getDicts(genTable));
|
||||
velocityContext.put("dictList", getDictList(genTable));
|
||||
velocityContext.put("pkColumn", genTable.getPkColumn());
|
||||
velocityContext.put("columns", genTable.getColumns());
|
||||
velocityContext.put("table", genTable);
|
||||
velocityContext.put("StrUtil", new StrUtil());
|
||||
setMenuVelocityContext(velocityContext, genTable);
|
||||
if (GenConstants.TPL_TREE.equals(tplCategory)) {
|
||||
setTreeVelocityContext(velocityContext, genTable);
|
||||
}
|
||||
return velocityContext;
|
||||
}
|
||||
|
||||
public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) {
|
||||
String options = genTable.getOptions();
|
||||
Dict paramsObj = JsonUtils.parseMap(options);
|
||||
String parentMenuId = getParentMenuId(paramsObj);
|
||||
context.put("parentMenuId", parentMenuId);
|
||||
}
|
||||
|
||||
public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) {
|
||||
String options = genTable.getOptions();
|
||||
Dict paramsObj = JsonUtils.parseMap(options);
|
||||
String treeCode = getTreecode(paramsObj);
|
||||
String treeParentCode = getTreeParentCode(paramsObj);
|
||||
String treeName = getTreeName(paramsObj);
|
||||
|
||||
context.put("treeCode", treeCode);
|
||||
context.put("treeParentCode", treeParentCode);
|
||||
context.put("treeName", treeName);
|
||||
context.put("expandColumn", getExpandColumn(genTable));
|
||||
if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
|
||||
context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE));
|
||||
}
|
||||
if (paramsObj.containsKey(GenConstants.TREE_NAME)) {
|
||||
context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板信息
|
||||
*
|
||||
* @return 模板列表
|
||||
*/
|
||||
public static List<String> getTemplateList(String tplCategory) {
|
||||
List<String> templates = new ArrayList<>();
|
||||
templates.add("vm/java/domain.java.vm");
|
||||
templates.add("vm/java/vo.java.vm");
|
||||
templates.add("vm/java/bo.java.vm");
|
||||
templates.add("vm/java/mapper.java.vm");
|
||||
templates.add("vm/java/service.java.vm");
|
||||
templates.add("vm/java/serviceImpl.java.vm");
|
||||
templates.add("vm/java/controller.java.vm");
|
||||
templates.add("vm/xml/mapper.xml.vm");
|
||||
DataBaseType dataBaseType = DataBaseHelper.getDataBaseType();
|
||||
if (dataBaseType.isOracle()) {
|
||||
templates.add("vm/sql/oracle/sql.vm");
|
||||
} else if (dataBaseType.isPostgreSql()) {
|
||||
templates.add("vm/sql/postgres/sql.vm");
|
||||
} else if (dataBaseType.isSqlServer()) {
|
||||
templates.add("vm/sql/sqlserver/sql.vm");
|
||||
} else {
|
||||
templates.add("vm/sql/sql.vm");
|
||||
}
|
||||
templates.add("vm/soy/typings/api.d.ts.vm");
|
||||
templates.add("vm/soy/api/api.ts.vm");
|
||||
templates.add("vm/soy/modules/search.vue.vm");
|
||||
templates.add("vm/soy/modules/operate-drawer.vue.vm");
|
||||
if (GenConstants.TPL_CRUD.equals(tplCategory)) {
|
||||
templates.add("vm/soy/index.vue.vm");
|
||||
} else if (GenConstants.TPL_TREE.equals(tplCategory)) {
|
||||
templates.add("vm/soy/index-tree.vue.vm");
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名
|
||||
*/
|
||||
public static String getFileName(String template, GenTable genTable) {
|
||||
// 文件名称
|
||||
String fileName = "";
|
||||
// 包路径
|
||||
String packageName = genTable.getPackageName();
|
||||
// 模块名
|
||||
String moduleName = genTable.getModuleName();
|
||||
// 大写类名
|
||||
String className = genTable.getClassName();
|
||||
// 业务名称
|
||||
String businessName = genTable.getBusinessName();
|
||||
|
||||
String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/");
|
||||
String mybatisPath = MYBATIS_PATH + "/" + moduleName;
|
||||
String soybeanPath = "soy";
|
||||
String soybeanModuleName = StrUtil.toSymbolCase(moduleName, '-');
|
||||
if (template.contains("domain.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/{}.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("vo.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("bo.java.vm")) {
|
||||
fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className);
|
||||
}
|
||||
if (template.contains("mapper.java.vm")) {
|
||||
fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className);
|
||||
} else if (template.contains("service.java.vm")) {
|
||||
fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className);
|
||||
} else if (template.contains("serviceImpl.java.vm")) {
|
||||
fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className);
|
||||
} else if (template.contains("controller.java.vm")) {
|
||||
fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className);
|
||||
} else if (template.contains("mapper.xml.vm")) {
|
||||
fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className);
|
||||
} else if (template.contains("sql.vm")) {
|
||||
fileName = businessName + "Menu.sql";
|
||||
} else if (template.contains("index.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("index-tree.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/index.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("api.d.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/typings/api/{}.{}.api.d.ts", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("api.ts.vm")) {
|
||||
fileName = StringUtils.format("{}/service/api/{}/{}.ts", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("search.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-search.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
} else if (template.contains("operate-drawer.vue.vm")) {
|
||||
fileName = StringUtils.format("{}/views/{}/{}/modules/{}-operate-drawer.vue", soybeanPath, soybeanModuleName, StrUtil.toSymbolCase(businessName, '-'), StrUtil.toSymbolCase(businessName, '-'));
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取包前缀
|
||||
*
|
||||
* @param packageName 包名称
|
||||
* @return 包前缀名称
|
||||
*/
|
||||
public static String getPackagePrefix(String packageName) {
|
||||
int lastIndex = packageName.lastIndexOf(".");
|
||||
return StringUtils.substring(packageName, 0, lastIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列类型获取导入包
|
||||
*
|
||||
* @param genTable 业务表对象
|
||||
* @return 返回需要导入的包列表
|
||||
*/
|
||||
public static HashSet<String> getImportList(GenTable genTable) {
|
||||
List<GenTableColumn> columns = genTable.getColumns();
|
||||
HashSet<String> importList = new HashSet<>();
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) {
|
||||
importList.add("java.util.Date");
|
||||
importList.add("com.fasterxml.jackson.annotation.JsonFormat");
|
||||
} else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) {
|
||||
importList.add("java.math.BigDecimal");
|
||||
} else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) {
|
||||
importList.add("org.dromara.common.translation.annotation.Translation");
|
||||
importList.add("org.dromara.common.translation.constant.TransConstant");
|
||||
}
|
||||
}
|
||||
return importList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列类型获取字典组
|
||||
*
|
||||
* @param genTable 业务表对象
|
||||
* @return 返回字典组
|
||||
*/
|
||||
public static String getDicts(GenTable genTable) {
|
||||
List<GenTableColumn> columns = genTable.getColumns();
|
||||
Set<String> dicts = new HashSet<>();
|
||||
addDicts(dicts, columns);
|
||||
return StringUtils.join(dicts, ", ");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字典列表
|
||||
*
|
||||
* @param dicts 字典列表
|
||||
* @param columns 列集合
|
||||
*/
|
||||
public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
|
||||
column.getHtmlType(),
|
||||
new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
|
||||
dicts.add("'" + column.getDictType() + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列类型获取字典组
|
||||
*
|
||||
* @param genTable 业务表对象
|
||||
* @return 返回字典组
|
||||
*/
|
||||
public static Set<Map<String, Object>> getDictList(GenTable genTable) {
|
||||
List<GenTableColumn> columns = genTable.getColumns();
|
||||
Set<Map<String, Object>> dicts = new HashSet<>();
|
||||
addDictList(dicts, columns);
|
||||
return dicts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字典列表
|
||||
*
|
||||
* @param dicts 字典列表
|
||||
* @param columns 列集合
|
||||
*/
|
||||
public static void addDictList(Set<Map<String, Object>> dicts, List<GenTableColumn> columns) {
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
|
||||
column.getHtmlType(),
|
||||
new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
|
||||
Map<String, Object> dict = new HashMap<>();
|
||||
dict.put("type", column.getDictType());
|
||||
dict.put("name", StringUtils.toCamelCase(column.getDictType()));
|
||||
dict.put("immediate", !column.isList());
|
||||
dicts.add(dict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限前缀
|
||||
*
|
||||
* @param moduleName 模块名称
|
||||
* @param businessName 业务名称
|
||||
* @return 返回权限前缀
|
||||
*/
|
||||
public static String getPermissionPrefix(String moduleName, String businessName) {
|
||||
return StringUtils.format("{}:{}", moduleName, businessName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上级菜单ID字段
|
||||
*
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 上级菜单ID字段
|
||||
*/
|
||||
public static String getParentMenuId(Dict paramsObj) {
|
||||
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID)
|
||||
&& StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) {
|
||||
return paramsObj.getStr(GenConstants.PARENT_MENU_ID);
|
||||
}
|
||||
return DEFAULT_PARENT_MENU_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树编码
|
||||
*
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树编码
|
||||
*/
|
||||
public static String getTreecode(Map<String, Object> paramsObj) {
|
||||
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) {
|
||||
return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE)));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树父编码
|
||||
*
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树父编码
|
||||
*/
|
||||
public static String getTreeParentCode(Dict paramsObj) {
|
||||
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) {
|
||||
return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树名称
|
||||
*
|
||||
* @param paramsObj 生成其他选项
|
||||
* @return 树名称
|
||||
*/
|
||||
public static String getTreeName(Dict paramsObj) {
|
||||
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) {
|
||||
return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME));
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要在哪一列上面显示展开按钮
|
||||
*
|
||||
* @param genTable 业务表对象
|
||||
* @return 展开按钮列序号
|
||||
*/
|
||||
public static int getExpandColumn(GenTable genTable) {
|
||||
String options = genTable.getOptions();
|
||||
Dict paramsObj = JsonUtils.parseMap(options);
|
||||
String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
|
||||
int num = 0;
|
||||
for (GenTableColumn column : genTable.getColumns()) {
|
||||
if (column.isList()) {
|
||||
num++;
|
||||
String columnName = column.getColumnName();
|
||||
if (columnName.equals(treeName)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
const app = createApp(App)
|
||||
app.use(hljsVuePlugin).mount('#app'<
|
||||
@@ -33,7 +33,7 @@ INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`
|
||||
UPDATE `sys_menu` SET `component` = 'FrameView', `query_param` = 'https://ruoyi.xlsea.cn/admin/', `is_frame` = 2, `icon` = 'bx:bxl-spring-boot', `menu_name` = 'menu.monitor_admin' WHERE `menu_id` = 117;
|
||||
UPDATE `sys_menu` SET `component` = 'FrameView', `query_param` = 'https://preview.snailjob.opensnail.com/', `is_frame` = 2, `icon` = 'gridicons:scheduled', `menu_name` = 'menu.monitor_snail-job' WHERE `menu_id` = 120;
|
||||
-- 外链类型
|
||||
UPDATE `sys_menu` SET `menu_name` = 'RuoYi-Vue-Plus', `order_num` = 100, `path` = 'https://gitee.com/dromara/RuoYi-Vue-Plus', `component` = 'FrameView', `remark` = 'RuoYi-Vue-Plus 仓库地址' WHERE `menu_id` = 4;
|
||||
UPDATE `sys_menu` SET `menu_name` = 'RuoYi-Vue-Plus', `order_num` = 100, `path` = 'https://gitee.com/dromara/RuoYi-Vue-Plus', `component` = 'FrameView', `icon` = 'local-icon-gitee', `remark` = 'RuoYi-Vue-Plus 仓库地址' WHERE `menu_id` = 4;
|
||||
INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (7, 'Soybean Admin', 0, 100, 'https://github.com/soybeanjs', 'FrameView', '', 0, 0, 'M', '0', '0', '', 'mdi:github', 103, 1, sysdate(), null, null, 'Soybean Admin 仓库地址') ON DUPLICATE KEY UPDATE `update_time` = sysdate();
|
||||
INSERT INTO `sys_menu` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (8, 'RuoYi-Plus-Soybean', 0, 100, 'https://gitee.com/xlsea/ruoyi-plus-soybean', 'FrameView', '', 0, 0, 'M', '0', '0', '', 'local-icon-gitee', 103, 1, sysdate(), null, null, 'RuoYi-Plus-Soybean 仓库地址') ON DUPLICATE KEY UPDATE `update_time` = sysdate();
|
||||
|
||||
|
||||
+1
-1
@@ -126,8 +126,8 @@ watch(visible, () => {
|
||||
restoreValidation();
|
||||
}
|
||||
});
|
||||
|
||||
#if($tplCategory == 'tree')
|
||||
|
||||
const treeOptions = computed(() => {
|
||||
return [
|
||||
{
|
||||
|
||||
Vendored
+1
-1
@@ -69,8 +69,8 @@ async function search() {
|
||||
#end
|
||||
emit('search');
|
||||
}
|
||||
|
||||
#if($tplCategory == 'tree')
|
||||
|
||||
const treeOptions = computed(() => {
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -75,7 +75,6 @@
|
||||
"highlight.js": "^11.11.1",
|
||||
"jsencrypt": "^3.5.4",
|
||||
"json5": "2.2.3",
|
||||
"monaco-editor": "^0.55.1",
|
||||
"naive-ui": "2.43.2",
|
||||
"nprogress": "0.2.0",
|
||||
"pinia": "3.0.4",
|
||||
@@ -114,7 +113,6 @@
|
||||
"unplugin-icons": "22.5.0",
|
||||
"unplugin-vue-components": "30.0.0",
|
||||
"vite": "7.2.6",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-progress": "0.0.7",
|
||||
"vite-plugin-svg-icons": "2.0.1",
|
||||
"vite-plugin-vue-devtools": "8.0.5",
|
||||
|
||||
Generated
-37
@@ -59,9 +59,6 @@ importers:
|
||||
json5:
|
||||
specifier: 2.2.3
|
||||
version: 2.2.3
|
||||
monaco-editor:
|
||||
specifier: ^0.55.1
|
||||
version: 0.55.1
|
||||
naive-ui:
|
||||
specifier: 2.43.2
|
||||
version: 2.43.2(vue@3.5.25(typescript@5.9.3))
|
||||
@@ -171,9 +168,6 @@ importers:
|
||||
vite:
|
||||
specifier: 7.2.6
|
||||
version: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(sass@1.94.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
vite-plugin-monaco-editor:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(monaco-editor@0.55.1)
|
||||
vite-plugin-progress:
|
||||
specifier: 0.0.7
|
||||
version: 0.0.7(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(sass@1.94.2)(tsx@4.21.0)(yaml@2.8.2))
|
||||
@@ -2921,9 +2915,6 @@ packages:
|
||||
resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
dompurify@3.2.7:
|
||||
resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==}
|
||||
|
||||
dompurify@3.3.0:
|
||||
resolution: {integrity: sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==}
|
||||
|
||||
@@ -3949,11 +3940,6 @@ packages:
|
||||
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||
hasBin: true
|
||||
|
||||
marked@14.0.0:
|
||||
resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
marked@16.4.2:
|
||||
resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==}
|
||||
engines: {node: '>= 20'}
|
||||
@@ -4036,9 +4022,6 @@ packages:
|
||||
mlly@1.8.0:
|
||||
resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==}
|
||||
|
||||
monaco-editor@0.55.1:
|
||||
resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==}
|
||||
|
||||
mrmime@2.0.1:
|
||||
resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5129,11 +5112,6 @@ packages:
|
||||
'@nuxt/kit':
|
||||
optional: true
|
||||
|
||||
vite-plugin-monaco-editor@1.1.0:
|
||||
resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==}
|
||||
peerDependencies:
|
||||
monaco-editor: '>=0.33.0'
|
||||
|
||||
vite-plugin-progress@0.0.7:
|
||||
resolution: {integrity: sha512-zyvKdcc/X+6hnw3J1HVV1TKrlFKC4Rh8GnDnWG/2qhRXjqytTcM++xZ+SAPnoDsSyWl8O93ymK0wZRgHAoglEQ==}
|
||||
engines: {node: '>=14', pnpm: '>=7.0.0'}
|
||||
@@ -8215,10 +8193,6 @@ snapshots:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
|
||||
dompurify@3.2.7:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
|
||||
dompurify@3.3.0:
|
||||
optionalDependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
@@ -9363,8 +9337,6 @@ snapshots:
|
||||
punycode.js: 2.3.1
|
||||
uc.micro: 2.1.0
|
||||
|
||||
marked@14.0.0: {}
|
||||
|
||||
marked@16.4.2: {}
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
@@ -9471,11 +9443,6 @@ snapshots:
|
||||
pkg-types: 1.3.1
|
||||
ufo: 1.6.1
|
||||
|
||||
monaco-editor@0.55.1:
|
||||
dependencies:
|
||||
dompurify: 3.2.7
|
||||
marked: 14.0.0
|
||||
|
||||
mrmime@2.0.1: {}
|
||||
|
||||
ms@2.0.0: {}
|
||||
@@ -10744,10 +10711,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-monaco-editor@1.1.0(monaco-editor@0.55.1):
|
||||
dependencies:
|
||||
monaco-editor: 0.55.1
|
||||
|
||||
vite-plugin-progress@0.0.7(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(sass@1.94.2)(tsx@4.21.0)(yaml@2.8.2)):
|
||||
dependencies:
|
||||
picocolors: 1.1.1
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref, watch } from 'vue';
|
||||
import * as monaco from 'monaco-editor';
|
||||
import type { editor } from 'monaco-editor';
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
|
||||
defineOptions({ name: 'MonacoEditor' });
|
||||
|
||||
interface Props {
|
||||
language?: string;
|
||||
readOnly?: boolean;
|
||||
valueFormat?: string;
|
||||
height?: string;
|
||||
config?: editor.IStandaloneEditorConstructionOptions;
|
||||
lineNumbers?: 'on' | 'off';
|
||||
autoToggleTheme?: boolean;
|
||||
theme?: 'vs-light' | 'vs-dark' | 'hc-black';
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
language: 'json',
|
||||
readOnly: false,
|
||||
valueFormat: 'string',
|
||||
lineNumbers: 'on',
|
||||
theme: 'vs-light',
|
||||
height: '150px',
|
||||
autoToggleTheme: true,
|
||||
config: () => ({
|
||||
selectOnLineNumbers: true,
|
||||
minimap: {
|
||||
enabled: false
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const value = defineModel<any>('value', { required: true, default: '' });
|
||||
|
||||
const isActive = ref(false);
|
||||
const editContainer = ref<HTMLElement | null>(null);
|
||||
|
||||
let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null;
|
||||
const { darkMode: isDark } = useThemeStore();
|
||||
|
||||
function handleToggleTheme() {
|
||||
if (isDark) {
|
||||
monaco.editor.setTheme('vs-dark');
|
||||
} else {
|
||||
monaco.editor.setTheme('vs-light');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文本
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
function setValue(text: string) {
|
||||
monacoEditor?.setValue(text || '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 光标处插入文本
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
function insertText(text: string) {
|
||||
// 获取光标位置
|
||||
const position = monacoEditor?.getPosition();
|
||||
// 未获取到光标位置信息
|
||||
if (!position) {
|
||||
return;
|
||||
}
|
||||
// 插入
|
||||
monacoEditor?.executeEdits('', [
|
||||
{
|
||||
range: new monaco.Range(position.lineNumber, position.column, position.lineNumber, position.column),
|
||||
text
|
||||
}
|
||||
]);
|
||||
// 设置新的光标位置
|
||||
monacoEditor?.setPosition({ ...position, column: position.column + text.length });
|
||||
// 重新聚焦
|
||||
monacoEditor?.focus();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
monacoEditor = monaco.editor.create(editContainer.value as HTMLElement, {
|
||||
value: getValue(),
|
||||
...props.config,
|
||||
language: props.language,
|
||||
readOnly: props.readOnly,
|
||||
lineNumbers: props.lineNumbers,
|
||||
theme: props.theme,
|
||||
automaticLayout: false
|
||||
});
|
||||
|
||||
// 自动切换主题
|
||||
if (props.autoToggleTheme) {
|
||||
watch(
|
||||
() => isDark,
|
||||
() => {
|
||||
nextTick(() => handleToggleTheme());
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// 获取值
|
||||
function getValue() {
|
||||
// valueFormat 为json 格式,需要转换处理
|
||||
if (props.valueFormat === 'json') {
|
||||
if (value.value) {
|
||||
return JSON.stringify(value.value, null, 2);
|
||||
}
|
||||
}
|
||||
return value.value ?? '';
|
||||
}
|
||||
|
||||
// 监听值变化
|
||||
monacoEditor.onDidChangeModelContent(() => {
|
||||
const currenValue = monacoEditor?.getValue();
|
||||
|
||||
// valueFormat 为json 格式,需要转换处理
|
||||
if (props.valueFormat === 'json' && currenValue) {
|
||||
value.value = JSON.parse(currenValue);
|
||||
return;
|
||||
}
|
||||
|
||||
value.value = currenValue ?? '';
|
||||
});
|
||||
|
||||
const decorationsOverviewRuler = document.querySelector('.decorationsOverviewRuler');
|
||||
decorationsOverviewRuler?.removeAttribute('width');
|
||||
decorationsOverviewRuler?.removeAttribute('height');
|
||||
});
|
||||
|
||||
watch(
|
||||
() => value.value,
|
||||
val => {
|
||||
monacoEditor?.setValue(val || '');
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.language,
|
||||
val => {
|
||||
monaco.editor.setModelLanguage(monacoEditor?.getModel() as monaco.editor.ITextModel, val);
|
||||
}
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
setValue,
|
||||
insertText
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NCard
|
||||
class="h-full"
|
||||
:class="isActive ? 'code-editor-border' : ''"
|
||||
@click="() => (isActive = true)"
|
||||
@mouseout="() => (isActive = false)"
|
||||
>
|
||||
<div ref="editContainer" class="azd-code-editor" :style="{ height: height }" />
|
||||
</NCard>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.n-card {
|
||||
border: 1px solid rgb(224, 224, 230) !important;
|
||||
|
||||
:deep(.n-card__content) {
|
||||
padding: 6px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.n-card {
|
||||
--n-color-modal: rgb(30, 30, 30, 1) !important;
|
||||
border: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.n-card:hover {
|
||||
border: 1px solid rgb(var(--primary-color)) !important;
|
||||
}
|
||||
|
||||
.code-editor-border {
|
||||
border: 1px solid rgb(var(--primary-color)) !important;
|
||||
box-shadow: 0 0 0 2px rgba(30, 94, 253, 0.2) !important;
|
||||
}
|
||||
|
||||
.azd-code-editor {
|
||||
--n-border-radius: 3px;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 150px;
|
||||
border-radius: var(--n-border-radius);
|
||||
|
||||
:deep(.monaco-editor) {
|
||||
height: 100%;
|
||||
border-radius: var(--n-border-radius) !important;
|
||||
|
||||
.overflow-guard {
|
||||
border-radius: var(--n-border-radius) !important;
|
||||
}
|
||||
|
||||
.decorationsOverviewRuler,
|
||||
.scrollbar,
|
||||
.slider {
|
||||
border: 0 !important;
|
||||
width: 7px !important;
|
||||
color: rgba(0, 0, 0, 0.5) !important;
|
||||
border-radius: 7px !important;
|
||||
}
|
||||
|
||||
.scroll-decoration {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Vendored
+2
@@ -68,6 +68,7 @@ declare module 'vue' {
|
||||
MenuTreeSelect: typeof import('./../components/custom/menu-tree-select.vue')['default']
|
||||
MonacoEditor: typeof import('./../components/common/monaco-editor.vue')['default']
|
||||
NA: typeof import('naive-ui')['NA']
|
||||
NAffix: typeof import('naive-ui')['NAffix']
|
||||
NAlert: typeof import('naive-ui')['NAlert']
|
||||
NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
NBadge: typeof import('naive-ui')['NBadge']
|
||||
@@ -217,6 +218,7 @@ declare global {
|
||||
const MenuTreeSelect: typeof import('./../components/custom/menu-tree-select.vue')['default']
|
||||
const MonacoEditor: typeof import('./../components/common/monaco-editor.vue')['default']
|
||||
const NA: typeof import('naive-ui')['NA']
|
||||
const NAffix: typeof import('naive-ui')['NAffix']
|
||||
const NAlert: typeof import('naive-ui')['NAlert']
|
||||
const NAvatar: typeof import('naive-ui')['NAvatar']
|
||||
const NBadge: typeof import('naive-ui')['NBadge']
|
||||
|
||||
@@ -2,9 +2,22 @@
|
||||
import { ref, watch } from 'vue';
|
||||
import { useClipboard } from '@vueuse/core';
|
||||
import { useLoading } from '@sa/hooks';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import java from 'highlight.js/lib/languages/java';
|
||||
import xml from 'highlight.js/lib/languages/xml';
|
||||
import sql from 'highlight.js/lib/languages/sql';
|
||||
import typescript from 'highlight.js/lib/languages/typescript';
|
||||
import html from 'highlight.js/lib/languages/vbscript-html';
|
||||
import plaintext from 'highlight.js/lib/languages/plaintext';
|
||||
import { fetchGetGenPreview } from '@/service/api/tool';
|
||||
import { $t } from '@/locales';
|
||||
import MonacoEditor from '@/components/common/monaco-editor.vue';
|
||||
|
||||
hljs.registerLanguage('java', java);
|
||||
hljs.registerLanguage('xml', xml);
|
||||
hljs.registerLanguage('sql', sql);
|
||||
hljs.registerLanguage('typescript', typescript);
|
||||
hljs.registerLanguage('html', html);
|
||||
hljs.registerLanguage('plaintext', plaintext);
|
||||
|
||||
defineOptions({
|
||||
name: 'GenTablePreviewDrawer'
|
||||
@@ -115,31 +128,73 @@ function getGenLanguage(name: string) {
|
||||
}
|
||||
|
||||
if (name.endsWith('.vue')) {
|
||||
return 'html';
|
||||
return 'vue';
|
||||
}
|
||||
|
||||
return 'plaintext';
|
||||
}
|
||||
|
||||
function splitVueSFC(source: string) {
|
||||
const lineNumbers = source.split('\n').length;
|
||||
const scriptOpenTag = '<script setup';
|
||||
const scriptCloseTag = `<${'/'}script>`;
|
||||
|
||||
// 找到 <script setup ...> 的起始位置
|
||||
const startIdx = source.indexOf(scriptOpenTag);
|
||||
if (startIdx === -1) throw new Error('未找到 <script setup>');
|
||||
|
||||
// 找到 <script ...> 标签的结束位置(即第一个 >)
|
||||
const scriptTagEndIdx = source.indexOf('>', startIdx);
|
||||
const part1 = source.slice(startIdx, scriptTagEndIdx + 1);
|
||||
|
||||
// 找到 <\/script>
|
||||
const endIdx = source.indexOf(scriptCloseTag);
|
||||
if (endIdx === -1) throw new Error(`未找到 <${'/'}script>`);
|
||||
|
||||
// 中间脚本内容
|
||||
const part2 = source.slice(scriptTagEndIdx + 1, endIdx).trim();
|
||||
|
||||
// script 后的内容
|
||||
const part3 = source.slice(endIdx).trim();
|
||||
|
||||
return { part1, part2, part3, lineNumbers };
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NDrawer v-model:show="visible" display-directive="show" width="100%">
|
||||
<NDrawerContent title="代码预览" :native-scrollbar="false" closable>
|
||||
<NSpin :show="loading" class="h-full" content-class="h-full">
|
||||
<div class="flex flex-row">
|
||||
<NTabs v-model:value="tab" type="line" placement="left" class="h-full" pane-class="h-full">
|
||||
<div class="flex flex-col">
|
||||
<NTabs
|
||||
v-model:value="tab"
|
||||
type="card"
|
||||
class="sticky top-0 h-full bg-white dark:bg-#2f2e32"
|
||||
pane-class="h-full"
|
||||
>
|
||||
<NTab v-for="(gen, index) in Object.keys(previewData)" :key="index" :name="gen" display-directive="show">
|
||||
{{ genMap[gen] }}
|
||||
</NTab>
|
||||
</NTabs>
|
||||
<MonacoEditor
|
||||
v-model:value="previewData[tab]"
|
||||
class="tab-pane"
|
||||
read-only
|
||||
<div v-if="tab.endsWith('.vue.vm')" class="flex p-16px">
|
||||
<pre class="code-line-numbers">{{
|
||||
Array.from({ length: splitVueSFC(previewData[tab]).lineNumbers }, (_, i) => i + 1).join('\n')
|
||||
}}</pre>
|
||||
<div>
|
||||
<NCode :hljs="hljs" :code="splitVueSFC(previewData[tab]).part1" language="xml" />
|
||||
<NCode :hljs="hljs" :code="splitVueSFC(previewData[tab]).part2" language="typescript" />
|
||||
<NCode :hljs="hljs" :code="splitVueSFC(previewData[tab]).part3" language="xml" />
|
||||
</div>
|
||||
</div>
|
||||
<NCode
|
||||
v-else
|
||||
class="p-16px"
|
||||
:hljs="hljs"
|
||||
:code="previewData[tab]"
|
||||
:language="getGenLanguage(genMap[tab])"
|
||||
height="calc(100vh - 162px)"
|
||||
show-line-numbers
|
||||
/>
|
||||
<div class="position-absolute right-42px top-2px">
|
||||
<div class="position-absolute right-42px top-58px">
|
||||
<NButton text :focusable="false" class="flex-center" @click="handleCopyCode">
|
||||
<template #icon>
|
||||
<icon-ep-copy-document class="text-14px" />
|
||||
@@ -172,11 +227,14 @@ function getGenLanguage(name: string) {
|
||||
width: 5px !important;
|
||||
}
|
||||
|
||||
.tab-pane {
|
||||
transition:
|
||||
color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
padding-left: 12px;
|
||||
.code-line-numbers {
|
||||
margin: 0;
|
||||
line-height: inherit;
|
||||
font-size: inherit;
|
||||
user-select: none;
|
||||
padding-right: 12px;
|
||||
text-align: right;
|
||||
transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
color: rgb(118, 124, 130);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user