fix: 删除原有菜单'系统参数'、'角色管理',初步整合xpack插件模块

This commit is contained in:
fit2cloud-chenyw 2021-05-30 20:24:54 +08:00
parent d6d6dcda18
commit ae733b0776
32 changed files with 635 additions and 72 deletions

View File

@ -351,6 +351,13 @@
<artifactId>c3p0</artifactId> <artifactId>c3p0</artifactId>
<version>0.9.1.2</version> <version>0.9.1.2</version>
</dependency> </dependency>
<!--由于暂时插件接口未注册到公司仓库请先down下代码安装到本地仓库
https://github.com/dataease/dataease-plugins-->
<dependency>
<groupId>io.dataease</groupId>
<artifactId>dataease-plugin-xpack</artifactId>
<version>1.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -29,6 +29,8 @@ public class DynamicMenuDto implements Serializable {
private Integer type; private Integer type;
private Boolean isPlugin;
private List<DynamicMenuDto> children; private List<DynamicMenuDto> children;
} }

View File

@ -13,9 +13,11 @@ import io.dataease.auth.util.RsaUtil;
import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CodingUtil; import io.dataease.commons.utils.CodingUtil;
import io.dataease.commons.utils.ServletUtils; import io.dataease.commons.utils.ServletUtils;
/*import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.dto.response.SysSettingDto; import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.service.DePluginXpackService;*/
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
import io.dataease.plugins.xpack.display.service.DisPlayXpackService;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
@ -108,14 +110,15 @@ public class AuthServer implements AuthApi {
SysUserEntity userById = authUserService.getUserById(4L); SysUserEntity userById = authUserService.getUserById(4L);
String nickName = userById.getNickName(); String nickName = userById.getNickName();
// System.out.println(nickName); // System.out.println(nickName);
/* Map<String, DePluginXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(DePluginXpackService.class); Map<String, DisPlayXpackService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType(DisPlayXpackService.class);
for (Map.Entry entry : beansOfType.entrySet()) { for (Map.Entry entry : beansOfType.entrySet()) {
Object key = entry.getKey(); Object key = entry.getKey();
DePluginXpackService value = (DePluginXpackService)entry.getValue(); DisPlayXpackService value = (DisPlayXpackService)entry.getValue();
List<SysSettingDto> sysSettingDtos = value.systemSettings(); List<SysSettingDto> sysSettingDtos = value.systemSettings();
String name = entry.getValue().getClass().getName(); String name = entry.getValue().getClass().getName();
System.out.println("key: "+ key + ", value: "+ name); System.out.println("key: "+ key + ", value: "+ name);
}*/ }
return "apple"; return "apple";
} }
} }

View File

@ -5,6 +5,11 @@ import io.dataease.auth.entity.SysUserEntity;
import io.dataease.base.mapper.ext.AuthMapper; import io.dataease.base.mapper.ext.AuthMapper;
import io.dataease.auth.service.AuthUserService; import io.dataease.auth.service.AuthUserService;
import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.constants.AuthConstants;
import io.dataease.plugins.common.dto.PluginSysMenu;
import io.dataease.plugins.common.service.PluginMenuService;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.util.PluginUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
@ -53,6 +58,14 @@ public class AuthUserServiceImpl implements AuthUserService {
@Override @Override
public List<String> permissions(Long userId){ public List<String> permissions(Long userId){
List<String> permissions = authMapper.permissions(userId); List<String> permissions = authMapper.permissions(userId);
List<PluginSysMenu> pluginSysMenus = PluginUtils.pluginMenus();
if (CollectionUtils.isNotEmpty(pluginSysMenus)) {
List<Long> menuIds = authMapper.userMenuIds(userId);
List<String> pluginPermissions = pluginSysMenus.stream().
filter(sysMenu -> menuIds.contains(sysMenu.getMenuId()))
.map(menu -> menu.getPermission()).collect(Collectors.toList());
permissions.addAll(pluginPermissions);
}
return permissions.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList()); return permissions.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
} }

View File

@ -6,6 +6,9 @@ import io.dataease.auth.service.DynamicMenuService;
import io.dataease.base.domain.SysMenu; import io.dataease.base.domain.SysMenu;
import io.dataease.base.domain.SysMenuExample; import io.dataease.base.domain.SysMenuExample;
import io.dataease.base.mapper.SysMenuMapper; import io.dataease.base.mapper.SysMenuMapper;
import io.dataease.plugins.common.dto.PluginSysMenu;
import io.dataease.plugins.util.PluginUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,6 +28,12 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
sysMenuExample.setOrderByClause(" menu_sort "); sysMenuExample.setOrderByClause(" menu_sort ");
List<SysMenu> sysMenus = sysMenuMapper.selectByExample(sysMenuExample); List<SysMenu> sysMenus = sysMenuMapper.selectByExample(sysMenuExample);
List<DynamicMenuDto> dynamicMenuDtos = sysMenus.stream().map(this::convert).collect(Collectors.toList()); List<DynamicMenuDto> dynamicMenuDtos = sysMenus.stream().map(this::convert).collect(Collectors.toList());
//增加插件中的菜单
List<PluginSysMenu> pluginSysMenus = PluginUtils.pluginMenus();
if (CollectionUtils.isNotEmpty(pluginSysMenus) ) {
List<DynamicMenuDto> pluginDtos = pluginSysMenus.stream().map(this::convert).collect(Collectors.toList());
dynamicMenuDtos.addAll(pluginDtos);
}
List<DynamicMenuDto> result = buildTree(dynamicMenuDtos); List<DynamicMenuDto> result = buildTree(dynamicMenuDtos);
return result; return result;
} }
@ -44,6 +53,25 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
dynamicMenuDto.setMeta(menuMeta); dynamicMenuDto.setMeta(menuMeta);
dynamicMenuDto.setPermission(sysMenu.getPermission()); dynamicMenuDto.setPermission(sysMenu.getPermission());
dynamicMenuDto.setHidden(sysMenu.getHidden()); dynamicMenuDto.setHidden(sysMenu.getHidden());
dynamicMenuDto.setIsPlugin(false);
return dynamicMenuDto;
}
private DynamicMenuDto convert(PluginSysMenu sysMenu){
DynamicMenuDto dynamicMenuDto = new DynamicMenuDto();
dynamicMenuDto.setId(sysMenu.getMenuId());
dynamicMenuDto.setPid(sysMenu.getPid());
dynamicMenuDto.setName(sysMenu.getName());
dynamicMenuDto.setPath(sysMenu.getPath());
dynamicMenuDto.setRedirect(null);
dynamicMenuDto.setType(sysMenu.getType());
dynamicMenuDto.setComponent(sysMenu.getComponent());
MenuMeta menuMeta = new MenuMeta();
menuMeta.setTitle(sysMenu.getTitle());
menuMeta.setIcon(sysMenu.getIcon());
dynamicMenuDto.setMeta(menuMeta);
dynamicMenuDto.setPermission(sysMenu.getPermission());
dynamicMenuDto.setHidden(sysMenu.getHidden());
dynamicMenuDto.setIsPlugin(true);
return dynamicMenuDto; return dynamicMenuDto;
} }

