diff --git a/pom.xml b/pom.xml index bc3e45cf..91ac13ce 100644 --- a/pom.xml +++ b/pom.xml @@ -18,13 +18,13 @@ UTF-8 1.8 3.1.1 - 1.2.6 + 1.2.8 1.21 3.0.0 - 2.3.2 - 2.1.4 - 1.3.1 - 1.2.76 + 2.3.2 + 2.2.0 + 1.4.0 + 1.2.78 5.8.0 5.8.0 2.11.0 @@ -43,7 +43,7 @@ org.springframework.boot spring-boot-dependencies - 2.2.13.RELEASE + 2.5.5 pom import diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java index e88a2ad6..f1552e03 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysRegisterController.java @@ -1,13 +1,13 @@ package com.ruoyi.web.controller.system; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.model.RegisterBody; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.SysRegisterService; import com.ruoyi.system.service.ISysConfigService; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java index 4588a7a5..f1afe51c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/TestController.java @@ -47,7 +47,7 @@ public class TestController extends BaseController } @ApiOperation("获取用户详细") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) @GetMapping("/{userId}") public AjaxResult getUser(@PathVariable Integer userId) { @@ -63,10 +63,10 @@ public class TestController extends BaseController @ApiOperation("新增用户") @ApiImplicitParams({ - @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer"), - @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String"), - @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String"), - @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String") + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) }) @PostMapping("/save") public AjaxResult save(UserEntity user) @@ -95,7 +95,7 @@ public class TestController extends BaseController } @ApiOperation("删除用户信息") - @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) @DeleteMapping("/{userId}") public AjaxResult delete(@PathVariable Integer userId) { diff --git a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml index c7c36e37..4b8c4962 100644 --- a/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml +++ b/ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml @@ -3,13 +3,18 @@ PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> - - - - - - - + + + + + + + + + + + + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java index 50482c57..9fb64da1 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java @@ -5,6 +5,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.math.BigDecimal; +import com.ruoyi.common.utils.poi.ExcelHandlerAdapter; /** * 自定义导出Excel数据注解 @@ -108,7 +109,17 @@ public @interface Excel /** * 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右) */ - Align align() default Align.AUTO; + public Align align() default Align.AUTO; + + /** + * 自定义数据处理器 + */ + public Class handler() default ExcelHandlerAdapter.class; + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; public enum Align { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java index 3458c882..4b1f1307 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/Log.java @@ -38,4 +38,9 @@ public @interface Log * 是否保存请求的参数 */ public boolean isSaveRequestData() default true; + + /** + * 是否保存响应的参数 + */ + public boolean isSaveResponseData() default true; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java index 628eef1e..40830052 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RepeatSubmit.java @@ -19,5 +19,13 @@ import java.lang.annotation.Target; @Documented public @interface RepeatSubmit { + /** + * 间隔时间(ms),小于此时间视为重复提交 + */ + public int interval() default 5000; + /** + * 提示消息 + */ + public String message() default "不允许重复提交,请稍后再试"; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java index 7b1d8966..993ca226 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java @@ -4,7 +4,7 @@ import java.util.Collection; import java.util.Set; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -import com.fasterxml.jackson.annotation.JsonIgnore; +import com.alibaba.fastjson.annotation.JSONField; import com.ruoyi.common.core.domain.entity.SysUser; /** @@ -119,7 +119,7 @@ public class LoginUser implements UserDetails this.permissions = permissions; } - @JsonIgnore + @JSONField(serialize = false) @Override public String getPassword() { @@ -135,7 +135,7 @@ public class LoginUser implements UserDetails /** * 账户是否未过期,过期无法验证 */ - @JsonIgnore + @JSONField(serialize = false) @Override public boolean isAccountNonExpired() { @@ -147,7 +147,7 @@ public class LoginUser implements UserDetails * * @return */ - @JsonIgnore + @JSONField(serialize = false) @Override public boolean isAccountNonLocked() { @@ -159,7 +159,7 @@ public class LoginUser implements UserDetails * * @return */ - @JsonIgnore + @JSONField(serialize = false) @Override public boolean isCredentialsNonExpired() { @@ -171,7 +171,7 @@ public class LoginUser implements UserDetails * * @return */ - @JsonIgnore + @JSONField(serialize = false) @Override public boolean isEnabled() { diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java index 04ae9b1d..8d8f5a6a 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java @@ -211,6 +211,7 @@ public class FileUtils .append(percentEncodedFileName); response.setHeader("Content-disposition", contentDispositionValue.toString()); + response.setHeader("download-filename", percentEncodedFileName); } /** diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java index 3de26bb4..415acbab 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/html/HTMLFilter.java @@ -387,7 +387,7 @@ public final class HTMLFilter { paramValue = processParamProtocol(paramValue); } - params.append(' ').append(paramName).append("=\"").append(paramValue).append("\""); + params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\""); } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java index 20037432..c920f5b1 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -19,6 +19,7 @@ import javax.net.ssl.X509TrustManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.utils.StringUtils; /** * 通用http发送方法 @@ -55,7 +56,7 @@ public class HttpUtils BufferedReader in = null; try { - String urlNameString = url + "?" + param; + String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; log.info("sendGet - {}", urlNameString); URL realUrl = new URL(urlNameString); URLConnection connection = realUrl.openConnection(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java new file mode 100644 index 00000000..c9ca2d5e --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java @@ -0,0 +1,19 @@ +package com.ruoyi.common.utils.poi; + +/** + * Excel数据格式处理适配器 + * + * @author ruoyi + */ +public interface ExcelHandlerAdapter +{ + /** + * 格式化 + * + * @param value 单元格数据值 + * @param args excel注解args参数组 + * + * @return 处理后的值 + */ + Object format(Object value, String[] args); +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 54157f35..4169360a 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.ArrayList; @@ -46,6 +47,7 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.util.IOUtils; import org.apache.poi.xssf.streaming.SXSSFWorkbook; @@ -124,6 +126,16 @@ public class ExcelUtil */ private List fields; + /** + * 当前行号 + */ + private int rownum; + + /** + * 标题 + */ + private String title; + /** * 最大高度 */ @@ -149,7 +161,7 @@ public class ExcelUtil this.clazz = clazz; } - public void init(List list, String sheetName, Type type) + public void init(List list, String sheetName, String title, Type type) { if (list == null) { @@ -158,8 +170,27 @@ public class ExcelUtil this.list = list; this.sheetName = sheetName; this.type = type; + this.title = title; createExcelField(); createWorkbook(); + createTitle(); + } + + /** + * 创建excel第一行标题 + */ + public void createTitle() + { + if (StringUtils.isNotEmpty(title)) + { + Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); + titleRow.setHeightInPoints(30); + Cell titleCell = titleRow.createCell(0); + titleCell.setCellStyle(styles.get("title")); + titleCell.setCellValue(title); + sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), + this.fields.size() - 1)); + } } /** @@ -170,17 +201,30 @@ public class ExcelUtil */ public List importExcel(InputStream is) throws Exception { - return importExcel(StringUtils.EMPTY, is); + return importExcel(is, 0); + } + + /** + * 对excel表单默认第一个索引名转换成list + * + * @param is 输入流 + * @param titleNum 标题占用行数 + * @return 转换后集合 + */ + public List importExcel(InputStream is, int titleNum) throws Exception + { + return importExcel(StringUtils.EMPTY, is, titleNum); } /** * 对excel表单指定表格索引名转换成list * * @param sheetName 表格索引名 + * @param titleNum 标题占用行数 * @param is 输入流 * @return 转换后集合 */ - public List importExcel(String sheetName, InputStream is) throws Exception + public List importExcel(String sheetName, InputStream is, int titleNum) throws Exception { this.type = Type.IMPORT; this.wb = WorkbookFactory.create(is); @@ -209,7 +253,7 @@ public class ExcelUtil // 定义一个map用于存放excel列的序号和field. Map cellMap = new HashMap(); // 获取表头 - Row heard = sheet.getRow(0); + Row heard = sheet.getRow(titleNum); for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) { Cell cell = heard.getCell(i); @@ -224,25 +268,18 @@ public class ExcelUtil } } // 有数据时才处理 得到类的所有field. - Field[] allFields = clazz.getDeclaredFields(); - // 定义一个map用于存放列的序号和field. - Map fieldsMap = new HashMap(); - for (int col = 0; col < allFields.length; col++) + List fields = this.getFields(); + Map fieldsMap = new HashMap(); + for (Object[] objects : fields) { - Field field = allFields[col]; - Excel attr = field.getAnnotation(Excel.class); - if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + Excel attr = (Excel) objects[1]; + Integer column = cellMap.get(attr.name()); + if (column != null) { - // 设置类的私有字段属性可访问. - field.setAccessible(true); - Integer column = cellMap.get(attr.name()); - if (column != null) - { - fieldsMap.put(column, field); - } + fieldsMap.put(column, objects); } } - for (int i = 1; i <= rows; i++) + for (int i = titleNum + 1; i <= rows; i++) { // 从第2行开始取数据,默认第一行是表头. Row row = sheet.getRow(i); @@ -252,14 +289,15 @@ public class ExcelUtil continue; } T entity = null; - for (Map.Entry entry : fieldsMap.entrySet()) + for (Map.Entry entry : fieldsMap.entrySet()) { Object val = this.getCellValue(row, entry.getKey()); // 如果不存在实例则新建. entity = (entity == null ? clazz.newInstance() : entity); // 从map中得到对应列的field. - Field field = fieldsMap.get(entry.getKey()); + Field field = (Field) entry.getValue()[0]; + Excel attr = (Excel) entry.getValue()[1]; // 取得类型,并根据对象类型设置值. Class fieldType = field.getType(); if (String.class == fieldType) @@ -319,7 +357,6 @@ public class ExcelUtil } if (StringUtils.isNotNull(fieldType)) { - Excel attr = field.getAnnotation(Excel.class); String propertyName = field.getName(); if (StringUtils.isNotEmpty(attr.targetAttr())) { @@ -333,6 +370,10 @@ public class ExcelUtil { val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + val = dataFormatHandlerAdapter(val, attr); + } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) { PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey()); @@ -340,8 +381,11 @@ public class ExcelUtil { val = ""; } - byte[] data = image.getData(); - val = FileUtils.writeImportBytes(data); + else + { + byte[] data = image.getData(); + val = FileUtils.writeImportBytes(data); + } } ReflectUtils.invokeSetter(entity, propertyName, val); } @@ -361,7 +405,20 @@ public class ExcelUtil */ public AjaxResult exportExcel(List list, String sheetName) { - this.init(list, sheetName, Type.EXPORT); + return exportExcel(list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult exportExcel(List list, String sheetName, String title) + { + this.init(list, sheetName, title, Type.EXPORT); return exportExcel(); } @@ -374,11 +431,26 @@ public class ExcelUtil * @return 结果 * @throws IOException */ - public void exportExcel(HttpServletResponse response, List list, String sheetName) throws IOException + public void exportExcel(HttpServletResponse response, List list, String sheetName)throws IOException + { + exportExcel(response, list, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param response 返回数据 + * @param list 导出数据集合 + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + * @throws IOException + */ + public void exportExcel(HttpServletResponse response, List list, String sheetName, String title) throws IOException { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); - this.init(list, sheetName, Type.EXPORT); + this.init(list, sheetName, title, Type.EXPORT); exportExcel(response.getOutputStream()); } @@ -390,7 +462,19 @@ public class ExcelUtil */ public AjaxResult importTemplateExcel(String sheetName) { - this.init(null, sheetName, Type.IMPORT); + return importTemplateExcel(sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public AjaxResult importTemplateExcel(String sheetName, String title) + { + this.init(null, sheetName, title, Type.IMPORT); return exportExcel(); } @@ -401,10 +485,22 @@ public class ExcelUtil * @return 结果 */ public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException + { + importTemplateExcel(response, sheetName, StringUtils.EMPTY); + } + + /** + * 对list数据源将其里面的数据导入到excel表单 + * + * @param sheetName 工作表的名称 + * @param title 标题 + * @return 结果 + */ + public void importTemplateExcel(HttpServletResponse response, String sheetName, String title) throws IOException { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); - this.init(null, sheetName, Type.IMPORT); + this.init(null, sheetName, title, Type.IMPORT); exportExcel(response.getOutputStream()); } @@ -465,13 +561,13 @@ public class ExcelUtil public void writeSheet() { // 取出一共有多少个sheet. - double sheetNo = Math.ceil(list.size() / sheetSize); - for (int index = 0; index <= sheetNo; index++) + int sheetNo = Math.max(1, (int) Math.ceil(list.size() * 1.0 / sheetSize)); + for (int index = 0; index < sheetNo; index++) { createSheet(sheetNo, index); // 产生一行 - Row row = sheet.createRow(0); + Row row = sheet.createRow(rownum); int column = 0; // 写入各个字段的列头名称 for (Object[] os : fields) @@ -499,7 +595,7 @@ public class ExcelUtil int endNo = Math.min(startNo + sheetSize, list.size()); for (int i = startNo; i < endNo; i++) { - row = sheet.createRow(i + 1 - startNo); + row = sheet.createRow(i + 1 + rownum - startNo); // 得到导出对象. T vo = (T) list.get(i); int column = 0; @@ -507,8 +603,6 @@ public class ExcelUtil { Field field = (Field) os[0]; Excel excel = (Excel) os[1]; - // 设置实体类私有属性可访问 - field.setAccessible(true); this.addCell(excel, row, vo, field, column++); } } @@ -527,6 +621,16 @@ public class ExcelUtil CellStyle style = wb.createCellStyle(); style.setAlignment(HorizontalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER); + Font titleFont = wb.createFont(); + titleFont.setFontName("Arial"); + titleFont.setFontHeightInPoints((short) 16); + titleFont.setBold(true); + style.setFont(titleFont); + styles.put("title", style); + + style = wb.createCellStyle(); + style.setAlignment(HorizontalAlignment.CENTER); + style.setVerticalAlignment(VerticalAlignment.CENTER); style.setBorderRight(BorderStyle.THIN); style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); style.setBorderLeft(BorderStyle.THIN); @@ -726,6 +830,10 @@ public class ExcelUtil { cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).toString()); } + else if (!attr.handler().equals(ExcelHandlerAdapter.class)) + { + cell.setCellValue(dataFormatHandlerAdapter(value, attr)); + } else { // 设置列类型 @@ -898,6 +1006,28 @@ public class ExcelUtil return DictUtils.getDictValue(dictType, dictLabel, separator); } + /** + * 数据处理器 + * + * @param value 数据值 + * @param excel 数据注解 + * @return + */ + public String dataFormatHandlerAdapter(Object value, Excel excel) + { + try + { + Object instance = excel.handler().newInstance(); + Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); + value = formatMethod.invoke(instance, value, excel.args()); + } + catch (Exception e) + { + log.error("不能格式化数据 " + excel.handler(), e.getMessage()); + } + return Convert.toStr(value); + } + /** * 合计统计信息 */ @@ -1025,7 +1155,17 @@ public class ExcelUtil */ private void createExcelField() { - this.fields = new ArrayList(); + this.fields = getFields(); + this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); + this.maxHeight = getRowHeight(); + } + + /** + * 获取字段注解信息 + */ + public List getFields() + { + List fields = new ArrayList(); List tempFields = new ArrayList<>(); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); @@ -1034,7 +1174,12 @@ public class ExcelUtil // 单注解 if (field.isAnnotationPresent(Excel.class)) { - putToField(field, field.getAnnotation(Excel.class)); + Excel attr = field.getAnnotation(Excel.class); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } } // 多注解 @@ -1042,14 +1187,17 @@ public class ExcelUtil { Excels attrs = field.getAnnotation(Excels.class); Excel[] excels = attrs.value(); - for (Excel excel : excels) + for (Excel attr : excels) { - putToField(field, excel); + if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) + { + field.setAccessible(true); + fields.add(new Object[] { field, attr }); + } } } } - this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); - this.maxHeight = getRowHeight(); + return fields; } /** @@ -1066,23 +1214,15 @@ public class ExcelUtil return (short) (maxHeight * 20); } - /** - * 放到字段集合中 - */ - private void putToField(Field field, Excel attr) - { - if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) - { - this.fields.add(new Object[] { field, attr }); - } - } - /** * 创建一个工作簿 */ public void createWorkbook() { this.wb = new SXSSFWorkbook(500); + this.sheet = wb.createSheet(); + wb.setSheetName(0, sheetName); + this.styles = createStyles(wb); } /** @@ -1091,17 +1231,13 @@ public class ExcelUtil * @param sheetNo sheet数量 * @param index 序号 */ - public void createSheet(double sheetNo, int index) + public void createSheet(int sheetNo, int index) { - this.sheet = wb.createSheet(); - this.styles = createStyles(wb); // 设置工作表的名称. - if (sheetNo == 0) - { - wb.setSheetName(index, sheetName); - } - else + if (sheetNo > 1 && index > 0) { + this.sheet = wb.createSheet(); + this.createTitle(); wb.setSheetName(index, sheetName + index); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java index e4340d01..1074e05a 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java @@ -1,12 +1,8 @@ package com.ruoyi.framework.aspectj; -import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.core.domain.BaseEntity; @@ -55,27 +51,15 @@ public class DataScopeAspect */ public static final String DATA_SCOPE = "dataScope"; - // 配置织入点 - @Pointcut("@annotation(com.ruoyi.common.annotation.DataScope)") - public void dataScopePointCut() - { - } - - @Before("dataScopePointCut()") - public void doBefore(JoinPoint point) throws Throwable + @Before("@annotation(controllerDataScope)") + public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable { clearDataScope(point); - handleDataScope(point); + handleDataScope(point, controllerDataScope); } - protected void handleDataScope(final JoinPoint joinPoint) + protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) { - // 获得注解 - DataScope controllerDataScope = getAnnotationLog(joinPoint); - if (controllerDataScope == null) - { - return; - } // 获取当前的用户 LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNotNull(loginUser)) @@ -150,22 +134,6 @@ public class DataScopeAspect } } - /** - * 是否存在注解,如果存在就获取 - */ - private DataScope getAnnotationLog(JoinPoint joinPoint) - { - Signature signature = joinPoint.getSignature(); - MethodSignature methodSignature = (MethodSignature) signature; - Method method = methodSignature.getMethod(); - - if (method != null) - { - return method.getAnnotation(DataScope.class); - } - return null; - } - /** * 拼接权限sql前先清空params.dataScope参数防止注入 */ diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java index b7cf17bb..a2aaf222 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/LogAspect.java @@ -1,18 +1,13 @@ package com.ruoyi.framework.aspectj; -import java.lang.reflect.Method; import java.util.Collection; -import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -43,21 +38,15 @@ public class LogAspect { private static final Logger log = LoggerFactory.getLogger(LogAspect.class); - // 配置织入点 - @Pointcut("@annotation(com.ruoyi.common.annotation.Log)") - public void logPointCut() - { - } - /** * 处理完请求后执行 * * @param joinPoint 切点 */ - @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") - public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) + @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") + public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { - handleLog(joinPoint, null, jsonResult); + handleLog(joinPoint, controllerLog, null, jsonResult); } /** @@ -66,22 +55,16 @@ public class LogAspect * @param joinPoint 切点 * @param e 异常 */ - @AfterThrowing(value = "logPointCut()", throwing = "e") - public void doAfterThrowing(JoinPoint joinPoint, Exception e) + @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") + public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) { - handleLog(joinPoint, e, null); + handleLog(joinPoint, controllerLog, e, null); } - protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) + protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { try { - // 获得注解 - Log controllerLog = getAnnotationLog(joinPoint); - if (controllerLog == null) - { - return; - } // 获取当前的用户 LoginUser loginUser = SecurityUtils.getLoginUser(); @@ -92,9 +75,6 @@ public class LogAspect // 请求的地址 String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); operLog.setOperIp(ip); - // 返回参数 - operLog.setJsonResult(JSON.toJSONString(jsonResult)); - operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); if (loginUser != null) { @@ -113,7 +93,7 @@ public class LogAspect // 设置请求方式 operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); // 处理设置注解上的参数 - getControllerMethodDescription(joinPoint, controllerLog, operLog); + getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); // 保存数据库 AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); } @@ -133,7 +113,7 @@ public class LogAspect * @param operLog 操作日志 * @throws Exception */ - public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception + public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog, Object jsonResult) throws Exception { // 设置action动作 operLog.setBusinessType(log.businessType().ordinal()); @@ -147,6 +127,11 @@ public class LogAspect // 获取参数的信息,传入到数据库中。 setRequestValue(joinPoint, operLog); } + // 是否需要保存response,参数和值 + if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) + { + operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); + } } /** @@ -170,22 +155,6 @@ public class LogAspect } } - /** - * 是否存在注解,如果存在就获取 - */ - private Log getAnnotationLog(JoinPoint joinPoint) throws Exception - { - Signature signature = joinPoint.getSignature(); - MethodSignature methodSignature = (MethodSignature) signature; - Method method = methodSignature.getMethod(); - - if (method != null) - { - return method.getAnnotation(Log.class); - } - return null; - } - /** * 参数拼装 */ @@ -194,12 +163,18 @@ public class LogAspect String params = ""; if (paramsArray != null && paramsArray.length > 0) { - for (int i = 0; i < paramsArray.length; i++) + for (Object o : paramsArray) { - if (StringUtils.isNotNull(paramsArray[i]) && !isFilterObject(paramsArray[i])) + if (StringUtils.isNotNull(o) && !isFilterObject(o)) { - Object jsonObj = JSON.toJSON(paramsArray[i]); - params += jsonObj.toString() + " "; + try + { + Object jsonObj = JSON.toJSON(o); + params += jsonObj.toString() + " "; + } + catch (Exception e) + { + } } } } @@ -223,17 +198,17 @@ public class LogAspect else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) o; - for (Iterator iter = collection.iterator(); iter.hasNext();) + for (Object value : collection) { - return iter.next() instanceof MultipartFile; + return value instanceof MultipartFile; } } else if (Map.class.isAssignableFrom(clazz)) { Map map = (Map) o; - for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) + for (Object value : map.entrySet()) { - Map.Entry entry = (Map.Entry) iter.next(); + Map.Entry entry = (Map.Entry) value; return entry.getValue() instanceof MultipartFile; } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java index fd456b0d..5020d000 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java @@ -4,10 +4,8 @@ import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,16 +47,9 @@ public class RateLimiterAspect this.limitScript = limitScript; } - // 配置织入点 - @Pointcut("@annotation(com.ruoyi.common.annotation.RateLimiter)") - public void rateLimiterPointCut() + @Before("@annotation(rateLimiter)") + public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable { - } - - @Before("rateLimiterPointCut()") - public void doBefore(JoinPoint point) throws Throwable - { - RateLimiter rateLimiter = getAnnotationRateLimiter(point); String key = rateLimiter.key(); int time = rateLimiter.time(); int count = rateLimiter.count(); @@ -84,33 +75,17 @@ public class RateLimiterAspect } } - /** - * 是否存在注解,如果存在就获取 - */ - private RateLimiter getAnnotationRateLimiter(JoinPoint joinPoint) - { - Signature signature = joinPoint.getSignature(); - MethodSignature methodSignature = (MethodSignature) signature; - Method method = methodSignature.getMethod(); - - if (method != null) - { - return method.getAnnotation(RateLimiter.class); - } - return null; - } - public String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { StringBuffer stringBuffer = new StringBuffer(rateLimiter.key()); if (rateLimiter.limitType() == LimitType.IP) { - stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())); + stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest())).append("-"); } MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); Class targetClass = method.getDeclaringClass(); - stringBuffer.append("-").append(targetClass.getName()).append("- ").append(method.getName()); + stringBuffer.append(targetClass.getName()).append("-").append(method.getName()); return stringBuffer.toString(); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java index 322d6e34..fe1822f7 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java @@ -68,12 +68,12 @@ public class RedisConfig extends CachingConfigurerSupport "local time = tonumber(ARGV[2])\n" + "local current = redis.call('get', key);\n" + "if current and tonumber(current) > count then\n" + - " return current;\n" + + " return tonumber(current);\n" + "end\n" + "current = redis.call('incr', key)\n" + "if tonumber(current) == 1 then\n" + " redis.call('expire', key, time)\n" + "end\n" + - "return current;"; + "return tonumber(current);"; } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java index 9cd523e7..24ef0dec 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java @@ -28,10 +28,12 @@ public class ResourcesConfig implements WebMvcConfigurer public void addResourceHandlers(ResourceHandlerRegistry registry) { /** 本地文件上传路径 */ - registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); + registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**") + .addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); /** swagger配置 */ - registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); } /** @@ -49,17 +51,20 @@ public class ResourcesConfig implements WebMvcConfigurer @Bean public CorsFilter corsFilter() { - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 设置访问源地址 - config.addAllowedOrigin("*"); + config.addAllowedOriginPattern("*"); // 设置访问源请求头 config.addAllowedHeader("*"); // 设置访问源请求方法 config.addAllowedMethod("*"); - // 对接口配置跨域设置 + // 有效期 1800秒 + config.setMaxAge(1800L); + // 添加映射路径,拦截一切请求 + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); + // 返回新的CorsFilter return new CorsFilter(source); } } \ No newline at end of file diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index bd362290..58dd02ad 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -107,8 +107,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter "/**/*.js", "/profile/**" ).permitAll() - .antMatchers("/common/download**").anonymous() - .antMatchers("/common/download/resource**").anonymous() .antMatchers("/swagger-ui.html").anonymous() .antMatchers("/swagger-resources/**").anonymous() .antMatchers("/webjars/**").anonymous() diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java index d310382f..509e2873 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/RepeatSubmitInterceptor.java @@ -5,7 +5,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import org.springframework.web.servlet.HandlerInterceptor; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.domain.AjaxResult; @@ -17,7 +17,7 @@ import com.ruoyi.common.utils.ServletUtils; * @author ruoyi */ @Component -public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter +public abstract class RepeatSubmitInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception @@ -29,9 +29,9 @@ public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class); if (annotation != null) { - if (this.isRepeatSubmit(request)) + if (this.isRepeatSubmit(request, annotation)) { - AjaxResult ajaxResult = AjaxResult.error("不允许重复提交,请稍后再试"); + AjaxResult ajaxResult = AjaxResult.error(annotation.message()); ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult)); return false; } @@ -40,7 +40,7 @@ public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter } else { - return super.preHandle(request, response, handler); + return true; } } @@ -51,5 +51,5 @@ public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter * @return * @throws Exception */ - public abstract boolean isRepeatSubmit(HttpServletRequest request); + public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation); } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java index 3e82309e..33c9c876 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSONObject; +import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.filter.RepeatedlyRequestWrapper; @@ -35,21 +36,9 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor @Autowired private RedisCache redisCache; - /** - * 间隔时间,单位:秒 默认10秒 - * - * 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据 - */ - private int intervalTime = 10; - - public void setIntervalTime(int intervalTime) - { - this.intervalTime = intervalTime; - } - @SuppressWarnings("unchecked") @Override - public boolean isRepeatSubmit(HttpServletRequest request) + public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) { String nowParams = ""; if (request instanceof RepeatedlyRequestWrapper) @@ -87,7 +76,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor if (sessionMap.containsKey(url)) { Map preDataMap = (Map) sessionMap.get(url); - if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap)) + if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) { return true; } @@ -95,7 +84,7 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor } Map cacheMap = new HashMap(); cacheMap.put(url, nowDataMap); - redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS); + redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); return false; } @@ -112,11 +101,11 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor /** * 判断两次间隔时间 */ - private boolean compareTime(Map nowMap, Map preMap) + private boolean compareTime(Map nowMap, Map preMap, int interval) { long time1 = (Long) nowMap.get(REPEAT_TIME); long time2 = (Long) preMap.get(REPEAT_TIME); - if ((time1 - time2) < (this.intervalTime * 1000)) + if ((time1 - time2) < interval) { return true; } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 07bb03cf..2b547432 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -87,7 +87,7 @@ public class SysLoginService } AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); LoginUser loginUser = (LoginUser) authentication.getPrincipal(); - recordLoginInfo(loginUser.getUser()); + recordLoginInfo(loginUser.getUserId()); // 生成token return tokenService.createToken(loginUser); } @@ -119,11 +119,15 @@ public class SysLoginService /** * 记录登录信息 + * + * @param userId 用户ID */ - public void recordLoginInfo(SysUser user) + public void recordLoginInfo(Long userId) { - user.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest())); - user.setLoginDate(DateUtils.getNowDate()); - userService.updateUserProfile(user); + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest())); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserProfile(sysUser); } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java index c7fbdc94..35a425c7 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysRegisterService.java @@ -2,7 +2,6 @@ package com.ruoyi.framework.web.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.core.domain.entity.SysUser; @@ -12,6 +11,7 @@ import com.ruoyi.common.exception.user.CaptchaException; import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.system.service.ISysConfigService; diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java index 6481057c..2683ec8f 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java @@ -58,6 +58,7 @@ public class VelocityUtils velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); velocityContext.put("columns", genTable.getColumns()); velocityContext.put("table", genTable); + velocityContext.put("dicts", getDicts(genTable)); setMenuVelocityContext(velocityContext, genTable); if (GenConstants.TPL_TREE.equals(tplCategory)) { @@ -260,6 +261,27 @@ public class VelocityUtils return importList; } + /** + * 根据列类型获取字典组 + * + * @param genTable 业务表对象 + * @return 返回字典组 + */ + public static String getDicts(GenTable genTable) + { + List columns = genTable.getColumns(); + List dicts = new ArrayList(); + for (GenTableColumn column : columns) + { + if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( + column.getHtmlType(), new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO })) + { + dicts.add("'" + column.getDictType() + "'"); + } + } + return StringUtils.join(dicts, ", "); + } + /** * 获取权限前缀 * diff --git a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm index 42d015db..7e7d7c26 100644 --- a/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm @@ -69,7 +69,7 @@ public interface ${ClassName}Mapper * @param ${pkColumn.javaField}s 需要删除的数据主键集合 * @return 结果 */ - public int delete${subClassName}By${pkColumn.capJavaField}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); + public int delete${subClassName}By${subTableFkClassName}s(${pkColumn.javaType}[] ${pkColumn.javaField}s); /** * 批量新增${subTable.functionName} diff --git a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index 51c447ee..19802cee 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -25,10 +25,10 @@ @@ -108,7 +108,7 @@ #elseif($column.list && "" != $column.dictType) #elseif($column.list && "" != $javaField) @@ -184,10 +184,10 @@ @@ -202,10 +202,10 @@ - {{dict.dictLabel}} + v-for="dict in dict.type.${dictType}" + :key="dict.value" + :label="dict.value"> + {{dict.label}} @@ -219,11 +219,11 @@ {{dict.dictLabel}} + >{{dict.label}} #elseif($column.htmlType == "radio" && $dictType) @@ -265,6 +265,9 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css"; export default { name: "${BusinessName}", +#if(${dicts} != '') + dicts: [${dicts}], +#end components: { Treeselect }, @@ -283,16 +286,7 @@ export default { // 是否显示弹出层 open: false, #foreach ($column in $columns) -#set($parentheseIndex=$column.columnComment.indexOf("(")) -#if($parentheseIndex != -1) -#set($comment=$column.columnComment.substring(0, $parentheseIndex)) -#else -#set($comment=$column.columnComment) -#end -#if(${column.dictType} != '') - // $comment字典 - ${column.javaField}Options: [], -#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") +#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) // $comment时间范围 daterange${AttrName}: [], @@ -330,13 +324,6 @@ export default { }, created() { this.getList(); -#foreach ($column in $columns) -#if(${column.dictType} != '') - this.getDicts("${column.dictType}").then(response => { - this.${column.javaField}Options = response.data; - }); -#end -#end }, methods: { /** 查询${functionName}列表 */ @@ -461,13 +448,13 @@ export default { #end if (this.form.${pkColumn.javaField} != null) { update${BusinessName}(this.form).then(response => { - this.msgSuccess("修改成功"); + this.#[[$modal]]#.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { add${BusinessName}(this.form).then(response => { - this.msgSuccess("新增成功"); + this.#[[$modal]]#.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -477,16 +464,12 @@ export default { }, /** 删除按钮操作 */ handleDelete(row) { - this.$confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return del${BusinessName}(row.${pkColumn.javaField}); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?').then(function() { + return del${BusinessName}(row.${pkColumn.javaField}); + }).then(() => { + this.getList(); + this.#[[$modal]]#.msgSuccess("删除成功"); + }).catch(() => {}); } } }; diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 00865594..867225ab 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -25,10 +25,10 @@ @@ -137,7 +137,7 @@ #elseif($column.list && "" != $column.dictType) #elseif($column.list && "" != $javaField) @@ -206,10 +206,10 @@ @@ -224,10 +224,10 @@ - {{dict.dictLabel}} + v-for="dict in dict.type.${dictType}" + :key="dict.value" + :label="dict.value"> + {{dict.label}} @@ -241,11 +241,11 @@ {{dict.dictLabel}} + >{{dict.label}} #elseif($column.htmlType == "radio" && $dictType) @@ -317,6 +317,9 @@ import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${Busin export default { name: "${BusinessName}", +#if(${dicts} != '') + dicts: [${dicts}], +#end data() { return { // 遮罩层 @@ -348,16 +351,7 @@ export default { // 是否显示弹出层 open: false, #foreach ($column in $columns) -#set($parentheseIndex=$column.columnComment.indexOf("(")) -#if($parentheseIndex != -1) -#set($comment=$column.columnComment.substring(0, $parentheseIndex)) -#else -#set($comment=$column.columnComment) -#end -#if(${column.dictType} != '') - // $comment字典 - ${column.javaField}Options: [], -#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") +#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) // $comment时间范围 daterange${AttrName}: [], @@ -397,13 +391,6 @@ export default { }, created() { this.getList(); -#foreach ($column in $columns) -#if(${column.dictType} != '') - this.getDicts("${column.dictType}").then(response => { - this.${column.javaField}Options = response.data; - }); -#end -#end }, methods: { /** 查询${functionName}列表 */ @@ -516,13 +503,13 @@ export default { #end if (this.form.${pkColumn.javaField} != null) { update${BusinessName}(this.form).then(response => { - this.msgSuccess("修改成功"); + this.#[[$modal]]#.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { add${BusinessName}(this.form).then(response => { - this.msgSuccess("新增成功"); + this.#[[$modal]]#.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -533,16 +520,12 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const ${pkColumn.javaField}s = row.${pkColumn.javaField} || this.ids; - this.$confirm('是否确认删除${functionName}编号为"' + ${pkColumn.javaField}s + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return del${BusinessName}(${pkColumn.javaField}s); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + ${pkColumn.javaField}s + '"的数据项?').then(function() { + return del${BusinessName}(${pkColumn.javaField}s); + }).then(() => { + this.getList(); + this.#[[$modal]]#.msgSuccess("删除成功"); + }).catch(() => {}); }, #if($table.sub) /** ${subTable.functionName}序号 */ @@ -563,7 +546,7 @@ export default { /** ${subTable.functionName}删除按钮操作 */ handleDelete${subClassName}() { if (this.checked${subClassName}.length == 0) { - this.msgError("请先选择要删除的${subTable.functionName}数据"); + this.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据"); } else { const ${subclassName}List = this.${subclassName}List; const checked${subClassName} = this.checked${subClassName}; @@ -580,17 +563,13 @@ export default { /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有${functionName}数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return export${BusinessName}(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.#[[$modal]]#.confirm('是否确认导出所有${functionName}数据项?').then(() => { + this.exportLoading = true; + return export${BusinessName}(queryParams); + }).then(response => { + this.#[[$download]]#.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java index f450caa4..af97f149 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java @@ -169,6 +169,7 @@ public class SysMenuServiceImpl implements ISysMenuService children.setComponent(menu.getComponent()); children.setName(StringUtils.capitalize(menu.getPath())); children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + children.setQuery(menu.getQuery()); childrenList.add(children); router.setChildren(childrenList); } diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 9048f5a4..034e0642 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -41,8 +41,8 @@ "clipboard": "2.0.6", "core-js": "3.8.1", "echarts": "4.9.0", - "element-ui": "2.15.5", - "file-saver": "2.0.4", + "element-ui": "2.15.6", + "file-saver": "2.0.5", "fuse.js": "6.4.3", "highlight.js": "9.18.5", "js-beautify": "1.13.0", @@ -71,8 +71,8 @@ "eslint-plugin-vue": "7.2.0", "lint-staged": "10.5.3", "runjs": "4.4.2", - "sass": "1.32.0", - "sass-loader": "10.1.0", + "sass": "1.32.13", + "sass-loader": "10.1.1", "script-ext-html-webpack-plugin": "2.1.5", "svg-sprite-loader": "5.1.1", "vue-template-compiler": "2.6.12" diff --git a/ruoyi-ui/src/components/DictData/index.js b/ruoyi-ui/src/components/DictData/index.js new file mode 100644 index 00000000..24e3e9c8 --- /dev/null +++ b/ruoyi-ui/src/components/DictData/index.js @@ -0,0 +1,21 @@ +import Vue from 'vue' +import DataDict from '@/utils/dict' +import { getDicts as getDicts } from '@/api/system/dict/data' + +function install() { + Vue.use(DataDict, { + metas: { + '*': { + labelField: 'dictLabel', + valueField: 'dictValue', + request(dictMeta) { + return getDicts(dictMeta.type).then(res => res.data) + }, + }, + }, + }) +} + +export default { + install, +} \ No newline at end of file diff --git a/ruoyi-ui/src/components/DictTag/index.vue b/ruoyi-ui/src/components/DictTag/index.vue index 542c6edd..4c196c48 100644 --- a/ruoyi-ui/src/components/DictTag/index.vue +++ b/ruoyi-ui/src/components/DictTag/index.vue @@ -1,51 +1,52 @@ - - - - \ No newline at end of file diff --git a/ruoyi-ui/src/layout/components/Settings/index.vue b/ruoyi-ui/src/layout/components/Settings/index.vue index 0a6becac..4dff1d0c 100644 --- a/ruoyi-ui/src/layout/components/Settings/index.vue +++ b/ruoyi-ui/src/layout/components/Settings/index.vue @@ -162,14 +162,8 @@ export default { this.sideTheme = val; }, saveSetting() { - const loading = this.$loading({ - lock: true, - fullscreen: false, - text: "正在保存到本地,请稍后...", - spinner: "el-icon-loading", - background: "rgba(0, 0, 0, 0.7)" - }); - localStorage.setItem( + this.$modal.loading("正在保存到本地,请稍后..."); + this.$cache.local.set( "layout-setting", `{ "topNav":${this.topNav}, @@ -181,17 +175,11 @@ export default { "theme":"${this.theme}" }` ); - setTimeout(loading.close(), 1000) + setTimeout(this.$modal.closeLoading(), 1000) }, resetSetting() { - this.$loading({ - lock: true, - fullscreen: false, - text: "正在清除设置缓存并刷新,请稍后...", - spinner: "el-icon-loading", - background: "rgba(0, 0, 0, 0.7)" - }); - localStorage.removeItem("layout-setting") + this.$modal.loading("正在清除设置缓存并刷新,请稍后..."); + this.$cache.local.remove("layout-setting") setTimeout("window.location.reload()", 1000) } } diff --git a/ruoyi-ui/src/main.js b/ruoyi-ui/src/main.js index 292cbb4a..489600aa 100644 --- a/ruoyi-ui/src/main.js +++ b/ruoyi-ui/src/main.js @@ -11,12 +11,14 @@ import App from './App' import store from './store' import router from './router' import directive from './directive' //directive +import plugins from './plugins' // plugins import './assets/icons' // icon import './permission' // permission control import { getDicts } from "@/api/system/dict/data"; import { getConfigKey } from "@/api/system/config"; -import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, download, handleTree } from "@/utils/ruoyi"; +import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi"; +// 分页组件 import Pagination from "@/components/Pagination"; // 自定义表格工具组件 import RightToolbar from "@/components/RightToolbar" @@ -30,6 +32,8 @@ import ImageUpload from "@/components/ImageUpload" import DictTag from '@/components/DictTag' // 头部标签组件 import VueMeta from 'vue-meta' +// 字典数据组件 +import DictData from '@/components/DictData' // 全局方法挂载 Vue.prototype.getDicts = getDicts @@ -39,21 +43,8 @@ Vue.prototype.resetForm = resetForm Vue.prototype.addDateRange = addDateRange Vue.prototype.selectDictLabel = selectDictLabel Vue.prototype.selectDictLabels = selectDictLabels -Vue.prototype.download = download Vue.prototype.handleTree = handleTree -Vue.prototype.msgSuccess = function (msg) { - this.$message({ showClose: true, message: msg, type: "success" }); -} - -Vue.prototype.msgError = function (msg) { - this.$message({ showClose: true, message: msg, type: "error" }); -} - -Vue.prototype.msgInfo = function (msg) { - this.$message.info(msg); -} - // 全局组件挂载 Vue.component('DictTag', DictTag) Vue.component('Pagination', Pagination) @@ -63,7 +54,9 @@ Vue.component('FileUpload', FileUpload) Vue.component('ImageUpload', ImageUpload) Vue.use(directive) +Vue.use(plugins) Vue.use(VueMeta) +DictData.install() /** * If you don't want to use mock-server diff --git a/ruoyi-ui/src/plugins/cache.js b/ruoyi-ui/src/plugins/cache.js new file mode 100644 index 00000000..6f71b8e5 --- /dev/null +++ b/ruoyi-ui/src/plugins/cache.js @@ -0,0 +1,77 @@ +const sessionCache = { + set (key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get (key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + sessionStorage.removeItem(key); + } +} +const localCache = { + set (key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get (key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + localStorage.removeItem(key); + } +} + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +} diff --git a/ruoyi-ui/src/plugins/download.js b/ruoyi-ui/src/plugins/download.js new file mode 100644 index 00000000..cb10ab0e --- /dev/null +++ b/ruoyi-ui/src/plugins/download.js @@ -0,0 +1,48 @@ +import { saveAs } from 'file-saver' +import axios from 'axios' +import { getToken } from '@/utils/auth' + +const baseURL = process.env.VUE_APP_BASE_API + +export default { + name(name, isDelete = true) { + var url = baseURL + "/common/download?fileName=" + encodeURI(name) + "&delete=" + isDelete + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(res => { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURI(res.headers['download-filename'])) + }) + }, + resource(resource) { + var url = baseURL + "/common/download/resource?resource=" + encodeURI(resource); + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(res => { + const blob = new Blob([res.data]) + this.saveAs(blob, decodeURI(res.headers['download-filename'])) + }) + }, + zip(url, name) { + var url = baseURL + url + axios({ + method: 'get', + url: url, + responseType: 'blob', + headers: { 'Authorization': 'Bearer ' + getToken() } + }).then(res => { + const blob = new Blob([res.data], { type: 'application/zip' }) + this.saveAs(blob, name) + }) + }, + saveAs(text, name, opts) { + saveAs(text, name, opts); + } +} + diff --git a/ruoyi-ui/src/plugins/index.js b/ruoyi-ui/src/plugins/index.js new file mode 100644 index 00000000..a138e6d6 --- /dev/null +++ b/ruoyi-ui/src/plugins/index.js @@ -0,0 +1,14 @@ +import cache from './cache' +import modal from './modal' +import download from './download' + +export default { + install(Vue) { + // 缓存对象 + Vue.prototype.$cache = cache + // 模态框对象 + Vue.prototype.$modal = modal + // 下载文件 + Vue.prototype.$download = download + } +} diff --git a/ruoyi-ui/src/plugins/modal.js b/ruoyi-ui/src/plugins/modal.js new file mode 100644 index 00000000..7df61a89 --- /dev/null +++ b/ruoyi-ui/src/plugins/modal.js @@ -0,0 +1,75 @@ +import { Message, MessageBox, Notification, Loading } from 'element-ui' + +let loadingInstance; + +export default { + // 消息提示 + msg(content) { + Message.info(content) + }, + // 错误消息 + msgError(content) { + Message.error(content) + }, + // 成功消息 + msgSuccess(content) { + Message.success(content) + }, + // 警告消息 + msgWarning(content) { + Message.warning(content) + }, + // 弹出提示 + alert(content) { + MessageBox.alert(content, "系统提示") + }, + // 错误提示 + alertError(content) { + MessageBox.alert(content, "系统提示", { type: 'error' }) + }, + // 成功提示 + alertSuccess(content) { + MessageBox.alert(content, "系统提示", { type: 'success' }) + }, + // 警告提示 + alertWarning(content) { + MessageBox.alert(content, "系统提示", { type: 'warning' }) + }, + // 通知提示 + notify(content) { + Notification.info(content) + }, + // 错误通知 + notifyError(content) { + Notification.error(content); + }, + // 成功通知 + notifySuccess(content) { + Notification.success(content) + }, + // 警告通知 + notifyWarning(content) { + Notification.warning(content) + }, + // 确认窗体 + confirm(content) { + return MessageBox.confirm(content, "系统提示", { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: "warning", + }) + }, + // 打开遮罩层 + loading(content) { + loadingInstance = Loading.service({ + lock: true, + text: content, + spinner: "el-icon-loading", + background: "rgba(0, 0, 0, 0.7)", + }) + }, + // 关闭遮罩层 + closeLoading() { + loadingInstance.close(); + } +} diff --git a/ruoyi-ui/src/utils/dict/Dict.js b/ruoyi-ui/src/utils/dict/Dict.js new file mode 100644 index 00000000..22db32fe --- /dev/null +++ b/ruoyi-ui/src/utils/dict/Dict.js @@ -0,0 +1,82 @@ +import Vue from 'vue' +import { mergeRecursive } from "@/utils/ruoyi"; +import DictMeta from './DictMeta' +import DictData from './DictData' + +const DEFAULT_DICT_OPTIONS = { + types: [], +} + +/** + * @classdesc 字典 + * @property {Object} label 标签对象,内部属性名为字典类型名称 + * @property {Object} dict 字段数组,内部属性名为字典类型名称 + * @property {Array.} _dictMetas 字典元数据数组 + */ +export default class Dict { + constructor() { + this.owner = null + this.label = {} + this.type = {} + } + + init(options) { + if (options instanceof Array) { + options = { types: options } + } + const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options) + if (opts.types === undefined) { + throw new Error('need dict types') + } + const ps = [] + this._dictMetas = opts.types.map(t => DictMeta.parse(t)) + this._dictMetas.forEach(dictMeta => { + const type = dictMeta.type + Vue.set(this.label, type, {}) + Vue.set(this.type, type, []) + if (dictMeta.lazy) { + return + } + ps.push(loadDict(this, dictMeta)) + }) + return Promise.all(ps) + } + + /** + * 重新加载字典 + * @param {String} type 字典类型 + */ + reloadDict(type) { + const dictMeta = this._dictMetas.find(e => e.type === type) + if (dictMeta === undefined) { + return Promise.reject(`the dict meta of ${type} was not found`) + } + return loadDict(this, dictMeta) + } +} + +/** + * 加载字典 + * @param {Dict} dict 字典 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {Promise} + */ +function loadDict(dict, dictMeta) { + return dictMeta.request(dictMeta) + .then(response => { + const type = dictMeta.type + let dicts = dictMeta.responseConverter(response, dictMeta) + if (!(dicts instanceof Array)) { + console.error('the return of responseConverter must be Array.') + dicts = [] + } else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) { + console.error('the type of elements in dicts must be DictData') + dicts = [] + } + dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) + dicts.forEach(d => { + Vue.set(dict.label[type], d.value, d.label) + }) + return dicts + }) +} diff --git a/ruoyi-ui/src/utils/dict/DictConverter.js b/ruoyi-ui/src/utils/dict/DictConverter.js new file mode 100644 index 00000000..576ff546 --- /dev/null +++ b/ruoyi-ui/src/utils/dict/DictConverter.js @@ -0,0 +1,17 @@ +import DictOptions from './DictOptions' +import DictData from './DictData' + +export default function(dict, dictMeta) { + const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS) + const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS) + return new DictData(dict[label], dict[value], dict) +} + +/** + * 确定字典字段 + * @param {DictData} dict + * @param {...String} fields + */ +function determineDictField(dict, ...fields) { + return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f)) +} diff --git a/ruoyi-ui/src/utils/dict/DictData.js b/ruoyi-ui/src/utils/dict/DictData.js new file mode 100644 index 00000000..37a60d5c --- /dev/null +++ b/ruoyi-ui/src/utils/dict/DictData.js @@ -0,0 +1,13 @@ +/** + * @classdesc 字典数据 + * @property {String} label 标签 + * @property {*} value 标签 + * @property {Object} raw 原始数据 + */ +export default class DictData { + constructor(label, value, raw) { + this.label = label + this.value = value + this.raw = raw + } +} diff --git a/ruoyi-ui/src/utils/dict/DictMeta.js b/ruoyi-ui/src/utils/dict/DictMeta.js new file mode 100644 index 00000000..8ae6133e --- /dev/null +++ b/ruoyi-ui/src/utils/dict/DictMeta.js @@ -0,0 +1,38 @@ +import { mergeRecursive } from "@/utils/ruoyi"; +import DictOptions from './DictOptions' + +/** + * @classdesc 字典元数据 + * @property {String} type 类型 + * @property {Function} request 请求 + * @property {String} label 标签字段 + * @property {String} value 值字段 + */ +export default class DictMeta { + constructor(options) { + this.type = options.type + this.request = options.request, + this.responseConverter = options.responseConverter + this.labelField = options.labelField + this.valueField = options.valueField + this.lazy = options.lazy === true + } +} + + +/** + * 解析字典元数据 + * @param {Object} options + * @returns {DictMeta} + */ +DictMeta.parse= function(options) { + let opts = null + if (typeof options === 'string') { + opts = DictOptions.metas[options] || {} + opts.type = options + } else if (typeof options === 'object') { + opts = options + } + opts = mergeRecursive(DictOptions.metas['*'], opts) + return new DictMeta(opts) +} diff --git a/ruoyi-ui/src/utils/dict/DictOptions.js b/ruoyi-ui/src/utils/dict/DictOptions.js new file mode 100644 index 00000000..5e1cc41f --- /dev/null +++ b/ruoyi-ui/src/utils/dict/DictOptions.js @@ -0,0 +1,51 @@ +import { mergeRecursive } from "@/utils/ruoyi"; +import dictConverter from './DictConverter' + +export const options = { + metas: { + '*': { + /** + * 字典请求,方法签名为function(dictMeta: DictMeta): Promise + */ + request: (dictMeta) => { + console.log(`load dict ${dictMeta.type}`) + return Promise.resolve([]) + }, + /** + * 字典响应数据转换器,方法签名为function(response: Object, dictMeta: DictMeta): DictData + */ + responseConverter, + labelField: 'label', + valueField: 'value', + }, + }, + /** + * 默认标签字段 + */ + DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'], + /** + * 默认值字段 + */ + DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'], +} + +/** + * 映射字典 + * @param {Object} response 字典数据 + * @param {DictMeta} dictMeta 字典元数据 + * @returns {DictData} + */ +function responseConverter(response, dictMeta) { + const dicts = response.content instanceof Array ? response.content : response + if (dicts === undefined) { + console.warn(`no dict data of "${dictMeta.type}" found in the response`) + return [] + } + return dicts.map(d => dictConverter(d, dictMeta)) +} + +export function mergeOptions(src) { + mergeRecursive(options, src) +} + +export default options diff --git a/ruoyi-ui/src/utils/dict/index.js b/ruoyi-ui/src/utils/dict/index.js new file mode 100644 index 00000000..66ddfef9 --- /dev/null +++ b/ruoyi-ui/src/utils/dict/index.js @@ -0,0 +1,33 @@ +import Dict from './Dict' +import { mergeOptions } from './DictOptions' + +export default function(Vue, options) { + mergeOptions(options) + Vue.mixin({ + data() { + if (this.$options.dicts === undefined || this.$options.dicts === null) { + return {} + } + const dict = new Dict() + dict.owner = this + return { + dict + } + }, + created() { + if (!(this.dict instanceof Dict)) { + return + } + options.onCreated && options.onCreated(this.dict) + this.dict.init(this.$options.dicts).then(() => { + options.onReady && options.onReady(this.dict) + this.$nextTick(() => { + this.$emit('dictReady', this.dict) + if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) { + this.$options.methods.onDictReady.call(this, this.dict) + } + }) + }) + }, + }) +} diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js index c136ed01..63bd379b 100644 --- a/ruoyi-ui/src/utils/ruoyi.js +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -3,8 +3,6 @@ * Copyright (c) 2019 ruoyi */ -const baseURL = process.env.VUE_APP_BASE_API - // 日期格式化 export function parseTime(time, pattern) { if (arguments.length === 0 || !time) { @@ -72,8 +70,8 @@ export function addDateRange(params, dateRange, propName) { export function selectDictLabel(datas, value) { var actions = []; Object.keys(datas).some((key) => { - if (datas[key].dictValue == ('' + value)) { - actions.push(datas[key].dictLabel); + if (datas[key].value == ('' + value)) { + actions.push(datas[key].label); return true; } }) @@ -95,11 +93,6 @@ export function selectDictLabels(datas, value, separator) { return actions.join('').substring(0, actions.join('').length - 1); } -// 通用下载方法 -export function download(fileName) { - window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true; -} - // 字符串格式化(%s ) export function sprintf(str) { var args = arguments, flag = true, i = 1; @@ -122,6 +115,22 @@ export function praseStrEmpty(str) { return str; } +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]); + } else { + source[p] = target[p]; + } + } catch(e) { + source[p] = target[p]; + } + } + return source; +}; + /** * 构造树型结构数据 * @param {*} data 数据源 diff --git a/ruoyi-ui/src/utils/zipdownload.js b/ruoyi-ui/src/utils/zipdownload.js deleted file mode 100644 index 8a1b8198..00000000 --- a/ruoyi-ui/src/utils/zipdownload.js +++ /dev/null @@ -1,42 +0,0 @@ -import axios from 'axios' -import { getToken } from '@/utils/auth' - -const mimeMap = { - xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - zip: 'application/zip' -} - -const baseUrl = process.env.VUE_APP_BASE_API -export function downLoadZip(str, filename) { - var url = baseUrl + str - axios({ - method: 'get', - url: url, - responseType: 'blob', - headers: { 'Authorization': 'Bearer ' + getToken() } - }).then(res => { - resolveBlob(res, mimeMap.zip) - }) -} -/** - * 解析blob响应内容并下载 - * @param {*} res blob响应内容 - * @param {String} mimeType MIME类型 - */ -export function resolveBlob(res, mimeType) { - const aLink = document.createElement('a') - var blob = new Blob([res.data], { type: mimeType }) - // //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名; - var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') - var contentDisposition = decodeURI(res.headers['content-disposition']) - var result = patt.exec(contentDisposition) - var fileName = result[1] - fileName = fileName.replace(/\"/g, '') - aLink.style.display = 'none' - aLink.href = URL.createObjectURL(blob) - aLink.setAttribute('download', fileName) // 设置下载文件名称 - document.body.appendChild(aLink) - aLink.click() - URL.revokeObjectURL(aLink.href);//清除引用 - document.body.removeChild(aLink); -} diff --git a/ruoyi-ui/src/views/monitor/cache/index.vue b/ruoyi-ui/src/views/monitor/cache/index.vue index 98eed22e..22501dc3 100644 --- a/ruoyi-ui/src/views/monitor/cache/index.vue +++ b/ruoyi-ui/src/views/monitor/cache/index.vue @@ -8,34 +8,34 @@ - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + +
Redis版本
{{ cache.info.redis_version }}
运行模式
{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}
端口
{{ cache.info.tcp_port }}
客户端数
{{ cache.info.connected_clients }}
Redis版本
{{ cache.info.redis_version }}
运行模式
{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}
端口
{{ cache.info.tcp_port }}
客户端数
{{ cache.info.connected_clients }}
运行时间(天)
{{ cache.info.uptime_in_days }}
使用内存
{{ cache.info.used_memory_human }}
使用CPU
{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}
内存配置
{{ cache.info.maxmemory_human }}
运行时间(天)
{{ cache.info.uptime_in_days }}
使用内存
{{ cache.info.used_memory_human }}
使用CPU
{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}
内存配置
{{ cache.info.maxmemory_human }}
AOF是否开启
{{ cache.info.aof_enabled == "0" ? "否" : "是" }}
RDB是否成功
{{ cache.info.rdb_last_bgsave_status }}
Key数量
{{ cache.dbSize }}
网络入口/出口
{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps
AOF是否开启
{{ cache.info.aof_enabled == "0" ? "否" : "是" }}
RDB是否成功
{{ cache.info.rdb_last_bgsave_status }}
Key数量
{{ cache.dbSize }}
网络入口/出口
{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps
@@ -74,8 +74,6 @@ export default { name: "Server", data() { return { - // 加载层信息 - loading: [], // 统计命令信息 commandstats: null, // 使用内存 @@ -93,7 +91,7 @@ export default { getList() { getCache().then((response) => { this.cache = response.data; - this.loading.close(); + this.$modal.closeLoading(); this.commandstats = echarts.init(this.$refs.commandstats, "macarons"); this.commandstats.setOption({ @@ -141,12 +139,7 @@ export default { }, // 打开加载层 openLoading() { - this.loading = this.$loading({ - lock: true, - text: "拼命读取中", - spinner: "el-icon-loading", - background: "rgba(0, 0, 0, 0.7)", - }); + this.$modal.loading("正在加载缓存监控数据,请稍后!"); }, }, }; diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue index 753309e5..06b939d8 100644 --- a/ruoyi-ui/src/views/monitor/job/index.vue +++ b/ruoyi-ui/src/views/monitor/job/index.vue @@ -13,20 +13,20 @@ @@ -99,7 +99,7 @@ @@ -168,10 +168,10 @@ @@ -225,10 +225,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_job_status" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -240,7 +240,7 @@ - + @@ -301,6 +301,7 @@ import Crontab from '@/components/Crontab' export default { components: { Crontab }, name: "Job", + dicts: ['sys_job_group', 'sys_job_status'], data() { return { // 遮罩层 @@ -329,10 +330,6 @@ export default { openCron: false, // 传入的表达式 expression: "", - // 任务组名字典 - jobGroupOptions: [], - // 状态字典 - statusOptions: [], // 查询参数 queryParams: { pageNum: 1, @@ -359,12 +356,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_job_group").then(response => { - this.jobGroupOptions = response.data; - }); - this.getDicts("sys_job_status").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询定时任务列表 */ @@ -378,7 +369,7 @@ export default { }, // 任务组名字典翻译 jobGroupFormat(row, column) { - return this.selectDictLabel(this.jobGroupOptions, row.jobGroup); + return this.selectDictLabel(this.dict.type.sys_job_group, row.jobGroup); }, // 取消按钮 cancel() { @@ -434,29 +425,21 @@ export default { // 任务状态修改 handleStatusChange(row) { let text = row.status === "0" ? "启用" : "停用"; - this.$confirm('确认要"' + text + '""' + row.jobName + '"任务吗?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return changeJobStatus(row.jobId, row.status); - }).then(() => { - this.msgSuccess(text + "成功"); - }).catch(function() { - row.status = row.status === "0" ? "1" : "0"; - }); + this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗?').then(function() { + return changeJobStatus(row.jobId, row.status); + }).then(() => { + this.$modal.msgSuccess(text + "成功"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); }, /* 立即执行一次 */ handleRun(row) { - this.$confirm('确认要立即执行一次"' + row.jobName + '"任务吗?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return runJob(row.jobId, row.jobGroup); - }).then(() => { - this.msgSuccess("执行成功"); - }).catch(() => {}); + this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗?').then(function() { + return runJob(row.jobId, row.jobGroup); + }).then(() => { + this.$modal.msgSuccess("执行成功"); + }).catch(() => {}); }, /** 任务详细信息 */ handleView(row) { @@ -501,13 +484,13 @@ export default { if (valid) { if (this.form.jobId != undefined) { updateJob(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addJob(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -518,31 +501,23 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const jobIds = row.jobId || this.ids; - this.$confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delJob(jobIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除定时任务编号为"' + jobIds + '"的数据项?').then(function() { + return delJob(jobIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm("是否确认导出所有定时任务数据项?", "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportJob(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有定时任务数据项?').then(() => { + this.exportLoading = true; + return exportJob(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/monitor/job/log.vue b/ruoyi-ui/src/views/monitor/job/log.vue index b55b0115..44efe5f1 100644 --- a/ruoyi-ui/src/views/monitor/job/log.vue +++ b/ruoyi-ui/src/views/monitor/job/log.vue @@ -20,10 +20,10 @@ style="width: 240px" >
@@ -36,10 +36,10 @@ style="width: 240px" >
@@ -112,14 +112,14 @@ @@ -190,6 +190,7 @@ import { listJobLog, delJobLog, exportJobLog, cleanJobLog } from "@/api/monitor/ export default { name: "JobLog", + dicts: ['sys_common_status', 'sys_job_group'], data() { return { // 遮罩层 @@ -212,10 +213,6 @@ export default { dateRange: [], // 表单参数 form: {}, - // 执行状态字典 - statusOptions: [], - // 任务组名字典 - jobGroupOptions: [], // 查询参数 queryParams: { pageNum: 1, @@ -237,12 +234,6 @@ export default { } else { this.getList(); } - this.getDicts("sys_common_status").then(response => { - this.statusOptions = response.data; - }); - this.getDicts("sys_job_group").then(response => { - this.jobGroupOptions = response.data; - }); }, methods: { /** 查询调度日志列表 */ @@ -284,44 +275,32 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const jobLogIds = this.ids; - this.$confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delJobLog(jobLogIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除调度日志编号为"' + jobLogIds + '"的数据项?').then(function() { + return delJobLog(jobLogIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 清空按钮操作 */ handleClean() { - this.$confirm("是否确认清空所有调度日志数据项?", "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return cleanJobLog(); - }).then(() => { - this.getList(); - this.msgSuccess("清空成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认清空所有调度日志数据项?').then(function() { + return cleanJobLog(); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("清空成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm("是否确认导出所有调度日志数据项?", "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportJobLog(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有调度日志数据项?').then(() => { + this.exportLoading = true; + return exportJobLog(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/monitor/logininfor/index.vue b/ruoyi-ui/src/views/monitor/logininfor/index.vue index 59df72ce..63414199 100644 --- a/ruoyi-ui/src/views/monitor/logininfor/index.vue +++ b/ruoyi-ui/src/views/monitor/logininfor/index.vue @@ -30,10 +30,10 @@ style="width: 240px" > @@ -101,7 +101,7 @@ @@ -127,6 +127,7 @@ import { list, delLogininfor, cleanLogininfor, exportLogininfor } from "@/api/mo export default { name: "Logininfor", + dicts: ['sys_common_status'], data() { return { // 遮罩层 @@ -143,8 +144,6 @@ export default { total: 0, // 表格数据 list: [], - // 状态数据字典 - statusOptions: [], // 日期范围 dateRange: [], // 默认排序 @@ -161,9 +160,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_common_status").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询登录日志列表 */ @@ -202,44 +198,32 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const infoIds = row.infoId || this.ids; - this.$confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delLogininfor(infoIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除访问编号为"' + infoIds + '"的数据项?').then(function() { + return delLogininfor(infoIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 清空按钮操作 */ handleClean() { - this.$confirm('是否确认清空所有登录日志数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return cleanLogininfor(); - }).then(() => { - this.getList(); - this.msgSuccess("清空成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认清空所有登录日志数据项?').then(function() { + return cleanLogininfor(); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("清空成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有操作日志数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportLogininfor(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有操作日志数据项?').then(() => { + this.exportLoading = true; + return exportLogininfor(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/monitor/online/index.vue b/ruoyi-ui/src/views/monitor/online/index.vue index baec6e0b..ab66827b 100644 --- a/ruoyi-ui/src/views/monitor/online/index.vue +++ b/ruoyi-ui/src/views/monitor/online/index.vue @@ -111,16 +111,12 @@ export default { }, /** 强退按钮操作 */ handleForceLogout(row) { - this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return forceLogout(row.tokenId); - }).then(() => { - this.getList(); - this.msgSuccess("强退成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认强退名称为"' + row.userName + '"的数据项?').then(function() { + return forceLogout(row.tokenId); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("强退成功"); + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/monitor/operlog/index.vue b/ruoyi-ui/src/views/monitor/operlog/index.vue index 783908b8..0aee4a6a 100644 --- a/ruoyi-ui/src/views/monitor/operlog/index.vue +++ b/ruoyi-ui/src/views/monitor/operlog/index.vue @@ -30,10 +30,10 @@ style="width: 240px" > @@ -46,10 +46,10 @@ style="width: 240px" > @@ -113,7 +113,7 @@ @@ -122,7 +122,7 @@ @@ -200,6 +200,7 @@ import { list, delOperlog, cleanOperlog, exportOperlog } from "@/api/monitor/ope export default { name: "Operlog", + dicts: ['sys_oper_type', 'sys_common_status'], data() { return { // 遮罩层 @@ -218,10 +219,6 @@ export default { list: [], // 是否显示弹出层 open: false, - // 类型数据字典 - typeOptions: [], - // 类型数据字典 - statusOptions: [], // 日期范围 dateRange: [], // 默认排序 @@ -241,12 +238,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_oper_type").then(response => { - this.typeOptions = response.data; - }); - this.getDicts("sys_common_status").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询登录日志 */ @@ -261,7 +252,7 @@ export default { }, // 操作日志类型字典翻译 typeFormat(row, column) { - return this.selectDictLabel(this.typeOptions, row.businessType); + return this.selectDictLabel(this.dict.type.sys_oper_type, row.businessType); }, /** 搜索按钮操作 */ handleQuery() { @@ -294,44 +285,32 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const operIds = row.operId || this.ids; - this.$confirm('是否确认删除日志编号为"' + operIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delOperlog(operIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除日志编号为"' + operIds + '"的数据项?').then(function() { + return delOperlog(operIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 清空按钮操作 */ handleClean() { - this.$confirm('是否确认清空所有操作日志数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return cleanOperlog(); - }).then(() => { - this.getList(); - this.msgSuccess("清空成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认清空所有操作日志数据项?').then(function() { + return cleanOperlog(); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("清空成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有操作日志数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportOperlog(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有操作日志数据项?').then(() => { + this.exportLoading = true; + return exportOperlog(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/monitor/server/index.vue b/ruoyi-ui/src/views/monitor/server/index.vue index 6a5060dc..503bf9b6 100644 --- a/ruoyi-ui/src/views/monitor/server/index.vue +++ b/ruoyi-ui/src/views/monitor/server/index.vue @@ -8,26 +8,26 @@ - - + + - - + + - - + + - - + + - - + +
属性
属性
核心数
{{ server.cpu.cpuNum }}
核心数
{{ server.cpu.cpuNum }}
用户使用率
{{ server.cpu.used }}%
用户使用率
{{ server.cpu.used }}%
系统使用率
{{ server.cpu.sys }}%
系统使用率
{{ server.cpu.sys }}%
当前空闲率
{{ server.cpu.free }}%
当前空闲率
{{ server.cpu.free }}%
@@ -42,31 +42,31 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + +
属性
内存
JVM
属性
内存
JVM
总内存
{{ server.mem.total }}G
{{ server.jvm.total }}M
总内存
{{ server.mem.total }}G
{{ server.jvm.total }}M
已用内存
{{ server.mem.used}}G
{{ server.jvm.used}}M
已用内存
{{ server.mem.used}}G
{{ server.jvm.used}}M
剩余内存
{{ server.mem.free }}G
{{ server.jvm.free }}M
剩余内存
{{ server.mem.free }}G
{{ server.jvm.free }}M
使用率
{{ server.mem.usage }}%
{{ server.jvm.usage }}%
使用率
{{ server.mem.usage }}%
{{ server.jvm.usage }}%
@@ -83,16 +83,16 @@ - - - - + + + + - - - - + + + +
服务器名称
{{ server.sys.computerName }}
操作系统
{{ server.sys.osName }}
服务器名称
{{ server.sys.computerName }}
操作系统
{{ server.sys.osName }}
服务器IP
{{ server.sys.computerIp }}
系统架构
{{ server.sys.osArch }}
服务器IP
{{ server.sys.computerIp }}
系统架构
{{ server.sys.osArch }}
@@ -109,24 +109,24 @@ - - - - + + + + - - - - + + + + - - + + - - + +
Java名称
{{ server.jvm.name }}
Java版本
{{ server.jvm.version }}
Java名称
{{ server.jvm.name }}
Java版本
{{ server.jvm.version }}
启动时间
{{ server.jvm.startTime }}
运行时长
{{ server.jvm.runTime }}
启动时间
{{ server.jvm.startTime }}
运行时长
{{ server.jvm.runTime }}
安装路径
{{ server.jvm.home }}
安装路径
{{ server.jvm.home }}
项目路径
{{ server.sys.userDir }}
项目路径
{{ server.sys.userDir }}
@@ -143,24 +143,24 @@ - - - - - - - + + + + + + + - - - - - - - - + + + + + + + +
盘符路径
文件系统
盘符类型
总大小
可用大小
已用大小
已用百分比
盘符路径
文件系统
盘符类型
总大小
可用大小
已用大小
已用百分比
{{ sysFile.dirName }}
{{ sysFile.sysTypeName }}
{{ sysFile.typeName }}
{{ sysFile.total }}
{{ sysFile.free }}
{{ sysFile.used }}
{{ sysFile.usage }}%
{{ sysFile.dirName }}
{{ sysFile.sysTypeName }}
{{ sysFile.typeName }}
{{ sysFile.total }}
{{ sysFile.free }}
{{ sysFile.used }}
{{ sysFile.usage }}%
@@ -178,8 +178,6 @@ export default { name: "Server", data() { return { - // 加载层信息 - loading: [], // 服务器信息 server: [] }; @@ -193,17 +191,12 @@ export default { getList() { getServer().then(response => { this.server = response.data; - this.loading.close(); + this.$modal.closeLoading(); }); }, // 打开加载层 openLoading() { - this.loading = this.$loading({ - lock: true, - text: "拼命读取中", - spinner: "el-icon-loading", - background: "rgba(0, 0, 0, 0.7)" - }); + this.$modal.loading("正在加载服务监控数据,请稍后!"); } } }; diff --git a/ruoyi-ui/src/views/system/config/index.vue b/ruoyi-ui/src/views/system/config/index.vue index b8472a80..efb69615 100644 --- a/ruoyi-ui/src/views/system/config/index.vue +++ b/ruoyi-ui/src/views/system/config/index.vue @@ -24,10 +24,10 @@ @@ -114,7 +114,7 @@ @@ -166,10 +166,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_yes_no" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -189,6 +189,7 @@ import { listConfig, getConfig, delConfig, addConfig, updateConfig, exportConfig export default { name: "Config", + dicts: ['sys_yes_no'], data() { return { // 遮罩层 @@ -211,8 +212,6 @@ export default { title: "", // 是否显示弹出层 open: false, - // 类型数据字典 - typeOptions: [], // 日期范围 dateRange: [], // 查询参数 @@ -241,9 +240,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_yes_no").then(response => { - this.typeOptions = response.data; - }); }, methods: { /** 查询参数列表 */ @@ -312,13 +308,13 @@ export default { if (valid) { if (this.form.configId != undefined) { updateConfig(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addConfig(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -329,36 +325,28 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const configIds = row.configId || this.ids; - this.$confirm('是否确认删除参数编号为"' + configIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { + this.$modal.confirm('是否确认删除参数编号为"' + configIds + '"的数据项?').then(function() { return delConfig(configIds); }).then(() => { this.getList(); - this.msgSuccess("删除成功"); + this.$modal.msgSuccess("删除成功"); }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有参数数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportConfig(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有参数数据项?').then(() => { + this.exportLoading = true; + return exportConfig(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); }, /** 刷新缓存按钮操作 */ handleRefreshCache() { refreshCache().then(() => { - this.msgSuccess("刷新成功"); + this.$modal.msgSuccess("刷新成功"); }); } } diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue index 037c9984..f9c7741e 100644 --- a/ruoyi-ui/src/views/system/dept/index.vue +++ b/ruoyi-ui/src/views/system/dept/index.vue @@ -13,10 +13,10 @@ @@ -61,7 +61,7 @@ @@ -135,10 +135,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -159,6 +159,7 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css"; export default { name: "Dept", + dicts: ['sys_normal_disable'], components: { Treeselect }, data() { return { @@ -180,8 +181,6 @@ export default { refreshTable: true, // 是否展开 expand: false, - // 状态数据字典 - statusOptions: [], // 查询参数 queryParams: { deptName: undefined, @@ -219,9 +218,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询部门列表 */ @@ -309,13 +305,13 @@ export default { if (valid) { if (this.form.deptId != undefined) { updateDept(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addDept(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -325,16 +321,12 @@ export default { }, /** 删除按钮操作 */ handleDelete(row) { - this.$confirm('是否确认删除名称为"' + row.deptName + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delDept(row.deptId); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() { + return delDept(row.deptId); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/dict/data.vue b/ruoyi-ui/src/views/system/dict/data.vue index aa3849a6..36eb6afd 100644 --- a/ruoyi-ui/src/views/system/dict/data.vue +++ b/ruoyi-ui/src/views/system/dict/data.vue @@ -23,10 +23,10 @@ @@ -96,7 +96,7 @@ @@ -164,10 +164,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -188,6 +188,7 @@ import { listType, getType } from "@/api/system/dict/type"; export default { name: "Data", + dicts: ['sys_normal_disable'], data() { return { // 遮罩层 @@ -239,8 +240,6 @@ export default { label: "危险" } ], - // 状态数据字典 - statusOptions: [], // 类型数据字典 typeOptions: [], // 查询参数 @@ -271,9 +270,6 @@ export default { const dictId = this.$route.params && this.$route.params.dictId; this.getType(dictId); this.getTypeList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询字典类型详细 */ @@ -358,13 +354,13 @@ export default { if (valid) { if (this.form.dictCode != undefined) { updateData(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addData(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -375,31 +371,23 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const dictCodes = row.dictCode || this.ids; - this.$confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delData(dictCodes); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除字典编码为"' + dictCodes + '"的数据项?').then(function() { + return delData(dictCodes); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportData(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有数据项?').then(() => { + this.exportLoading = true; + return exportData(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/dict/index.vue b/ruoyi-ui/src/views/system/dict/index.vue index 20cf5ce9..37de40f3 100644 --- a/ruoyi-ui/src/views/system/dict/index.vue +++ b/ruoyi-ui/src/views/system/dict/index.vue @@ -30,10 +30,10 @@ style="width: 240px" > @@ -125,7 +125,7 @@ @@ -174,10 +174,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -197,6 +197,7 @@ import { listType, getType, delType, addType, updateType, exportType, refreshCac export default { name: "Dict", + dicts: ['sys_normal_disable'], data() { return { // 遮罩层 @@ -219,8 +220,6 @@ export default { title: "", // 是否显示弹出层 open: false, - // 状态数据字典 - statusOptions: [], // 日期范围 dateRange: [], // 查询参数 @@ -246,9 +245,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询字典类型列表 */ @@ -316,13 +312,13 @@ export default { if (valid) { if (this.form.dictId != undefined) { updateType(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addType(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -333,36 +329,28 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const dictIds = row.dictId || this.ids; - this.$confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delType(dictIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?').then(function() { + return delType(dictIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有类型数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportType(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有类型数据项?').then(() => { + this.exportLoading = true; + return exportType(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); }, /** 刷新缓存按钮操作 */ handleRefreshCache() { refreshCache().then(() => { - this.msgSuccess("刷新成功"); + this.$modal.msgSuccess("刷新成功"); }); } } diff --git a/ruoyi-ui/src/views/system/menu/index.vue b/ruoyi-ui/src/views/system/menu/index.vue index 0f4296c1..a89e1ee7 100644 --- a/ruoyi-ui/src/views/system/menu/index.vue +++ b/ruoyi-ui/src/views/system/menu/index.vue @@ -13,10 +13,10 @@ @@ -68,7 +68,7 @@ @@ -240,10 +240,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_show_hide" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -257,10 +257,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -282,6 +282,7 @@ import IconSelect from "@/components/IconSelect"; export default { name: "Menu", + dicts: ['sys_show_hide', 'sys_normal_disable'], components: { Treeselect, IconSelect }, data() { return { @@ -301,10 +302,6 @@ export default { isExpandAll: false, // 重新渲染表格状态 refreshTable: true, - // 显示状态数据字典 - visibleOptions: [], - // 菜单状态数据字典 - statusOptions: [], // 查询参数 queryParams: { menuName: undefined, @@ -328,12 +325,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_show_hide").then(response => { - this.visibleOptions = response.data; - }); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { // 选择图标 @@ -434,13 +425,13 @@ export default { if (valid) { if (this.form.menuId != undefined) { updateMenu(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addMenu(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -450,16 +441,12 @@ export default { }, /** 删除按钮操作 */ handleDelete(row) { - this.$confirm('是否确认删除名称为"' + row.menuName + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delMenu(row.menuId); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除名称为"' + row.menuName + '"的数据项?').then(function() { + return delMenu(row.menuId); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue index 7b4eb2d0..22b2ad5e 100644 --- a/ruoyi-ui/src/views/system/notice/index.vue +++ b/ruoyi-ui/src/views/system/notice/index.vue @@ -22,10 +22,10 @@ @@ -82,12 +82,12 @@ /> @@ -137,10 +137,10 @@ @@ -149,10 +149,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_notice_status" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -176,6 +176,7 @@ import { listNotice, getNotice, delNotice, addNotice, updateNotice } from "@/api export default { name: "Notice", + dicts: ['sys_notice_status', 'sys_notice_type'], data() { return { // 遮罩层 @@ -196,10 +197,6 @@ export default { title: "", // 是否显示弹出层 open: false, - // 类型数据字典 - statusOptions: [], - // 状态数据字典 - typeOptions: [], // 查询参数 queryParams: { pageNum: 1, @@ -223,12 +220,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_notice_status").then(response => { - this.statusOptions = response.data; - }); - this.getDicts("sys_notice_type").then(response => { - this.typeOptions = response.data; - }); }, methods: { /** 查询公告列表 */ @@ -294,13 +285,13 @@ export default { if (valid) { if (this.form.noticeId != undefined) { updateNotice(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addNotice(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -311,16 +302,12 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const noticeIds = row.noticeId || this.ids - this.$confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delNotice(noticeIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除公告编号为"' + noticeIds + '"的数据项?').then(function() { + return delNotice(noticeIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/post/index.vue b/ruoyi-ui/src/views/system/post/index.vue index 10eca78a..e2069687 100644 --- a/ruoyi-ui/src/views/system/post/index.vue +++ b/ruoyi-ui/src/views/system/post/index.vue @@ -22,10 +22,10 @@ @@ -90,7 +90,7 @@ @@ -141,10 +141,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -164,6 +164,7 @@ import { listPost, getPost, delPost, addPost, updatePost, exportPost } from "@/a export default { name: "Post", + dicts: ['sys_normal_disable'], data() { return { // 遮罩层 @@ -186,8 +187,6 @@ export default { title: "", // 是否显示弹出层 open: false, - // 状态数据字典 - statusOptions: [], // 查询参数 queryParams: { pageNum: 1, @@ -214,9 +213,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询岗位列表 */ @@ -283,13 +279,13 @@ export default { if (valid) { if (this.form.postId != undefined) { updatePost(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { addPost(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -300,31 +296,23 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const postIds = row.postId || this.ids; - this.$confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delPost(postIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?').then(function() { + return delPost(postIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有岗位数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportPost(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有岗位数据项?').then(() => { + this.exportLoading = true; + return exportPost(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/role/authUser.vue b/ruoyi-ui/src/views/system/role/authUser.vue index a65ccbf6..e18ea8b3 100644 --- a/ruoyi-ui/src/views/system/role/authUser.vue +++ b/ruoyi-ui/src/views/system/role/authUser.vue @@ -69,7 +69,7 @@ @@ -107,6 +107,7 @@ import selectUser from "./selectUser"; export default { name: "AuthUser", + dicts: ['sys_normal_disable'], components: { selectUser }, data() { return { @@ -122,8 +123,6 @@ export default { total: 0, // 用户表格数据 userList: [], - // 状态数据字典 - statusOptions: [], // 查询参数 queryParams: { pageNum: 1, @@ -139,9 +138,6 @@ export default { if (roleId) { this.queryParams.roleId = roleId; this.getList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); } }, methods: { @@ -182,30 +178,22 @@ export default { /** 取消授权按钮操作 */ cancelAuthUser(row) { const roleId = this.queryParams.roleId; - this.$confirm('确认要取消该用户"' + row.userName + '"角色吗?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { + this.$modal.confirm('确认要取消该用户"' + row.userName + '"角色吗?').then(function() { return authUserCancel({ userId: row.userId, roleId: roleId }); }).then(() => { this.getList(); - this.msgSuccess("取消授权成功"); + this.$modal.msgSuccess("取消授权成功"); }).catch(() => {}); }, /** 批量取消授权按钮操作 */ cancelAuthUserAll(row) { const roleId = this.queryParams.roleId; const userIds = this.userIds.join(","); - this.$confirm('是否取消选中用户授权数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - return authUserCancelAll({ roleId: roleId, userIds: userIds }); + this.$modal.confirm('是否取消选中用户授权数据项?').then(function() { + return authUserCancelAll({ roleId: roleId, userIds: userIds }); }).then(() => { this.getList(); - this.msgSuccess("取消授权成功"); + this.$modal.msgSuccess("取消授权成功"); }).catch(() => {}); } } diff --git a/ruoyi-ui/src/views/system/role/index.vue b/ruoyi-ui/src/views/system/role/index.vue index 27167c9d..6e585586 100644 --- a/ruoyi-ui/src/views/system/role/index.vue +++ b/ruoyi-ui/src/views/system/role/index.vue @@ -30,10 +30,10 @@ style="width: 240px" > @@ -183,10 +183,10 @@ {{dict.dictLabel}} + v-for="dict in dict.type.sys_normal_disable" + :key="dict.value" + :label="dict.value" + >{{dict.label}} @@ -265,6 +265,7 @@ import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/d export default { name: "Role", + dicts: ['sys_normal_disable'], data() { return { // 遮罩层 @@ -295,8 +296,6 @@ export default { deptNodeAll: false, // 日期范围 dateRange: [], - // 状态数据字典 - statusOptions: [], // 数据范围选项 dataScopeOptions: [ { @@ -354,9 +353,6 @@ export default { }, created() { this.getList(); - this.getDicts("sys_normal_disable").then(response => { - this.statusOptions = response.data; - }); }, methods: { /** 查询角色列表 */ @@ -417,17 +413,13 @@ export default { // 角色状态修改 handleStatusChange(row) { let text = row.status === "0" ? "启用" : "停用"; - this.$confirm('确认要"' + text + '""' + row.roleName + '"角色吗?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return changeRoleStatus(row.roleId, row.status); - }).then(() => { - this.msgSuccess(text + "成功"); - }).catch(function() { - row.status = row.status === "0" ? "1" : "0"; - }); + this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function() { + return changeRoleStatus(row.roleId, row.status); + }).then(() => { + this.$modal.msgSuccess(text + "成功"); + }).catch(function() { + row.status = row.status === "0" ? "1" : "0"; + }); }, // 取消按钮 cancel() { @@ -583,14 +575,14 @@ export default { if (this.form.roleId != undefined) { this.form.menuIds = this.getMenuAllCheckedKeys(); updateRole(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.open = false; this.getList(); }); } else { this.form.menuIds = this.getMenuAllCheckedKeys(); addRole(this.form).then(response => { - this.msgSuccess("新增成功"); + this.$modal.msgSuccess("新增成功"); this.open = false; this.getList(); }); @@ -603,7 +595,7 @@ export default { if (this.form.roleId != undefined) { this.form.deptIds = this.getDeptAllCheckedKeys(); dataScope(this.form).then(response => { - this.msgSuccess("修改成功"); + this.$modal.msgSuccess("修改成功"); this.openDataScope = false; this.getList(); }); @@ -612,31 +604,23 @@ export default { /** 删除按钮操作 */ handleDelete(row) { const roleIds = row.roleId || this.ids; - this.$confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return delRole(roleIds); - }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); - }).catch(() => {}); + this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function() { + return delRole(roleIds); + }).then(() => { + this.getList(); + this.$modal.msgSuccess("删除成功"); + }).catch(() => {}); }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams; - this.$confirm('是否确认导出所有角色数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(() => { - this.exportLoading = true; - return exportRole(queryParams); - }).then(response => { - this.download(response.msg); - this.exportLoading = false; - }).catch(() => {}); + this.$modal.confirm('是否确认导出所有用户数据项?').then(() => { + this.exportLoading = true; + return exportRole(queryParams); + }).then(response => { + this.$download.name(response.msg); + this.exportLoading = false; + }).catch(() => {}); } } }; diff --git a/ruoyi-ui/src/views/system/role/selectUser.vue b/ruoyi-ui/src/views/system/role/selectUser.vue index 5a97095f..a9e2ce0f 100644 --- a/ruoyi-ui/src/views/system/role/selectUser.vue +++ b/ruoyi-ui/src/views/system/role/selectUser.vue @@ -34,7 +34,7 @@ @@ -61,6 +61,7 @@