From 4e1b7bf17a5717ebd6e77a1b56d6ce1a19726161 Mon Sep 17 00:00:00 2001 From: thinkgem Date: Thu, 28 Sep 2023 16:39:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E6=BA=90=E5=85=A8=E9=83=A8=E5=9F=BA?= =?UTF-8?q?=E7=A1=80=E5=8A=9F=E8=83=BD=E7=9A=84=E5=89=8D=E7=AB=AF=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E5=92=8C=E6=8E=A7=E5=88=B6=E5=99=A8=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../file/web/FileUploadController.java | 126 ++++++ .../modules/file/web/UserfilesController.java | 107 +++++ .../modules/sys/web/AuditController.java | 145 +++++++ .../modules/sys/web/ConfigController.java | 158 +++++++ .../modules/sys/web/DictDataController.java | 297 +++++++++++++ .../modules/sys/web/DictTypeController.java | 198 +++++++++ .../modules/sys/web/MenuController.java | 282 +++++++++++++ .../modules/sys/web/ModuleController.java | 213 ++++++++++ .../modules/sys/web/RoleController.java | 389 ++++++++++++++++++ .../modules/sys/web/TagsController.java | 54 +++ .../modules/sys/web/ValidCodeController.java | 53 +++ .../views/modules/sys/auditList.html | 98 +++++ .../views/modules/sys/auditMenuList.html | 186 +++++++++ .../views/modules/sys/auditUserList.html | 166 ++++++++ .../views/modules/sys/configForm.html | 104 +++++ .../views/modules/sys/configList.html | 102 +++++ .../views/modules/sys/dictDataForm.html | 151 +++++++ .../views/modules/sys/dictDataList.html | 116 ++++++ .../views/modules/sys/dictTypeForm.html | 90 ++++ .../views/modules/sys/dictTypeList.html | 95 +++++ .../resources/views/modules/sys/langForm.html | 103 +++++ .../resources/views/modules/sys/langList.html | 95 +++++ .../resources/views/modules/sys/menuForm.html | 284 +++++++++++++ .../views/modules/sys/menuIndex.html | 88 ++++ .../resources/views/modules/sys/menuList.html | 166 ++++++++ .../views/modules/sys/moduleForm.html | 160 +++++++ .../views/modules/sys/moduleList.html | 83 ++++ .../resources/views/modules/sys/roleForm.html | 310 ++++++++++++++ .../modules/sys/roleFormAuthDataScope.html | 216 ++++++++++ .../views/modules/sys/roleFormAuthUser.html | 138 +++++++ .../resources/views/modules/sys/roleList.html | 124 ++++++ 31 files changed, 4897 insertions(+) create mode 100644 modules/core/src/main/java/com/jeesite/modules/file/web/FileUploadController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/file/web/UserfilesController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/AuditController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/ConfigController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/DictDataController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/DictTypeController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/MenuController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/ModuleController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/RoleController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/TagsController.java create mode 100644 modules/core/src/main/java/com/jeesite/modules/sys/web/ValidCodeController.java create mode 100644 modules/core/src/main/resources/views/modules/sys/auditList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/auditMenuList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/auditUserList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/configForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/configList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/dictDataForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/dictDataList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/dictTypeForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/dictTypeList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/langForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/langList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/menuForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/menuIndex.html create mode 100644 modules/core/src/main/resources/views/modules/sys/menuList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/moduleForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/moduleList.html create mode 100644 modules/core/src/main/resources/views/modules/sys/roleForm.html create mode 100644 modules/core/src/main/resources/views/modules/sys/roleFormAuthDataScope.html create mode 100644 modules/core/src/main/resources/views/modules/sys/roleFormAuthUser.html create mode 100644 modules/core/src/main/resources/views/modules/sys/roleList.html diff --git a/modules/core/src/main/java/com/jeesite/modules/file/web/FileUploadController.java b/modules/core/src/main/java/com/jeesite/modules/file/web/FileUploadController.java new file mode 100644 index 00000000..878fd140 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/file/web/FileUploadController.java @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.file.web; + +import com.jeesite.common.codec.EncodeUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.mapper.JsonMapper; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.file.entity.FileUpload; +import com.jeesite.modules.file.entity.FileUploadParams; +import com.jeesite.modules.file.service.FileUploadService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * 文件管理Controller + * @author ThinkGem + * @version 2019-12-23 + */ +@Controller +@RequestMapping(value = "${adminPath}/file") +@ConditionalOnProperty(name={"file.enabled","web.core.enabled"}, havingValue="true", matchIfMissing=true) +public class FileUploadController extends BaseController { + + @Autowired + private FileUploadService fileUploadService; + + /** + * 上传文件参数 + */ + @RequestMapping(value = "params") + @ResponseBody + public Map params() { + Map model = MapUtils.newHashMap(); + model.put("imageAllowSuffixes", Global.getConfig("file.imageAllowSuffixes", ".gif,.bmp,.jpeg,.jpg,.ico,.png,.tif,.tiff,")); + model.put("mediaAllowSuffixes", Global.getConfig("file.mediaAllowSuffixes", ".flv,.swf,.mkv,webm,.mid,.mov,.mp3,.mp4,.m4v,.mpc,.mpeg,.mpg,.swf,.wav,.wma,.wmv,.avi,.rm,.rmi,.rmvb,.aiff,.asf,.ogg,.ogv,")); + model.put("fileAllowSuffixes", Global.getConfig("file.fileAllowSuffixes", ".doc,.docx,.rtf,.xls,.xlsx,.csv,.ppt,.pptx,.pdf,.vsd,.txt,.md,.xml,.rar,.zip,.7z,.tar,.tgz,.jar,.gz,.gzip,.bz2,.cab,.iso,")); + model.put("chunked", Global.getConfig("file.chunked", "true")); + model.put("chunkSize", Global.getConfigToInteger("file.chunkSize", "10*1024*1024")); + model.put("threads", Global.getConfigToInteger("file.threads", "3")); + model.put("imageMaxWidth", Global.getConfigToInteger("file.imageMaxWidth", "1024")); + model.put("imageMaxHeight", Global.getConfigToInteger("file.imageMaxHeight", "768")); + return model; + } + + /** + * 上传文件 + */ + @RequestMapping(value = "upload") + @ResponseBody + public Map upload(FileUploadParams params) { + return fileUploadService.uploadFile(params); + } + + /** + * 下载文件 + */ + @RequestMapping(value = "/download/{fileUploadId}") + public String download(@PathVariable("fileUploadId") String fileUploadId, String preview, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + FileUpload fileUpload = fileUploadService.get(fileUploadId); + if (fileUpload != null && fileUpload.getFileEntity() != null && fileUpload.getFileEntity().getFileMd5() != null) { + // 如果是文件预览,则跳转到文件下载页面,并传输文件预览参数 + if (StringUtils.isNotBlank(preview)){ + fileUpload.setPreviewFileUrl(true); + String url = fileUpload.getFileUrl(); + if (StringUtils.contains(url, "://")) { + url = "/userfiles/?url=" + EncodeUtils.encodeUrl(url); + url += "&uid=" + fileUploadId; + } + url += StringUtils.contains(url, "?") ? "&" : "?"; + url += "fileName=" + EncodeUtils.encodeUrl(fileUpload.getFileName()); + url += "&preview=" + EncodeUtils.encodeUrl(preview); + return REDIRECT + url; + } + // 下载文件流或获取下载文件URL并跳转 + String url = fileUploadService.getFileUploadServiceExtend().downFile(fileUpload, request, response); + if (!"404".equals(url)){ + if (StringUtils.isNotBlank(url)){ + return REDIRECT + url; + } + return null; + } + } + request.setAttribute("responseStatus", 200); + request.setAttribute("message", text("sys.file.downloadFileNotExist")); + request.getRequestDispatcher("/error/404").forward(request, response); + return null; + } + + /** + * 获取业务附件列表数据 + * @param fileUpload bizKey 和 bizType 为必填参数 + */ + @RequestMapping(value = "fileList") + @ResponseBody + public String fileList(FileUpload fileUpload, Boolean bizKeyIsLike) { + if (StringUtils.isNotBlank(fileUpload.getBizKey()) + && StringUtils.isNotBlank(fileUpload.getBizType())){ + if (bizKeyIsLike != null && bizKeyIsLike){ + fileUpload.setBizKey_rightLike(fileUpload.getBizKey()); + fileUpload.setBizKey(null); + } + List list = fileUploadService.findList(fileUpload); + if(list != null && !list.isEmpty()){ + return JsonMapper.toJson(list); + } + } + return renderResult(Global.FALSE, "No files."); + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/file/web/UserfilesController.java b/modules/core/src/main/java/com/jeesite/modules/file/web/UserfilesController.java new file mode 100644 index 00000000..72c3dace --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/file/web/UserfilesController.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.file.web; + +import com.jeesite.common.codec.EncodeUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.io.FileUtils; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.web.BaseController; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.io.File; +import java.io.IOException; + +/** + * 用户文件下载 + * @author ThinkGem + * @version 2022-09-27 + */ +@Controller +@ConditionalOnProperty(name="file.isFileStreamDown", havingValue="true", matchIfMissing=true) +@Hidden +public class UserfilesController extends BaseController { + + @RequestMapping(value="/userfiles/**") + public String fileStreamDown(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + // 获取相对文件地址 + String fileUri = request.getRequestURI(); + String filePath = StringUtils.substringAfter(fileUri, Global.USERFILES_BASE_URL); + String fileName = request.getParameter("fileName"); + + // 如果开启了文件预览,则跳转到具体的文件预览组件地址。 + String preview = request.getParameter("preview"); + if (StringUtils.isNotBlank(preview)){ + String fileUrl = request.getRequestURL() + "?source=preview"; + String url = request.getParameter("url"); + String uid = request.getParameter("uid"); + if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(uid)){ + fileUrl = url; //EncodeUtils.decodeUrl(url); 不用解码,否则腾讯云存储的时候预览不能显示 + fileUri = request.getContextPath() + Global.getAdminPath() + "/file/download/" + uid; + filePath = fileName; + } else if (StringUtils.isNotBlank(fileName)){ + fileUri += "?fileName=" + EncodeUtils.encodeUrl(fileName); + } + String previewUrl = "/file/" + preview + "/preview"; + request.setAttribute("fileUrl", fileUrl); // 文件访问地址 + request.setAttribute("fileUri", fileUri); // 文件下载地址(fileDown) + request.setAttribute("filePath", filePath); // 文件相对路径或文件名 + request.setAttribute("fileUrls", request.getParameter("urls")); // 前后照片列表 + request.setAttribute("javax.servlet.forward.request_uri", previewUrl); + request.getRequestDispatcher(previewUrl).forward(request, response); + return null; + } + + // 获取文件实际路径 + filePath = Global.getUserfilesBaseDir(filePath); + + // 根据实际路径获取文件对象 + File file = new File(EncodeUtils.decodeUrl(filePath)); + + // 如果文件不存在,尝试下gbk编码 + if (!file.exists()){ + File gbkFile = new File(EncodeUtils.decodeUrl(filePath, "GBK")); + if (gbkFile.exists()){ + file = gbkFile; + } + } + + // 下载文件,发送到客户浏览器 + String range = request.getHeader("Range"); + if (StringUtils.isNotBlank(range)){ + logger.debug("File: {} Range: {}", file, range); + }else{ + logger.debug("File: {}", file); + } + if (StringUtils.isBlank(fileName)){ + fileName = file.getName(); + } + // 替换到百度编辑器上传的日期时间后缀 + String filenameTimeSuffix = StringUtils.substringAfterLast(FileUtils.getFileNameWithoutExtension(fileName), "_$"); + if (NumberUtils.isCreatable(filenameTimeSuffix)){ + fileName = StringUtils.replace(fileName, "_$" + filenameTimeSuffix, ""); + } + if (file.exists()){ + FileUtils.downFile(file, request, response, fileName); + return null; + } + + // 找不到下载文件,提示文件丢失或不存在 + request.setAttribute("responseStatus", 200); + request.setAttribute("message", text("sys.file.downloadFileNotExist")); + request.getRequestDispatcher("/error/404").forward(request, response); + return null; + } + +} diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/AuditController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/AuditController.java new file mode 100644 index 00000000..4b56e352 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/AuditController.java @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.entity.Page; +import com.jeesite.common.lang.DateUtils; +import com.jeesite.common.lang.ObjectUtils; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.utils.excel.ExcelExport; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.Audit; +import com.jeesite.modules.sys.entity.Menu; +import com.jeesite.modules.sys.service.AuditService; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; +import java.util.Map; + +/** + * 安全审计Controller + * @author ThinkGem + * @version 2020-3-12 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/audit") +@ConditionalOnProperty(name={"user.enabled","web.core.enabled"}, havingValue="true", matchIfMissing=true) +@Hidden +public class AuditController extends BaseController { + + @Autowired + private AuditService auditService; + + /** + * 安全审计列表 + */ + @RequiresPermissions("sys:audit:pwd") + @RequestMapping(value = "list") + public String auditList(Audit audit, Model model) { + model.addAttribute("audit", audit); + return "modules/sys/auditList"; + } + + /** + * 安全审计列表数据 + */ + @RequiresPermissions("sys:audit:pwd") + @ResponseBody + @RequestMapping(value = "listData") + public Page auditListData(Audit audit, HttpServletRequest request, HttpServletResponse response) { + audit.setPage(new Page<>(request, response)); + Page page = auditService.findAuditPage(audit); + return page; + } + + /** + * 安全审计数据导出 + */ + @RequiresPermissions("sys:audit:pwd") + @RequestMapping(value = "exportData") + public void auditExportData(Audit audit, HttpServletRequest request, HttpServletResponse response) { + String fileName = "安全审计数据" + DateUtils.getDate("yyyyMMdd") + ".xlsx"; + audit.setPage(new Page<>(1, Page.PAGE_SIZE_NOT_PAGING, Page.COUNT_NOT_COUNT)); + List list = auditService.findAuditPage(audit).getList(); + try (ExcelExport ee = new ExcelExport("安全审计数据", Audit.class)) { + ee.setDataList(list).write(response, fileName); + } + } + + /** + * 根据权限查用户 + */ + @RequiresPermissions("sys:audit:user") + @RequestMapping(value = "userList") + public String userList(Audit audit, Model model) { + model.addAttribute("audit", audit); + return "modules/sys/auditUserList"; + } + + /** + * 根据权限查用户数据 + */ + @RequiresPermissions("sys:audit:user") + @RequestMapping(value = "userListData") + @ResponseBody + public Page userListData(Audit audit, HttpServletRequest request, HttpServletResponse response) { + audit.setPage(new Page<>(request, response)); + Page page = auditService.findUserPage(audit); + return page; + } + + /** + * 根据用户查权限 + */ + @RequiresPermissions("sys:audit:menu") + @RequestMapping(value = "menuList") + public String menuList(Audit audit, Model model) { + model.addAttribute("audit", audit); + return "modules/sys/auditMenuList"; + } + + /** + * 根据用户查权限数据 + */ + @RequiresPermissions("sys:audit:menu") + @ResponseBody + @RequestMapping(value = "menuTreeData") + public Map menuListData(Audit audit) { + Map model = MapUtils.newHashMap(); + List menuList = auditService.findMenuList(audit); + Map>> map = MapUtils.newLinkedHashMap(); + for (Menu menu : menuList){ + List> list = map.get(menu.getSysCode()); + if (list == null){ + list = ListUtils.newArrayList(); + map.put(menu.getSysCode(), list); + } + Map m = MapUtils.newHashMap(); + m.put("id", menu.getMenuCode()); + m.put("pId", menu.getParentCode()); + m.put("name", menu.getMenuName() + "     " + + StringUtils.abbr(ObjectUtils.toString(menu.getPermission()) + "   " + + ObjectUtils.toString(menu.getMenuHref()), 50) + ""); + m.put("title", menu.getMenuName() + " " + + ObjectUtils.toString(menu.getPermission()) + "\n" + + ObjectUtils.toString(menu.getMenuHref())); + list.add(m); + } + model.put("menuMap", map); + return model; + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/ConfigController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/ConfigController.java new file mode 100644 index 00000000..92cf4f35 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/ConfigController.java @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.jeesite.common.config.Global; +import com.jeesite.common.entity.Page; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.Config; +import com.jeesite.modules.sys.service.ConfigService; + + +/** + * 参数设置Controller + * @author ThinkGem + * @version 2019-07-31 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/config") +@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true) +@Hidden +public class ConfigController extends BaseController { + + @Autowired + private ConfigService configService; + + /** + * 获取数据 + * @param id + * @return + */ + @ModelAttribute + public Config get(String id, boolean isNewRecord) { + return configService.get(id, isNewRecord); + } + + /** + * 查询列表 + * @param config + * @param model + * @return + */ + @RequiresPermissions("sys:config:view") + @RequestMapping(value = "list") + public String list(Config config, Model model) { + model.addAttribute("config", config); + return "modules/sys/configList"; + } + + /** + * 查询列表 + * @param config + * @param request + * @param response + * @return + */ + @RequiresPermissions("sys:config:view") + @RequestMapping(value = "listData") + @ResponseBody + public Page listData(Config config, HttpServletRequest request, HttpServletResponse response) { + config.setPage(new Page<>(request, response)); + Page page = configService.findPage(config); + return page; + } + + /** + * 查看编辑表单 + * @param config + * @param model + * @return + */ + @RequiresPermissions("sys:config:view") + @RequestMapping(value = "form") + public String form(Config config, Model model) { + model.addAttribute("config", config); + return "modules/sys/configForm"; + } + + /** + * 保存数据 + * @param config + * @return + */ + @RequiresPermissions("sys:config:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated Config config, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Config old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !config.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + // 不是超级管理员,不能修改Name和Key + if (!config.currentUser().isSuperAdmin()){ + config.setConfigName(old.getConfigName()); + config.setConfigKey(old.getConfigKey()); + config.setIsSys(Global.NO); + } + configService.save(config); + return renderResult(Global.TRUE, text("保存参数成功")); + } + + /** + * 验证Key是否有效 + */ + @RequiresPermissions("sys:config:edit") + @RequestMapping(value = "checkConfigKey") + @ResponseBody + public String checkConfigKey(String oldConfigKey, String configKey) { + Config where = new Config(); + where.setConfigKey(configKey); + if (configKey != null && configKey.equals(oldConfigKey)) { + return Global.TRUE; + } else if (configKey != null && configService.findCount(where) == 0) { + return Global.TRUE; + } + return Global.FALSE; + } + + /** + * 删除数据 + * @param config + * @return + */ + @RequiresPermissions("sys:config:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(Config config, HttpServletRequest request) { + if (StringUtils.isNotBlank(request.getParameter("isSys"))){ + return renderResult(Global.FALSE, text("越权操作,isSys非法参数")); + } + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Config old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !config.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + configService.delete(config); + return renderResult(Global.TRUE, text("删除参数成功")); + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/DictDataController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/DictDataController.java new file mode 100644 index 00000000..ee88847d --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/DictDataController.java @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.idgen.IdGen; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.DictData; +import com.jeesite.modules.sys.entity.DictType; +import com.jeesite.modules.sys.service.DictDataService; +import com.jeesite.modules.sys.service.DictTypeService; +import com.jeesite.modules.sys.utils.DictUtils; +import com.jeesite.modules.sys.utils.UserUtils; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; +import java.util.Map; + + +/** + * 字典管理Controller + * @author ThinkGem + * @version 2019-07-27 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/dictData") +@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true) +@Hidden +public class DictDataController extends BaseController { + + @Autowired + private DictDataService dictDataService; + @Autowired + private DictTypeService dictTypeService; + + /** + * 获取数据 + */ + @ModelAttribute + public DictData get(String dictCode, boolean isNewRecord) { + return dictDataService.get(dictCode, isNewRecord); + } + + /** + * 查询列表 + */ + @RequiresPermissions("sys:dictData:view") + @RequestMapping(value = "list") + public String list(DictData dictData, Model model) { + model.addAttribute("dictData", dictData); + return "modules/sys/dictDataList"; + } + + /** + * 查询列表数据 + */ + @RequiresPermissions("sys:dictData:view") + @RequestMapping(value = "listData") + @ResponseBody + public List listData(DictData dictData) { + if (StringUtils.isBlank(dictData.getParentCode())) { + dictData.setParentCode(DictData.ROOT_CODE); + } + List list = dictDataService.findList(dictData); + return list; + } + + /** + * 查看编辑表单 + */ + @RequiresPermissions("sys:dictData:view") + @RequestMapping(value = "form") + public String form(DictData dictData, Model model) { + // 创建并初始化下一个节点信息 + dictData = createNextNode(dictData); + model.addAttribute("dictData", dictData); + return "modules/sys/dictDataForm"; + } + + /** + * 创建并初始化下一个节点信息,如:排序号、默认值 + */ + @RequiresPermissions("sys:dictData:edit") + @RequestMapping(value = "createNextNode") + @ResponseBody + public DictData createNextNode(DictData dictData) { + if (StringUtils.isNotBlank(dictData.getParentCode())) { + dictData.setParent(dictDataService.get(dictData.getParentCode())); + } + if (dictData.getIsNewRecord()) { + DictData where = new DictData(); + where.setDictType(dictData.getDictType()); + where.setParentCode(dictData.getParentCode()); + DictData last = dictDataService.getLastByParentCode(where); + // 获取到下级最后一个节点 + if (last != null){ + dictData.setTreeSort(last.getTreeSort() + 30); + dictData.setDictValue(IdGen.nextCode(last.getDictValue())); + // 默认设置是否系统 + if (dictData.getIsSys() == null){ + dictData.setIsSys(last.getIsSys()); + } + }else if(dictData.getParent() != null){ + dictData.setDictValue(dictData.getParent().getDictValue() + "001"); + // 默认设置是否系统 + if (dictData.getIsSys() == null){ + // 验证字典类型是否设置正确,如果没有找到这个字典类型则不可保存 + DictType dictType = new DictType(); + dictType.setDictType(dictData.getDictType()); + dictType = dictTypeService.get(dictType); + if (dictType != null){ + dictData.setIsSys(dictType.getIsSys()); + } + } + } + } + // 以下设置表单默认数据 + if (dictData.getTreeSort() == null){ + dictData.setTreeSort(DictData.DEFAULT_TREE_SORT); + } + return dictData; + } + + /** + * 保存数据 + */ + @RequiresPermissions("sys:dictData:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated DictData dictData, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + DictData old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictData.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + // 只有系统管理员才能保存为系统字典! + if (!dictData.currentUser().isSuperAdmin() && Global.YES.equals(dictData.getIsSys())){ + return renderResult(Global.FALSE, text("保存失败,只有系统管理员才能保存为系统字典!")); + } + // 验证字典类型是否设置正确,如果没有找到这个字典类型则不可保存 + DictType dictType = new DictType(); + dictType.setDictType(dictData.getDictType()); + dictType = dictTypeService.get(dictType); + if (dictType == null){ + return renderResult(Global.FALSE, text("保存失败,没有找到''{0}''字典类型!", dictData.getDictType())); + } + // 如果字段类型是系统字典类型,则它的字段数据也是系统的 + if (Global.YES.equals(dictType.getIsSys()) && !Global.YES.equals(dictData.getIsSys())){ + return renderResult(Global.FALSE, text("保存失败,字典类型是系统的,字典数据也必须是系统字典!")); + } + // 如果字典类型不是系统字典,则默认情况下字典数据的isSys使用字典类型的 + if (StringUtils.isBlank(dictData.getIsSys())){ + dictData.setIsSys(dictType.getIsSys()); + } + dictDataService.save(dictData); + return renderResult(Global.TRUE, text("保存字典成功")); + } + + /** + * 停用字典 + * @param dictData + */ + @RequiresPermissions("sys:dictData:edit") + @RequestMapping(value = "disable") + @ResponseBody + public String disable(DictData dictData, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + DictData old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictData.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + DictData where = new DictData(); + where.setStatus(DictData.STATUS_NORMAL); + where.setParentCodes("," + dictData.getId() + ","); + long count = dictDataService.findCount(where); + if (count > 0) { + return renderResult(Global.FALSE, text("该字典包含未停用的子字典!")); + } + dictData.setStatus(DictData.STATUS_DISABLE); + dictDataService.updateStatus(dictData); + return renderResult(Global.TRUE, text("停用字典成功")); + } + + /** + * 启用字典 + * @param dictData + */ + @RequiresPermissions("sys:dictData:edit") + @RequestMapping(value = "enable") + @ResponseBody + public String enable(DictData dictData, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + DictData old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictData.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + dictData.setStatus(DictData.STATUS_NORMAL); + dictDataService.updateStatus(dictData); + return renderResult(Global.TRUE, text("启用字典成功")); + } + + /** + * 删除数据 + */ + @RequiresPermissions("sys:dictData:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(DictData dictData, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + DictData old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictData.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + dictDataService.delete(dictData); + return renderResult(Global.TRUE, text("删除字典成功")); + } + + /** + * 获取树结构数据。 + * @param dictType 字典类型,加 __all(双下划线+all) 后缀,则返回停用的字典 v4.2.0 + * @param excludeCode 排除的ID + * @param isShowCode 是否显示值(true or 1:显示在左侧;2:显示在右侧;false or null:不显示) + * @param isShowRawName 是否显示原文(默认false) + */ + @RequestMapping(value = "treeData") + @ResponseBody + public List> treeData(String dictType, String excludeCode, + String isShowCode, boolean isShowRawName) { + List> mapList = ListUtils.newArrayList(); + List list = DictUtils.getDictList(dictType); + for (int i=0; i map = MapUtils.newHashMap(); + map.put("id", e.getId()); + map.put("pId", e.getParentCode()); + map.put("name", StringUtils.getTreeNodeName(isShowCode, e.getDictValue(), + isShowRawName ? e.getDictLabelRaw() : e.getDictLabel())); + map.put("value", e.getDictValue()); + if (StringUtils.isNotBlank(e.getDictIcon())) { + map.put("icon", e.getDictIcon()); + } + if (StringUtils.isNotBlank(e.getCssClass())) { + map.put("cssClass", e.getCssClass()); + } + if (StringUtils.isNotBlank(e.getCssStyle())) { + map.put("cssStyle", e.getCssStyle()); + } + mapList.add(map); + } + return mapList; + } + + /** + * 树结构数据修复 + * @return + */ + @RequiresPermissions("sys:dictData:edit") + @RequestMapping(value = "fixTreeData") + @ResponseBody + public String fixTreeData(){ + if (!UserUtils.getUser().isAdmin()){ + return renderResult(Global.FALSE, text("操作失败,只有管理员才能进行修复!")); + } + dictDataService.fixTreeData(); + return renderResult(Global.TRUE, text("数据修复成功")); + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/DictTypeController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/DictTypeController.java new file mode 100644 index 00000000..24018fc4 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/DictTypeController.java @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.entity.Page; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.DictType; +import com.jeesite.modules.sys.service.DictTypeService; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 字典分类管理Controller + * @author ThinkGem + * @version 2019-3-24 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/dictType") +@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true) +@Hidden +public class DictTypeController extends BaseController { + + @Autowired + private DictTypeService dictTypeService; + + /** + * 获取数据 + */ + @ModelAttribute + public DictType get(String id, boolean isNewRecord) { + return dictTypeService.get(id, isNewRecord); + } + + /** + * 查询列表 + */ + @RequiresPermissions("sys:dictType:view") + @RequestMapping(value = "list") + public String list(DictType dictType, Model model) { + if (!dictType.currentUser().isSuperAdmin()){ + dictType.setIsSys(Global.NO); + } + model.addAttribute("dictType", dictType); + return "modules/sys/dictTypeList"; + } + + /** + * 查询列表数据 + */ + @RequiresPermissions("sys:dictType:view") + @RequestMapping(value = "listData") + @ResponseBody + public Page listData(DictType dictType, HttpServletRequest request, HttpServletResponse response) { + dictType.setPage(new Page<>(request, response)); + Page page = dictTypeService.findPage(dictType); + return page; + } + + /** + * 查看编辑表单 + */ + @RequiresPermissions("sys:dictType:view") + @RequestMapping(value = "form") + public String form(DictType dictType, Model model) { + if (StringUtils.isBlank(dictType.getIsSys())){ + dictType.setIsSys(Global.YES); + } + model.addAttribute("dictType", dictType); + return "modules/sys/dictTypeForm"; + } + + /** + * 保存数据 + */ + @RequiresPermissions("sys:dictType:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated DictType dictType, HttpServletRequest request) { + // 获取老字典类型的isSys状态,如果是系统字典,则必须超级管理员编辑 + DictType old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictType.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + dictTypeService.save(dictType, old); + return renderResult(Global.TRUE, text("保存字典类型成功")); + } + + /** + * 验证字段类型是否有效 + * @return + */ + @RequiresPermissions("sys:dictType:edit") + @RequestMapping(value = "checkDictType") + @ResponseBody + public String checkDictType(String oldDictType, String dictType) { + DictType where = new DictType(); + where.setDictType(dictType); + if (dictType != null && dictType.equals(oldDictType)) { + return Global.TRUE; + } else if (dictType != null && dictTypeService.findCount(where) == 0) { + return Global.TRUE; + } + return Global.FALSE; + } + + /** + * 停用字典类型 + */ + @RequiresPermissions("sys:dictType:edit") + @RequestMapping(value = "disable") + @ResponseBody + public String disable(DictType dictType) { + dictType.setStatus(DictType.STATUS_DISABLE); + dictTypeService.updateStatus(dictType); + return renderResult(Global.TRUE, text("停用字典类型成功")); + } + + /** + * 启用字典类型 + */ + @RequiresPermissions("sys:dictType:edit") + @RequestMapping(value = "enable") + @ResponseBody + public String enable(DictType dictType) { + dictType.setStatus(DictType.STATUS_NORMAL); + dictTypeService.updateStatus(dictType); + return renderResult(Global.TRUE, text("启用字典类型成功")); + } + + /** + * 删除数据 + */ + @RequiresPermissions("sys:dictType:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(DictType dictType, HttpServletRequest request) { + // 获取老字典类型的isSys状态,如果是系统字典,则必须超级管理员编辑 + DictType old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !dictType.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + dictTypeService.delete(dictType); + return renderResult(Global.TRUE, text("删除字典类型成功")); + } + + /** + * 获取树结构数据。 + * @param dictType 字典类型 + * @param excludeCode 排除的ID + * @param isShowCode 是否显示值(true or 1:显示在左侧;2:显示在右侧;false or null:不显示) + */ + @RequiresPermissions("sys:dictType:view") + @RequestMapping(value = "treeData") + @ResponseBody + public List> treeData(String dictType, String excludeCode, + @RequestParam(defaultValue="1") String isShowCode) { + List> mapList = ListUtils.newArrayList(); + List list = dictTypeService.findList(new DictType()); + for (int i=0; i map = MapUtils.newHashMap(); + map.put("id", e.getId()); + map.put("pId", "0"); + map.put("name", StringUtils.getTreeNodeName(isShowCode, e.getDictType(), e.getDictName())); + map.put("value", e.getDictType()); + mapList.add(map); + } + return mapList; + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/MenuController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/MenuController.java new file mode 100644 index 00000000..69f20616 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/MenuController.java @@ -0,0 +1,282 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.Menu; +import com.jeesite.modules.sys.entity.Module; +import com.jeesite.modules.sys.service.MenuService; +import com.jeesite.modules.sys.service.ModuleService; +import com.jeesite.modules.sys.utils.UserUtils; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; +import java.util.Map; + +/** + * 菜单管理Controller + * @author ThinkGem + * @version 2019-8-19 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/menu") +@ConditionalOnProperty(name={"user.enabled","web.core.enabled"}, havingValue="true", matchIfMissing=true) +@Hidden +public class MenuController extends BaseController { + + @Autowired + private MenuService menuService; + @Autowired + private ModuleService moduleService; + + @ModelAttribute + public Menu get(String menuCode, boolean isNewRecord) { + return menuService.get(menuCode, isNewRecord); + } + + @RequiresPermissions("sys:menu:view") + @RequestMapping(value = "index") + public String index(Menu menu, Model model) { + if (StringUtils.isBlank(menu.getSysCode())){ + menu.setSysCode(Menu.SYS_CODE_DEFAULT); + } + model.addAttribute("menu", menu); + return "modules/sys/menuIndex"; + } + + @RequiresPermissions("sys:menu:view") + @RequestMapping(value = "list") + public String list(Menu menu, Model model) { + if (StringUtils.isBlank(menu.getSysCode())){ + menu.setSysCode(Menu.SYS_CODE_DEFAULT); + } + model.addAttribute("menu", menu); + return "modules/sys/menuList"; + } + + @RequiresPermissions("sys:menu:view") + @RequestMapping(value = "listData") + @ResponseBody + public List listData(Menu menu) { + if (StringUtils.isBlank(menu.getParentCode())) { + menu.setParentCode(Menu.ROOT_CODE); + } + if (StringUtils.isNotBlank(menu.getMenuNameRaw())){ + menu.setParentCode(null); + } + if (StringUtils.isNotBlank(menu.getMenuHref())){ + menu.setParentCode(null); + } + if (StringUtils.isNotBlank(menu.getPermission())){ + menu.setParentCode(null); + } + List list = menuService.findList(menu); + return list; + } + + @RequiresPermissions("sys:menu:view") + @RequestMapping(value = "form") + public String form(Menu menu, Model model) { + // 创建并初始化下一个节点信息 + menu = createNextNode(menu); + model.addAttribute("menu", menu); + // 获取所有模块列表 + Module module = new Module(); + List moduleList = moduleService.findList(module); + model.addAttribute("moduleList", moduleList); + return "modules/sys/menuForm"; + } + + /** + * 创建并初始化下一个节点信息,如:排序号、默认值 + */ + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "createNextNode") + @ResponseBody + public Menu createNextNode(Menu menu) { + if (StringUtils.isNotBlank(menu.getParentCode())) { + menu.setParent(menuService.get(menu.getParentCode())); + } + if (menu.getIsNewRecord()) { + Menu where = new Menu(); + where.setParentCode(menu.getParentCode()); + Menu last = menuService.getLastByParentCode(where); + // 获取到下级最后一个节点 + if (last != null){ + menu.setTreeSort(last.getTreeSort() + 30); + menu.setMenuType(last.getMenuType()); + if (last.getIsRoot()) { + menu.setModuleCodes(Module.MODULE_CORE); + }else{ + menu.setModuleCodes(last.getModuleCodes()); + } + }else if(menu.getParent() != null){ + menu.setMenuType(menu.getParent().getMenuType()); + menu.setModuleCodes(menu.getParent().getModuleCodes()); + } + } + // 以下设置表单默认数据 + if (menu.getTreeSort() == null){ + menu.setTreeSort(Menu.DEFAULT_TREE_SORT); + } + if (menu.getWeight() == null) { + menu.setWeight(Menu.WEIGHT_SEC_ADMIN); + } + if (StringUtils.isBlank(menu.getSysCode())){ + menu.setSysCode(Menu.SYS_CODE_DEFAULT); + } + if (StringUtils.isBlank(menu.getMenuType())){ + menu.setMenuType(Menu.TYPE_MENU); + } + if (StringUtils.isBlank(menu.getIsShow())){ + menu.setIsShow(Global.YES); + } + return menu; + } + + @RequiresPermissions("sys:menu:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated Menu menu) { + if (!menu.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + menuService.save(menu); + return renderResult(Global.TRUE, text("保存菜单''{0}''成功", menu.getMenuNameRaw()), menu); + } + + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "disable") + @ResponseBody + public String disable(Menu menu, HttpServletRequest request){ + if (!menu.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + menu.setStatus(Menu.STATUS_DISABLE); + menuService.updateStatus(menu); + return renderResult(Global.TRUE, text("停用菜单''{0}''成功", menu.getMenuName())); + } + + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "enable") + @ResponseBody + public String enable(Menu menu, HttpServletRequest request){ + if (!menu.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + menu.setStatus(Menu.STATUS_NORMAL); + menuService.updateStatus(menu); + return renderResult(Global.TRUE, text("启用菜单''{0}''成功", menu.getMenuName())); + } + + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(Menu menu) { + if (!menu.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + menuService.delete(menu); + return renderResult(Global.TRUE, text("删除菜单''{0}''成功", menu.getMenuNameRaw())); + } + + /** + * 返回树结构数据 + * @param excludeCode 排除的编码 + * @param isShowRawName 是否显示原文(默认false) + * @return + */ + @RequiresPermissions("sys:menu:view") + @RequestMapping(value = "treeData") + @ResponseBody + public List> treeData(String excludeCode, String parentCode, String isShowHide, + String sysCode, boolean isShowRawName, HttpServletResponse response) { + List> mapList = ListUtils.newArrayList(); + Menu where = new Menu(); + where.setStatus(Menu.STATUS_NORMAL); + if (StringUtils.isNotBlank(parentCode)){ + where.setParentCode(parentCode); + } + List list = menuService.findList(where); + for (int i = 0; i < list.size(); i++) { + Menu e = list.get(i); + // 过滤非正常的数据 + if (!Menu.STATUS_NORMAL.equals(e.getStatus())){ + continue; + } + // 过滤被排除的编码(包括所有子级) + if (StringUtils.isNotBlank(excludeCode)){ + if (e.getId().equals(excludeCode)){ + continue; + } + if (e.getParentCodes().contains("," + excludeCode + ",")){ + continue; + } + } + // 是否隐藏(0:隐藏的不查询;1:查询隐藏的) + if (StringUtils.isNotBlank(isShowHide) && isShowHide.equals(Global.HIDE) + && e.getIsShow().equals(Global.HIDE)) { + continue; + } + // 只查询该归属系统下的菜单 + if (StringUtils.isNotBlank(sysCode) && !sysCode.equals(e.getSysCode())){ + continue; + } + Map map = MapUtils.newHashMap(); + map.put("id", e.getId()); + map.put("pId", e.getParentCode()); + map.put("name", isShowRawName ? e.getMenuNameRaw() : e.getMenuName()); + map.put("isParent", !e.getIsTreeLeaf()); + mapList.add(map); + } + return mapList; + } + + /** + * 批量修改菜单排序 + */ + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "updateTreeSort") + @ResponseBody + public String updateTreeSort(String[] ids, Integer[] sorts) { + if (!UserUtils.getUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + for (int i = 0; i < ids.length; i++) { + Menu menu = new Menu(ids[i]); + menu.setTreeSort(sorts[i]); + menuService.updateTreeSort(menu); + } + return renderResult(Global.TRUE, text("保存菜单排序成功")); + } + + @RequiresPermissions("sys:menu:edit") + @RequestMapping(value = "fixTreeData") + @ResponseBody + public String fixTreeData(){ + if (!UserUtils.getUser().isAdmin()){ + return renderResult(Global.FALSE, text("操作失败,只有管理员才能进行修复!")); + } + menuService.fixTreeData(); + return renderResult(Global.TRUE, text("数据修复成功")); + } + +} diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/ModuleController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/ModuleController.java new file mode 100644 index 00000000..1be1d809 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/ModuleController.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.config.Global; +import com.jeesite.common.entity.Page; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.utils.SpringUtils; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.gen.entity.config.GenConfig; +import com.jeesite.modules.gen.utils.GenModuleUtils; +import com.jeesite.modules.gen.utils.GenUtils; +import com.jeesite.modules.sys.entity.Module; +import com.jeesite.modules.sys.service.ModuleService; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.List; + + +/** + * 模块管理Controller + * @author ThinkGem + * @version 2020-3-21 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/module") +@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true) +@Hidden +public class ModuleController extends BaseController { + + @Autowired + private ModuleService moduleService; + + /** + * 获取数据 + * @param moduleCode + * @return + */ + @ModelAttribute + public Module get(String moduleCode, boolean isNewRecord) { + return moduleService.get(moduleCode, isNewRecord); + } + + /** + * 查询列表 + * @param module + * @param model + * @return + */ + @RequiresPermissions("sys:module:view") + @RequestMapping(value = "list") + public String list(Module module, Model model) { + module.setStatus(StringUtils.EMPTY); + model.addAttribute("module", module); + return "modules/sys/moduleList"; + } + + /** + * 查询列表 + * @param module + * @param request + * @param response + * @return + */ + @RequiresPermissions("sys:module:view") + @RequestMapping(value = "listData") + @ResponseBody + public Page listData(Module module, HttpServletRequest request, HttpServletResponse response) { + module.setPage(new Page<>(request, response)); + Page page = moduleService.findPage(module); + return page; + } + + /** + * 查看编辑表单 + * @param module + * @param model + * @return + */ + @RequiresPermissions("sys:module:view") + @RequestMapping(value = "form") + public String form(Module module, Model model) { + if (StringUtils.isBlank(module.getMainClassName())){ + module.setMainClassName("com.jeesite.modules.sys.web.LoginController"); + } + if (StringUtils.isBlank(module.getCurrentVersion())) { + module.setCurrentVersion(SpringUtils.getLastVersion()); + } + GenConfig config = GenUtils.getConfig(); + model.addAttribute("config", config); + List genBaseDirList = GenModuleUtils.getGenBaseDirList(); + model.addAttribute("genBaseDirList", genBaseDirList); + model.addAttribute("genBaseDir", genBaseDirList.get(0)); + model.addAttribute("module", module); + return "modules/sys/moduleForm"; + } + + /** + * 保存数据 + * @param module + * @return + */ + @RequiresPermissions("sys:module:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated Module module) { + if (!module.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + if (StringUtils.equals(module.getGenFlag(), "2") && StringUtils.isBlank(module.getTplCategory())) { + return renderResult(Global.FALSE, text("请选择代码生成模板!")); + } + moduleService.save(module); + // 如果设置生成标记,则编译或生成代码 1编译输出到控制台 2生成文件 + if (StringUtils.inString(module.getGenFlag(), "1", "2") && StringUtils.isNotBlank(module.getTplCategory())){ + String result = GenModuleUtils.generateCode(module); + String flagMsg = ("1".equals(module.getGenFlag()) ? "编译" : "生成"); + String msg = "posfull:保存模块并" + flagMsg + "成功:
" + result; + return renderResult(Global.TRUE, msg); + }else { + return renderResult(Global.TRUE, text("保存模块成功")); + } + } + + /** + * 验证编码是否有效 + * @return + */ + @RequiresPermissions("sys:module:edit") + @RequestMapping(value = "checkModuleCode") + @ResponseBody + public String checkModuleCode(String oldCode, String moduleCode) { + Module module = new Module(); + module.setModuleCode(moduleCode); + if (moduleCode != null && moduleCode.equals(oldCode)) { + return Global.TRUE; + } else if (moduleCode != null && moduleService.get(module) == null) { + return Global.TRUE; + } + return Global.FALSE; + } + + /** + * 停用数据 + * @param module + * @return + */ + @RequiresPermissions("sys:module:edit") + @RequestMapping(value = "disable") + @ResponseBody + public String disable(Module module) { + if (!module.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + if (Module.MODULE_CORE.equals(module.getModuleCode())){ + return renderResult(Global.FALSE, text("核心模块,不允许停用")); + } + module.setStatus(Module.STATUS_DISABLE); + moduleService.updateStatus(module); + return renderResult(Global.TRUE, text("停用模块成功")); + } + + /** + * 启用数据 + * @param module + * @return + */ + @RequiresPermissions("sys:module:edit") + @RequestMapping(value = "enable") + @ResponseBody + public String enable(Module module) { + if (!module.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + module.setStatus(Module.STATUS_NORMAL); + moduleService.updateStatus(module); + return renderResult(Global.TRUE, text("启用模块成功")); + } + + /** + * 删除数据 + * @param module + * @return + */ + @RequiresPermissions("sys:module:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(Module module) { + if (!module.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改此数据!")); + } + if (Module.MODULE_CORE.equals(module.getModuleCode())){ + return renderResult(Global.FALSE, text("核心模块,不允许删除")); + } + moduleService.delete(module); + return renderResult(Global.TRUE, text("删除模块成功")); + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/RoleController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/RoleController.java new file mode 100644 index 00000000..d31945d2 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/RoleController.java @@ -0,0 +1,389 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.MapUtils; +import com.jeesite.common.config.Global; +import com.jeesite.common.entity.Page; +import com.jeesite.common.lang.ObjectUtils; +import com.jeesite.common.lang.StringUtils; +import com.jeesite.common.mapper.JsonMapper; +import com.jeesite.common.web.BaseController; +import com.jeesite.modules.sys.entity.*; +import com.jeesite.modules.sys.service.MenuService; +import com.jeesite.modules.sys.service.RoleService; +import com.jeesite.modules.sys.utils.DictUtils; +import com.jeesite.modules.sys.utils.ModuleUtils; +import com.jeesite.modules.sys.utils.RoleUtils; +import io.swagger.v3.oas.annotations.Hidden; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * 角色Controller + * @author ThinkGem + * @version 2020-3-20 + */ +@Controller +@RequestMapping(value = "${adminPath}/sys/role") +@ConditionalOnProperty(name={"user.enabled","web.core.enabled"}, havingValue="true", matchIfMissing=true) +@Hidden +public class RoleController extends BaseController { + + @Autowired + private RoleService roleService; + + @Autowired + private MenuService menuService; + + @ModelAttribute + public Role get(String roleCode, boolean isNewRecord) { + return roleService.get(roleCode, isNewRecord); + } + + @RequiresPermissions("sys:role:view") + @RequestMapping(value = "list") + public String list(Role role, Model model) { + model.addAttribute("role", role); + model.addAttribute("ctrlPermi", Global.getConfig("user.adminCtrlPermi", "2")); + return "modules/sys/roleList"; + } + + @RequiresPermissions("sys:role:view") + @RequestMapping(value = "listData") + @ResponseBody + public Page listData(Role role, String ctrlPermi, HttpServletRequest request, HttpServletResponse response) { + // 不是超级管理员,则添加数据权限过滤 + if (!role.currentUser().isSuperAdmin()){ + roleService.addDataScopeFilter(role, ctrlPermi); + } + role.setPage(new Page<>(request, response)); + Page page = roleService.findPage(role); + return page; + } + + @RequiresPermissions("sys:role:view") + @RequestMapping(value = "form") + public String form(Role role, String op, Model model) { + if(role.getIsNewRecord()){ + role.setRoleSort((int)roleService.findCount(role) * 10); + role.setUserType(User.USER_TYPE_EMPLOYEE); + role.setIsSys(Global.NO); + role.setIsShow(Global.SHOW); + } + // 操作类型:add: 全部; edit: 编辑; auth: 授权; + model.addAttribute("op", op); + model.addAttribute("role", role); + return "modules/sys/roleForm"; + } + + @RequiresPermissions("sys:role:edit") + @PostMapping(value = "save") + @ResponseBody + public String save(@Validated Role role, String op, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Role old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + // 只有系统管理员才能保存为系统字典! + if (!role.currentUser().isSuperAdmin() && Global.YES.equals(role.getIsSys())){ + return renderResult(Global.FALSE, text("保存失败,只有系统管理员才能保存为系统角色!")); + } + if (!Global.TRUE.equals(checkRoleName(old != null ? old.getRoleName() : "", role.getRoleName()))) { + return renderResult(Global.FALSE, text("保存角色''{0}''失败,角色名称已存在", role.getRoleName())); + } + if (StringUtils.inString(op, Global.OP_ADD, Global.OP_EDIT)){ + roleService.save(role); + } + if (StringUtils.inString(op, Global.OP_ADD, Global.OP_AUTH)){ + roleService.saveAuth(role); + } + return renderResult(Global.TRUE, text("保存角色''{0}''成功", role.getRoleName())); + } + + /** + * 验证角色名是否有效 + * @param oldRoleName + * @param roleName + * @return + */ + @RequiresPermissions("user") + @RequestMapping(value = "checkRoleName") + @ResponseBody + public String checkRoleName(String oldRoleName, String roleName) { + Role role = new Role(); + role.setRoleName(roleName); + if (roleName != null && roleName.equals(oldRoleName)) { + return Global.TRUE; + } else if (roleName != null && roleService.getByRoleName(role) == null) { + return Global.TRUE; + } + return Global.FALSE; + } + + /** + * 停用角色 + * @param role + * @return + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "disable") + @ResponseBody + public String disable(Role role, HttpServletRequest request){ + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Role old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + role.setStatus(Role.STATUS_DISABLE); + roleService.updateStatus(role); + return renderResult(Global.TRUE, text("停用角色''{0}''成功", role.getRoleName())); + } + + /** + * 启用角色 + * @param role + * @return + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "enable") + @ResponseBody + public String enable(Role role, HttpServletRequest request){ + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Role old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + role.setStatus(Role.STATUS_NORMAL); + roleService.updateStatus(role); + return renderResult(Global.TRUE, text("启用角色''{0}''成功", role.getRoleName())); + } + + /** + * 删除角色 + * @param role + * @return + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "delete") + @ResponseBody + public String delete(Role role, HttpServletRequest request) { + if (Role.CORP_ADMIN_ROLE_CODE.equals(role.getRoleCode())){ + return renderResult(Global.FALSE, text("非法操作,此角色为内置角色,不允许删除!")); + } + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Role old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + //if(roleService.hasUserRoleByRoleCode(role)){ + // return renderResult(Global.FALSE, text("删除角色''{0}''失败,角色关联了用户", role.getRoleName())); + //} + roleService.delete(role); + return renderResult(Global.TRUE, text("删除角色''{0}''成功", role.getRoleName())); + } + + /** + * 判断某用户是包含某角色 + * @param userCode + * @param roleCode + * @return + */ + @RequiresPermissions("user") + @RequestMapping(value = "hasUserRole") + @ResponseBody + public Boolean hasUserRole(String userCode, String roleCode){ + if (StringUtils.isNotBlank(userCode)){ + return RoleUtils.hasUserRole(userCode, roleCode); + }else{ + return RoleUtils.hasCurrentUserRole(roleCode); + } + } + + /** + * 查询菜单的树结构数据 + * @param role + * @param request + */ + @RequiresPermissions("sys:role:view") + @RequestMapping(value = "menuTreeData") + @ResponseBody + public Map menuTreeData(Role role, HttpServletRequest request) { + Map model = MapUtils.newHashMap(); + List menuList = null; + // 获取菜单列表,根据归属系统转换为zTree能够接受的数据 + Menu menuWhere = new Menu(); + // 根据权限设置可查看的菜单权重级别 + User user = role.currentUser(); + if (user.isSuperAdmin()){ + menuWhere.setWeight_lt(Menu.WEIGHT_SUPER_ADMIN); + menuList = menuService.findList(menuWhere); + }else if (User.MGR_TYPE_CORP_ADMIN.equals(user.getMgrType()) + && Global.getPropertyToBoolean("role.corpAdminAllMenu", "false")){ + menuWhere.setWeight_lt(Menu.WEIGHT_CORP_ADMIN); + menuList = menuService.findList(menuWhere); + }else{ + // 二级管理员、普通 用户,只可分配自己的拥有的菜单 + menuWhere.setUserCode(user.getUserCode()); + menuList = menuService.findByUserCode(menuWhere); + } + List sysCodes = ListUtils.newArrayList(); + for (DictData sysCode : DictUtils.getDictList("sys_menu_sys_code")) { + sysCodes.add(sysCode.getDictValue()); + } + Map>> map = MapUtils.newLinkedHashMap(); + for (Menu menu : menuList){ + // 过滤已经禁用的子系统 + if (!sysCodes.contains(menu.getSysCode())) { + continue; + } + List> list = map.get(menu.getSysCode()); + if (list == null){ + list = ListUtils.newArrayList(); + map.put(menu.getSysCode(), list); + } + Map m = MapUtils.newHashMap(); + m.put("id", menu.getMenuCode()); + m.put("pId", menu.getParentCode()); + m.put("name", menu.getMenuName() + "     " + + StringUtils.abbr(ObjectUtils.toString(menu.getPermission()) + "   " + + ObjectUtils.toString(menu.getMenuHref()), 50) + ""); + m.put("title", menu.getMenuName() + " " + + ObjectUtils.toString(menu.getPermission()) + "\n" + + ObjectUtils.toString(menu.getMenuHref())); + list.add(m); + } + model.put("menuMap", map); + if (StringUtils.isNotBlank(role.getRoleCode())) { + menuWhere = new Menu(); + menuWhere.setRoleCode(role.getRoleCode()); + List roleMenuList = menuService.findByRoleCode(menuWhere); + model.put("roleMenuList", roleMenuList); + } + return model; + } + + /** + * 角色授权数据权限 + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "formAuthDataScope") + public String formAuthDataScope(Role role, String checkbox, Model model, HttpServletRequest request) { + RoleDataScope roleDataScope = new RoleDataScope(); + roleDataScope.setRoleCode(role.getRoleCode()); + List roleDataScopeList = roleService.findDataScopeList(roleDataScope); + model.addAttribute("roleDataScopeList", roleDataScopeList); + model.addAttribute("role", role); + model.addAttribute("moduleCodes", ModuleUtils.getEnableModuleCodes()); + model.addAttribute("dataScopes", JsonMapper.fromJson(Global.getConfig("user.dataScopes", "[]"), List.class)); + return "modules/sys/roleFormAuthDataScope"; + } + + /** + * 保存角色授权数据权限 + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "saveAuthDataScope") + @ResponseBody + public String saveAuthDataScope(Role role, HttpServletRequest request) { + // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 + Role old = super.getWebDataBinderSource(request); + if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ + return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); + } + roleService.saveAuthDataScope(role); + return renderResult(Global.TRUE, text("角色授权数据权限成功")); + } + + /** + * 获取角色树结构数据 + * @param isAll 是否显示所有机构(true:不进行权限过滤) + * @param isShowCode 是否显示编码(true or 1:显示在左侧;2:显示在右侧;false or null:不显示) + * @return + */ + @RequiresPermissions("user") + @RequestMapping(value = "treeData") + @ResponseBody + public List> treeData(String userType, Boolean isAll, String isShowCode, String ctrlPermi) { + List> mapList = ListUtils.newArrayList(); + Role where = new Role(); + where.setStatus(Role.STATUS_NORMAL); + if (!(isAll != null && isAll) || Global.isStrictMode()){ + if (!"__all".equals(userType)) { + where.setUserType(StringUtils.defaultIfBlank(userType, User.USER_TYPE_EMPLOYEE)); + } + roleService.addDataScopeFilter(where, ctrlPermi); + } + List list = roleService.findList(where); + list.forEach(e -> { + Map map = MapUtils.newHashMap(); + map.put("id", e.getId()); + map.put("pId", "0"); + map.put("code", e.getViewCode()); + map.put("name", StringUtils.getTreeNodeName(isShowCode, e.getViewCode(), e.getRoleName()) + (!"__all".equals(userType) + ? "" : "(" + DictUtils.getDictLabel("sys_user_type", e.getUserType(), text("未知")) + ")")); + mapList.add(map); + }); + return mapList; + } + + /** + * 角色授权给用户 + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "formAuthUser") + public String formAuthUser(Role role, Model model, HttpServletRequest request) { + model.addAttribute("role", role); + return "modules/sys/roleFormAuthUser"; + } + + /** + * 保存角色授权给用户 + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "saveAuthUser") + @ResponseBody + public String saveAuthUser(Role role, HttpServletRequest request) { +// // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 +// Role old = super.getWebDataBinderSource(request); +// if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ +// return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); +// } + roleService.saveAuthUser(role); + return renderResult(Global.TRUE, text("角色授权给用户成功")); + } + + /** + * 删除角色授权给用户 + */ + @RequiresPermissions("sys:role:edit") + @RequestMapping(value = "deleteAuthUser") + @ResponseBody + public String deleteAuthUser(Role role, HttpServletRequest request) { +// // 获取原数据的isSys状态,如果是系统数据,则必须超级管理员编辑 +// Role old = super.getWebDataBinderSource(request); +// if (old != null && Global.YES.equals(old.getIsSys()) && !role.currentUser().isSuperAdmin()){ +// return renderResult(Global.FALSE, text("越权操作,只有超级管理员才能修改系统数据!")); +// } + roleService.deleteAuthUser(role); + return renderResult(Global.TRUE, text("取消用户角色授权成功")); + } + +} \ No newline at end of file diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/TagsController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/TagsController.java new file mode 100644 index 00000000..53990468 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/TagsController.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.web.BaseController; +import com.jeesite.common.web.http.ServletUtils; +import io.swagger.v3.oas.annotations.Hidden; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 公共标签Controller + * @author ThinkGem + * @version 2020-5-7 + */ +@Controller +@RequestMapping(value = "tags") +@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true) +@Hidden +public class TagsController extends BaseController { + + /** + * 树结构选择标签使用 + */ + @RequestMapping(value = "treeselect") + public String treeselect(HttpServletRequest request, Model model) { + model.addAllAttributes(ServletUtils.getParameters(request)); + return "tagsview/form/treeselect"; + } + + /** + * 图标选择标签 + */ + @RequestMapping(value = "iconselect") + public String iconselect(HttpServletRequest request, Model model) { + model.addAllAttributes(ServletUtils.getParameters(request)); + return "tagsview/form/iconselect"; + } + + /** + * 图片裁剪标签 + */ + @RequestMapping(value = "imageclip") + public String imageclip(HttpServletRequest request, Model model) { + model.addAllAttributes(ServletUtils.getParameters(request)); + return "tagsview/form/imageclip"; + } + +} diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/ValidCodeController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/ValidCodeController.java new file mode 100644 index 00000000..4a2ee181 --- /dev/null +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/ValidCodeController.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. + */ +package com.jeesite.modules.sys.web; + +import com.jeesite.common.config.Global; +import com.jeesite.modules.sys.utils.ValidCodeUtils; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 验证码控制器 + * @author ThinkGem + * @version 2019年12月17日 + */ +@Controller +@Tag(name = "ValidCode - 验证码服务") +public class ValidCodeController { + + @RequestMapping(value="/validCode") + public void validCode(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // 如果传递了validCode参数,则代表是验证方法,成功返回true,失败返回false + String validCode = request.getParameter(ValidCodeUtils.VALID_CODE); + if (StringUtils.isNotBlank(validCode)){ + boolean result = ValidCodeUtils.validate(request, ValidCodeUtils.VALID_CODE, validCode, false); + response.getOutputStream().print(result ? Global.TRUE : Global.FALSE); + } + else{ + // 设置响应头 + response.setContentType("image/png"); + response.setHeader("Cache-Control", "no-cache, no-store"); + response.setHeader("Pragma", "no-cache"); + long time = System.currentTimeMillis(); + response.setDateHeader("Last-Modified", time); + response.setDateHeader("Date", time); + response.setDateHeader("Expires", time); + // 生成输出验证码 + String s = ValidCodeUtils.generateCaptcha(response.getOutputStream()); +// System.out.println(s); + request.getSession().setAttribute(ValidCodeUtils.VALID_CODE, s); + } + } + +} diff --git a/modules/core/src/main/resources/views/modules/sys/auditList.html b/modules/core/src/main/resources/views/modules/sys/auditList.html new file mode 100644 index 00000000..a710e14a --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/auditList.html @@ -0,0 +1,98 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '安全审计', libs: ['dataGrid']}){ %> +
+ +
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/auditMenuList.html b/modules/core/src/main/resources/views/modules/sys/auditMenuList.html new file mode 100644 index 00000000..37fe390e --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/auditMenuList.html @@ -0,0 +1,186 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '安全审计', libs: ['layout', 'zTree', 'dataGrid']}){ %> +
+ +
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/auditUserList.html b/modules/core/src/main/resources/views/modules/sys/auditUserList.html new file mode 100644 index 00000000..b6224fc7 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/auditUserList.html @@ -0,0 +1,166 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '安全审计', libs: ['layout', 'zTree', 'dataGrid']}){ %> +
+ +
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/configForm.html b/modules/core/src/main/resources/views/modules/sys/configForm.html new file mode 100644 index 00000000..95c53106 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/configForm.html @@ -0,0 +1,104 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '参数设置', libs: ['validate']}){ %> +
+
+
+
+ ${text(config.isNewRecord ? '新增参数' : '编辑参数')} +
+
+ +
+
+ <#form:form id="inputForm" model="${config}" action="${ctx}/sys/config/save" method="post" class="form-horizontal"> + <#form:hidden path="id" /> +
+
${text('基本信息')}
+
+
+
+ +
+ <#form:input path="configName" maxlength="100" class="form-control required" + readonly="${!user().superAdmin}"/> +
+
+
+
+
+
+
+ +
+ <#form:input path="configKey" maxlength="100" class="form-control required" + readonly="${!user().superAdmin}" + remote="${ctx}/sys/config/checkConfigKey?oldConfigKey=${config.configKey}" + data-msg-remote="${text('参数键名已存在')}"/> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="configValue" rows="4" maxlength="2000" class="form-control "/> +
+
+
+
+
+
+
+ +
+ <#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="remarks" rows="3" maxlength="300" class="form-control"/> +
+
+
+
+
+ + +
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/configList.html b/modules/core/src/main/resources/views/modules/sys/configList.html new file mode 100644 index 00000000..a2d1e5e0 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/configList.html @@ -0,0 +1,102 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '参数设置', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('参数设置')} +
+
+ ${text('查询')} + <% if(hasPermi('sys:config:edit')){ %> + ${text('新增')} + ${text('清理全部缓存')} + <% } %> + + + + + + + + + + + +
+
+
+ <#form:form id="searchForm" model="${config}" action="${ctx}/sys/config/listData" method="post" class="form-inline " + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> +
+ +
+ <#form:input path="configName" maxlength="100" class="form-control" /> +
+
+
+ +
+ <#form:input path="configKey_like" maxlength="100" class="form-control" /> +
+
+
+ +
+ <#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/> +
+
+
+ + +
+ +
+
+
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/dictDataForm.html b/modules/core/src/main/resources/views/modules/sys/dictDataForm.html new file mode 100644 index 00000000..dd94e90e --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/dictDataForm.html @@ -0,0 +1,151 @@ +<% layout('/layouts/default.html', {title: '字典数据管理', libs: ['validate']}){ %> +
+
+
+
+ ${text(dictData.isNewRecord ? '新增字典' : '编辑字典')}(${dictData.dictType}) +
+
+ +
+
+ <#form:form id="inputForm" model="${dictData}" action="${ctx}/sys/dictData/save" method="post" class="form-horizontal"> +
+
${text('基本信息')}
+
+
+
+ +
+ <#form:treeselect id="parent" title="${text('上级字典')}" + path="parent.id" labelPath="parent.dictLabelRaw" + url="${ctx}/sys/dictData/treeData?excludeCode=${dictData.id}&dictType=${dictData.dictType}&isShowRawName=true" + class="" allowClear="true" canSelectRoot="true" canSelectParent="true" isReturnValue="false"/> +
+
+
+
+ <#form:hidden path="dictCode"/> + <#form:hidden path="dictType"/> +
+
+
+ +
+ <#form:input path="dictLabelRaw" maxlength="100" class="form-control required "/> +
+
+
+
+
+ +
+ <#form:input path="dictValue" maxlength="100" class="form-control required "/> +
+
+
+
+
+
+
+ +
+ <#form:input path="treeSort" maxlength="9" class="form-control required digits"/> +
+
+
+
+
+ +
+ <#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:input path="description" maxlength="500" class="form-control "/> +
+
+
+
+
+ +
+ <#form:iconselect path="dictIcon" class=""/> +
+
+
+
+
${text('其它信息')}
+
+
+
+ +
+ <#form:input path="cssClass" maxlength="500" class="form-control "/> +
+
+
+
+
+ +
+ <#form:input path="cssStyle" maxlength="500" class="form-control "/> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/> +
+
+
+
+ <#form:extend collapsed="true" /> +
+ + +
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/dictDataList.html b/modules/core/src/main/resources/views/modules/sys/dictDataList.html new file mode 100644 index 00000000..a9351288 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/dictDataList.html @@ -0,0 +1,116 @@ +<% layout('/layouts/default.html', {title: '字典数据管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('字典数据')}(${dictData.dictType}) +
+
+ ${text('查询')} + ${text('刷新')} + ${text('展开')} + ${text('折叠')} + <% if(hasPermi('sys:dictData:edit')){ %> + ${text('新增')} + <% } %> + +
+
+
+ <#form:form id="searchForm" model="${dictData}" action="${ctx}/sys/dictData/listData" method="post" class="form-inline " + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> +
+ +
+ <#form:input path="dictLabelRaw" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:input path="dictValue" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:input path="dictType" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/> +
+
+
+ +
+ <#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ +
+
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/dictTypeForm.html b/modules/core/src/main/resources/views/modules/sys/dictTypeForm.html new file mode 100644 index 00000000..afa8ec06 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/dictTypeForm.html @@ -0,0 +1,90 @@ +<% layout('/layouts/default.html', {title: '字典类型管理', libs: ['validate']}){ %> +
+
+
+
+ ${text(dictType.isNewRecord ? '新增字典类型' : '编辑字典类型')} +
+
+ +
+
+ <#form:form id="inputForm" model="${dictType}" action="${ctx}/sys/dictType/save" method="post" class="form-horizontal"> +
+
${text('基本信息')}
+ <#form:hidden path="id"/> +
+
+
+ +
+ <#form:input path="dictName" maxlength="100" class="form-control required "/> +
+
+
+
+
+
+
+ +
+ <#form:input path="dictType" maxlength="100" class="form-control required abc" + remote="${ctx}/sys/dictType/checkDictType?oldDictType=${dictType.dictType}" + data-msg-remote="${text('字典类型已存在')}"/> +
+
+
+
+
+
+
+ +
+ <#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/> +
+
+
+
+
+ + +
+
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/dictTypeList.html b/modules/core/src/main/resources/views/modules/sys/dictTypeList.html new file mode 100644 index 00000000..d88f8a08 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/dictTypeList.html @@ -0,0 +1,95 @@ +<% layout('/layouts/default.html', {title: '字典管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('字典管理')} +
+
+ ${text('查询')} + <% if(hasPermi('sys:dictType:edit')){ %> + ${text('新增')} + <% } %> + +
+
+
+ <#form:form id="searchForm" model="${dictType}" action="${ctx}/sys/dictType/listData" method="post" class="form-inline " + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> +
+ +
+ <#form:input path="dictName" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:input path="dictType_like" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/> +
+
+
+ +
+ <#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ +
+
+
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/langForm.html b/modules/core/src/main/resources/views/modules/sys/langForm.html new file mode 100644 index 00000000..2b9b23a0 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/langForm.html @@ -0,0 +1,103 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '国际化管理', libs: ['validate']}){ %> +
+
+
+
+ ${text(lang.isNewRecord ? '新增语言' : '编辑语言')} +
+
+ +
+
+ <#form:form id="inputForm" model="${lang}" action="${ctx}/sys/lang/save" method="post" class="form-horizontal"> +
+
${text('基本信息')}
+ <#form:hidden path="id"/> +
+
+
+ +
+ + <#form:input path="langCode" maxlength="500" class="form-control required "/> +
+
+
+
+
+
+
+ +
+ <#form:input path="langText" maxlength="500" class="form-control required "/> +
+
+
+
+
+
+
+ +
+ + <#form:radio path="langType" dictType="sys_lang_type" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:radio path="module.moduleCode" items="${moduleList}" itemLabel="moduleName" itemValue="moduleCode" class="form-control required" /> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/> +
+
+
+
+
+ + +
+
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/langList.html b/modules/core/src/main/resources/views/modules/sys/langList.html new file mode 100644 index 00000000..b608806c --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/langList.html @@ -0,0 +1,95 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '国际化管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('国际化管理')} +
+
+ ${text('查询')} + <% if(hasPermi('sys:lang:edit')){ %> + ${text('新增')} + ${text('清理缓存')} + <% } %> + +
+
+
+ <#form:form id="searchForm" model="${lang}" action="${ctx}/sys/lang/listData" method="post" class="form-inline " + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> +
+ +
+ <#form:input path="langCode_like" maxlength="500" class="form-control width-120"/> +
+
+
+ +
+ <#form:input path="langText" maxlength="500" class="form-control width-120"/> +
+
+
+ +
+ <#form:select path="langType" dictType="sys_lang_type" blankOption="true" class="form-control"/> +
+
+
+ +
+ <#form:select path="module.moduleCode" items="${moduleList}" itemLabel="moduleName" + itemValue="moduleCode" class="form-control" blankOption="true"/> +
+
+
+ + +
+ +
+
+
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/menuForm.html b/modules/core/src/main/resources/views/modules/sys/menuForm.html new file mode 100644 index 00000000..a58ef5c6 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/menuForm.html @@ -0,0 +1,284 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '菜单管理', libs: ['validate']}){ %> + +
+
+
+
+ ${text(menu.isNewRecord ? '新增菜单' : '编辑菜单')}( +
+ +
+
+ +
+
+ <#form:form id="inputForm" model="${menu}" action="${ctx}/sys/menu/save" method="post" class="form-horizontal"> + <#form:hidden path="sysCode" /> + <#form:hidden path="menuCode" /> +
+
${text('基本信息')}
+
+
+
+ +
+ <#form:treeselect id="parent" title="${text('上级菜单')}" + path="parent.id" labelPath="parent.menuNameRaw" + url="${ctx}/sys/menu/treeData?excludeCode=${menu.menuCode}&sysCode=${menu.sysCode}&isShowRawName=true" + class="" allowClear="true" canSelectRoot="true" canSelectParent="true"/> +
+
+
+
+
+ +
+ <#form:radio path="menuType" dictType="sys_menu_type" class="form-control required" /> +
+
+
+
+
+
+
+ +
+ <#form:input path="menuNameRaw" maxlength="50" class="form-control required" /> +
+
+
+
+
+ +
+ <#form:select multiple="true" path="moduleCodes" items="${moduleList}" itemLabel="moduleName" itemValue="moduleCode" class="form-control required" /> +
+
+
+
+
+
+
+ +
+ <#form:input path="menuHref" maxlength="2000" class="form-control"/> +
+
+
+
+
+ +
+ <#form:input path="menuTarget" maxlength="10" class="form-control"/> +
+
+
+
+
+
+
+ +
+ <#form:input path="treeSort" maxlength="9" class="form-control required"/> +
+
+
+
+
+ +
+ <#form:input path="permission" maxlength="100" class="form-control"/> +
+
+
+
+
+
+
+ +
+ <#form:iconselect path="menuIcon" class=""/> +
+
+
+
+
+ +
+
+ <#form:input path="menuColor" maxlength="50" class="form-control"/> + + + +
+
+
+
+
+
+
+
+ +
+ <#form:input path="menuTitle" maxlength="50" class="form-control" /> +
+
+
+
+
+ +
+ <#form:radio path="isShow" dictType="sys_show_hide" class="form-control required"/> +
+
+
+
+
+
+
+ +
+ <#form:select path="weight" dictType="sys_menu_weight" class="form-control required"/> +
+
+
+
+
${text('其它信息')}
+
+
+
+ +
+ <#form:textarea path="remarks" rows="3" maxlength="200" class="form-control"/> +
+
+
+
+ <% if (menu.isNewRecord){ /*%> +
+
+
+ +
+ <#form:textarea name="quickCreatePermi" rows="2" maxlength="200" class="form-control"/> + + 格式举例:[查看] sys:user:view; [编辑] sys:user:edit; [授权] sys:user:auth + +
+
+
+
+ <% */} %> + <#form:extend collapsed="true" /> +
+ + +
+
+<% } %> + + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/menuIndex.html b/modules/core/src/main/resources/views/modules/sys/menuIndex.html new file mode 100644 index 00000000..ef7bbea9 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/menuIndex.html @@ -0,0 +1,88 @@ +<% layout('/layouts/default.html', {title: '菜单管理', libs: ['layout','zTree']}){ %> +
+
+
+
+
+ + +
+
+ + + +
+
+
+
+
+
+
+
+
+ +
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/menuList.html b/modules/core/src/main/resources/views/modules/sys/menuList.html new file mode 100644 index 00000000..1f25f87b --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/menuList.html @@ -0,0 +1,166 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '菜单管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('菜单管理')}( +
+ +
+ +
+
+ <#form:form id="searchForm" model="${menu}" action="${ctx}/sys/menu/listData" method="post" class="form-inline hide"> + <#form:hidden path="moduleCodes" class="isReset" /> + <#form:hidden path="menuCode" class="isReset"/> + <#form:hidden path="sysCode" /> +
+ +
+ <#form:input path="menuNameRaw" maxlength="50" class="form-control" /> +
+
+
+ +
+ <#form:input path="menuHref" maxlength="50" class="form-control" /> +
+
+
+ +
+ <#form:input path="permission" maxlength="50" class="form-control" /> +
+
+
+ +
+ <#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ + <#form:form id="dataGridForm" action="${ctx}/sys/menu/updateTreeSort" method="post"> +
+ +
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/moduleForm.html b/modules/core/src/main/resources/views/modules/sys/moduleForm.html new file mode 100644 index 00000000..fdb352f4 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/moduleForm.html @@ -0,0 +1,160 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '模块管理', libs: ['validate']}){ %> +<% var moduleNames = [ + 'app','bpm','cms','core','filemanager','filepreview','oauth2', + 'oss-client','sharding','swagger','ureport','visual','weixin' +], isCustomModule = !@moduleNames.contains(module.moduleCode); %> +
+
+
+
+ ${text(module.isNewRecord ? '新增模块' : '编辑模块')} +
+
+ +
+
+ <#form:form id="inputForm" model="${module}" action="${ctx}/sys/module/save" method="post" class="form-horizontal"> +
+
${text('基本信息')}
+
+
+
+ +
+ <#form:input path="moduleName" maxlength="100" class="form-control required"/> +
+
+
+
+
+ +
+ <#form:hidden path="isNewRecord"/> + <#form:input path="moduleCode" maxlength="64" readonly="${!module.isNewRecord}" class="form-control abc2 required"/> +
+
+
+
+
+
+
+ +
+ <#form:input path="mainClassName" maxlength="500" class="form-control"/> +
+
+
+
+
+
+
+ +
+ <#form:textarea path="description" rows="4" maxlength="500" class="form-control"/> +
+
+
+
+
+
+
+ + <% if(isNotBlank(module.upgradeInfo)){ %> +
+ ${module.currentVersion}   ${module.upgradeInfo} +
+ <% }else{ %> +
+ <#form:input path="currentVersion" maxlength="50" class="form-control"/> +
+ <% } %> +
+
+
+ <% if (hasPermi('sys:module:edit') && isCustomModule){ %> +
${text('生成工程代码')}
+
+
+
+ +
+
+ <#form:input name="genBaseDir" value="${genBaseDir}" maxlength="2000" class="form-control"/> +
+ + +
+
+
+
+
+
+
+
+
+ +
+ <#form:select path="tplCategory" items="${config.moduleTplCategoryList}" itemLabel="label" itemValue="value" blankOption="true" class="form-control "/> +
+
+ <#form:checkbox path="replaceFile" label="${text('是否替换现有文件')}" class="form-control" title="${text('如果生成文件已经存在,选中该选项原文件则被覆盖。')}"/> +
+
+
+
+ <% } %> +
+ + <%/* 乐观锁,前台提交时间戳作为该表单的版本号,后台更新数据前只要调用baseValidator即可验证版本。 + */%> + +
+
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/moduleList.html b/modules/core/src/main/resources/views/modules/sys/moduleList.html new file mode 100644 index 00000000..172c1ccc --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/moduleList.html @@ -0,0 +1,83 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '模块管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('模块管理')} +
+
+ ${text('查询')} + <% if(hasPermi('sys:module:edit')){ %> + ${text('新增')} + <% } %> + +
+
+
+ <#form:form id="searchForm" model="${module}" action="${ctx}/sys/module/listData" method="post" class="form-inline hide" + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> +
+ +
+ <#form:input path="moduleName" maxlength="100" class="form-control"/> +
+
+
+ +
+ <#form:input path="mainClassName" maxlength="500" class="form-control"/> +
+
+
+ +
+ <#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ +
+
+
+
+
+<% } %> + \ No newline at end of file diff --git a/modules/core/src/main/resources/views/modules/sys/roleForm.html b/modules/core/src/main/resources/views/modules/sys/roleForm.html new file mode 100644 index 00000000..cc77d018 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/roleForm.html @@ -0,0 +1,310 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '角色管理', libs: ['validate', 'zTree']}){ %> +
+
+
+
+ ${text(role.isNewRecord ? '新增角色' : op == 'auth' ? '角色分配功能权限' : '编辑角色')} +
+
+ +
+
+ <#form:form id="inputForm" model="${role}" action="${ctx}/sys/role/save" method="post" class="form-horizontal"> + <#form:hidden name="op" value="${op}"/> +
+
${text('基本信息')}
+
+
+
+ +
+ <#form:hidden name="oldRoleName" value="${role.roleName}"/> + <#form:input path="roleName" maxlength="100" readonly="${op=='auth'}" class="form-control required " + remote="${ctx}/sys/role/checkRoleName?oldRoleName=${role.roleName}" + data-msg-remote="${text('角色名称已存在')}"/> +
+
+
+ <% if(!role.isNewRecord) { %> +
+
+ +
+ <#form:hidden path="isNewRecord"/> + <#form:hidden path="viewCode"/> + <#form:input path="roleCode" maxlength="64" readonly="${!role.isNewRecord}" class="form-control required abc"/> +
+
+
+ <% } else { %> +
+
+ +
+ <#form:hidden path="isNewRecord"/> + <#form:hidden path="roleCode"/> + <#form:input path="viewCode" maxlength="64" readonly="${!role.isNewRecord}" class="form-control required abc"/> +
+
+
+ <% } %> +
+ <% if(op == 'add' || op == 'edit') {%> +
+
+
+ +
+ <#form:input path="roleSort" maxlength="10" class="form-control required digits"/> +
+
+
+
+
+ +
+ <#form:select path="userType" dictType="sys_user_type" blankOption="true" class="form-control " /> +
+
+
+
+
+
+
+ +
+ <#form:select path="roleType" dictType="sys_role_type" blankOption="true" class="form-control " /> +
+
+
+
+
+ +
+ <#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:input path="desktopUrl" maxlength="250" class="form-control " /> +
+
+
+
+
+ +
+ <#form:radio path="isShow" dictType="sys_show_hide" class="form-control required " /> +
+
+
+
+ <% } %> + <% if(op == 'add' || op == 'auth') {%> +
+
+
+ +
+ <#form:select path="sysCodes" dictType="sys_menu_sys_code" multiple="true" class="form-control " /> +
+
+
+
+ <% } %> + <% if(op == 'add' || op == 'edit') {%> +
+
+
+ +
+ <#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/> +
+
+
+
+ <#form:extend collapsed="true" /> + <% } %> + <% if(op == 'add' || op == 'auth') {%> +
${text('授权功能菜单')}
+ + + <#form:hidden name="roleMenuListJson"/> + <% } %> +
+ + +
+
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/roleFormAuthDataScope.html b/modules/core/src/main/resources/views/modules/sys/roleFormAuthDataScope.html new file mode 100644 index 00000000..70fa6761 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/roleFormAuthDataScope.html @@ -0,0 +1,216 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '角色管理', libs: ['validate', 'zTree']}){ %> +
+
+
+
+ ${text('角色分配数据权限')} +
+
+ +
+
+ <#form:form id="inputForm" model="${role}" action="${ctx}/sys/role/saveAuthDataScope" method="post" class="form-horizontal"> +

+
+
+
+ +
+ <#form:hidden name="oldRoleName" value="${role.roleName}"/> + <#form:input path="roleName" maxlength="100" readonly="true" class="form-control required "/> +
+
+
+
+
+ +
+ <#form:hidden path="isNewRecord"/> + <#form:hidden path="roleCode"/> + <#form:input path="viewCode" maxlength="64" readonly="true" class="form-control required abc"/> +
+
+
+
+
+
+
+ +
+ <#form:radio path="dataScope" dictType="sys_role_data_scope" class="form-control required " /> +
+
+
+
+
+
+
+ +
+ <#form:select path="bizScope" dictType="sys_role_biz_scope" class="form-control " multiple="true"/> +
+
+
+
+
${text('授权数据权限')}
+
+ + <#form:hidden name="roleDataScopeListJson"/> +
+ + +
+
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/roleFormAuthUser.html b/modules/core/src/main/resources/views/modules/sys/roleFormAuthUser.html new file mode 100644 index 00000000..c21fe872 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/roleFormAuthUser.html @@ -0,0 +1,138 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '角色管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('角色分配用户')}(${role.roleName}-${role.viewCode}-${@DictUtils.getDictLabel('sys_user_type',role.userType,'未设置')}) +
+ +
+
+ <#form:form id="searchForm" action="${ctx}/sys/user/listData" method="post" class="form-inline " + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> + <#form:hidden name="roleCode" value="${role.roleCode}"/> + <#form:hidden name="userType" value="${role.userType}"/> +
+ +
+ <#form:input name="loginCode" maxlength="100" class="form-control width-90"/> +
+
+
+ +
+ <#form:input name="userName" maxlength="100" class="form-control width-90"/> +
+
+
+ +
+ <#form:input name="email" maxlength="300" class="form-control width-90"/> +
+
+
+ +
+ <#form:input name="mobile" maxlength="100" class="form-control width-90"/> +
+
+
+ +
+ <#form:input name="phone" maxlength="100" class="form-control width-90"/> +
+
+
+ +
+ <#form:select path="status" dictType="sys_user_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ +
+
+
+
+
+
<#form:listselect id="userSelect" title="${text('用户选择')}" + url="${ctx}/sys/user/userSelect?userType=${role.userType}" allowClear="false" + checkbox="true" itemCode="userCode" itemName="userName"/>
+<% } %> + diff --git a/modules/core/src/main/resources/views/modules/sys/roleList.html b/modules/core/src/main/resources/views/modules/sys/roleList.html new file mode 100644 index 00000000..26a73457 --- /dev/null +++ b/modules/core/src/main/resources/views/modules/sys/roleList.html @@ -0,0 +1,124 @@ +<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved. + * No deletion without permission, or be held responsible to law. */ %> +<% layout('/layouts/default.html', {title: '角色管理', libs: ['dataGrid']}){ %> +
+
+
+
+ ${text('角色管理')} +
+
+ ${text('查询')} + <% if(hasPermi('sys:role:edit')){ %> + ${text('新增')} + <% } %> + +
+
+
+ <#form:form id="searchForm" model="${role}" action="${ctx}/sys/role/listData" method="post" class="form-inline hide" + data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}"> + <#form:hidden name="ctrlPermi" value="${ctrlPermi}"/> +
+ +
+ <#form:input path="roleName_like" maxlength="100" class="form-control width-120"/> +
+
+
+ +
+ <#form:input path="roleCode_like" maxlength="100" class="form-control width-120"/> +
+
+
+ +
+ <#form:select path="userType" dictType="sys_user_type" blankOption="true" class="form-control"/> +
+
+
+ +
+ <#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/> +
+
+ +
+ +
+ <#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/> +
+
+
+ + +
+ +
+
+
+
+
+<% } %> + \ No newline at end of file