View File

@ -47,7 +47,7 @@ public class ShiroServiceImpl implements ShiroService {
filterChainDefinitionMap.put("/system/ui/**", ANON); filterChainDefinitionMap.put("/system/ui/**", ANON);
filterChainDefinitionMap.put("/PluginDemo.js", ANON); filterChainDefinitionMap.put("/SystemParam.js", ANON);
filterChainDefinitionMap.put("/DeXPack.js", ANON); filterChainDefinitionMap.put("/DeXPack.js", ANON);
filterChainDefinitionMap.put("/api/auth/test", ANON); filterChainDefinitionMap.put("/api/auth/test", ANON);

View File

@ -21,6 +21,8 @@ public class MyPlugin implements Serializable {
private String creator; private String creator;
private Boolean loadMybatis;
private Long releaseTime; private Long releaseTime;
private Long installTime; private Long installTime;

View File

@ -624,6 +624,66 @@ public class MyPluginExample {
return (Criteria) this; return (Criteria) this;
} }
public Criteria andLoadMybatisIsNull() {
addCriterion("load_mybatis is null");
return (Criteria) this;
}
public Criteria andLoadMybatisIsNotNull() {
addCriterion("load_mybatis is not null");
return (Criteria) this;
}
public Criteria andLoadMybatisEqualTo(Boolean value) {
addCriterion("load_mybatis =", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisNotEqualTo(Boolean value) {
addCriterion("load_mybatis <>", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisGreaterThan(Boolean value) {
addCriterion("load_mybatis >", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisGreaterThanOrEqualTo(Boolean value) {
addCriterion("load_mybatis >=", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisLessThan(Boolean value) {
addCriterion("load_mybatis <", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisLessThanOrEqualTo(Boolean value) {
addCriterion("load_mybatis <=", value, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisIn(List<Boolean> values) {
addCriterion("load_mybatis in", values, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisNotIn(List<Boolean> values) {
addCriterion("load_mybatis not in", values, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisBetween(Boolean value1, Boolean value2) {
addCriterion("load_mybatis between", value1, value2, "loadMybatis");
return (Criteria) this;
}
public Criteria andLoadMybatisNotBetween(Boolean value1, Boolean value2) {
addCriterion("load_mybatis not between", value1, value2, "loadMybatis");
return (Criteria) this;
}
public Criteria andReleaseTimeIsNull() { public Criteria andReleaseTimeIsNull() {
addCriterion("release_time is null"); addCriterion("release_time is null");
return (Criteria) this; return (Criteria) this;

View File

@ -10,6 +10,7 @@
<result column="version" jdbcType="VARCHAR" property="version" /> <result column="version" jdbcType="VARCHAR" property="version" />
<result column="install_type" jdbcType="INTEGER" property="installType" /> <result column="install_type" jdbcType="INTEGER" property="installType" />
<result column="creator" jdbcType="VARCHAR" property="creator" /> <result column="creator" jdbcType="VARCHAR" property="creator" />
<result column="load_mybatis" jdbcType="BIT" property="loadMybatis" />
<result column="release_time" jdbcType="BIGINT" property="releaseTime" /> <result column="release_time" jdbcType="BIGINT" property="releaseTime" />
<result column="install_time" jdbcType="BIGINT" property="installTime" /> <result column="install_time" jdbcType="BIGINT" property="installTime" />
<result column="module_name" jdbcType="VARCHAR" property="moduleName" /> <result column="module_name" jdbcType="VARCHAR" property="moduleName" />
@ -75,8 +76,8 @@
</where> </where>
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
plugin_id, `name`, `free`, cost, descript, version, install_type, creator, release_time, plugin_id, `name`, `free`, cost, descript, version, install_type, creator, load_mybatis,
install_time, module_name, bean_name, icon release_time, install_time, module_name, bean_name, icon
</sql> </sql>
<select id="selectByExample" parameterType="io.dataease.base.domain.MyPluginExample" resultMap="BaseResultMap"> <select id="selectByExample" parameterType="io.dataease.base.domain.MyPluginExample" resultMap="BaseResultMap">
select select
@ -111,14 +112,14 @@
<insert id="insert" parameterType="io.dataease.base.domain.MyPlugin"> <insert id="insert" parameterType="io.dataease.base.domain.MyPlugin">
insert into my_plugin (plugin_id, `name`, `free`, insert into my_plugin (plugin_id, `name`, `free`,
cost, descript, version, cost, descript, version,
install_type, creator, release_time, install_type, creator, load_mybatis,
install_time, module_name, bean_name, release_time, install_time, module_name,
icon) bean_name, icon)
values (#{pluginId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{free,jdbcType=BIT}, values (#{pluginId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{free,jdbcType=BIT},
#{cost,jdbcType=INTEGER}, #{descript,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR}, #{cost,jdbcType=INTEGER}, #{descript,jdbcType=VARCHAR}, #{version,jdbcType=VARCHAR},
#{installType,jdbcType=INTEGER}, #{creator,jdbcType=VARCHAR}, #{releaseTime,jdbcType=BIGINT}, #{installType,jdbcType=INTEGER}, #{creator,jdbcType=VARCHAR}, #{loadMybatis,jdbcType=BIT},
#{installTime,jdbcType=BIGINT}, #{moduleName,jdbcType=VARCHAR}, #{beanName,jdbcType=VARCHAR}, #{releaseTime,jdbcType=BIGINT}, #{installTime,jdbcType=BIGINT}, #{moduleName,jdbcType=VARCHAR},
#{icon,jdbcType=VARCHAR}) #{beanName,jdbcType=VARCHAR}, #{icon,jdbcType=VARCHAR})
</insert> </insert>
<insert id="insertSelective" parameterType="io.dataease.base.domain.MyPlugin"> <insert id="insertSelective" parameterType="io.dataease.base.domain.MyPlugin">
insert into my_plugin insert into my_plugin
@ -147,6 +148,9 @@
<if test="creator != null"> <if test="creator != null">
creator, creator,
</if> </if>
<if test="loadMybatis != null">
load_mybatis,
</if>
<if test="releaseTime != null"> <if test="releaseTime != null">
release_time, release_time,
</if> </if>
@ -188,6 +192,9 @@
<if test="creator != null"> <if test="creator != null">
#{creator,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR},
</if> </if>
<if test="loadMybatis != null">
#{loadMybatis,jdbcType=BIT},
</if>
<if test="releaseTime != null"> <if test="releaseTime != null">
#{releaseTime,jdbcType=BIGINT}, #{releaseTime,jdbcType=BIGINT},
</if> </if>
@ -238,6 +245,9 @@
<if test="record.creator != null"> <if test="record.creator != null">
creator = #{record.creator,jdbcType=VARCHAR}, creator = #{record.creator,jdbcType=VARCHAR},
</if> </if>
<if test="record.loadMybatis != null">
load_mybatis = #{record.loadMybatis,jdbcType=BIT},
</if>
<if test="record.releaseTime != null"> <if test="record.releaseTime != null">
release_time = #{record.releaseTime,jdbcType=BIGINT}, release_time = #{record.releaseTime,jdbcType=BIGINT},
</if> </if>
@ -268,6 +278,7 @@
version = #{record.version,jdbcType=VARCHAR}, version = #{record.version,jdbcType=VARCHAR},
install_type = #{record.installType,jdbcType=INTEGER}, install_type = #{record.installType,jdbcType=INTEGER},
creator = #{record.creator,jdbcType=VARCHAR}, creator = #{record.creator,jdbcType=VARCHAR},
load_mybatis = #{record.loadMybatis,jdbcType=BIT},
release_time = #{record.releaseTime,jdbcType=BIGINT}, release_time = #{record.releaseTime,jdbcType=BIGINT},
install_time = #{record.installTime,jdbcType=BIGINT}, install_time = #{record.installTime,jdbcType=BIGINT},
module_name = #{record.moduleName,jdbcType=VARCHAR}, module_name = #{record.moduleName,jdbcType=VARCHAR},
@ -301,6 +312,9 @@
<if test="creator != null"> <if test="creator != null">
creator = #{creator,jdbcType=VARCHAR}, creator = #{creator,jdbcType=VARCHAR},
</if> </if>
<if test="loadMybatis != null">
load_mybatis = #{loadMybatis,jdbcType=BIT},
</if>
<if test="releaseTime != null"> <if test="releaseTime != null">
release_time = #{releaseTime,jdbcType=BIGINT}, release_time = #{releaseTime,jdbcType=BIGINT},
</if> </if>
@ -328,6 +342,7 @@
version = #{version,jdbcType=VARCHAR}, version = #{version,jdbcType=VARCHAR},
install_type = #{installType,jdbcType=INTEGER}, install_type = #{installType,jdbcType=INTEGER},
creator = #{creator,jdbcType=VARCHAR}, creator = #{creator,jdbcType=VARCHAR},
load_mybatis = #{loadMybatis,jdbcType=BIT},
release_time = #{releaseTime,jdbcType=BIGINT}, release_time = #{releaseTime,jdbcType=BIGINT},
install_time = #{installTime,jdbcType=BIGINT}, install_time = #{installTime,jdbcType=BIGINT},
module_name = #{moduleName,jdbcType=VARCHAR}, module_name = #{moduleName,jdbcType=VARCHAR},

View File

@ -16,6 +16,8 @@ public interface AuthMapper {
List<String> permissions(@Param("userId") Long userId); List<String> permissions(@Param("userId") Long userId);
List<Long> userMenuIds(@Param("userId") Long userId);
SysUserEntity findUser(@Param("userId") Long userId); SysUserEntity findUser(@Param("userId") Long userId);

View File

@ -42,6 +42,13 @@
where sur.user_id = #{userId} where sur.user_id = #{userId}
</select> </select>
<select id="userMenuIds" resultType="Long">
select srm.menu_id
from sys_roles_menus srm
left join sys_users_roles sur on sur.role_id = srm.role_id
where sur.user_id = #{userId}
</select>
<select id="roles" resultMap="roleMap"> <select id="roles" resultMap="roleMap">
select r.role_id, r.name select r.role_id, r.name
from sys_role r from sys_role r

View File

@ -4,6 +4,7 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.*; import java.io.*;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.util.Arrays;
public class DeFileUtils { public class DeFileUtils {
@ -112,4 +113,14 @@ public class DeFileUtils {
return null; return null;
} }
} }
public static void deleteFile(String path) {
File file = new File(path);
if (file.exists()){
if (file.isDirectory()) {
Arrays.stream(file.listFiles()).forEach(item -> deleteFile(item.getAbsolutePath()));
}
file.delete();
}
}
} }

View File

@ -17,7 +17,7 @@ import java.util.List;
import java.util.Properties; import java.util.Properties;
@Configuration @Configuration
@MapperScan(basePackages = {"io.dataease.base.mapper", "io.dataease.xpack.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory") @MapperScan(basePackages = {"io.dataease.base.mapper", "io.dataease.plugins"}, sqlSessionFactoryRef = "sqlSessionFactory")
@EnableTransactionManagement @EnableTransactionManagement
public class MybatisConfig { public class MybatisConfig {

View File

@ -6,6 +6,7 @@ import io.dataease.base.domain.MyPlugin;
import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager; import io.dataease.commons.utils.Pager;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.PluginStatus;
import io.dataease.service.sys.PluginService; import io.dataease.service.sys.PluginService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@ -32,8 +33,21 @@ public class SysPluginController {
return PageUtils.setPageInfo(page, pluginService.query(request)); return PageUtils.setPageInfo(page, pluginService.query(request));
} }
@ApiOperation("安装插件")
@PostMapping("upload") @PostMapping("upload")
public Map<String, Object> localUpload(@RequestParam("file") MultipartFile file) throws Exception { public Map<String, Object> localUpload(@RequestParam("file") MultipartFile file) throws Exception {
return pluginService.localInstall(file); return pluginService.localInstall(file);
} }
@ApiOperation("卸载插件")
@PostMapping("/uninstall/{pluginId}")
public Boolean unInstall(@PathVariable Long pluginId) {
return pluginService.uninstall(pluginId);
}
@ApiOperation("切换插件状态")
@PostMapping("/changeStatus")
public Boolean changeStatus(@RequestBody PluginStatus pluginStatus) {
return pluginService.changeStatus(pluginStatus.getPluginId(), pluginStatus.getStatus());
}
} }

View File

@ -0,0 +1,12 @@
package io.dataease.controller.sys.request;
import lombok.Data;
@Data
public class PluginStatus {
private Long pluginId;
private Boolean status;
}

View File

@ -1,7 +1,10 @@
package io.dataease.plugins.config; package io.dataease.plugins.config;
import io.dataease.base.domain.MyPlugin;
import io.dataease.plugins.loader.ClassloaderResponsity; import io.dataease.plugins.loader.ClassloaderResponsity;
import io.dataease.plugins.loader.ModuleClassLoader; import io.dataease.plugins.loader.ModuleClassLoader;
import io.dataease.plugins.loader.MybatisLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.File; import java.io.File;
@ -15,27 +18,27 @@ import java.util.Map;
@Component @Component
public class LoadjarUtil { public class LoadjarUtil {
public List<?> loadJar(String jarPath){ @Autowired
private MybatisLoader mybatisLoader;
public List<?> loadJar(String jarPath, MyPlugin myPlugin) throws Exception{
File jar = new File(jarPath); File jar = new File(jarPath);
URI uri = jar.toURI(); URI uri = jar.toURI();
String moduleName = jarPath.substring(jarPath.lastIndexOf("/")+1,jarPath.lastIndexOf(".")); String moduleName = jarPath.substring(jarPath.lastIndexOf("/")+1,jarPath.lastIndexOf("."));
try {
if(ClassloaderResponsity.getInstance().containsClassLoader(moduleName)){
ClassloaderResponsity.getInstance().removeClassLoader(moduleName);
}
ModuleClassLoader classLoader = new ModuleClassLoader(new URL[]{uri.toURL()}, Thread.currentThread().getContextClassLoader()); if(ClassloaderResponsity.getInstance().containsClassLoader(moduleName)){
SpringContextUtil.getBeanFactory().setBeanClassLoader(classLoader); ClassloaderResponsity.getInstance().removeClassLoader(moduleName);
Thread.currentThread().setContextClassLoader(classLoader);
classLoader.initBean();
ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
ModuleClassLoader classLoader = new ModuleClassLoader(new URL[]{uri.toURL()}, Thread.currentThread().getContextClassLoader());
SpringContextUtil.getBeanFactory().setBeanClassLoader(classLoader);
Thread.currentThread().setContextClassLoader(classLoader);
classLoader.initBean();
mybatisLoader.loadMybatis(myPlugin);
ClassloaderResponsity.getInstance().addClassLoader(moduleName,classLoader);
return SpringContextUtil.getAllBean(); return SpringContextUtil.getAllBean();
} }

View File

@ -0,0 +1,53 @@
package io.dataease.plugins.config;
import io.dataease.base.domain.MyPlugin;
import io.dataease.commons.utils.DeFileUtils;
import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.service.sys.PluginService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.List;
@Component
public class PluginRunner implements ApplicationRunner {
@Value("${dataease.plugin.dir:/opt/dataease/plugins/}")
private String pluginDir;
@Autowired
private PluginService pluginService;
@Override
public void run(ApplicationArguments args) throws Exception {
// 执行加载插件逻辑
BaseGridRequest request = new BaseGridRequest();
List<MyPlugin> plugins = pluginService.query(request);
plugins.stream().forEach(plugin -> {
String name = plugin.getName();
String version = plugin.getVersion();
String versionDir = pluginDir + name + "/" + version + "/";
File fileDir = new File(versionDir);
File[] jarFiles = fileDir.listFiles(this::isPluginJar);
File jarFile = jarFiles[0];
String jarPath = jarFile.getAbsolutePath();
try {
pluginService.loadJar(jarPath, plugin);
} catch (Exception e) {
e.printStackTrace();
}
});
}
private boolean isPluginJar(File file) {
String name = file.getName();
return StringUtils.equals(DeFileUtils.getExtensionName(name), "jar");
}
}

View File

@ -1,6 +1,11 @@
package io.dataease.plugins.loader; package io.dataease.plugins.loader;
import io.dataease.plugins.common.annotation.PluginResultMap;
import io.dataease.plugins.config.SpringContextUtil; import io.dataease.plugins.config.SpringContextUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -53,15 +58,20 @@ public class ModuleClassLoader extends URLClassLoader {
@Override @Override
public Class<?> loadClass(String name) throws ClassNotFoundException { public Class<?> loadClass(String name) throws ClassNotFoundException {
if(findLoadedClass(name)==null){ if(findLoadedClass(name)==null){
return super.loadClass(name); Class<?> aClass = super.loadClass(name);
Optional.ofNullable(aClass.getAnnotation(PluginResultMap.class)).ifPresent(anno -> {
SqlSessionFactory sqlSessionFactory = SpringContextUtil.getBean(SqlSessionFactory.class);
Configuration configuration = sqlSessionFactory.getConfiguration();
TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();
typeAliasRegistry.registerAlias(name.toLowerCase(), aClass);
});
return aClass;
}else{ }else{
return cacheClassMap.get(name); return cacheClassMap.get(name);
} }
} }
/** /**
* 方法描述 初始化类加载器保存字节码 * 方法描述 初始化类加载器保存字节码
* @method init * @method init
@ -76,8 +86,8 @@ public class ModuleClassLoader extends URLClassLoader {
JarEntry je = en.nextElement(); JarEntry je = en.nextElement();
String name = je.getName(); String name = je.getName();
//这里添加了路径扫描限制 //这里添加了路径扫描限制
if (name.endsWith(".class")) { if (name.endsWith(".class")) {String className = name.replace(".class", "").replaceAll("/", ".");
String className = name.replace(".class", "").replaceAll("/", ".");
input = jarFile.getInputStream(je); input = jarFile.getInputStream(je);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bufferSize = 4096; int bufferSize = 4096;
@ -89,6 +99,9 @@ public class ModuleClassLoader extends URLClassLoader {
byte[] classBytes = baos.toByteArray(); byte[] classBytes = baos.toByteArray();
classBytesMap.put(className,classBytes); classBytesMap.put(className,classBytes);
} }
/*if (name.endsWith(".xml")) {
loadMapperXml(name);
}*/
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -0,0 +1,39 @@
package io.dataease.plugins.loader;
import io.dataease.plugins.config.SpringContextUtil;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class MyScanner implements BeanDefinitionRegistryPostProcessor {
@Resource
private MapperScannerConfigurer mapperScannerConfigurer;
private BeanDefinitionRegistry beanDefinitionRegistry;
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
this.beanDefinitionRegistry = beanDefinitionRegistry;
System.out.println("-----");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
public void scanner() {
if (null == mapperScannerConfigurer){
mapperScannerConfigurer = SpringContextUtil.getBean(MapperScannerConfigurer.class);
}
mapperScannerConfigurer.postProcessBeanDefinitionRegistry(this.beanDefinitionRegistry);
}
}

View File

@ -0,0 +1,22 @@
package io.dataease.plugins.loader;
import io.dataease.base.domain.MyPlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MybatisLoader {
@Autowired
private MyScanner myScanner;
public void loadMybatis(MyPlugin myPlugin) {
if (!myPlugin.getLoadMybatis()) return;
myScanner.scanner();
}
}

View File

@ -0,0 +1,32 @@
package io.dataease.plugins.server;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.display.dto.response.SysSettingDto;
import io.dataease.plugins.xpack.display.service.DisPlayXpackService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.Map;
@RequestMapping("/api/display")
@RestController
public class DisplayServer {
@GetMapping("/uiInfo")
public List<SysSettingDto> uiInfo() {
DisPlayXpackService disPlayXpackService = SpringContextUtil.getBean(DisPlayXpackService.class);
return disPlayXpackService.systemSettings();
}
@PostMapping(value="/save", consumes = {"multipart/form-data"})
public void saveUIInfo(@RequestPart("request") Map<String,List<SysSettingDto>> systemParameterMap, @RequestPart(value = "files", required = false) List<MultipartFile> bodyFiles) throws Exception {
DisPlayXpackService disPlayXpackService = SpringContextUtil.getBean(DisPlayXpackService.class);
disPlayXpackService.save(systemParameterMap, bodyFiles);
}
}

View File

@ -0,0 +1,65 @@
package io.dataease.plugins.server;
import io.dataease.commons.utils.ServletUtils;
import io.dataease.plugins.common.dto.PluginSysMenu;
import io.dataease.plugins.common.service.PluginMenuService;
import io.dataease.plugins.config.SpringContextUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@RestController
@RequestMapping("/api/pluginCommon")
public class PluginCommonServer {
@GetMapping("/async/{menuId}")
public void componentInfo(@PathVariable Long menuId) {
Map<String, PluginMenuService> pluginMenuServiceMap = SpringContextUtil.getApplicationContext().getBeansOfType(PluginMenuService.class);
pluginMenuServiceMap.values().stream().forEach(service -> {
AtomicReference<PluginSysMenu> atomicReference = new AtomicReference<>();
List<PluginSysMenu> menus = service.menus();
if (menus.stream().anyMatch(menu -> {
atomicReference.set(menu);
return menu.getMenuId() == menuId;
})) {
String jsName = atomicReference.get().getComponent();
HttpServletResponse response = ServletUtils.response();
BufferedInputStream bis = null;
InputStream inputStream = null;
OutputStream os = null; //输出流
try{
inputStream = service.vueResource(jsName);
byte[] buffer = new byte[1024];
os = response.getOutputStream();
bis = new BufferedInputStream(inputStream);
int i = bis.read(buffer);
while(i != -1){
os.write(buffer, 0, i);
i = bis.read(buffer);
}
os.flush();
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
bis.close();
inputStream.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return;
});
}
}

View File

@ -0,0 +1,54 @@
package io.dataease.plugins.server;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager;
import io.dataease.plugins.common.entity.XpackGridRequest;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.role.dto.response.XpackRoleDto;
import io.dataease.plugins.xpack.role.dto.response.XpackRoleItemDto;
import io.dataease.plugins.xpack.role.service.RoleXpackService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequestMapping("/plugin/role")
@RestController
public class RoleServer {
@PostMapping("/create")
public void create(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.save(role);
}
@PostMapping("/delete/{roleId}")
public void delete(@PathVariable("roleId") Long roleId){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.delete(roleId);
}
@PostMapping("/update")
public void update(@RequestBody XpackRoleDto role){
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
roleXpackService.update(role);
}
@PostMapping("/roleGrid/{goPage}/{pageSize}")
public Pager<List<XpackRoleDto>> roleGrid(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody XpackGridRequest request) {
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
Pager<List<XpackRoleDto>> listPager = PageUtils.setPageInfo(page, roleXpackService.query(request));
return listPager;
}
@PostMapping("/all")
public List<XpackRoleItemDto> all() {
RoleXpackService roleXpackService = SpringContextUtil.getBean(RoleXpackService.class);
return roleXpackService.allRoles();
}
}

View File

@ -0,0 +1,22 @@
package io.dataease.plugins.util;
import io.dataease.plugins.common.dto.PluginSysMenu;
import io.dataease.plugins.common.service.PluginMenuService;
import io.dataease.plugins.config.SpringContextUtil;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class PluginUtils {
public static List<PluginSysMenu> pluginMenus() {
Map<String, PluginMenuService> pluginMenuServiceMap = SpringContextUtil.getApplicationContext().getBeansOfType(PluginMenuService.class);
List<PluginSysMenu> menus = pluginMenuServiceMap.values().stream().flatMap(item -> item.menus().stream()).collect(Collectors.toList());
return menus;
}
}

View File

@ -66,9 +66,9 @@ public class FileService {
example2.createCriteria().andFileIdIn(ids); example2.createCriteria().andFileIdIn(ids);
fileContentMapper.deleteByExample(example2); fileContentMapper.deleteByExample(example2);
LoadTestFileExample example3 = new LoadTestFileExample(); /* LoadTestFileExample example3 = new LoadTestFileExample();
example3.createCriteria().andFileIdIn(ids); example3.createCriteria().andFileIdIn(ids);
loadTestFileMapper.deleteByExample(example3); loadTestFileMapper.deleteByExample(example3);*/
} }
public void deleteFileRelatedByIds(List<String> ids) { public void deleteFileRelatedByIds(List<String> ids) {

View File

@ -5,17 +5,16 @@ import io.dataease.base.domain.MyPlugin;
import io.dataease.base.mapper.MyPluginMapper; import io.dataease.base.mapper.MyPluginMapper;
import io.dataease.base.mapper.ext.ExtSysPluginMapper; import io.dataease.base.mapper.ext.ExtSysPluginMapper;
import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.DeFileUtils; import io.dataease.commons.utils.DeFileUtils;
import io.dataease.commons.utils.ZipUtils; import io.dataease.commons.utils.ZipUtils;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.plugins.config.LoadjarUtil; import io.dataease.plugins.config.LoadjarUtil;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -38,9 +37,10 @@ public class PluginService {
@Resource @Resource
private MyPluginMapper myPluginMapper; private MyPluginMapper myPluginMapper;
@Resource @Autowired
private LoadjarUtil loadjarUtil; private LoadjarUtil loadjarUtil;
public List<MyPlugin> query(BaseGridRequest request) { public List<MyPlugin> query(BaseGridRequest request) {
GridExample gridExample = request.convertExample(); GridExample gridExample = request.convertExample();
List<MyPlugin> results = extSysPluginMapper.query(gridExample); List<MyPlugin> results = extSysPluginMapper.query(gridExample);
@ -60,6 +60,8 @@ public class PluginService {
try { try {
ZipUtils.upZipFile(dest, folder); ZipUtils.upZipFile(dest, folder);
} catch (IOException e) { } catch (IOException e) {
DeFileUtils.deleteFile(pluginDir+"temp/");
DeFileUtils.deleteFile(folder);
// 需要删除文件 // 需要删除文件
e.printStackTrace(); e.printStackTrace();
} }
@ -67,29 +69,80 @@ public class PluginService {
File folderFile = new File(folder); File folderFile = new File(folder);
File[] jsonFiles = folderFile.listFiles(this::isPluginJson); File[] jsonFiles = folderFile.listFiles(this::isPluginJson);
if (ArrayUtils.isEmpty(jsonFiles)) { if (ArrayUtils.isEmpty(jsonFiles)) {
DeFileUtils.deleteFile(pluginDir+"temp/");
DeFileUtils.deleteFile(folder);
throw new RuntimeException("缺少插件描述文件"); throw new RuntimeException("缺少插件描述文件");
} }
MyPlugin myPlugin = formatJsonFile(jsonFiles[0]); MyPlugin myPlugin = formatJsonFile(jsonFiles[0]);
//4.加载jar包 失败则 直接返回错误 删除文件 //4.加载jar包 失败则 直接返回错误 删除文件
File[] jarFiles = folderFile.listFiles(this::isPluginJar); File[] jarFiles = folderFile.listFiles(this::isPluginJar);
if (ArrayUtils.isEmpty(jarFiles)) { if (ArrayUtils.isEmpty(jarFiles)) {
DeFileUtils.deleteFile(pluginDir+"temp/");
DeFileUtils.deleteFile(folder);
throw new RuntimeException("缺少插件jar文件"); throw new RuntimeException("缺少插件jar文件");
} }
File jarFile = jarFiles[0]; String versionDir = null;
String jarRoot = pluginDir+"jar/";
String jarPath = null;
try { try {
jarPath = DeFileUtils.copy(jarFile, jarRoot); File jarFile = jarFiles[0];
} catch (IOException e) { versionDir = makeVersionDir(myPlugin);
String jarPath = null;
jarPath = DeFileUtils.copy(jarFile, versionDir);
//DeFileUtils.copy(folderFile, versionDir);
loadJar(jarPath, myPlugin);
myPluginMapper.insert(myPlugin);
} catch (Exception e) {
if (StringUtils.isNotEmpty(versionDir)) {
DeFileUtils.deleteFile(versionDir);
}
e.printStackTrace(); e.printStackTrace();
}finally {
DeFileUtils.deleteFile(pluginDir+"temp/");
DeFileUtils.deleteFile(folder);
} }
loadjarUtil.loadJar(jarPath);
//mybatisLoader.loadMybatis(myPlugin);
//5.写表到my_plugin //5.写表到my_plugin
myPlugin.setPluginId(0L); // myPlugin.setPluginId(0L);
myPluginMapper.insert(myPlugin);
return null; return null;
} }
public void loadJar(String jarPath, MyPlugin myPlugin) throws Exception {
loadjarUtil.loadJar(jarPath, myPlugin);
}
private String makeVersionDir(MyPlugin myPlugin) {
String name = myPlugin.getName();
String dir = pluginDir + name + "/" + myPlugin.getVersion() + "/";
File fileDir = new File(dir);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
return dir;
}
/**
* 卸载插件
* @param pluginId
* @return
*/
public Boolean uninstall(Long pluginId) {
myPluginMapper.deleteByPrimaryKey(pluginId);
return true;
}
/**
* 改变插件状态
* @param pluginId
* @param status true 使用状态 : 禁用状态
* @return
*/
public Boolean changeStatus(Long pluginId, Boolean status) {
return false;
}
//判断当前文件是否实插件描述文件 //判断当前文件是否实插件描述文件
//文件名称必须plugin.json //文件名称必须plugin.json
private boolean isPluginJson(File file) { private boolean isPluginJson(File file) {
@ -110,6 +163,7 @@ public class PluginService {
Gson gson = new Gson(); Gson gson = new Gson();
Map<String, Object> myPlugin = gson.fromJson(str, Map.class); Map<String, Object> myPlugin = gson.fromJson(str, Map.class);
myPlugin.put("free", (Double)myPlugin.get("free") > 0.0); myPlugin.put("free", (Double)myPlugin.get("free") > 0.0);
myPlugin.put("loadMybatis", (Double)myPlugin.get("loadMybatis") > 0.0);
MyPlugin result = new MyPlugin(); MyPlugin result = new MyPlugin();
try { try {
org.apache.commons.beanutils.BeanUtils.populate(result, myPlugin); org.apache.commons.beanutils.BeanUtils.populate(result, myPlugin);

View File

@ -164,21 +164,22 @@ CREATE TABLE `sys_users_roles` (
DROP TABLE IF EXISTS `my_plugin`; DROP TABLE IF EXISTS `my_plugin`;
CREATE TABLE `my_plugin` ( CREATE TABLE `my_plugin` (
`plugin_id` bigint(20) NOT NULL COMMENT '主键', `plugin_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '插件名称', `name` varchar(255) DEFAULT NULL COMMENT '插件名称',
`free` tinyint(1) DEFAULT NULL COMMENT '是否免费', `free` tinyint(1) DEFAULT '0' COMMENT '是否免费',
`cost` int(10) DEFAULT NULL COMMENT '费用', `cost` int(10) DEFAULT NULL COMMENT '费用',
`descript` varchar(255) DEFAULT NULL COMMENT '描述', `descript` varchar(255) DEFAULT NULL COMMENT '描述',
`version` varchar(255) DEFAULT NULL COMMENT '版本号', `version` varchar(255) DEFAULT NULL COMMENT '版本号',
`install_type` int(4) DEFAULT NULL COMMENT '安装类型', `install_type` int(4) DEFAULT NULL COMMENT '安装类型',
`creator` varchar(255) DEFAULT NULL COMMENT '开发者', `creator` varchar(255) DEFAULT NULL COMMENT '开发者',
`release_time` bigint(13) DEFAULT NULL COMMENT '发布时间', `load_mybatis` tinyint(1) DEFAULT '0' COMMENT '是否需要加载mybatis',
`install_time` bigint(13) DEFAULT NULL COMMENT '安装时间', `release_time` bigint(13) DEFAULT NULL COMMENT '发布时间',
`module_name` varchar(255) DEFAULT NULL COMMENT 'jar包名称', `install_time` bigint(13) DEFAULT NULL COMMENT '安装时间',
`bean_name` varchar(40) DEFAULT NULL COMMENT 'bean名称', `module_name` varchar(255) DEFAULT NULL COMMENT 'jar包名称',
`icon` varchar(255) DEFAULT NULL COMMENT '图标', `bean_name` varchar(40) DEFAULT NULL COMMENT 'bean名称',
PRIMARY KEY (`plugin_id`) `icon` varchar(255) DEFAULT NULL COMMENT '图标',
) ENGINE=InnoDB DEFAULT CHARSET=utf8; PRIMARY KEY (`plugin_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='插件表';
DROP TABLE IF EXISTS `license`; DROP TABLE IF EXISTS `license`;
CREATE TABLE `license` ( CREATE TABLE `license` (

View File

@ -14,8 +14,9 @@ INSERT INTO `sys_menu` VALUES (1, 0, 3, 0, '系统管理', 'system', 'Layout', 6
INSERT INTO `sys_menu` VALUES (2, 1, 4, 1, '用户管理', 'system-user', 'system/user/index', 1, 'peoples', 'user', NULL, b'0', b'0', 'user:read', NULL, NULL, NULL, 1620281952752); INSERT INTO `sys_menu` VALUES (2, 1, 4, 1, '用户管理', 'system-user', 'system/user/index', 1, 'peoples', 'user', NULL, b'0', b'0', 'user:read', NULL, NULL, NULL, 1620281952752);
INSERT INTO `sys_menu` VALUES (3, 1, 3, 1, '菜单管理', 'system-menu', 'system/menu/index', 2, 'menu', 'menu', NULL, b'0', b'0', 'menu:read', NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (3, 1, 3, 1, '菜单管理', 'system-menu', 'system/menu/index', 2, 'menu', 'menu', NULL, b'0', b'0', 'menu:read', NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (4, 1, 3, 1, '组织管理', 'system-dept', 'system/dept/index', 3, 'dept', 'dept', NULL, b'0', b'0', 'dept:read', NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (4, 1, 3, 1, '组织管理', 'system-dept', 'system/dept/index', 3, 'dept', 'dept', NULL, b'0', b'0', 'dept:read', NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (5, 1, 3, 1, '角色管理', 'system-role', 'system/role/index', 4, 'role', 'role', b'0', b'0', b'0', 'role:read', NULL, NULL, 1614683852133, 1614683852133);
INSERT INTO `sys_menu` VALUES (6, 1, 0, 1, '参数管理', 'system-param', 'system/systemParamSettings/index', 5, 'sys-tools', 'systemParamSettings', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1615790294169); ---INSERT INTO `sys_menu` VALUES (5, 1, 3, 1, '角色管理', 'system-role', 'system/role/index', 4, 'role', 'role', b'0', b'0', b'0', 'role:read', NULL, NULL, 1614683852133, 1614683852133);
---INSERT INTO `sys_menu` VALUES (6, 1, 0, 1, '参数管理', 'system-param', 'system/systemParamSettings/index', 5, 'sys-tools', 'systemParamSettings', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1615790294169);
INSERT INTO `sys_menu` VALUES (8, 0, 0, 1, '数据集', 'dataset', 'dataset/index', 3, '', '/dataset', NULL, b'0', b'0', 'data:read', NULL, NULL, NULL, 1614916684821); INSERT INTO `sys_menu` VALUES (8, 0, 0, 1, '数据集', 'dataset', 'dataset/index', 3, '', '/dataset', NULL, b'0', b'0', 'data:read', NULL, NULL, NULL, 1614916684821);
INSERT INTO `sys_menu` VALUES (10, 0, 0, 1, '视图', 'view', 'chart/index', 2, '', '/chart', NULL, b'0', b'0', 'chart:read', NULL, NULL, NULL, 1614915491036); INSERT INTO `sys_menu` VALUES (10, 0, 0, 1, '视图', 'view', 'chart/index', 2, '', '/chart', NULL, b'0', b'0', 'chart:read', NULL, NULL, NULL, 1614915491036);
INSERT INTO `sys_menu` VALUES (12, 3, 0, 2, '创建菜单', NULL, NULL, 999, NULL, NULL, b'0', b'0', b'0', 'menu:add', NULL, NULL, 1614924617327, 1614924617327); INSERT INTO `sys_menu` VALUES (12, 3, 0, 2, '创建菜单', NULL, NULL, 999, NULL, NULL, b'0', b'0', b'0', 'menu:add', NULL, NULL, 1614924617327, 1614924617327);
@ -40,7 +41,7 @@ INSERT INTO `sys_menu` VALUES (34, 0, 4, 1, '数据源', 'datasource', 'system/d
INSERT INTO `sys_menu` VALUES (35, 1, 0, 1, '用户表单', 'system-user-form', 'system/user/form', 10, '', 'user-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (35, 1, 0, 1, '用户表单', 'system-user-form', 'system/user/form', 10, '', 'user-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (36, 1, 0, 1, '菜单表单', 'system-menu-form', 'system/menu/form', 11, '', 'menu-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (36, 1, 0, 1, '菜单表单', 'system-menu-form', 'system/menu/form', 11, '', 'menu-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (37, 1, 0, 1, '组织表单', 'system-dept-form', 'system/dept/form', 12, '', 'dept-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (37, 1, 0, 1, '组织表单', 'system-dept-form', 'system/dept/form', 12, '', 'dept-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', 'system-role-form', 'system/role/form', 13, '', 'role-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); ---INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', 'system-role-form', 'system/role/form', 13, '', 'role-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', 'datasource-form', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', 'datasource-form', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', 'system-template', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'template:read', NULL, NULL, NULL, 1620444227389); INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', 'system-template', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'template:read', NULL, NULL, NULL, 1620444227389);
INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', 'system-auth', 'system/authority/index', 14, 'password', 'system/authority/index', b'0', b'0', b'0', 'auth:read', NULL, NULL, NULL, 1620447312657); INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', 'system-auth', 'system/authority/index', 14, 'password', 'system/authority/index', b'0', b'0', b'0', 'auth:read', NULL, NULL, NULL, 1620447312657);

View File

@ -1,6 +1,7 @@
import request from '@/utils/request' import request from '@/utils/request'
const pathMap = { const pathMap = {
queryPath: '/api/plugin/pluginGrid/' queryPath: '/api/plugin/pluginGrid/',
uninstallPath: 'api/plugin/uninstall/'
} }
export function pluginLists(page, size, data) { export function pluginLists(page, size, data) {
return request({ return request({
@ -11,3 +12,11 @@ export function pluginLists(page, size, data) {
}) })
} }
export function uninstall(pluginId) {
return request({
url: pathMap.queryPath + pluginId,
method: 'post',
loading: true
})
}

View File

@ -7,7 +7,9 @@
</template> </template>
<script> <script>
import Axios from 'axios' // import Axios from 'axios'
import { get } from '@/api/system/dynamic'
export default { export default {
name: 'AsyncComponent', name: 'AsyncComponent',
@ -36,13 +38,15 @@ export default {
} }
let res let res
if (!window.SyncComponentCache[this.url]) { if (!window.SyncComponentCache[this.url]) {
window.SyncComponentCache[this.url] = Axios.get(this.url) window.SyncComponentCache[this.url] = get(this.url)
// window.SyncComponentCache[this.url] = Axios.get(this.url)
res = await window.SyncComponentCache[this.url] res = await window.SyncComponentCache[this.url]
} else { } else {
res = await window.SyncComponentCache[this.url] res = await window.SyncComponentCache[this.url]
} }
const Fn = Function const Fn = Function
this.mode = new Fn(`return ${res.data}`)() this.mode = new Fn(`return ${res.data || res}`)()
} }
} }
}, },

View File

@ -36,6 +36,14 @@ export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由
if (router.type === 1 && router.pid === 0 && router.component && router.component !== 'Layout') { if (router.type === 1 && router.pid === 0 && router.component && router.component !== 'Layout') {
router = decorate(router) router = decorate(router)
} }
if (router.isPlugin) {
const jsName = router.component
router.component = 'system/plugin/dynamic'
router.props = {
jsname: jsName,
menuid: router.id
}
}
if (router.component) { if (router.component) {
if (router.component === 'Layout') { // Layout组件特殊处理 if (router.component === 'Layout') { // Layout组件特殊处理
router.component = Layout router.component = Layout
@ -47,6 +55,7 @@ export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由
if (router.children && router.children.length) { if (router.children && router.children.length) {
router.children = filterAsyncRouter(router.children) router.children = filterAsyncRouter(router.children)
} }
router.hasOwnProperty('id') && delete router.id router.hasOwnProperty('id') && delete router.id
router.hasOwnProperty('type') && delete router.type router.hasOwnProperty('type') && delete router.type
router.hasOwnProperty('pid') && delete router.pid router.hasOwnProperty('pid') && delete router.pid

View File

@ -54,7 +54,7 @@ import ComplexTable from '@/components/business/complex-table'
import { checkPermission } from '@/utils/permission' import { checkPermission } from '@/utils/permission'
import { formatCondition } from '@/utils/index' import { formatCondition } from '@/utils/index'
import { pluginLists } from '@/api/system/plugin' import { pluginLists, uninstall } from '@/api/system/plugin'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
export default { export default {
@ -131,6 +131,12 @@ export default {
cancelButtonText: this.$t('commons.cancel'), cancelButtonText: this.$t('commons.cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
uninstall(row.pluginId).then(res => {
this.search()
this.$success('卸载成功')
}).catch(() => {
this.$error('卸载失败')
})
}).catch(() => { }).catch(() => {
this.$info(this.$t('commons.delete_cancel')) this.$info(this.$t('commons.delete_cancel'))
}) })