开源全部基础功能的前端视图和控制器文件
This commit is contained in:
@@ -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<String, Object> params() {
|
||||
Map<String, Object> 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<String, Object> 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<FileUpload> list = fileUploadService.findList(fileUpload);
|
||||
if(list != null && !list.isEmpty()){
|
||||
return JsonMapper.toJson(list);
|
||||
}
|
||||
}
|
||||
return renderResult(Global.FALSE, "No files.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Audit> auditListData(Audit audit, HttpServletRequest request, HttpServletResponse response) {
|
||||
audit.setPage(new Page<>(request, response));
|
||||
Page<Audit> 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<Audit> 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<Audit> userListData(Audit audit, HttpServletRequest request, HttpServletResponse response) {
|
||||
audit.setPage(new Page<>(request, response));
|
||||
Page<Audit> 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<String, Object> menuListData(Audit audit) {
|
||||
Map<String, Object> model = MapUtils.newHashMap();
|
||||
List<Menu> menuList = auditService.findMenuList(audit);
|
||||
Map<String, List<Map<String, String>>> map = MapUtils.newLinkedHashMap();
|
||||
for (Menu menu : menuList){
|
||||
List<Map<String, String>> list = map.get(menu.getSysCode());
|
||||
if (list == null){
|
||||
list = ListUtils.newArrayList();
|
||||
map.put(menu.getSysCode(), list);
|
||||
}
|
||||
Map<String, String> m = MapUtils.newHashMap();
|
||||
m.put("id", menu.getMenuCode());
|
||||
m.put("pId", menu.getParentCode());
|
||||
m.put("name", menu.getMenuName() + "<font color=#888> "
|
||||
+ StringUtils.abbr(ObjectUtils.toString(menu.getPermission()) + " "
|
||||
+ ObjectUtils.toString(menu.getMenuHref()), 50) + "</font>");
|
||||
m.put("title", menu.getMenuName() + " "
|
||||
+ ObjectUtils.toString(menu.getPermission()) + "\n"
|
||||
+ ObjectUtils.toString(menu.getMenuHref()));
|
||||
list.add(m);
|
||||
}
|
||||
model.put("menuMap", map);
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Config> listData(Config config, HttpServletRequest request, HttpServletResponse response) {
|
||||
config.setPage(new Page<>(request, response));
|
||||
Page<Config> 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("删除参数成功"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<DictData> listData(DictData dictData) {
|
||||
if (StringUtils.isBlank(dictData.getParentCode())) {
|
||||
dictData.setParentCode(DictData.ROOT_CODE);
|
||||
}
|
||||
List<DictData> 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<Map<String, Object>> treeData(String dictType, String excludeCode,
|
||||
String isShowCode, boolean isShowRawName) {
|
||||
List<Map<String, Object>> mapList = ListUtils.newArrayList();
|
||||
List<DictData> list = DictUtils.getDictList(dictType);
|
||||
for (int i=0; i<list.size(); i++){
|
||||
DictData e = list.get(i);
|
||||
// 过滤非正常的数据(状态为空的除外)
|
||||
if (!DictData.STATUS_NORMAL.equals(e.getStatus()) && e.getStatus() != null){
|
||||
continue;
|
||||
}
|
||||
// 过滤被排除的编码(包括所有子级)
|
||||
if (StringUtils.isNotBlank(excludeCode)){
|
||||
if (e.getId().equals(excludeCode)){
|
||||
continue;
|
||||
}
|
||||
if (e.getParentCodes().contains("," + excludeCode + ",")){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Map<String, Object> 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("数据修复成功"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<DictType> listData(DictType dictType, HttpServletRequest request, HttpServletResponse response) {
|
||||
dictType.setPage(new Page<>(request, response));
|
||||
Page<DictType> 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<Map<String, Object>> treeData(String dictType, String excludeCode,
|
||||
@RequestParam(defaultValue="1") String isShowCode) {
|
||||
List<Map<String, Object>> mapList = ListUtils.newArrayList();
|
||||
List<DictType> list = dictTypeService.findList(new DictType());
|
||||
for (int i=0; i<list.size(); i++){
|
||||
DictType e = list.get(i);
|
||||
// 过滤非正常的数据
|
||||
if (!DictType.STATUS_NORMAL.equals(e.getStatus())){
|
||||
continue;
|
||||
}
|
||||
// 过滤被排除的编码(包括所有子级)
|
||||
if (StringUtils.isNotBlank(excludeCode)){
|
||||
if (e.getId().equals(excludeCode)){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Map<String, Object> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Menu> 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<Menu> 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<Module> 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<Map<String, Object>> treeData(String excludeCode, String parentCode, String isShowHide,
|
||||
String sysCode, boolean isShowRawName, HttpServletResponse response) {
|
||||
List<Map<String, Object>> mapList = ListUtils.newArrayList();
|
||||
Menu where = new Menu();
|
||||
where.setStatus(Menu.STATUS_NORMAL);
|
||||
if (StringUtils.isNotBlank(parentCode)){
|
||||
where.setParentCode(parentCode);
|
||||
}
|
||||
List<Menu> 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<String, Object> 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("数据修复成功"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Module> listData(Module module, HttpServletRequest request, HttpServletResponse response) {
|
||||
module.setPage(new Page<>(request, response));
|
||||
Page<Module> 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<String> 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 + "成功: <br/>" + 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("删除模块成功"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Role> listData(Role role, String ctrlPermi, HttpServletRequest request, HttpServletResponse response) {
|
||||
// 不是超级管理员,则添加数据权限过滤
|
||||
if (!role.currentUser().isSuperAdmin()){
|
||||
roleService.addDataScopeFilter(role, ctrlPermi);
|
||||
}
|
||||
role.setPage(new Page<>(request, response));
|
||||
Page<Role> 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<String, Object> menuTreeData(Role role, HttpServletRequest request) {
|
||||
Map<String, Object> model = MapUtils.newHashMap();
|
||||
List<Menu> 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<String> sysCodes = ListUtils.newArrayList();
|
||||
for (DictData sysCode : DictUtils.getDictList("sys_menu_sys_code")) {
|
||||
sysCodes.add(sysCode.getDictValue());
|
||||
}
|
||||
Map<String, List<Map<String, String>>> map = MapUtils.newLinkedHashMap();
|
||||
for (Menu menu : menuList){
|
||||
// 过滤已经禁用的子系统
|
||||
if (!sysCodes.contains(menu.getSysCode())) {
|
||||
continue;
|
||||
}
|
||||
List<Map<String, String>> list = map.get(menu.getSysCode());
|
||||
if (list == null){
|
||||
list = ListUtils.newArrayList();
|
||||
map.put(menu.getSysCode(), list);
|
||||
}
|
||||
Map<String, String> m = MapUtils.newHashMap();
|
||||
m.put("id", menu.getMenuCode());
|
||||
m.put("pId", menu.getParentCode());
|
||||
m.put("name", menu.getMenuName() + "<font color=#888> "
|
||||
+ StringUtils.abbr(ObjectUtils.toString(menu.getPermission()) + " "
|
||||
+ ObjectUtils.toString(menu.getMenuHref()), 50) + "</font>");
|
||||
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<Menu> 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<RoleDataScope> 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<Map<String, Object>> treeData(String userType, Boolean isAll, String isShowCode, String ctrlPermi) {
|
||||
List<Map<String, Object>> 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<Role> list = roleService.findList(where);
|
||||
list.forEach(e -> {
|
||||
Map<String, Object> 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("取消用户角色授权成功"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="nav-tabs-custom nav-main">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="${ctx}/sys/audit/list"><i class="fa icon-energy"></i> ${text('账号密码审计')}</a></li>
|
||||
<li><a href="${ctx}/sys/audit/userList"><i class="fa icon-book-open"></i> ${text('菜单权限审计')}</a></li>
|
||||
<li><a href="${ctx}/sys/audit/menuList"><i class="fa icon-user"></i> ${text('用户权限审计')}</a></li>
|
||||
</ul>
|
||||
<div class="box-body">
|
||||
<#form:form id="searchForm" model="${audit}" action="${ctx}/sys/audit/listData" method="post" class="form-inline"
|
||||
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('类型')}:</label>
|
||||
<div class="control-inline">
|
||||
<div class="btn-group" id="btnAuditType">
|
||||
<button type="button" class="btn btn-default active" data-type="0">${text('全部问题')}</button>
|
||||
<button type="button" class="btn btn-default" data-type="1">${text('未修改初始密码')}</button>
|
||||
<button type="button" class="btn btn-default" data-type="2" title="${text('密码等级是弱或者很弱的')}">${text('使用简单密码')}</button>
|
||||
<button type="button" class="btn btn-default" data-type="3" title="${text('定期未修改密码的账号 {0\} 天内不被审查', @Global.getConfig('sys.user.passwordModifyCycle'))}"><i class="fa icon-question "></i> ${text('定期未修改密码')}</button>
|
||||
<button type="button" class="btn btn-default" data-type="4" title="${text('长期未登录的账号 {0\} 天内不被审查', @Global.getConfig('sys.user.passwordModifyCycle'))}"><i class="fa icon-question "></i> ${text('长期未登录')}</button>
|
||||
<button type="button" class="btn btn-default" data-type="5">${text('未设置密保')}</button>
|
||||
</div>
|
||||
<#form:hidden path="auditType" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="inline-block">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('账号')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="loginCode" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('昵称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="userName" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('机构')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:treeselect id="office" title="${text('机构选择')}"
|
||||
path="officeCode" labelPath="officeName"
|
||||
url="${ctx}/sys/office/treeData" btnClass="btn-sm" allowClear="true" canSelectParent="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
<button type="button" id="btnExport" class="btn btn-default btn-sm">${text('导出')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("登录账号")}', name:'loginCode', index:'u.login_code', width:80, align:"center"},
|
||||
{header:'${text("用户昵称")}', name:'userName', index:'u.user_name', width:80, align:"center"},
|
||||
{header:'${text("归属机构")}', name:'officeName', index:'o.office_name', width:90, align:"center"},
|
||||
{header:'${text("审计结果")}', name:'auditResult', sortable:false, width:235, align:"left"},
|
||||
{header:'${text("创建时间")}', name:'createDate', index:'u.create_date', width:100, align:"center"},
|
||||
{header:'${text("密码修改时间")}', name:'pwdUpdateDate',index:'u.pwd_update_date', align:"center", width:100},
|
||||
{header:'${text("最后登录时间")}', name:'lastLoginDate',index:'u.last_login_date', align:"center", width:100},
|
||||
{header:'${text("状态")}', name:'status', index:'u.status', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("类型")}', name:'userType', index:'u.user_type', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_user_type')}", val, '无', true);
|
||||
}},
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
$('#btnAuditType button').click(function(){
|
||||
$('#btnAuditType button').removeClass('active');
|
||||
$('#auditType').val($(this).addClass('active').data('type'));
|
||||
$('#searchForm').submit();
|
||||
});
|
||||
$('#btnExport').click(function(){
|
||||
js.ajaxSubmitForm($('#searchForm'), {
|
||||
url: '${ctx}/sys/audit/exportData',
|
||||
clearParams: 'pageNo,pageSize',
|
||||
downloadFile: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="nav-tabs-custom nav-main">
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="${ctx}/sys/audit/list"><i class="fa icon-energy"></i> ${text('账号密码审计')}</a></li>
|
||||
<li><a href="${ctx}/sys/audit/userList"><i class="fa icon-book-open"></i> ${text('菜单权限审计')}</a></li>
|
||||
<li class="active"><a href="${ctx}/sys/audit/menuList"><i class="fa icon-user"></i> ${text('用户权限审计')}</a></li>
|
||||
</ul>
|
||||
<div id="layout">
|
||||
<div class="ui-layout-east">
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
${text('菜单权限')}
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" id="btnRefresh" title="${text('刷新')}"><i class="fa fa-refresh"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-content">
|
||||
<div id="menuTrees"></div>
|
||||
<script id="menuTpl" type="text/template">
|
||||
<div class="pull-left" style="width:100%;overflow:hidden">
|
||||
<div class="box box-solid box-trees">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<label>{{d.label}}</label>
|
||||
</div>
|
||||
<div class="box-tools pull-right" style="top:8px;">
|
||||
<a class="btn btn-box-tool" id="expand_{{d.key}}"
|
||||
value="menuTree_{{d.key}}" >${text('展开')}</a>/<a
|
||||
class="btn btn-box-tool" id="collapse_{{d.key}}"
|
||||
value="menuTree_{{d.key}}" >${text('折叠')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="menuTree_{{d.key}}" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-center">
|
||||
<div class="ui-layout-content box-body">
|
||||
<#form:form id="searchForm" model="${audit}" action="${ctx}/sys/audit/userListData" method="post" class="form-inline"
|
||||
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
|
||||
<#form:hidden name="isAll" value="true"/>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('账号')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="loginCode" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('昵称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="userName" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('机构')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:treeselect id="office" title="${text('机构选择')}"
|
||||
path="officeCode" labelPath="officeName"
|
||||
url="${ctx}/sys/office/treeData" btnClass="btn-sm" allowClear="true" canSelectParent="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化大小
|
||||
$(window).resize(function(){
|
||||
$('#layout').height($(window).height() - $('.nav-tabs').height() - 6);
|
||||
}).resize();
|
||||
//# // 初始化布局
|
||||
$('#layout').layout({
|
||||
east__size: '40%',
|
||||
onresize_end: function(){
|
||||
$('#dataGrid').dataGrid('resize');
|
||||
}
|
||||
});
|
||||
//# // 树结构初始化加载
|
||||
var setting = {view:{selectedMulti:false,nameIsHTML: true},data:{key:{title:"title"},simpleData:{enable:true}},
|
||||
callback:{onClick:function(event, treeId, treeNode){
|
||||
var tree = $.fn.zTree.getZTreeObj(treeId);
|
||||
tree.expandNode(treeNode);
|
||||
$('#menuCode').val(treeNode.id);
|
||||
page();
|
||||
}}
|
||||
},
|
||||
sysCodeDict = "#{@DictUtils.getDictListJson('sys_menu_sys_code')}",
|
||||
userCode = '', menuTrees = {},
|
||||
loadTree = function(){
|
||||
$('#menuTrees').empty();
|
||||
js.ajaxSubmit("${ctx}/sys/audit/menuTreeData?___t=" + new Date().getTime(),
|
||||
{userCode: userCode}, function(data){
|
||||
for (var sysCode in data.menuMap){
|
||||
var menuMap = data.menuMap[sysCode];
|
||||
$('#menuTrees').append(js.template('menuTpl', {key: sysCode,
|
||||
label: js.getDictLabel(sysCodeDict, sysCode, '未知', true)}));
|
||||
//# // 初始化树结构
|
||||
var tree = $.fn.zTree.init($("#menuTree_"+sysCode), setting, menuMap);
|
||||
var level = -1, nodes;
|
||||
while (++level <= 1) {
|
||||
nodes = tree.getNodesByParam("level", level);
|
||||
if (nodes.length > 10) { break; }
|
||||
for(var i=0; i<nodes.length; i++) {
|
||||
tree.expandNode(nodes[i], true, false, false);
|
||||
}
|
||||
}
|
||||
//# // 展开和折叠按钮绑定
|
||||
$('#expand_'+sysCode).click(function(){
|
||||
var sysCode = $(this).attr('sysCode');
|
||||
menuTrees[sysCode].expandAll(true);
|
||||
}).attr("sysCode", sysCode);
|
||||
$('#collapse_'+sysCode).click(function(){
|
||||
var sysCode = $(this).attr('sysCode');
|
||||
menuTrees[sysCode].expandAll(false);
|
||||
}).attr("sysCode", sysCode);
|
||||
//# // 将树对象存储到全局数组里
|
||||
menuTrees[sysCode] = tree;
|
||||
}
|
||||
}, null, null, js.text('loading.message'));
|
||||
};loadTree();
|
||||
$('#btnRefresh').click(function(){
|
||||
loadTree();
|
||||
});
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
autoGridHeight: function(){
|
||||
return $('.ui-layout-content').height()
|
||||
- $('#searchForm').height() - $('#dataGridPage').height() - 16;
|
||||
},
|
||||
columnModel: [
|
||||
{header:'${text("登录账号")}', name:'loginCode', index:'u.login_code', width:80, align:"center"},
|
||||
{header:'${text("用户昵称")}', name:'userName', index:'u.user_name', width:80, align:"center"},
|
||||
{header:'${text("归属机构")}', name:'officeName', index:'o.office_name', width:90, align:"center"},
|
||||
{header:'${text("创建时间")}', name:'createDate', index:'u.create_date', width:100, align:"center"},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'u.update_date', width:100, align:"center"},
|
||||
{header:'${text("状态")}', name:'status', index:'u.status', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("类型")}', name:'userType', index:'u.user_type', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_user_type')}", val, '无', true);
|
||||
}},
|
||||
],
|
||||
onSelectRow: function(id, isSelect, event){
|
||||
userCode = id;
|
||||
loadTree();
|
||||
},
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
$('#btnAuditType button').click(function(){
|
||||
$('#btnAuditType button').removeClass('active');
|
||||
$('#auditType').val($(this).addClass('active').data('type'));
|
||||
$('#searchForm').submit();
|
||||
});
|
||||
$('#btnExport').click(function(){
|
||||
js.ajaxSubmitForm($('#searchForm'), {
|
||||
url: '${ctx}/sys/audit/exportData',
|
||||
clearParams: 'pageNo,pageSize',
|
||||
downloadFile: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="nav-tabs-custom nav-main">
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="${ctx}/sys/audit/list"><i class="fa icon-energy"></i> ${text('账号密码审计')}</a></li>
|
||||
<li class="active"><a href="${ctx}/sys/audit/userList"><i class="fa icon-book-open"></i> ${text('菜单权限审计')}</a></li>
|
||||
<li><a href="${ctx}/sys/audit/menuList"><i class="fa icon-user"></i> ${text('用户权限审计')}</a></li>
|
||||
</ul>
|
||||
<div id="layout">
|
||||
<div class="ui-layout-west">
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title dropdown">
|
||||
<div class="dropdown-toggle" data-toggle="dropdown" data-hover="dropdown">
|
||||
<span id="sysName">${@DictUtils.getDictLabel('sys_menu_sys_code', 'default', text('全部菜单'))}</span><b class="caret"></b>
|
||||
</div>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var dict in @DictUtils.getDictList('sys_menu_sys_code')){ %>
|
||||
<li><a href="javascript:" onclick="$('#sysName').text('${dict.dictLabel}');sysCode='${dict.dictValue}';loadTree();"> <i
|
||||
class="fa fa-angle-right"></i> ${dict.dictLabel}
|
||||
</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" id="btnExpand" title="${text('展开')}" style="display:none;"><i class="fa fa-chevron-up"></i></button>
|
||||
<button type="button" class="btn btn-box-tool" id="btnCollapse" title="${text('折叠')}"><i class="fa fa-chevron-down"></i></button>
|
||||
<button type="button" class="btn btn-box-tool" id="btnRefresh" title="${text('刷新')}"><i class="fa fa-refresh"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-content">
|
||||
<div id="tree" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-center">
|
||||
<div class="ui-layout-content box-body">
|
||||
<#form:form id="searchForm" model="${audit}" action="${ctx}/sys/audit/userListData" method="post" class="form-inline"
|
||||
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
|
||||
<#form:hidden path="menuCode"/>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('账号')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="loginCode" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('昵称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="userName" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('机构')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:treeselect id="office" title="${text('机构选择')}"
|
||||
path="officeCode" labelPath="officeName"
|
||||
url="${ctx}/sys/office/treeData" btnClass="btn-sm" allowClear="true" canSelectParent="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化大小
|
||||
$(window).resize(function(){
|
||||
$('#layout').height($(window).height() - $('.nav-tabs').height() - 6);
|
||||
}).resize();
|
||||
//# // 初始化布局
|
||||
$('#layout').layout({
|
||||
west__size: 250,
|
||||
onresize_end: function(){
|
||||
$('#dataGrid').dataGrid('resize');
|
||||
}
|
||||
});
|
||||
//# // 树结构初始化加载
|
||||
var setting = {view:{selectedMulti:false},data:{key:{title:"title"},simpleData:{enable:true}},
|
||||
callback:{onClick:function(event, treeId, treeNode){
|
||||
tree.expandNode(treeNode);
|
||||
$('#menuCode').val(treeNode.id);
|
||||
page();
|
||||
}}
|
||||
},
|
||||
sysCode = 'default',
|
||||
tree, loadTree = function(){
|
||||
js.ajaxSubmit("${ctx}/sys/menu/treeData?___t=" + new Date().getTime(),
|
||||
{sysCode:sysCode}, function(data){
|
||||
tree = $.fn.zTree.init($("#tree"), setting, data);
|
||||
// 展开第一级节点
|
||||
var nodes = tree.getNodesByParam("level", 0);
|
||||
for(var i=0; i<nodes.length; i++) {
|
||||
tree.expandNode(nodes[i], true, false, false);
|
||||
}
|
||||
// 展开第二级节点
|
||||
// nodes = tree.getNodesByParam("level", 1);
|
||||
// for(var i=0; i<nodes.length; i++) {
|
||||
// tree.expandNode(nodes[i], true, false, false);
|
||||
// }
|
||||
}, null, null, js.text('loading.message'));
|
||||
};loadTree();
|
||||
//# // 工具栏按钮绑定
|
||||
$('#btnExpand').click(function(){
|
||||
tree.expandAll(true);
|
||||
$(this).hide();
|
||||
$('#btnCollapse').show();
|
||||
});
|
||||
$('#btnCollapse').click(function(){
|
||||
tree.expandAll(false);
|
||||
$(this).hide();
|
||||
$('#btnExpand').show();
|
||||
});
|
||||
$('#btnRefresh').click(function(){
|
||||
loadTree();
|
||||
});
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
autoGridHeight: function(){
|
||||
return $('.ui-layout-content').height()
|
||||
- $('#searchForm').height() - $('#dataGridPage').height() - 16;
|
||||
},
|
||||
columnModel: [
|
||||
{header:'${text("登录账号")}', name:'loginCode', index:'u.login_code', width:80, align:"center"},
|
||||
{header:'${text("用户昵称")}', name:'userName', index:'u.user_name', width:80, align:"center"},
|
||||
{header:'${text("归属机构")}', name:'officeName', index:'o.office_name', width:90, align:"center"},
|
||||
{header:'${text("创建时间")}', name:'createDate', index:'u.create_date', width:100, align:"center"},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'u.update_date', width:100, align:"center"},
|
||||
{header:'${text("状态")}', name:'status', index:'u.status', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("类型")}', name:'userType', index:'u.user_type', width:50, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_user_type')}", val, '无', true);
|
||||
}},
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
$('#btnAuditType button').click(function(){
|
||||
$('#btnAuditType button').removeClass('active');
|
||||
$('#auditType').val($(this).addClass('active').data('type'));
|
||||
$('#searchForm').submit();
|
||||
});
|
||||
$('#btnExport').click(function(){
|
||||
js.ajaxSubmitForm($('#searchForm'), {
|
||||
url: '${ctx}/sys/audit/exportData',
|
||||
clearParams: 'pageNo,pageSize',
|
||||
downloadFile: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-wrench"></i> ${text(config.isNewRecord ? '新增参数' : '编辑参数')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${config}" action="${ctx}/sys/config/save" method="post" class="form-horizontal">
|
||||
<#form:hidden path="id" />
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">
|
||||
<span class="required">*</span> ${text('参数名称')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="configName" maxlength="100" class="form-control required"
|
||||
readonly="${!user().superAdmin}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">
|
||||
<span class="required">*</span> ${text('参数键名')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#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('参数键名已存在')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
${text('参数键值')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:textarea path="configValue" rows="4" maxlength="2000" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('系统参数')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">${text('参数描述')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:textarea path="remarks" rows="3" maxlength="300" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:config:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title" title="读取顺序:Environment --> JVM中启动的参数 --> application.yml --> 本参数设置中的参数,读取参数方法:Global.getConfig('参数键名')">
|
||||
<i class="fa icon-wrench"></i> ${text('参数设置')} <i class="fa icon-question f14"></i>
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-search"></i> ${text('查询')}</a>
|
||||
<% if(hasPermi('sys:config:edit')){ %>
|
||||
<a href="${ctx}/sys/config/form" class="btn btn-default btnTool" title="${text('新增参数')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnUpdateCache" title="${text('清理全部缓存,包括属性文件的配置')}"><i class="fa fa-refresh"></i> ${text('清理全部缓存')}</a>
|
||||
<% } %>
|
||||
<!-- <div class="btn-group"> -->
|
||||
<!-- <a href="javascript:" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> -->
|
||||
<!-- <i class="fa fa-cogs"></i> 更多 <span class="caret"></span> -->
|
||||
<!-- </a> -->
|
||||
<!-- <ul class="dropdown-menu"> -->
|
||||
<!-- <li><a href="#"><i class="fa fa-pencil"></i> 导出</a></li> -->
|
||||
<!-- <li><a href="#"><i class="fa fa-trash-o"></i> 导入</a></li> -->
|
||||
<!-- <li role="separator" class="divider"></li> -->
|
||||
<!-- </ul> -->
|
||||
<!-- </div> -->
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('参数名称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="configName" maxlength="100" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('参数键名')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="configKey_like" maxlength="100" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('系统参数')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("参数名称")}', name:'configName', index:'a.config_name', width:200, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/config/form?id='+row.id+'" class="btnList" data-title="${text("编辑参数")}">'+val+'</a>';
|
||||
}},
|
||||
{header:'${text("参数键名")}', name:'configKey', index:'a.config_key', width:200},
|
||||
{header:'${text("参数键值")}', name:'configValue', sortable:false, width:200, classes:"nowrap"},
|
||||
{header:'${text("系统参数")}', name:'isSys', index:'a.is_sys', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_yes_no')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:config:edit')){
|
||||
actions.push('<a href="${ctx}/sys/config/form?id='+row.id+'" class="btnList" title="${text("编辑参数")}"><i class="fa fa-pencil"></i></a> ');
|
||||
actions.push('<a href="${ctx}/sys/config/delete?id='+row.id+'" class="btnList" title="${text("删除参数")}" data-confirm="${text("确认要删除该参数吗?")}"><i class="fa fa-trash-o"></i></a> ');
|
||||
// actions.push('<a href="javascript:" class="btnMore" title="更多操作"><i class="fa fa-chevron-circle-right"></i></a> ');
|
||||
// actions.push('<div class="moreItems">');
|
||||
// actions.push('<a href="${ctx}/sys/config/form?id='+row.id+'" class="btn btn-default btn-xs btnList" title="编辑参数"><i class="fa fa-pencil"></i> 编辑参数</a> ');
|
||||
// actions.push('<a href="${ctx}/sys/config/form?id='+row.id+'" class="btn btn-default btn-xs btnList" title="编辑参数"><i class="fa fa-pencil"></i> 编辑参数</a> ');
|
||||
// actions.push('<a href="${ctx}/sys/config/form?id='+row.id+'" class="btn btn-default btn-xs btnList" title="编辑参数"><i class="fa fa-pencil"></i> 编辑参数</a> ');
|
||||
// actions.push('</div>');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// 更新平台中的全部缓存,包含属性配置文件。
|
||||
$("#btnUpdateCache").click(function(){
|
||||
js.ajaxSubmit("${ctx}/sys/cache/clearAll", function(data){
|
||||
js.showMessage(data.message);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,151 @@
|
||||
<% layout('/layouts/default.html', {title: '字典数据管理', libs: ['validate']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-social-dropbox"></i> ${text(dictData.isNewRecord ? '新增字典' : '编辑字典')}(${dictData.dictType})
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${dictData}" action="${ctx}/sys/dictData/save" method="post" class="form-horizontal">
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('上级字典')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#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"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<#form:hidden path="dictCode"/>
|
||||
<#form:hidden path="dictType"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('字典标签')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="dictLabelRaw" maxlength="100" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('字典键值')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="dictValue" maxlength="100" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="当前字典树结构层次级别的排序号">
|
||||
<span class="required ">*</span> ${text('排序号')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="treeSort" maxlength="9" class="form-control required digits"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('系统内置')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="工具提示,如select鼠标放到option上去会显示该描述信息">
|
||||
<span class="required hide">*</span> ${text('字典描述')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="description" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="下拉选项的图标。支持选择字体图标,也支持设置一个 img 地址,如:http://host/js/img/icon.jpg 或 /img/icon.jpg">
|
||||
${text('选项图标')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:iconselect path="dictIcon" class=""/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-unit">${text('其它信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="CSS类名(如:class=“red”, 请填写:red)">
|
||||
<span class="required hide">*</span> ${text('CSS类名')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="cssClass" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="CSS样式(如:style=“color:red”, 请填写:color:red)">
|
||||
<span class="required hide">*</span> ${text('CSS样式')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="cssStyle" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('备注信息')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<#form:extend collapsed="true" />
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:dictData:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<% layout('/layouts/default.html', {title: '字典数据管理', libs: ['dataGrid']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header" style="display:block">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-social-dropbox"></i> ${text('字典数据')}(${dictData.dictType})
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnRefreshTree" title="${text('刷新')}"><i class="fa fa-refresh"></i> ${text('刷新')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnExpandTreeNode" title="${text('展开一级')}"><i class="fa fa-angle-double-down"></i> ${text('展开')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnCollapseTreeNode" title="${text('折叠全部')}"><i class="fa fa-angle-double-up"></i> ${text('折叠')}</a>
|
||||
<% if(hasPermi('sys:dictData:edit')){ %>
|
||||
<a href="${ctx}/sys/dictData/form?dictType=${dictData.dictType}" class="btn btn-default btnTool" title="${text('新增字典数据')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('字典标签')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="dictLabelRaw" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('字典键值')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="dictValue" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group hide">
|
||||
<label class="control-label">${text('字典类型')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="dictType" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('系统内置')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("字典标签")}', name:'dictLabelRaw', index:'a.dict_label', width:200, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
var icon = row.dictIcon, iconHtml = '';
|
||||
if (icon && icon != ''){
|
||||
if (icon.indexOf('://') != -1){
|
||||
iconHtml = '<img src="' + icon + '" width="20" height="20">';
|
||||
}else if (icon.indexOf('/') == 0){
|
||||
iconHtml = '<img src="' + ctxPath + icon + '" width="20" height="20">';
|
||||
}else{
|
||||
iconHtml = '<i class="fa fa-fw ' + icon + '"></i> ';
|
||||
}
|
||||
}
|
||||
return '<a href="${ctx}/sys/dictData/form?dictCode='+row.dictCode+'" class="btnList '+row.cssClass+'" data-title="${text("编辑字典数据")}" style="'
|
||||
+row.cssStyle+'"> '+iconHtml+' '+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("字典键值")}', name:'dictValue', index:'a.dict_value', width:200, align:"left"},
|
||||
{header:'${text("排序号")}', name:'treeSort', width:63, align:"center", fixed:true},
|
||||
{header:'${text("系统内置")}', name:'isSys', index:'a.is_sys', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_yes_no')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("CSS类名")}', name:'cssClass', index:'a.css_class', width:100, align:"left"},
|
||||
{header:'${text("CSS样式")}', name:'cssStyle', index:'a.css_style', width:100, align:"left"},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
|
||||
{header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:200, align:"left"},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:60, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:dictData:edit')){
|
||||
actions.push('<a href="${ctx}/sys/dictData/form?dictCode='+row.dictCode+'" class="btnList" title="${text("编辑字典数据")}"><i class="fa fa-pencil"></i></a> ');
|
||||
if (row.status == Global.STATUS_NORMAL){
|
||||
actions.push('<a href="${ctx}/sys/dictData/disable?dictCode='+row.dictCode+'" class="btnList" title="${text("停用字典数据")}" data-confirm="${text("确认要停用该字典数据吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
|
||||
} else if (row.status == Global.STATUS_DISABLE){
|
||||
actions.push('<a href="${ctx}/sys/dictData/enable?dictCode='+row.dictCode+'" class="btnList" title="${text("启用字典数据")}" data-confirm="${text("确认要启用该字典数据吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
|
||||
}
|
||||
actions.push('<a href="${ctx}/sys/dictData/delete?dictCode='+row.dictCode+'" class="btnList" title="${text("删除字典数据")}" data-confirm="${text("确认要删除该字典数据及所有子字典数据吗?")}" data-deltreenode="'+row.id+'"><i class="fa fa-trash-o"></i></a> ');
|
||||
actions.push('<a href="${ctx}/sys/dictData/form?parentCode='+row.id+'&dictType='+row.dictType+'" class="btnList" title="${text("新增下级字典数据")}"><i class="fa fa-plus-square"></i></a> ');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
treeGrid: true, // 启用树结构表格
|
||||
defaultExpandLevel: 0, // 默认展开的层次
|
||||
expandNodeClearPostData: 'dictLabelRaw,dictValue,dictType,', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据)
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,90 @@
|
||||
<% layout('/layouts/default.html', {title: '字典类型管理', libs: ['validate']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-social-dropbox"></i> ${text(dictType.isNewRecord ? '新增字典类型' : '编辑字典类型')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${dictType}" action="${ctx}/sys/dictType/save" method="post" class="form-horizontal">
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<#form:hidden path="id"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('字典名称')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="dictName" maxlength="100" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('字典类型')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="dictType" maxlength="100" class="form-control required abc"
|
||||
remote="${ctx}/sys/dictType/checkDictType?oldDictType=${dictType.dictType}"
|
||||
data-msg-remote="${text('字典类型已存在')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('系统字典')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('备注信息')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:dictType:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,95 @@
|
||||
<% layout('/layouts/default.html', {title: '字典管理', libs: ['dataGrid']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-social-dropbox"></i> ${text('字典管理')}
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<% if(hasPermi('sys:dictType:edit')){ %>
|
||||
<a href="${ctx}/sys/dictType/form" class="btn btn-default btnTool" title="${text('新增字典类型')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('字典名称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="dictName" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('字典类型')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="dictType_like" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('系统字典')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("字典名称")}', name:'dictName', index:'a.dict_name', width:200, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/dictType/form?id='+row.id+'" class="btnList" data-title="${text("编辑字典类型")}">'+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("字典类型")}', name:'dictType', index:'a.dict_type', width:200, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/dictData/list?dictType='+row.dictType+'" class="btnList" data-title="${text("字典数据")}">'+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("系统字典")}', name:'isSys', index:'a.is_sys', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_yes_no')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
|
||||
{header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:200, align:"left"},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:60, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:130, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:dictType:edit')){
|
||||
actions.push('<a href="${ctx}/sys/dictType/form?id='+row.id+'" class="btnList" title="${text("编辑字典类型")}"><i class="fa fa-pencil"></i></a> ');
|
||||
//# }
|
||||
actions.push('<a href="${ctx}/sys/dictData/list?dictType='+row.dictType+'" class="btnList" title="${text("字典数据")}"><i class="fa fa-navicon"></i></a> ');
|
||||
//# if(hasPermi('sys:dictType:edit')){
|
||||
if (row.status == Global.STATUS_NORMAL){
|
||||
actions.push('<a href="${ctx}/sys/dictType/disable?id='+row.id+'" class="btnList" title="${text("停用字典类型")}" data-confirm="${text("确认要停用该字典类型吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
|
||||
} else if (row.status == Global.STATUS_DISABLE){
|
||||
actions.push('<a href="${ctx}/sys/dictType/enable?id='+row.id+'" class="btnList" title="${text("启用字典类型")}" data-confirm="${text("确认要启用该字典类型吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
|
||||
}
|
||||
actions.push('<a href="${ctx}/sys/dictType/delete?id='+row.id+'" class="btnList" title="${text("删除字典类型")}" data-confirm="${text("确认要删除该字典类型吗?")}"><i class="fa fa-trash-o"></i></a> ');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
103
modules/core/src/main/resources/views/modules/sys/langForm.html
Normal file
103
modules/core/src/main/resources/views/modules/sys/langForm.html
Normal file
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header with-border">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-globe"></i> ${text(lang.isNewRecord ? '新增语言' : '编辑语言')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${lang}" action="${ctx}/sys/lang/save" method="post" class="form-horizontal">
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<#form:hidden path="id"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('语言编码')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<input name="oldLangCode" type="hidden" value="${lang.langCode}">
|
||||
<#form:input path="langCode" maxlength="500" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('语言译文')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="langText" maxlength="500" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('语言类型')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<input name="oldLangType" type="hidden" value="${lang.langType}">
|
||||
<#form:radio path="langType" dictType="sys_lang_type" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required">*</span> ${text('归属模块')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="module.moduleCode" items="${moduleList}" itemLabel="moduleName" itemValue="moduleCode" class="form-control required" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('备注信息')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:lang:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-globe"></i> ${text('国际化管理')}
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<% if(hasPermi('sys:lang:edit')){ %>
|
||||
<a href="${ctx}/sys/lang/form" class="btn btn-default btnTool" title="${text('新增语言')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnUpdateCache" title="${text('清理国际化缓存')}"><i class="fa fa-refresh"></i> ${text('清理缓存')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('语言编码')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="langCode_like" maxlength="500" class="form-control width-120"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('语言译文')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="langText" maxlength="500" class="form-control width-120"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('语言类型')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:select path="langType" dictType="sys_lang_type" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('归属模块')}:</label>
|
||||
<div class="control-inline width-120">
|
||||
<#form:select path="module.moduleCode" items="${moduleList}" itemLabel="moduleName"
|
||||
itemValue="moduleCode" class="form-control" blankOption="true"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("语言编码")}', name:'langCode', index:'a.lang_code', width:200, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/lang/form?id='+row.id+'" class="btnList" data-title="${text("编辑语言")}">'+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("语言译文")}', name:'langText', index:'a.lang_text', width:200, align:"left"},
|
||||
{header:'${text("语言类型")}', name:'langType', index:'a.lang_type', width:200, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_lang_type')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("归属模块")}', name:'module.moduleName', index:'a.module_code', width:200, align:"center"},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:200, align:"center"},
|
||||
{header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:200, align:"left"},
|
||||
{header:'${text("操作")}', name:'actions', width:130, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:lang:edit')){
|
||||
actions.push('<a href="${ctx}/sys/lang/form?id='+row.id+'" class="btnList" title="${text("编辑语言")}"><i class="fa fa-pencil"></i></a> ');
|
||||
actions.push('<a href="${ctx}/sys/lang/delete?id='+row.id+'" class="btnList" title="${text("删除语言")}" data-confirm="${text("确认要删除该语言吗?")}"><i class="fa fa-trash-o"></i></a> ');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
//更新国际化缓存,包含语言属性文件。
|
||||
$("#btnUpdateCache").click(function(){
|
||||
js.ajaxSubmit("${ctx}/sys/lang/clearCache", function(data){
|
||||
js.showMessage(data.message);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
284
modules/core/src/main/resources/views/modules/sys/menuForm.html
Normal file
284
modules/core/src/main/resources/views/modules/sys/menuForm.html
Normal file
@@ -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']}){ %>
|
||||
<link rel="stylesheet" href="${ctxStatic}/colorpicker/bootstrap-colorpicker.css"/>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-book-open"></i> ${text(menu.isNewRecord ? '新增菜单' : '编辑菜单')}(
|
||||
</div>
|
||||
<div class="box-title dropdown input-inline">
|
||||
<div class="dropdown-toggle" data-toggle="dropdown">
|
||||
<span id="sysCodeName">${@DictUtils.getDictLabel('sys_menu_sys_code', menu.sysCode, text('全部菜单'))}</span><b class="caret"></b>
|
||||
</div>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var dict in @DictUtils.getDictList('sys_menu_sys_code')){ %>
|
||||
<li><a href="javascript:" onclick="
|
||||
$('#sysCode').val('${dict.dictValue}');
|
||||
$('#sysCodeName').text('${dict.dictLabel}');
|
||||
$('#parentDiv').attr('data-url','${ctx}/sys/menu/treeData?excludeCode=${menu.menuCode,xss}&sysCode=${dict.dictValue}');
|
||||
$('#parentCode,#parentName').val('');
|
||||
"><i class="fa fa-angle-right"></i> ${dict.dictLabel}</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="box-title">)</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${menu}" action="${ctx}/sys/menu/save" method="post" class="form-horizontal">
|
||||
<#form:hidden path="sysCode" />
|
||||
<#form:hidden path="menuCode" />
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('上级菜单')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#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"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="标识当前是否是个菜单,还是只是设置权限">
|
||||
<span class="required">*</span> ${text('菜单类型')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="menuType" dictType="sys_menu_type" class="form-control required" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('菜单名称')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="menuNameRaw" maxlength="50" class="form-control required" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="指定菜单所属的模块,在开启和禁用模块的时候停用所属菜单">
|
||||
<span class="required">*</span> ${text('归属模块')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:select multiple="true" path="moduleCodes" items="${moduleList}" itemLabel="moduleName" itemValue="moduleCode" class="form-control required" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="
|
||||
链接地址路径,外部链接加 “http://” 开头
|
||||
1、如果以 /// 开头,则代表是站点根路径(结果:http://localhost/{href})
|
||||
2、如果以 // 开头,则代表是工程根路径(结果:http://localhost/{ctxPath}/{href})
|
||||
3、如果以 / 开头,则代表是管理根路径(结果:http://localhost/{ctxPath}/{adminPath}/{href})(默认)
|
||||
可带变量,变量格式 {变量名}
|
||||
1、{ssoToken} : 单点登录的token编码,url参数中的参数分隔符请使用“%26”进行转义,
|
||||
例如:{projectUrl}/sso/{ssoToken}?url=/sys/user/list?p1=v1%26p2=v2&relogin=true
|
||||
2、{userCode} : 当前用户编码
|
||||
3、{userName} : 当前用户名称
|
||||
4、{userType} : 当前用户类型
|
||||
5、{corpCode} : 当前用户编码
|
||||
6、{corpName} : 当前用户名称
|
||||
7、{menuCode} : 当前菜单编码
|
||||
8、{menuParentCode} : 当前菜单上级编码
|
||||
9、{menuParentCodes} : 当前菜单所有上级编码
|
||||
10、userCache 中的 Key 可作为变量名
|
||||
11、yml 或 sys_config 中的 Key 可作为变量名 ">
|
||||
${text('链接(Href)')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="menuHref" maxlength="2000" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="链接打开的目标,默认addTabPage方式(新窗口中打开如:_blank)">
|
||||
${text('目标(Target)')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="menuTarget" maxlength="10" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('排序(升序)')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="treeSort" maxlength="9" class="form-control required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 isPerm2">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="控制器中定义的权限标识,如:@RequiresPermissions('权限标识')">
|
||||
${text('权限标识')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="permission" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 isMenu">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="支持选择字体图标,也支持设置一个 img 地址,如:http://host/js/img/icon.jpg 或 /img/icon.jpg">
|
||||
${text('菜单图标')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:iconselect path="menuIcon" class=""/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6 isMenu">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('字体颜色')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group input-color" data-color-format="hex">
|
||||
<#form:input path="menuColor" maxlength="50" class="form-control"/>
|
||||
<span class="input-group-addon">
|
||||
<i style="background-color:${isNotBlank(menu.menuColor)?menu.menuColor:'#ddd'};"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row isMenu">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="主页面的页签选项卡显示的标题文字,若不指定,默认显示菜单名称">
|
||||
${text('页签标题')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="menuTitle" maxlength="50" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4">${text('可见')}:</label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isShow" dictType="sys_show_hide" class="form-control required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="菜单权重:默认20;>=40一般管理员;>=60系统管理员;>=80超级管理员">
|
||||
${text('菜单权重')}:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:select path="weight" dictType="sys_menu_weight" class="form-control required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-unit">${text('其它信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">${text('备注信息')}:</label>
|
||||
<div class="col-sm-10">
|
||||
<#form:textarea path="remarks" rows="3" maxlength="200" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if (menu.isNewRecord){ /*%>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="快速建立下级权限菜单,不填写,则忽略">
|
||||
快速建立权限:<i class="fa icon-question"></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:textarea name="quickCreatePermi" rows="2" maxlength="200" class="form-control"/>
|
||||
<span class="help-block">
|
||||
格式举例:[查看] sys:user:view; [编辑] sys:user:edit; [授权] sys:user:auth
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% */} %>
|
||||
<#form:extend collapsed="true" />
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:menu:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script src="${ctxStatic}/colorpicker/bootstrap-colorpicker.js"></script>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
if ($('#moduleCodes').val() == null){
|
||||
js.showMessage('请选择归属模块!');
|
||||
return;
|
||||
}
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
(contentWindow.win||contentWindow).$('#dataGrid').dataGrid('refreshTreeChildren',
|
||||
$('#parentCode').val(), '${menu.id}');
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
|
||||
// 颜色控件初始化
|
||||
$('#inputForm .input-color').colorpicker();
|
||||
|
||||
// 根据类型显示不同的元素
|
||||
$('#menuType input').on('ifCreated ifChecked', function(){
|
||||
if ($(this).is(':checked')){
|
||||
// 1:菜单;2:权限
|
||||
if ($(this).val() == '1'){
|
||||
$('.isPerm').hide();
|
||||
$('.isMenu').show();
|
||||
}else{
|
||||
$('.isMenu').hide();
|
||||
$('.isPerm').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 选择上级节点回调方法
|
||||
function treeselectCallback(id, act, index, layero){
|
||||
if (id == 'parent' && (act == 'ok' || act == 'clear')){
|
||||
// 创建并初始化下一个节点信息,如:排序号、默认值
|
||||
$.get('${ctx}/sys/menu/createNextNode?parentCode='
|
||||
+$('#parentCode').val(), function(data){
|
||||
$('#treeSort').val(data.treeSort);
|
||||
$('#menuType input[value="'+data.menuType+'"]').iCheck('check');
|
||||
if (data.moduleCodes){
|
||||
$('#moduleCodes input').iCheck('uncheck');
|
||||
$.each(data.moduleCodes.split(','), function(i, v){
|
||||
$('#moduleCodes input[value="'+v+'"]').iCheck('check');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,88 @@
|
||||
<% layout('/layouts/default.html', {title: '菜单管理', libs: ['layout','zTree']}){ %>
|
||||
<div class="ui-layout-west">
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<div class="dropdown-toggle pointer" data-hover="dropdown" data-toggle="dropdown">
|
||||
<span id="sysCode" data-code="${menu.sysCode}">${@DictUtils.getDictLabel('sys_menu_sys_code',
|
||||
menu.sysCode, text('全部菜单'))}</span><b class="caret"></b>
|
||||
</div>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var dict in @DictUtils.getDictList('sys_menu_sys_code')){ %>
|
||||
<li><a href="javascript:" onclick="$('#sysCode').data('code', '${dict.dictValue}').text('${dict.dictLabel}');loadTree();"> <i
|
||||
class="fa fa-angle-right"></i> ${dict.dictLabel}
|
||||
</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" id="btnExpand" title="${text('展开')}" style="display:none;"><i class="fa fa-chevron-up"></i></button>
|
||||
<button type="button" class="btn btn-box-tool" id="btnCollapse" title="${text('折叠')}"><i class="fa fa-chevron-down"></i></button>
|
||||
<button type="button" class="btn btn-box-tool" id="btnRefresh" title="${text('刷新')}"><i class="fa fa-refresh"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-content">
|
||||
<div id="tree" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-layout-center">
|
||||
<iframe id="mainFrame" name="mainFrame" class="ui-layout-content p0"
|
||||
src="${ctx}/sys/menu/list"></iframe>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化布局
|
||||
$('body').layout({
|
||||
west__initClosed: $(window).width() <= 767, // 是否默认关闭
|
||||
west__size: 200
|
||||
});
|
||||
//# // 主页框架
|
||||
var win = $("#mainFrame")[0].contentWindow;
|
||||
//# // 树结构初始化加载
|
||||
var setting = {view:{selectedMulti:false},data:{key:{title:"title"},simpleData:{enable:true}},
|
||||
async:{enable:true,autoParam:["id=parentCode"],url:"${ctx}/sys/menu/treeData"},
|
||||
callback:{onClick:function(event, treeId, treeNode){
|
||||
tree.expandNode(treeNode);
|
||||
//win.$('button[type=reset]').click();
|
||||
win.$('#menuCode').val(treeNode.id);
|
||||
win.$('#sysCode').val($('#sysCode').data('code'));
|
||||
win.$('#sysCodeLabel').text($('#sysCode').text());
|
||||
win.page();
|
||||
}}
|
||||
}, tree, loadTree = function(){
|
||||
js.ajaxSubmit(setting.async.url+"?___t="+new Date().getTime(), {
|
||||
sysCode:$('#sysCode').data('code'),
|
||||
parentCode:'${parameter.parentCode!}'}, function(data){
|
||||
tree = $.fn.zTree.init($("#tree"), setting, data);
|
||||
var level = -1, nodes;
|
||||
while (++level <= 1) {
|
||||
nodes = tree.getNodesByParam("level", level);
|
||||
if (nodes.length > 10) { break; }
|
||||
for(var i=0; i<nodes.length; i++) {
|
||||
tree.expandNode(nodes[i], true, false, false);
|
||||
}
|
||||
}
|
||||
}, null, null, js.text('loading.message'));
|
||||
};loadTree();
|
||||
//# // 工具栏按钮绑定
|
||||
$('#btnExpand').click(function(){
|
||||
tree.expandAll(true);
|
||||
$(this).hide();
|
||||
$('#btnCollapse').show();
|
||||
});
|
||||
$('#btnCollapse').click(function(){
|
||||
tree.expandAll(false);
|
||||
$(this).hide();
|
||||
$('#btnExpand').show();
|
||||
});
|
||||
$('#btnRefresh').click(function(){
|
||||
loadTree();
|
||||
});
|
||||
//# // 调用子页分页函数
|
||||
function page(){
|
||||
win.page();
|
||||
}
|
||||
</script>
|
||||
166
modules/core/src/main/resources/views/modules/sys/menuList.html
Normal file
166
modules/core/src/main/resources/views/modules/sys/menuList.html
Normal file
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-book-open"></i> ${text('菜单管理')}(
|
||||
</div>
|
||||
<div class="box-title dropdown input-inline">
|
||||
<div class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown">
|
||||
<span id="sysCodeLabel">${@DictUtils.getDictLabel('sys_menu_sys_code',
|
||||
menu.sysCode, text('全部菜单'))}</span><b class="caret"></b>
|
||||
</div>
|
||||
<ul class="dropdown-menu">
|
||||
<% for(var dict in @DictUtils.getDictList('sys_menu_sys_code')){ %>
|
||||
<li><a href="${ctx}/sys/menu/list?sysCode=${dict.dictValue}"> <i
|
||||
class="fa fa-angle-right"></i> ${dict.dictLabel}
|
||||
</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="box-title">)</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnRefreshTree" title="${text('刷新')}"><i class="fa fa-refresh"></i> ${text('刷新')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnExpandTreeNode" title="${text('展开一级')}"><i class="fa fa-angle-double-down"></i> ${text('展开')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnCollapseTreeNode" title="${text('折叠全部')}"><i class="fa fa-angle-double-up"></i> ${text('折叠')}</a>
|
||||
<% if(hasPermi('sys:menu:edit')){ %>
|
||||
<a href="#" class="btn btn-default" id="btnUpdateSort" title="${text('保存排序')}"><i class="fa fa-sort-amount-asc"></i> ${text('保存排序')}</a>
|
||||
<a href="${ctx}/sys/menu/form?sysCode=${menu.sysCode}" class="btn btn-default btnTool" title="${text('新增菜单')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<a href="${ctx}/sys/menu/fixTreeData" class="btn btn-default hide" title="${text('树结构关联数据修复')}" onclick="js.confirm('确认要执行树结构关联数据修复程序吗?', this.href, function(data){js.showMessage(data.message)});return false;"><i class="fa fa-wrench"></i> ${text('数据修复')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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" />
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('菜单名称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="menuNameRaw" maxlength="50" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('链接(Href)')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="menuHref" maxlength="50" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('权限标识')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="permission" maxlength="50" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<#form:form id="dataGridForm" action="${ctx}/sys/menu/updateTreeSort" method="post">
|
||||
<table id="dataGrid"></table>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("菜单名称")}', name:'menuNameRaw', width:200, formatter: function(val, obj, row, act){
|
||||
var icon = row.menuIcon, iconHtml = '';
|
||||
if (icon && icon != ''){
|
||||
if (icon.indexOf('://') != -1){
|
||||
iconHtml = '<img src="' + icon + '" width="20" height="20">';
|
||||
}else if (icon.indexOf('/') == 0){
|
||||
iconHtml = '<img src="' + ctxPath + icon + '" width="20" height="20">';
|
||||
}else{
|
||||
iconHtml = '<i class="fa fa-fw ' + icon + '"></i> ';
|
||||
}
|
||||
}
|
||||
return ' '+iconHtml+' <a href="${ctx}/sys/menu/form?menuCode='
|
||||
+row.id+'" class="btnList" style="color:'+row.color+'" data-title="${text("编辑菜单")}">'+val+'</a>';
|
||||
}},
|
||||
{header:'${text("归属模块")}', name:'moduleCodes', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
return '<a href="javascript:" title="按模块查询" onclick="$(\'#moduleCodes\').val($(this).text());$(\'#dataGrid\').dataGrid(\'refreshTree\',1);">'+val+'</a>';
|
||||
}},
|
||||
{header:'${text("链接")}', name:'menuHref', width:150},
|
||||
{header:'${text("排序")}', name:'treeSort', width:63, align:"center", formatter: function(val, obj, row, act){
|
||||
var html = [];
|
||||
//# if(hasPermi('sys:menu:edit')){
|
||||
html.push('<input type="hidden" name="ids" value="'+row.id+'"/>');
|
||||
html.push('<input name="sorts" type="text" value="'+row.treeSort+'" style="width:50px;height:19px;margin:0;padding:0;text-align:center;border:1px solid #ddd">');
|
||||
//# }else{
|
||||
html.push(row.treeSort);
|
||||
//# }
|
||||
return html.join('');
|
||||
}},
|
||||
{header:'${text("类型")}', name:'menuType', width:50, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_menu_type')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("可见")}', name:'isShow', width:50, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
if (row.component && row.component != 'BEETL' && row.component != 'IFRAME') {
|
||||
return '<font color="#aaa" title="为什么设置 “显示隐藏” 不能改变可见性,通常是 Vue 版本中设置了\n'
|
||||
+'组件名称(component字段),不是 BEELT 或 IFRAME 值,\n'
|
||||
+'所以在 Beetl 视图中不会显示该菜单项">${text("隐藏")}</font>';
|
||||
}
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_show_hide')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("权限标识")}', name:'permission', width:150},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '${text("未知")}', true);
|
||||
}},
|
||||
{header:'${text("菜单权重")}', name:'weight', width:100, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_menu_weight')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:120, sortable:false, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:menu:edit')){
|
||||
actions.push('<a href="${ctx}/sys/menu/form?menuCode='+row.id+'" class="btnList" title="${text("编辑菜单")}"><i class="fa fa-pencil"></i></a> ');
|
||||
if (row.status == Global.STATUS_NORMAL){
|
||||
actions.push('<a href="${ctx}/sys/menu/disable?menuCode='+row.id+'" class="btnList" title="${text("停用菜单")}" data-confirm="${text("确认要停用该菜单吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
|
||||
} else if (row.status == Global.STATUS_DISABLE){
|
||||
actions.push('<a href="${ctx}/sys/menu/enable?menuCode='+row.id+'" class="btnList" title="${text("启用菜单")}" data-confirm="${text("确认要启用该菜单吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
|
||||
}
|
||||
actions.push('<a href="${ctx}/sys/menu/delete?menuCode='+row.id+'" class="btnList" title="${text("删除菜单")}" data-confirm="${text("确认要删除该菜单及所有子菜单吗?")}" data-deltreenode="'+row.id+'"><i class="fa fa-trash-o"></i></a> ');
|
||||
actions.push('<a href="${ctx}/sys/menu/form?parentCode='+row.id+'&sysCode='+row.sysCode+'" class="btnList" title="${text("新增下级菜单")}"><i class="fa fa-plus-square"></i></a> ');
|
||||
//actions.push('<a href="#" title="只看本节点" onclick="$(\'#dataGrid\').dataGrid(\'refreshTree\', 1, \''+row.id+'\')"><i class="fa fa-arrow-circle-down"></i></a> ');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
treeGrid: true, // 启用树结构表格
|
||||
defaultExpandLevel: 0, // 默认展开的层次
|
||||
expandNodeClearPostData: 'menuNameRaw,menuHref,permission', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据)
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
if ($('#menuCode').val() != ''){
|
||||
$('#menuCode').val('');
|
||||
$('#btnExpandTreeNode').click();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 绑定更新排序按钮
|
||||
$('#btnUpdateSort').click(function(){
|
||||
js.ajaxSubmitForm($("#dataGridForm"), function(data){
|
||||
if(data.result == Global.TRUE){
|
||||
$('#btnRefreshTree').click();
|
||||
}
|
||||
js.showMessage(data.message);
|
||||
}, "json");
|
||||
});
|
||||
</script>
|
||||
@@ -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); %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-grid f14"></i> ${text(module.isNewRecord ? '新增模块' : '编辑模块')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${module}" action="${ctx}/sys/module/save" method="post" class="form-horizontal">
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('模块名称')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="moduleName" maxlength="100" class="form-control required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('模块编码')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:hidden path="isNewRecord"/>
|
||||
<#form:input path="moduleCode" maxlength="64" readonly="${!module.isNewRecord}" class="form-control abc2 required"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="该模块的状态验证类,如果该类检测不存在,则该模块状态提示 “未安装” ,验证原理:Class.forName(\"com.jeesite.modules.sys.web.LoginController\")">
|
||||
<span class="required hide">*</span> ${text('主类全名')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:input path="mainClassName" maxlength="500" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('模块描述')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:textarea path="description" rows="4" maxlength="500" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('当前版本')}:<i class="fa icon-question hide"></i></label>
|
||||
<% if(isNotBlank(module.upgradeInfo)){ %>
|
||||
<div class="col-sm-6 control-text">
|
||||
${module.currentVersion} ${module.upgradeInfo}
|
||||
</div>
|
||||
<% }else{ %>
|
||||
<div class="col-sm-4">
|
||||
<#form:input path="currentVersion" maxlength="50" class="form-control"/>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if (hasPermi('sys:module:edit') && isCustomModule){ %>
|
||||
<div class="form-unit">${text('生成工程代码')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="${text('填写磁盘绝对路径,若不填写,则生成到默认的模块目录下')}">
|
||||
<span class="required hide">*</span> ${text('生成基础路径')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-10">
|
||||
<div class="input-group input-group-sm">
|
||||
<#form:input name="genBaseDir" value="${genBaseDir}" maxlength="2000" class="form-control"/>
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
|
||||
${text('生成路径快速选择')} <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" role="menu" style="max-height:100px;max-width:700px;${genBaseDirList.~size>2?'overflow:scroll;':''}">
|
||||
<% for(var e in genBaseDirList){ %>
|
||||
<li><a href="javascript:$('#genBaseDir').val('${@StringUtils.replace(e,'\\','\\\\')}')">${e}</a></li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('代码生成模板')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-4">
|
||||
<#form:select path="tplCategory" items="${config.moduleTplCategoryList}" itemLabel="label" itemValue="value" blankOption="true" class="form-control "/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<#form:checkbox path="replaceFile" label="${text('是否替换现有文件')}" class="form-control" title="${text('如果生成文件已经存在,选中该选项原文件则被覆盖。')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:module:edit')){ %>
|
||||
<#form:hidden path="genFlag"/>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"
|
||||
onclick="$('#genFlag').val('1');"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<% if (hasPermi('sys:module:edit') && isCustomModule){ %>
|
||||
<button type="submit" class="btn btn-sm btn-danger" id="btnSubmitAndGen"
|
||||
onclick="$('#genFlag').val('2');"><i class="fa fa-bug"></i> ${text('保存并生成代码')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%/* 乐观锁,前台提交时间戳作为该表单的版本号,后台更新数据前只要调用baseValidator即可验证版本。
|
||||
<input type="hidden" name="lastUpdateDateTime" value="${module.updateDate.time!}" /> */%>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
jQuery.validator.addMethod("abc2",function(value, element) {
|
||||
return this.optional(element) || /^[a-zA-Z]([a-zA-Z0-9_\-])*[a-zA-Z0-9]$/.test(value);
|
||||
}, "${text('请输入2个以上字符,字母开头、允许字母数字下划线或减号、字母数字结尾')}");
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-grid f14"></i> ${text('模块管理')}
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<% if(hasPermi('sys:module:edit')){ %>
|
||||
<a href="${ctx}/sys/module/form" class="btn btn-default btnTool" title="${text('新增模块')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}">
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('模块名称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="moduleName" maxlength="100" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('主类全名')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="mainClassName" maxlength="500" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("模块名称")}', name:'moduleName', index:'a.module_name', width:200, align:"center", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/module/form?moduleCode='+row.moduleCode+'" class="btnList" data-title="${text("编辑模块")}">'+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("模块编码")}', name:'moduleCode', index:'a.module_code', width:200, align:"center"},
|
||||
{header:'${text("模块描述")}', name:'description', index:'a.description', width:300, align:"left"},
|
||||
{header:'${text("版本")}', name:'currentVersion', index:'a.current_version', width:100, align:"center"},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:60, sortable:false, fixed:true, align:"center", formatter: function(val, obj, row, act){
|
||||
return row.isLoader ? js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '<font color=red>${text("未知")}</font>', true) : '<font color=red>${text("未安装")}</font>';
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:module:edit')){
|
||||
actions.push('<a href="${ctx}/sys/module/form?moduleCode='+row.moduleCode+'" class="btnList" title="${text("编辑模块")}"><i class="fa fa-pencil"></i></a> ');
|
||||
if (row.status == Global.STATUS_NORMAL){
|
||||
actions.push('<a href="${ctx}/sys/module/disable?moduleCode='+row.moduleCode+'" class="btnList" title="${text("停用模块")}" data-confirm="${text("确认要停用该模块吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
|
||||
}else if (row.status == Global.STATUS_DISABLE){
|
||||
actions.push('<a href="${ctx}/sys/module/enable?moduleCode='+row.moduleCode+'" class="btnList" title="${text("启用模块")}" data-confirm="${text("确认要启用该模块吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
|
||||
}
|
||||
actions.push('<a href="${ctx}/sys/module/delete?moduleCode='+row.moduleCode+'" class="btnList" title="${text("删除模块")}" data-confirm="${text("确认要删除该模块吗?")}"><i class="fa fa-trash-o"></i></a> ');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
310
modules/core/src/main/resources/views/modules/sys/roleForm.html
Normal file
310
modules/core/src/main/resources/views/modules/sys/roleForm.html
Normal file
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-people"></i> ${text(role.isNewRecord ? '新增角色' : op == 'auth' ? '角色分配功能权限' : '编辑角色')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${role}" action="${ctx}/sys/role/save" method="post" class="form-horizontal">
|
||||
<#form:hidden name="op" value="${op}"/>
|
||||
<div class="box-body">
|
||||
<div class="form-unit">${text('基本信息')}</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('角色名称')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#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('角色名称已存在')}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if(!role.isNewRecord) { %>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('角色编码')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:hidden path="isNewRecord"/>
|
||||
<#form:hidden path="viewCode"/>
|
||||
<#form:input path="roleCode" maxlength="64" readonly="${!role.isNewRecord}" class="form-control required abc"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('角色代码')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:hidden path="isNewRecord"/>
|
||||
<#form:hidden path="roleCode"/>
|
||||
<#form:input path="viewCode" maxlength="64" readonly="${!role.isNewRecord}" class="form-control required abc"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<% if(op == 'add' || op == 'edit') {%>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('排序号')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="roleSort" maxlength="10" class="form-control required digits"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required hide">*</span> ${text('用户类型')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:select path="userType" dictType="sys_user_type" blankOption="true" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required hide">*</span> ${text('角色分类')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:select path="roleType" dictType="sys_role_type" blankOption="true" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="只有超管可以维护,多租户情况下系统角色为共享角色">
|
||||
<span class="required ">*</span> ${text('系统角色')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isSys" dictType="sys_yes_no" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="仪表盘地址,如果当前多个角色,则根据角色的排序优先级选择。">
|
||||
<span class="required hide">*</span> ${text('桌面地址')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:input path="desktopUrl" maxlength="250" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="切换身份列表中是否显示该角色">
|
||||
<span class="required ">*</span> ${text('是否可见')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:radio path="isShow" dictType="sys_show_hide" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(op == 'add' || op == 'auth') {%>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="${text('展示子系统列表的时候会根据此条件进行过滤,否则展示全部子系统')}">
|
||||
<span class="required hide">*</span> ${text('包含系统')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:select path="sysCodes" dictType="sys_menu_sys_code" multiple="true" class="form-control " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if(op == 'add' || op == 'edit') {%>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="">
|
||||
<span class="required hide">*</span> ${text('备注信息')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<#form:extend collapsed="true" />
|
||||
<% } %>
|
||||
<% if(op == 'add' || op == 'auth') {%>
|
||||
<div class="form-unit">${text('授权功能菜单')}</div>
|
||||
<div id="menuTrees"></div>
|
||||
<script id="menuTpl" type="text/template">
|
||||
<div id="menuDiv_{{d.key}}" class="pull-left" style="padding:0 15px;min-width:300px;">
|
||||
<div class="box box-solid box-trees">
|
||||
<div class="box-header">
|
||||
<div class="box-title icheck">
|
||||
<label><input type="checkbox" id="checkall_{{d.key}}"
|
||||
class="checkall"/> {{d.label}}</label>
|
||||
</div>
|
||||
<div class="box-tools pull-right" style="top:8px;">
|
||||
<a class="btn btn-box-tool" id="expand_{{d.key}}"
|
||||
value="menuTree_{{d.key}}" >${text('展开')}</a>/<a
|
||||
class="btn btn-box-tool" id="collapse_{{d.key}}"
|
||||
value="menuTree_{{d.key}}" >${text('折叠')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="menuTree_{{d.key}}" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<#form:hidden name="roleMenuListJson"/>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:role:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
//# if(op == 'add' || op == 'auth') {
|
||||
//# // 获取数据权限数据
|
||||
var menuData = [];
|
||||
$.each(menuTrees, function(key, menuTree){
|
||||
if ($('#'+menuTree.setting.treeId).is(':visible')) {
|
||||
var treeNodes = menuTree.getCheckedNodes(true);
|
||||
for(var i=0; i<treeNodes.length; i++) {
|
||||
menuData.push(treeNodes[i].id);
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#roleMenuListJson").val(JSON.stringify(menuData));
|
||||
//# }
|
||||
//# // 提交表单数据
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
//# if(op == 'add' || op == 'auth') {
|
||||
//# // 加载数据权限树结构
|
||||
var setting = {
|
||||
check:{enable:true,nocheckInherit:true,chkboxType:{"Y":"ps","N":"ps"}},
|
||||
view:{selectedMulti:false,nameIsHTML: true},
|
||||
data:{simpleData:{enable:true},key:{title:"title"}},
|
||||
callback:{
|
||||
beforeClick: function (treeId, treeNode, clickFlag) {
|
||||
var tree = $.fn.zTree.getZTreeObj(treeId);
|
||||
tree.checkNode(treeNode, !treeNode.checked, true, true);
|
||||
return false;
|
||||
},
|
||||
onCheck: function (event, treeId, treeNode){ }
|
||||
}
|
||||
},
|
||||
sysCodeDict = "#{@DictUtils.getDictListJson('sys_menu_sys_code')}",
|
||||
menuTrees = {};
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "${ctx}/sys/role/menuTreeData?___t=" + new Date().getTime(),
|
||||
data: {roleCode: '${role.roleCode}'},
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
error: function(data){
|
||||
js.showErrorMessage(data.responseText);
|
||||
},
|
||||
success: function(data, status, xhr){
|
||||
for (var sysCode in data.menuMap){
|
||||
var menuMap = data.menuMap[sysCode];
|
||||
$('#menuTrees').append(js.template('menuTpl', {key: sysCode,
|
||||
label: js.getDictLabel(sysCodeDict, sysCode, '未知', true)}));
|
||||
//# // 初始化树结构
|
||||
var tree = $.fn.zTree.init($("#menuTree_"+sysCode), setting, menuMap);
|
||||
var level = -1, nodes;
|
||||
while (++level <= 1) {
|
||||
nodes = tree.getNodesByParam("level", level);
|
||||
if (nodes.length > 10) { break; }
|
||||
for(var i=0; i<nodes.length; i++) {
|
||||
tree.expandNode(nodes[i], true, false, false);
|
||||
}
|
||||
}
|
||||
//# // 树结构:全选、取消全选
|
||||
$('#checkall_'+sysCode).iCheck({
|
||||
checkboxClass:'icheckbox_minimal-grey'
|
||||
}).on('ifChecked ifUnchecked', function(){
|
||||
var sysCode = $(this).attr('sysCode');
|
||||
if(this.checked){
|
||||
menuTrees[sysCode].checkAllNodes(true);
|
||||
}else{
|
||||
menuTrees[sysCode].checkAllNodes(false);
|
||||
}
|
||||
}).attr("sysCode", sysCode);
|
||||
//# // 展开和折叠按钮绑定
|
||||
$('#expand_'+sysCode).click(function(){
|
||||
var sysCode = $(this).attr('sysCode');
|
||||
menuTrees[sysCode].expandAll(true);
|
||||
}).attr("sysCode", sysCode);
|
||||
$('#collapse_'+sysCode).click(function(){
|
||||
var sysCode = $(this).attr('sysCode');
|
||||
menuTrees[sysCode].expandAll(false);
|
||||
}).attr("sysCode", sysCode);
|
||||
//# // 将树对象存储到全局数组里
|
||||
menuTrees[sysCode] = tree;
|
||||
//# // 如果没有数据,则隐藏选择框
|
||||
if (data.length === 0) {
|
||||
$("#menuDiv_"+sysCode).hide();
|
||||
}
|
||||
}
|
||||
//# // 默认选择节点
|
||||
for (var idx in data.roleMenuList || []){
|
||||
var roleMenu = data.roleMenuList[idx], sysCode = roleMenu.sysCode;
|
||||
if (menuTrees[sysCode]) {
|
||||
var node = menuTrees[sysCode].getNodeByParam("id", roleMenu.menuCode);
|
||||
try{menuTrees[sysCode].checkNode(node, true, false);}catch(e){}
|
||||
}
|
||||
}
|
||||
$('#sysCodes').on('change', function(){
|
||||
var sysCodes = $(this).val();
|
||||
if (sysCodes.length === 0) {
|
||||
$('#menuTrees > div').show();
|
||||
return;
|
||||
}
|
||||
$.each(sysCodeDict, function(idx, val){
|
||||
var code = val['dictValue'], isShow = false;
|
||||
for (var i in sysCodes) {
|
||||
if (sysCodes[i] === code) {
|
||||
isShow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$('#menuDiv_' + code).toggle(isShow);
|
||||
});
|
||||
}).change();
|
||||
}
|
||||
});
|
||||
//# }
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-people"></i> ${text('角色分配数据权限')}
|
||||
</div>
|
||||
<div class="box-tools pull-right hide">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<#form:form id="inputForm" model="${role}" action="${ctx}/sys/role/saveAuthDataScope" method="post" class="form-horizontal">
|
||||
<div class="box-body"><br/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('角色名称')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:hidden name="oldRoleName" value="${role.roleName}"/>
|
||||
<#form:input path="roleName" maxlength="100" readonly="true" class="form-control required "/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-4" title="">
|
||||
<span class="required ">*</span> ${text('角色编码')}:<i class="fa icon-question hide"></i></label>
|
||||
<div class="col-sm-8">
|
||||
<#form:hidden path="isNewRecord"/>
|
||||
<#form:hidden path="roleCode"/>
|
||||
<#form:input path="viewCode" maxlength="64" readonly="true" class="form-control required abc"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="${text('指定数据权限范围类型,多个角色同时指定,之间为或者关系')}">
|
||||
<span class="required ">*</span> ${text('数据范围')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:radio path="dataScope" dictType="sys_role_data_scope" class="form-control required " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2" title="${text('在 addFilter 权限过滤的时候指定适应的业务范围,不指定代表所有生效,如:有的功能看本部门,有的功能看本公司;新的业务范围从字典 sys_role_biz_scope 类型添加。')}">
|
||||
<span class="required hide">*</span> ${text('控制业务范围')}:<i class="fa icon-question "></i></label>
|
||||
<div class="col-sm-10">
|
||||
<#form:select path="bizScope" dictType="sys_role_biz_scope" class="form-control " multiple="true"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-unit">${text('授权数据权限')}</div>
|
||||
<div id="dataScopeTrees"></div>
|
||||
<script id="dataScopeTpl" type="text/template">
|
||||
<div id="dataScope_{{d.key}}" class="pull-left" style="padding:0 15px;min-width:300px;">
|
||||
<div class="box box-solid box-trees">
|
||||
<div class="box-header">
|
||||
<div class="box-title icheck">
|
||||
<label><input type="checkbox" id="checkall_{{d.key}}"
|
||||
class="checkall"/> {{d.label}}</label>
|
||||
</div>
|
||||
<div class="box-tools pull-right" style="top:8px;">
|
||||
<a class="btn btn-box-tool" id="expand_{{d.key}}"
|
||||
value="dataScopeTree_{{d.key}}" >${text('展开')}</a>/<a
|
||||
class="btn btn-box-tool" id="collapse_{{d.key}}"
|
||||
value="dataScopeTree_{{d.key}}" >${text('折叠')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="dataScopeTree_{{d.key}}" class="ztree"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<#form:hidden name="roleDataScopeListJson"/>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if (hasPermi('sys:role:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#form:form>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
$('#dataScope input').on('ifCreated ifChecked', function(){
|
||||
if ($(this).is(':checked')){
|
||||
if ($(this).val() == '2'){ // 2 自定义数据
|
||||
$('#dataScopeTrees').show().prev().show();
|
||||
}else{
|
||||
$('#dataScopeTrees').hide().prev().hide();
|
||||
}
|
||||
}
|
||||
}).change();
|
||||
$('#inputForm').validate({
|
||||
submitHandler: function(form){
|
||||
//# // 获取数据权限数据
|
||||
var dataScopeData = [];
|
||||
$.each(dataScopeTrees, function(key, dataScopeTree){
|
||||
var treeNodes = dataScopeTree.getCheckedNodes(true);
|
||||
for(var i=0; i<treeNodes.length; i++) {
|
||||
dataScopeData.push({
|
||||
ctrlType: key, ctrlData: treeNodes[i].id
|
||||
});
|
||||
}
|
||||
});
|
||||
$("#roleDataScopeListJson").val(JSON.stringify(dataScopeData));
|
||||
//# // 提交表单数据
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
js.showMessage(data.message);
|
||||
if(data.result == Global.TRUE){
|
||||
js.closeCurrentTabPage(function(contentWindow){
|
||||
contentWindow.page();
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
//# // 加载数据权限树结构
|
||||
var setting = {
|
||||
check:{enable:true,nocheckInherit:true},
|
||||
view:{selectedMulti:false,nameIsHTML: true},
|
||||
data:{simpleData:{enable:true},key:{title:"title"}},
|
||||
callback:{
|
||||
beforeClick: function (treeId, treeNode, clickFlag) {
|
||||
var tree = $.fn.zTree.getZTreeObj(treeId);
|
||||
tree.checkNode(treeNode, !treeNode.checked, true, true);
|
||||
return false;
|
||||
},
|
||||
onCheck: function (event, treeId, treeNode){
|
||||
$('#dataScope3').parent().click(); // 选中“自定义权限”单选按钮
|
||||
}
|
||||
}
|
||||
},
|
||||
moduleCodes = '"#{toJson(moduleCodes)}"';
|
||||
dataScopes = "#{toJson(dataScopes)}",
|
||||
dataScopeTrees = {};
|
||||
for (var i=0; i<dataScopes.length; i++){
|
||||
var dataScope = dataScopes[i];
|
||||
//# // 验证模块是否开启,如果未开启,则跳过
|
||||
if (moduleCodes.indexOf("\""+dataScope.moduleCode+"\"") == -1){
|
||||
continue;
|
||||
}
|
||||
//# // 控制权限 ctrlPermi: 0全部 1拥有权限 2管理权限
|
||||
if (!(dataScope.ctrlPermi == '0'
|
||||
|| dataScope.ctrlPermi == '1')){
|
||||
continue;
|
||||
}
|
||||
$('#dataScopeTrees').append(js.template('dataScopeTpl', {
|
||||
key: dataScope.ctrlType, label: dataScope["${'ctrlName_'+lang()}"] || dataScope.ctrlName}));
|
||||
var ctrlDataUrl = dataScope.ctrlDataUrl || '';
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: "${ctx}" + ctrlDataUrl + (ctrlDataUrl.indexOf("?")!=-1?'&':'?') + "___t=" + new Date().getTime(),
|
||||
data: {ctrlPermi: '2'},
|
||||
dataType: 'json',
|
||||
async: false,
|
||||
error: function(data){
|
||||
js.showErrorMessage(data.responseText);
|
||||
},
|
||||
success: function(data, status, xhr){
|
||||
//# // 初始化树结构
|
||||
var tree = $.fn.zTree.init($("#dataScopeTree_"+dataScope.ctrlType), setting, data);
|
||||
tree.setting.check.chkboxType = dataScope.chkboxType;
|
||||
//# // 默认展开节点(如果级别设置为-1,则:如果有1个根节点,则展开一级节点,否则不展开)
|
||||
$.fn.zTree.expandNodeByLevel(tree, dataScope.expandLevel);
|
||||
//# // 树结构:全选、取消全选
|
||||
$('#checkall_'+dataScope.ctrlType).iCheck({
|
||||
checkboxClass:'icheckbox_minimal-grey'
|
||||
}).on('ifChecked ifUnchecked', function(){
|
||||
var ctrlType = $(this).attr('ctrlType');
|
||||
if(this.checked){
|
||||
dataScopeTrees[ctrlType].checkAllNodes(true);
|
||||
}else{
|
||||
dataScopeTrees[ctrlType].checkAllNodes(false);
|
||||
}
|
||||
}).attr("ctrlType", dataScope.ctrlType);
|
||||
//# // 展开和折叠按钮绑定
|
||||
$('#expand_'+dataScope.ctrlType).click(function(){
|
||||
var ctrlType = $(this).attr('ctrlType');
|
||||
dataScopeTrees[ctrlType].expandAll(true);
|
||||
}).attr("ctrlType", dataScope.ctrlType);
|
||||
$('#collapse_'+dataScope.ctrlType).click(function(){
|
||||
var ctrlType = $(this).attr('ctrlType');
|
||||
dataScopeTrees[ctrlType].expandAll(false);
|
||||
}).attr("ctrlType", dataScope.ctrlType);
|
||||
//# // 将树对象存储到全局数组里
|
||||
dataScopeTrees[dataScope.ctrlType] = tree;
|
||||
//# // 如果没有数据,则隐藏选择框
|
||||
if (data.length == 0) {
|
||||
$("#dataScope_"+dataScope.ctrlType).hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
//# // 默认选择节点
|
||||
//# for(dataScope in roleDataScopeList){
|
||||
try{dataScopeTrees['${dataScope.ctrlType}'].checkNode(dataScopeTrees['${dataScope.ctrlType}']
|
||||
.getNodeByParam("id","${dataScope.ctrlData}"), true, false);}catch(e){}
|
||||
//# }
|
||||
</script>
|
||||
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header" style="display:block;">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-people"></i> ${text('角色分配用户')}(${role.roleName}-${role.viewCode}-${@DictUtils.getDictLabel('sys_user_type',role.userType,'未设置')})
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnAddUser" title="${text('添加用户')}"><i class="fa fa-plus"></i> ${text('添加用户')}</a>
|
||||
<a href="#" class="btn btn-default" id="btnDelUser" title="${text('删除用户')}"><i class="fa fa-remove"></i> ${text('批量取消')}</a>
|
||||
<a href="javascript:" class="btn btn-default" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}"/>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('账号')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input name="loginCode" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('昵称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input name="userName" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('邮箱')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input name="email" maxlength="300" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('手机')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input name="mobile" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('电话')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input name="phone" maxlength="100" class="form-control width-90"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:select path="status" dictType="sys_user_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hide"><#form:listselect id="userSelect" title="${text('用户选择')}"
|
||||
url="${ctx}/sys/user/userSelect?userType=${role.userType}" allowClear="false"
|
||||
checkbox="true" itemCode="userCode" itemName="userName"/></div>
|
||||
<% } %>
|
||||
<script>
|
||||
//初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("登录账号")}', name:'loginCode', index:'a.login_code', width:200, align:"center"},
|
||||
{header:'${text("用户昵称")}', name:'userName', index:'a.user_name', width:200, align:"center"},
|
||||
{header:'${text("电子邮箱")}', name:'email', index:'a.email', width:200, align:"center"},
|
||||
{header:'${text("手机号码")}', name:'mobile', index:'a.mobile', width:200, align:"center"},
|
||||
{header:'${text("办公电话")}', name:'phone', index:'a.phone', width:200, align:"center"},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:200, align:"center"},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:100, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
actions.push('<a href="${ctx}/sys/role/deleteAuthUser?roleCode=${role.roleCode}&userRoleString='+row.userCode+'" class="btnList" title="${text("取消授权")}" data-confirm="${text("确认要取消该用户角色吗?")}"><i class="fa fa-remove"></i></a> ');
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
showCheckbox: true,
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
$('#btnDelUser').click(function(){
|
||||
var userCodes = $('#dataGrid').dataGrid('getSelectRows');
|
||||
if (userCodes != null && userCodes.length > 0){
|
||||
js.confirm('${text("确认要取消选中的用户角色权限吗?")}', function(){
|
||||
js.ajaxSubmit('${ctx}/sys/role/deleteAuthUser', {
|
||||
roleCode: '${role.roleCode}',
|
||||
userRoleString: userCodes.join(',')
|
||||
}, function(data){
|
||||
js.showMessage(data.message);
|
||||
page();
|
||||
});
|
||||
});
|
||||
}else{
|
||||
js.showMessage('${text("请在列表选中要取消角色的用户")}');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#btnAddUser').click(function(){
|
||||
if ('${role.userType}' == 'employee'){
|
||||
$('#userSelectDiv').attr('data-url', '${ctx}/sys/empUser/empUserSelect');
|
||||
}else{
|
||||
$('#userSelectDiv').attr('data-url', '${ctx}/sys/user/userSelect?userType=${role.userType}');
|
||||
}
|
||||
$('#userSelectCode').val('');
|
||||
$('#userSelectName').val('').click();
|
||||
});
|
||||
function listselectCallback(id, action, index, layero){
|
||||
if (id == 'userSelect' && action == 'ok'){
|
||||
if ($('#userSelectCode').val() != ''){
|
||||
js.ajaxSubmit('${ctx}/sys/role/saveAuthUser', {
|
||||
roleCode: '${role.roleCode}',
|
||||
userRoleString: $('#userSelectCode').val()
|
||||
}, function(data){
|
||||
js.showMessage(data.message);
|
||||
page();
|
||||
});
|
||||
}else{
|
||||
js.showMessage('${text("没有选择要授权的用户")}');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
124
modules/core/src/main/resources/views/modules/sys/roleList.html
Normal file
124
modules/core/src/main/resources/views/modules/sys/roleList.html
Normal file
@@ -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']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-header">
|
||||
<div class="box-title">
|
||||
<i class="fa icon-people"></i> ${text('角色管理')}
|
||||
</div>
|
||||
<div class="box-tools pull-right">
|
||||
<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
|
||||
<% if(hasPermi('sys:role:edit')){ %>
|
||||
<a href="${ctx}/sys/role/form?op=add" class="btn btn-default btnTool" title="${text('新增角色')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
|
||||
<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<#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}"/>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('角色名称')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="roleName_like" maxlength="100" class="form-control width-120"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('角色编码')}:</label>
|
||||
<div class="control-inline">
|
||||
<#form:input path="roleCode_like" maxlength="100" class="form-control width-120"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('用户类型')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:select path="userType" dictType="sys_user_type" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('系统角色')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="isSys" dictType="sys_yes_no" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="form-group">
|
||||
<label class="control-label">${text('角色分类')}:</label>
|
||||
<div class="control-inline width-90">
|
||||
<#form:select path="roleType" dictType="sys_role_type" blankOption="true" class="form-control"/>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="form-group">
|
||||
<label class="control-label">${text('状态')}:</label>
|
||||
<div class="control-inline width-60">
|
||||
<#form:select path="status" dictType="sys_search_status" blankOption="true" class="form-control isQuick"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
|
||||
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
|
||||
</div>
|
||||
</#form:form>
|
||||
<table id="dataGrid"></table>
|
||||
<div id="dataGridPage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
<script>
|
||||
//# // 初始化DataGrid对象
|
||||
$('#dataGrid').dataGrid({
|
||||
searchForm: $('#searchForm'),
|
||||
columnModel: [
|
||||
{header:'${text("角色名称")}', name:'roleName', index:'a.role_name', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '<a href="${ctx}/sys/role/form?roleCode='+row.roleCode+'&op=edit" class="btnList" data-title="${text("编辑角色")}">'+(val||row.id)+'</a>';
|
||||
}},
|
||||
{header:'${text("角色编码")}', name:'roleCode', index:'a.role_code', width:150, align:"center"},
|
||||
{header:'${text("排序号")}', name:'roleSort', index:'a.role_sort', width:80, align:"center"},
|
||||
// {header:'${text("角色分类")}', name:'roleType', index:'a.role_type', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
// return js.getDictLabel("#{@DictUtils.getDictListJson('sys_role_type')}", val, '未知', true);
|
||||
// }},
|
||||
{header:'${text("用户类型")}', name:'userType', index:'a.user_type', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_user_type')}", val, '<font color=#aaa>${text("未设置")}</font>', true);
|
||||
}},
|
||||
{header:'${text("系统角色")}', name:'isSys', index:'a.is_sys', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_yes_no')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("数据范围")}', name:'dataScope', index:'a.data_scope', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_role_data_scope')}", val, '${text("未设置")}', true);
|
||||
}},
|
||||
{header:'${text("业务范围")}', name:'bizScope', index:'a.biz_scope', width:100, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_role_biz_scope')}", val, '${text("未设置")}', true);
|
||||
}},
|
||||
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:130, align:"center"},
|
||||
{header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:160, align:"left"},
|
||||
{header:'${text("状态")}', name:'status', index:'a.status', width:80, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_status')}", val, '未知', true);
|
||||
}},
|
||||
{header:'${text("操作")}', name:'actions', width:130, formatter: function(val, obj, row, act){
|
||||
var actions = [];
|
||||
//# if(hasPermi('sys:role:edit')){
|
||||
actions.push('<a href="${ctx}/sys/role/form?roleCode='+row.roleCode+'&op=edit" class="btnList" title="${text("编辑角色")}"><i class="fa fa-pencil"></i></a> ');
|
||||
if (row.status == Global.STATUS_NORMAL){
|
||||
actions.push('<a href="${ctx}/sys/role/disable?roleCode='+row.roleCode+'" class="btnList" title="${text("停用角色")}" data-confirm="${text("确认要停用该角色吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a> ');
|
||||
}else if (row.status == Global.STATUS_DISABLE){
|
||||
actions.push('<a href="${ctx}/sys/role/enable?roleCode='+row.roleCode+'" class="btnList" title="${text("启用角色")}" data-confirm="${text("确认要启用该角色吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a> ');
|
||||
}
|
||||
actions.push('<a href="${ctx}/sys/role/delete?roleCode='+row.roleCode+'" class="btnList" title="${text("删除角色")}" data-confirm="${text("确认要删除该角色吗?")}"><i class="fa fa-trash-o"></i></a> ');
|
||||
actions.push('<a href="javascript:" class="btnMore" title="${text("更多操作")}"><i class="fa fa-chevron-circle-right"></i></a> ');
|
||||
actions.push('<div class="moreItems">');
|
||||
actions.push('<a href="${ctx}/sys/role/form?roleCode='+row.id+'&op=auth" class="btn btn-default btn-xs btnList" title="${text("角色分配功能权限")}"><i class="fa fa-check-square-o"></i> ${text("授权菜单")}</a> ');
|
||||
actions.push('<a href="${ctx}/sys/role/formAuthDataScope?roleCode='+row.id+'" class="btn btn-default btn-xs btnList" title="${text("角色分配数据权限")}"><i class="fa fa-check-circle-o"></i> ${text("数据权限")}</a> ');
|
||||
actions.push('<a href="${ctx}/sys/role/formAuthUser?roleCode='+row.id+'" class="btn btn-default btn-xs btnList" title="${text("角色分配用户")}"><i class="fa fa-user"></i> ${text("分配用户")}</a> ');
|
||||
actions.push('</div>');
|
||||
//# }
|
||||
return actions.join('');
|
||||
}}
|
||||
],
|
||||
//# // 加载成功后执行事件
|
||||
ajaxSuccess: function(data){
|
||||
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user