Compare commits
No commits in common. "master" and "v3.6.6" have entirely different histories.
|
|
@ -126,4 +126,4 @@ com.ruoyi
|
|||
|
||||
## 若依微服务交流群
|
||||
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Kuaw0Xdlw2Nlgn6s8h9elzuquHGxGObD&authKey=cSrQcWQ%2BzQZAFFrwxaR%2BbzcumX4WRduZnd1O6JO1dlclQMiu%2BKwxAy8t2JfNp67V&noverify=0&group_code=112869560) 点击按钮入群。
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) 点击按钮入群。
|
||||
2
pom.xml
2
pom.xml
|
|
@ -35,7 +35,7 @@
|
|||
<springdoc.version>1.6.9</springdoc.version>
|
||||
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
|
||||
<!-- override dependency version -->
|
||||
<tomcat.version>9.0.112</tomcat.version>
|
||||
<tomcat.version>9.0.105</tomcat.version>
|
||||
<logback.version>1.2.13</logback.version>
|
||||
<spring-framework.version>5.3.39</spring-framework.version>
|
||||
</properties>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@ package com.ruoyi.system.api;
|
|||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.constant.ServiceNameConstants;
|
||||
|
|
@ -28,13 +26,4 @@ public interface RemoteFileService
|
|||
*/
|
||||
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param fileUrl 文件地址
|
||||
* @return 结果
|
||||
*/
|
||||
@DeleteMapping(value = "/delete", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||
public R<Boolean> delete(@RequestParam("fileUrl") String fileUrl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ import java.util.List;
|
|||
import javax.validation.constraints.*;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.ruoyi.common.core.annotation.Excel;
|
||||
import com.ruoyi.common.core.annotation.Excel.ColumnType;
|
||||
import com.ruoyi.common.core.annotation.Excel.Type;
|
||||
import com.ruoyi.common.core.annotation.Excels;
|
||||
import com.ruoyi.common.core.constant.UserConstants;
|
||||
import com.ruoyi.common.core.annotation.Excels;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
import com.ruoyi.common.core.xss.Xss;
|
||||
|
||||
|
|
@ -202,7 +201,6 @@ public class SysUser extends BaseEntity
|
|||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
|
|
|
|||
|
|
@ -30,12 +30,6 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
|
|||
{
|
||||
return R.fail("上传文件失败:" + throwable.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<Boolean> delete(String fileUrl)
|
||||
{
|
||||
return R.fail("删除文件失败:" + throwable.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,16 +87,6 @@ public class Constants
|
|||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 所有权限标识
|
||||
*/
|
||||
public static final String ALL_PERMISSION = "*:*:*";
|
||||
|
||||
/**
|
||||
* 管理员角色权限标识
|
||||
*/
|
||||
public static final String SUPER_ADMIN = "admin";
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
|
|
@ -130,7 +120,7 @@ public class Constants
|
|||
/**
|
||||
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||
*/
|
||||
public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" };
|
||||
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
|
||||
|
||||
/**
|
||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||
|
|
|
|||
|
|
@ -114,20 +114,20 @@ public class FileUtils
|
|||
}
|
||||
|
||||
/**
|
||||
* 校验文件路径合法性(安全性与扩展名)
|
||||
* 检查文件是否可下载
|
||||
*
|
||||
* @param fileUrl 待校验的文件地址
|
||||
* @param resource 需要下载的文件
|
||||
* @return true 正常 false 非法
|
||||
*/
|
||||
public static boolean validateFilePath(String fileUrl)
|
||||
public static boolean checkAllowDownload(String resource)
|
||||
{
|
||||
// 禁止目录上跳级别
|
||||
if (StringUtils.contains(fileUrl, ".."))
|
||||
if (StringUtils.contains(resource, ".."))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 判断是否在允许下载的文件规则内
|
||||
return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(fileUrl));
|
||||
return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -73,8 +73,6 @@ public class ExcelUtil<T>
|
|||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
|
||||
|
||||
public static final String SEPARATOR = ",";
|
||||
|
||||
public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
|
||||
|
||||
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
|
||||
|
|
@ -147,18 +145,23 @@ public class ExcelUtil<T>
|
|||
/**
|
||||
* 对象的子列表方法
|
||||
*/
|
||||
private Map<String, Method> subMethods;
|
||||
private Method subMethod;
|
||||
|
||||
/**
|
||||
* 对象的子列表属性
|
||||
*/
|
||||
private Map<String, List<Field>> subFieldsMap;
|
||||
private List<Field> subFields;
|
||||
|
||||
/**
|
||||
* 统计列表
|
||||
*/
|
||||
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
|
||||
|
||||
/**
|
||||
* 数字格式
|
||||
*/
|
||||
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
|
||||
|
||||
/**
|
||||
* 实体对象
|
||||
*/
|
||||
|
|
@ -225,10 +228,7 @@ public class ExcelUtil<T>
|
|||
int titleLastCol = this.fields.size() - 1;
|
||||
if (isSubList())
|
||||
{
|
||||
for (List<Field> currentSubFields : subFieldsMap.values())
|
||||
{
|
||||
titleLastCol = titleLastCol + currentSubFields.size() - 1;
|
||||
}
|
||||
titleLastCol = titleLastCol + subFields.size() - 1;
|
||||
}
|
||||
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
|
||||
titleRow.setHeightInPoints(30);
|
||||
|
|
@ -248,17 +248,16 @@ public class ExcelUtil<T>
|
|||
{
|
||||
Row subRow = sheet.createRow(rownum);
|
||||
int column = 0;
|
||||
int subFieldSize = subFields != null ? subFields.size() : 0;
|
||||
for (Object[] objects : fields)
|
||||
{
|
||||
Field field = (Field) objects[0];
|
||||
Excel attr = (Excel) objects[1];
|
||||
CellStyle cellStyle = styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()));
|
||||
if (Collection.class.isAssignableFrom(field.getType()))
|
||||
{
|
||||
Cell cell = subRow.createCell(column);
|
||||
cell.setCellValue(attr.name());
|
||||
cell.setCellStyle(cellStyle);
|
||||
int subFieldSize = subFieldsMap != null ? subFieldsMap.get(field.getName()).size() : 0;
|
||||
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
|
||||
if (subFieldSize > 1)
|
||||
{
|
||||
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
|
||||
|
|
@ -270,7 +269,7 @@ public class ExcelUtil<T>
|
|||
{
|
||||
Cell cell = subRow.createCell(column++);
|
||||
cell.setCellValue(attr.name());
|
||||
cell.setCellStyle(cellStyle);
|
||||
cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
|
||||
}
|
||||
}
|
||||
rownum++;
|
||||
|
|
@ -342,11 +341,7 @@ public class ExcelUtil<T>
|
|||
Map<String, Integer> cellMap = new HashMap<String, Integer>();
|
||||
// 获取表头
|
||||
Row heard = sheet.getRow(titleNum);
|
||||
if (heard == null)
|
||||
{
|
||||
throw new UtilException("文件标题行为空,请检查Excel文件格式");
|
||||
}
|
||||
for (int i = 0; i < heard.getLastCellNum(); i++)
|
||||
for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
|
||||
{
|
||||
Cell cell = heard.getCell(i);
|
||||
if (StringUtils.isNotNull(cell))
|
||||
|
|
@ -354,6 +349,10 @@ public class ExcelUtil<T>
|
|||
String value = this.getCellValue(heard, i).toString();
|
||||
cellMap.put(value, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
cellMap.put(null, i);
|
||||
}
|
||||
}
|
||||
// 有数据时才处理 得到类的所有field.
|
||||
List<Object[]> fields = this.getFields();
|
||||
|
|
@ -566,8 +565,7 @@ public class ExcelUtil<T>
|
|||
Excel excel = (Excel) os[1];
|
||||
if (Collection.class.isAssignableFrom(field.getType()))
|
||||
{
|
||||
List<Field> currentSubFields = subFieldsMap.get(field.getName());
|
||||
for (Field subField : currentSubFields)
|
||||
for (Field subField : subFields)
|
||||
{
|
||||
Excel subExcel = subField.getAnnotation(Excel.class);
|
||||
this.createHeadCell(subExcel, row, column++);
|
||||
|
|
@ -580,7 +578,7 @@ public class ExcelUtil<T>
|
|||
}
|
||||
if (Type.EXPORT.equals(type))
|
||||
{
|
||||
fillExcelData(index);
|
||||
fillExcelData(index, row);
|
||||
addStatisticsRow();
|
||||
}
|
||||
}
|
||||
|
|
@ -590,9 +588,10 @@ public class ExcelUtil<T>
|
|||
* 填充excel数据
|
||||
*
|
||||
* @param index 序号
|
||||
* @param row 单元格行
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void fillExcelData(int index)
|
||||
public void fillExcelData(int index, Row row)
|
||||
{
|
||||
int startNo = index * sheetSize;
|
||||
int endNo = Math.min(startNo + sheetSize, list.size());
|
||||
|
|
@ -600,7 +599,7 @@ public class ExcelUtil<T>
|
|||
|
||||
for (int i = startNo; i < endNo; i++)
|
||||
{
|
||||
Row row = sheet.createRow(currentRowNum);
|
||||
row = sheet.createRow(currentRowNum);
|
||||
T vo = (T) list.get(i);
|
||||
int column = 0;
|
||||
int maxSubListSize = getCurrentMaxSubListSize(vo);
|
||||
|
|
@ -613,7 +612,6 @@ public class ExcelUtil<T>
|
|||
try
|
||||
{
|
||||
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel);
|
||||
List<Field> currentSubFields = subFieldsMap.get(field.getName());
|
||||
if (subList != null && !subList.isEmpty())
|
||||
{
|
||||
int subIndex = 0;
|
||||
|
|
@ -626,15 +624,15 @@ public class ExcelUtil<T>
|
|||
}
|
||||
|
||||
int subColumn = column;
|
||||
for (Field subField : currentSubFields)
|
||||
for (Field subField : subFields)
|
||||
{
|
||||
Excel subExcel = subField.getAnnotation(Excel.class);
|
||||
addCell(subExcel, subRow, (T) subVo, subField, subColumn++);
|
||||
}
|
||||
subIndex++;
|
||||
}
|
||||
column += subFields.size();
|
||||
}
|
||||
column += currentSubFields.size();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -726,7 +724,6 @@ public class ExcelUtil<T>
|
|||
style = wb.createCellStyle();
|
||||
style.setAlignment(HorizontalAlignment.CENTER);
|
||||
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
style.setDataFormat(dataFormat.getFormat("######0.00"));
|
||||
Font totalFont = wb.createFont();
|
||||
totalFont.setFontName("Arial");
|
||||
totalFont.setFontHeightInPoints((short) 10);
|
||||
|
|
@ -987,7 +984,7 @@ public class ExcelUtil<T>
|
|||
{
|
||||
// 创建cell
|
||||
cell = row.createCell(column);
|
||||
if (isSubListValue(vo) && getListCellValue(vo) > 1 && attr.needMerge())
|
||||
if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
|
||||
{
|
||||
if (subMergedLastRowNum >= subMergedFirstRowNum)
|
||||
{
|
||||
|
|
@ -1084,36 +1081,18 @@ public class ExcelUtil<T>
|
|||
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
|
||||
{
|
||||
String hideSheetName = "combo_" + firstCol + "_" + endCol;
|
||||
Sheet hideSheet = null;
|
||||
String hideSheetDataName = hideSheetName + "_data";
|
||||
Name name = wb.getName(hideSheetDataName);
|
||||
if (name != null)
|
||||
Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
|
||||
for (int i = 0; i < textlist.length; i++)
|
||||
{
|
||||
// 名称已存在,尝试从名称的引用中找到sheet名称
|
||||
String refersToFormula = name.getRefersToFormula();
|
||||
if (StringUtils.isNotEmpty(refersToFormula) && refersToFormula.contains("!"))
|
||||
{
|
||||
String sheetNameFromFormula = refersToFormula.substring(0, refersToFormula.indexOf("!"));
|
||||
hideSheet = wb.getSheet(sheetNameFromFormula);
|
||||
}
|
||||
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
|
||||
}
|
||||
|
||||
if (hideSheet == null)
|
||||
{
|
||||
hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
|
||||
for (int i = 0; i < textlist.length; i++)
|
||||
{
|
||||
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
|
||||
}
|
||||
// 创建名称,可被其他单元格引用
|
||||
name = wb.createName();
|
||||
name.setNameName(hideSheetDataName);
|
||||
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
|
||||
}
|
||||
|
||||
// 创建名称,可被其他单元格引用
|
||||
Name name = wb.createName();
|
||||
name.setNameName(hideSheetName + "_data");
|
||||
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
|
||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||
// 加载下拉列表内容
|
||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetDataName);
|
||||
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
|
||||
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
||||
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
||||
// 数据有效性对象
|
||||
|
|
@ -1151,7 +1130,7 @@ public class ExcelUtil<T>
|
|||
public static String convertByExp(String propertyValue, String converterExp, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
String[] convertSource = converterExp.split(SEPARATOR);
|
||||
String[] convertSource = converterExp.split(",");
|
||||
for (String item : convertSource)
|
||||
{
|
||||
String[] itemArray = item.split("=");
|
||||
|
|
@ -1188,7 +1167,7 @@ public class ExcelUtil<T>
|
|||
public static String reverseByExp(String propertyValue, String converterExp, String separator)
|
||||
{
|
||||
StringBuilder propertyString = new StringBuilder();
|
||||
String[] convertSource = converterExp.split(SEPARATOR);
|
||||
String[] convertSource = converterExp.split(",");
|
||||
for (String item : convertSource)
|
||||
{
|
||||
String[] itemArray = item.split("=");
|
||||
|
|
@ -1276,7 +1255,7 @@ public class ExcelUtil<T>
|
|||
{
|
||||
cell = row.createCell(key);
|
||||
cell.setCellStyle(styles.get("total"));
|
||||
cell.setCellValue(statistics.get(key));
|
||||
cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
|
||||
}
|
||||
statistics.clear();
|
||||
}
|
||||
|
|
@ -1351,8 +1330,6 @@ public class ExcelUtil<T>
|
|||
{
|
||||
List<Object[]> fields = new ArrayList<Object[]>();
|
||||
List<Field> tempFields = new ArrayList<>();
|
||||
subFieldsMap = new HashMap<>();
|
||||
subMethods = new HashMap<>();
|
||||
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
|
||||
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||
if (StringUtils.isNotEmpty(includeFields))
|
||||
|
|
@ -1400,11 +1377,10 @@ public class ExcelUtil<T>
|
|||
}
|
||||
if (Collection.class.isAssignableFrom(field.getType()))
|
||||
{
|
||||
String fieldName = field.getName();
|
||||
subMethods.put(fieldName, getSubMethod(fieldName, clazz));
|
||||
subMethod = getSubMethod(field.getName(), clazz);
|
||||
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
||||
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
|
||||
subFieldsMap.put(fieldName, FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class));
|
||||
this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1473,8 +1449,7 @@ public class ExcelUtil<T>
|
|||
{
|
||||
this.sheet = wb.createSheet();
|
||||
this.createTitle();
|
||||
int actualIndex = wb.getSheetIndex(this.sheet);
|
||||
wb.setSheetName(actualIndex, sheetName + index);
|
||||
wb.setSheetName(index, sheetName + index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1599,7 +1574,7 @@ public class ExcelUtil<T>
|
|||
*/
|
||||
public boolean isSubList()
|
||||
{
|
||||
return !StringUtils.isEmpty(subFieldsMap);
|
||||
return StringUtils.isNotNull(subFields) && subFields.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1607,32 +1582,24 @@ public class ExcelUtil<T>
|
|||
*/
|
||||
public boolean isSubListValue(T vo)
|
||||
{
|
||||
return !StringUtils.isEmpty(subFieldsMap) && getListCellValue(vo) > 0;
|
||||
return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合的值
|
||||
*/
|
||||
public int getListCellValue(Object obj)
|
||||
public Collection<?> getListCellValue(Object obj)
|
||||
{
|
||||
Collection<?> value;
|
||||
int max = 0;
|
||||
Object value;
|
||||
try
|
||||
{
|
||||
for (String s : subMethods.keySet())
|
||||
{
|
||||
value = (Collection<?>) subMethods.get(s).invoke(obj);
|
||||
if (value.size() > max)
|
||||
{
|
||||
max = value.size();
|
||||
}
|
||||
}
|
||||
value = subMethod.invoke(obj, new Object[] {});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return 0;
|
||||
return new ArrayList<Object>();
|
||||
}
|
||||
return max;
|
||||
return (Collection<?>) value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public class DataScopeAspect
|
|||
List<String> conditions = new ArrayList<String>();
|
||||
List<String> scopeCustomIds = new ArrayList<String>();
|
||||
user.getRoles().forEach(role -> {
|
||||
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && (StringUtils.isEmpty(permission) || StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))))
|
||||
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||
{
|
||||
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ public class DataScopeAspect
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(permission) && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||
if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,6 @@ public class LogAspect
|
|||
/** 计算操作消耗时间 */
|
||||
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
|
||||
|
||||
/** 参数最大长度限制 */
|
||||
private static final int PARAM_MAX_LENGTH = 2000;
|
||||
|
||||
@Autowired
|
||||
private AsyncLogService asyncLogService;
|
||||
|
||||
|
|
@ -169,16 +166,16 @@ public class LogAspect
|
|||
*/
|
||||
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
|
||||
{
|
||||
String requestMethod = operLog.getRequestMethod();
|
||||
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
|
||||
String requestMethod = operLog.getRequestMethod();
|
||||
if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name()))
|
||||
{
|
||||
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
|
||||
operLog.setOperParam(params);
|
||||
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
|
||||
}
|
||||
else
|
||||
{
|
||||
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, PARAM_MAX_LENGTH));
|
||||
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +184,7 @@ public class LogAspect
|
|||
*/
|
||||
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
|
||||
{
|
||||
StringBuilder params = new StringBuilder();
|
||||
String params = "";
|
||||
if (paramsArray != null && paramsArray.length > 0)
|
||||
{
|
||||
for (Object o : paramsArray)
|
||||
|
|
@ -197,20 +194,15 @@ public class LogAspect
|
|||
try
|
||||
{
|
||||
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
|
||||
params.append(jsonObj).append(" ");
|
||||
if (params.length() >= PARAM_MAX_LENGTH)
|
||||
{
|
||||
return StringUtils.substring(params.toString(), 0, PARAM_MAX_LENGTH);
|
||||
}
|
||||
params += jsonObj.toString() + " ";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("请求参数拼装异常 msg:{}, 参数:{}", e.getMessage(), paramsArray, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return params.toString();
|
||||
return params.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
package com.ruoyi.file.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.DispatcherType;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.ruoyi.file.filter.RefererFilter;
|
||||
|
||||
/**
|
||||
* Filter配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class FilterConfig
|
||||
{
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
@Value("${file.prefix}")
|
||||
public String localFilePrefix;
|
||||
|
||||
@Value("${referer.allowed-domains}")
|
||||
private String allowedDomains;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
@ConditionalOnProperty(value = "referer.enabled", havingValue = "true")
|
||||
public FilterRegistrationBean refererFilterRegistration()
|
||||
{
|
||||
FilterRegistrationBean registration = new FilterRegistrationBean();
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
registration.setFilter(new RefererFilter());
|
||||
registration.addUrlPatterns(localFilePrefix + "/*");
|
||||
registration.setName("refererFilter");
|
||||
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
|
||||
Map<String, String> initParameters = new HashMap<String, String>();
|
||||
initParameters.put("allowedDomains", allowedDomains);
|
||||
registration.setInitParameters(initParameters);
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,10 @@ package com.ruoyi.file.controller;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||
import com.ruoyi.file.service.ISysFileService;
|
||||
import com.ruoyi.system.api.domain.SysFile;
|
||||
|
|
@ -47,26 +45,4 @@ public class SysFileController
|
|||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件删除请求
|
||||
*/
|
||||
@DeleteMapping("delete")
|
||||
public R<Boolean> delete(String fileUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!FileUtils.validateFilePath(fileUrl))
|
||||
{
|
||||
throw new Exception(StringUtils.format("资源文件({})非法,不允许删除。 ", fileUrl));
|
||||
}
|
||||
sysFileService.deleteFile(fileUrl);
|
||||
return R.ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("删除文件失败", e);
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package com.ruoyi.file.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 防盗链过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class RefererFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* 允许的域名列表
|
||||
*/
|
||||
public List<String> allowedDomains;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
String domains = filterConfig.getInitParameter("allowedDomains");
|
||||
this.allowedDomains = Arrays.asList(domains.split(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
|
||||
String referer = req.getHeader("Referer");
|
||||
|
||||
// 如果Referer为空,拒绝访问
|
||||
if (referer == null || referer.isEmpty())
|
||||
{
|
||||
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer header is required");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查Referer是否在允许的域名列表中
|
||||
boolean allowed = false;
|
||||
for (String domain : allowedDomains)
|
||||
{
|
||||
if (referer.contains(domain))
|
||||
{
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据检查结果决定是否放行
|
||||
if (allowed)
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer '" + referer + "' is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.ruoyi.file.service;
|
||||
|
||||
import java.io.InputStream;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
|
|
@ -53,24 +53,4 @@ public class FastDfsSysFileServiceImpl implements ISysFileService
|
|||
IoUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FastDFS文件删除接口
|
||||
*
|
||||
* @param fileUrl 文件访问URL
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void deleteFile(String fileUrl) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
StorePath storePath = StorePath.parseFromUrl(fileUrl);
|
||||
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("FastDfs Failed to delete file: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,4 @@ public interface ISysFileService
|
|||
* @throws Exception
|
||||
*/
|
||||
public String uploadFile(MultipartFile file) throws Exception;
|
||||
|
||||
/**
|
||||
* 文件删除接口
|
||||
*
|
||||
* @param fileUrl 文件访问URL
|
||||
* @throws Exception
|
||||
*/
|
||||
public void deleteFile(String fileUrl) throws Exception;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ import org.springframework.beans.factory.annotation.Value;
|
|||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.file.FileUtils;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -49,17 +47,4 @@ public class LocalSysFileServiceImpl implements ISysFileService
|
|||
String url = domain + localFilePrefix + name;
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地文件删除接口
|
||||
*
|
||||
* @param fileUrl 文件访问URL
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void deleteFile(String fileUrl) throws Exception
|
||||
{
|
||||
String localFile = StringUtils.substringAfter(fileUrl, localFilePrefix);
|
||||
FileUtils.deleteFile(localFilePath + localFile);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.alibaba.nacos.common.utils.IoUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.file.config.MinioConfig;
|
||||
import com.ruoyi.file.utils.FileUploadUtils;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.PutObjectArgs;
|
||||
import io.minio.RemoveObjectArgs;
|
||||
|
||||
/**
|
||||
* Minio 文件存储
|
||||
|
|
@ -59,24 +57,4 @@ public class MinioSysFileServiceImpl implements ISysFileService
|
|||
IoUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minio文件删除接口
|
||||
*
|
||||
* @param fileUrl 文件访问URL
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public void deleteFile(String fileUrl) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
String minioFile = StringUtils.substringAfter(fileUrl, minioConfig.getBucketName());
|
||||
client.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(minioFile).build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Minio Failed to delete file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ function getList() {
|
|||
#foreach ($column in $columns)
|
||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) {
|
||||
if (null != daterange${AttrName} && '' != daterange${AttrName}) {
|
||||
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
|
||||
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ function getList() {
|
|||
#foreach ($column in $columns)
|
||||
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) {
|
||||
if (null != daterange${AttrName} && '' != daterange${AttrName}) {
|
||||
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
|
||||
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,11 +131,11 @@ public class ScheduleUtils
|
|||
int count = StringUtils.countMatches(packageName, ".");
|
||||
if (count > 1)
|
||||
{
|
||||
return StringUtils.startsWithAny(invokeTarget, Constants.JOB_WHITELIST_STR);
|
||||
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
|
||||
}
|
||||
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
|
||||
String beanPackageName = obj.getClass().getPackage().getName();
|
||||
return StringUtils.startsWithAny(beanPackageName, Constants.JOB_WHITELIST_STR)
|
||||
&& !StringUtils.startsWithAny(beanPackageName, Constants.JOB_ERROR_STR);
|
||||
return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
|
||||
&& !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
|
||||
}
|
||||
}
|
||||
|
|
@ -100,9 +100,8 @@ public class SysProfileController extends BaseController
|
|||
String oldPassword = params.get("oldPassword");
|
||||
String newPassword = params.get("newPassword");
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
Long userId = loginUser.getUserid();
|
||||
SysUser user = userService.selectUserById(userId);
|
||||
String password = user.getPassword();
|
||||
String userName = loginUser.getUsername();
|
||||
String password = loginUser.getSysUser().getPassword();
|
||||
if (!SecurityUtils.matchesPassword(oldPassword, password))
|
||||
{
|
||||
return error("修改密码失败,旧密码错误");
|
||||
|
|
@ -112,7 +111,7 @@ public class SysProfileController extends BaseController
|
|||
return error("新密码不能与旧密码相同");
|
||||
}
|
||||
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||
if (userService.resetUserPwd(userId, newPassword) > 0)
|
||||
if (userService.resetUserPwd(userName, newPassword) > 0)
|
||||
{
|
||||
// 更新缓存用户密码&密码最后更新时间
|
||||
loginUser.getSysUser().setPwdUpdateDate(DateUtils.getNowDate());
|
||||
|
|
@ -144,13 +143,8 @@ public class SysProfileController extends BaseController
|
|||
return error("文件服务异常,请联系管理员");
|
||||
}
|
||||
String url = fileResult.getData().getUrl();
|
||||
if (userService.updateUserAvatar(loginUser.getUserid(), url))
|
||||
if (userService.updateUserAvatar(loginUser.getUsername(), url))
|
||||
{
|
||||
String oldAvatarUrl = loginUser.getSysUser().getAvatar();
|
||||
if (StringUtils.isNotEmpty(oldAvatarUrl))
|
||||
{
|
||||
remoteFileService.delete(oldAvatarUrl);
|
||||
}
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
ajax.put("imgUrl", url);
|
||||
// 更新缓存用户头像
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ public class SysUserController extends BaseController
|
|||
@PutMapping("/recordlogin")
|
||||
public R<Boolean> recordlogin(@RequestBody SysUser sysUser)
|
||||
{
|
||||
return R.ok(userService.updateLoginInfo(sysUser));
|
||||
return R.ok(userService.updateUserProfile(sysUser));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -70,37 +70,20 @@ public interface SysUserMapper
|
|||
/**
|
||||
* 修改用户头像
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param avatar 头像地址
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar);
|
||||
|
||||
/**
|
||||
* 修改用户状态
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param status 状态
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateUserStatus(@Param("userId") Long userId, @Param("status") String status);
|
||||
|
||||
/**
|
||||
* 更新用户登录信息(IP和登录时间)
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateLoginInfo(SysUser user);
|
||||
public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password);
|
||||
public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
|
||||
|
||||
/**
|
||||
* 通过用户ID删除用户
|
||||
|
|
|
|||
|
|
@ -155,19 +155,11 @@ public interface ISysUserService
|
|||
/**
|
||||
* 修改用户头像
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param avatar 头像地址
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean updateUserAvatar(Long userId, String avatar);
|
||||
|
||||
/**
|
||||
* 更新用户登录信息(IP和登录时间)
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean updateLoginInfo(SysUser user);
|
||||
public boolean updateUserAvatar(String userName, String avatar);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
|
|
@ -180,11 +172,11 @@ public interface ISysUserService
|
|||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
public int resetUserPwd(Long userId, String password);
|
||||
public int resetUserPwd(String userName, String password);
|
||||
|
||||
/**
|
||||
* 通过用户ID删除用户
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import java.util.Set;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import com.ruoyi.common.core.constant.Constants;
|
||||
import com.ruoyi.common.core.constant.UserConstants;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.system.api.domain.SysRole;
|
||||
|
|
@ -42,7 +41,7 @@ public class SysPermissionServiceImpl implements ISysPermissionService
|
|||
// 管理员拥有所有权限
|
||||
if (user.isAdmin())
|
||||
{
|
||||
roles.add(Constants.SUPER_ADMIN);
|
||||
roles.add("admin");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -64,7 +63,7 @@ public class SysPermissionServiceImpl implements ISysPermissionService
|
|||
// 管理员拥有所有权限
|
||||
if (user.isAdmin())
|
||||
{
|
||||
perms.add(Constants.ALL_PERMISSION);
|
||||
perms.add("*:*:*");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ public class SysUserServiceImpl implements ISysUserService
|
|||
@Override
|
||||
public int updateUserStatus(SysUser user)
|
||||
{
|
||||
return userMapper.updateUserStatus(user.getUserId(), user.getStatus());
|
||||
return userMapper.updateUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -344,25 +344,14 @@ public class SysUserServiceImpl implements ISysUserService
|
|||
/**
|
||||
* 修改用户头像
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param avatar 头像地址
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean updateUserAvatar(Long userId, String avatar)
|
||||
public boolean updateUserAvatar(String userName, String avatar)
|
||||
{
|
||||
return userMapper.updateUserAvatar(userId, avatar) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户登录信息(IP和登录时间)
|
||||
*
|
||||
* @param user 用户信息
|
||||
* @return 结果
|
||||
*/
|
||||
public boolean updateLoginInfo(SysUser user)
|
||||
{
|
||||
return userMapper.updateLoginInfo(user) > 0;
|
||||
return userMapper.updateUserAvatar(userName, avatar) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -374,20 +363,20 @@ public class SysUserServiceImpl implements ISysUserService
|
|||
@Override
|
||||
public int resetPwd(SysUser user)
|
||||
{
|
||||
return userMapper.resetUserPwd(user.getUserId(), user.getPassword());
|
||||
return userMapper.updateUser(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userName 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int resetUserPwd(Long userId, String password)
|
||||
public int resetUserPwd(String userName, String password)
|
||||
{
|
||||
return userMapper.resetUserPwd(userId, password);
|
||||
return userMapper.resetUserPwd(userName, password);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -528,7 +517,6 @@ public class SysUserServiceImpl implements ISysUserService
|
|||
checkUserDataScope(u.getUserId());
|
||||
deptService.checkDeptDataScope(user.getDeptId());
|
||||
user.setUserId(u.getUserId());
|
||||
user.setDeptId(u.getDeptId());
|
||||
user.setUpdateBy(operName);
|
||||
userMapper.updateUser(user);
|
||||
successNum++;
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="loginIp" column="login_ip" />
|
||||
<result property="loginDate" column="login_date" />
|
||||
<result property="pwdUpdateDate" column="pwd_update_date" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
<association property="dept" javaType="SysDept" resultMap="deptResult" />
|
||||
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
||||
<result property="createBy" column="create_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
<association property="dept" javaType="SysDept" resultMap="deptResult" />
|
||||
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="deptResult" type="SysDept">
|
||||
|
|
@ -180,7 +180,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<update id="updateUser" parameterType="SysUser">
|
||||
update sys_user
|
||||
<set>
|
||||
<if test="deptId != 0">dept_id = #{deptId},</if>
|
||||
<if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
|
||||
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
|
||||
<if test="email != null ">email = #{email},</if>
|
||||
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
|
||||
|
|
@ -198,19 +198,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</update>
|
||||
|
||||
<update id="updateUserStatus" parameterType="SysUser">
|
||||
update sys_user set status = #{status}, update_time = sysdate() where user_id = #{userId}
|
||||
update sys_user set status = #{status} where user_id = #{userId}
|
||||
</update>
|
||||
|
||||
<update id="updateUserAvatar" parameterType="SysUser">
|
||||
update sys_user set avatar = #{avatar}, update_time = sysdate() where user_id = #{userId}
|
||||
</update>
|
||||
|
||||
<update id="updateLoginInfo" parameterType="SysUser">
|
||||
update sys_user set login_ip = #{loginIp}, login_date = #{loginDate} where user_id = #{userId}
|
||||
update sys_user set avatar = #{avatar} where user_name = #{userName}
|
||||
</update>
|
||||
|
||||
<update id="resetUserPwd" parameterType="SysUser">
|
||||
update sys_user set pwd_update_date = sysdate(), password = #{password}, update_time = sysdate() where user_id = #{userId}
|
||||
update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName}
|
||||
</update>
|
||||
|
||||
<delete id="deleteUserById" parameterType="Long">
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
|
||||
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="Object.keys(columns).length > 0">
|
||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
||||
<el-button size="mini" circle icon="el-icon-menu" />
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
<el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> 列展示 </el-checkbox>
|
||||
</el-dropdown-item>
|
||||
<div class="check-line"></div>
|
||||
<template v-for="(item, key) in columns">
|
||||
<el-dropdown-item :key="key">
|
||||
<el-checkbox v-model="item.visible" @change="checkboxChange($event, key)" :label="item.label" />
|
||||
<template v-for="item in columns">
|
||||
<el-dropdown-item :key="item.key">
|
||||
<el-checkbox v-model="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
|
|
@ -30,13 +30,12 @@
|
|||
<el-transfer
|
||||
:titles="['显示', '隐藏']"
|
||||
v-model="value"
|
||||
:data="transferData"
|
||||
:data="columns"
|
||||
@change="dataChange"
|
||||
></el-transfer>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "RightToolbar",
|
||||
|
|
@ -56,10 +55,9 @@ export default {
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
/* 显隐列信息(数组格式、对象格式) */
|
||||
/* 显隐列信息 */
|
||||
columns: {
|
||||
type: [Array, Object],
|
||||
default: () => ({})
|
||||
type: Array
|
||||
},
|
||||
/* 是否显示检索图标 */
|
||||
search: {
|
||||
|
|
@ -87,36 +85,21 @@ export default {
|
|||
},
|
||||
isChecked: {
|
||||
get() {
|
||||
return Array.isArray(this.columns) ? this.columns.every((col) => col.visible) : Object.values(this.columns).every((col) => col.visible)
|
||||
return this.columns.every((col) => col.visible)
|
||||
},
|
||||
set() {}
|
||||
},
|
||||
isIndeterminate() {
|
||||
return Array.isArray(this.columns) ? this.columns.some((col) => col.visible) && !this.isChecked : Object.values(this.columns).some((col) => col.visible) && !this.isChecked
|
||||
},
|
||||
transferData() {
|
||||
if (Array.isArray(this.columns)) {
|
||||
return this.columns.map((item, index) => ({ key: index, label: item.label }))
|
||||
} else {
|
||||
return Object.keys(this.columns).map((key, index) => ({ key: index, label: this.columns[key].label }))
|
||||
}
|
||||
return this.columns.some((col) => col.visible) && !this.isChecked
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.showColumnsType == 'transfer') {
|
||||
// transfer穿梭显隐列初始默认隐藏列
|
||||
if (Array.isArray(this.columns)) {
|
||||
for (let item in this.columns) {
|
||||
if (this.columns[item].visible === false) {
|
||||
this.value.push(parseInt(item))
|
||||
}
|
||||
// 显隐列初始默认隐藏列
|
||||
for (let item in this.columns) {
|
||||
if (this.columns[item].visible === false) {
|
||||
this.value.push(parseInt(item))
|
||||
}
|
||||
} else {
|
||||
Object.keys(this.columns).forEach((key, index) => {
|
||||
if (this.columns[key].visible === false) {
|
||||
this.value.push(index)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -131,15 +114,9 @@ export default {
|
|||
},
|
||||
// 右侧列表元素变化
|
||||
dataChange(data) {
|
||||
if (Array.isArray(this.columns)) {
|
||||
for (let item in this.columns) {
|
||||
const key = this.columns[item].key
|
||||
this.columns[item].visible = !data.includes(key)
|
||||
}
|
||||
} else {
|
||||
Object.keys(this.columns).forEach((key, index) => {
|
||||
this.columns[key].visible = !data.includes(index)
|
||||
})
|
||||
for (let item in this.columns) {
|
||||
const key = this.columns[item].key
|
||||
this.columns[item].visible = !data.includes(key)
|
||||
}
|
||||
},
|
||||
// 打开显隐列dialog
|
||||
|
|
@ -147,26 +124,17 @@ export default {
|
|||
this.open = true
|
||||
},
|
||||
// 单勾选
|
||||
checkboxChange(event, key) {
|
||||
if (Array.isArray(this.columns)) {
|
||||
this.columns.filter(item => item.key == key)[0].visible = event
|
||||
} else {
|
||||
this.columns[key].visible = event
|
||||
}
|
||||
checkboxChange(event, label) {
|
||||
this.columns.filter(item => item.label == label)[0].visible = event
|
||||
},
|
||||
// 切换全选/反选
|
||||
toggleCheckAll() {
|
||||
const newValue = !this.isChecked
|
||||
if (Array.isArray(this.columns)) {
|
||||
this.columns.forEach((col) => (col.visible = newValue))
|
||||
} else {
|
||||
Object.values(this.columns).forEach((col) => (col.visible = newValue))
|
||||
}
|
||||
this.columns.forEach((col) => (col.visible = newValue))
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-transfer__button {
|
||||
border-radius: 50%;
|
||||
|
|
|
|||
|
|
@ -53,19 +53,12 @@ export default {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fixed-header + .app-main {
|
||||
overflow-y: auto;
|
||||
scrollbar-gutter: auto;
|
||||
height: calc(100vh - 50px);
|
||||
min-height: 0px;
|
||||
}
|
||||
|
||||
.app-main:has(.copyright) {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
|
||||
.fixed-header + .app-main {
|
||||
margin-top: 50px;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.hasTagsView {
|
||||
|
|
@ -75,14 +68,19 @@ export default {
|
|||
}
|
||||
|
||||
.fixed-header + .app-main {
|
||||
margin-top: 84px;
|
||||
height: calc(100vh - 84px);
|
||||
min-height: 0px;
|
||||
padding-top: 84px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
// fix css style bug in open el-dialog
|
||||
.el-popup-parent--hidden {
|
||||
.fixed-header {
|
||||
padding-right: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
|
|
|
|||
|
|
@ -34,14 +34,15 @@
|
|||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item @click.native="setLayout" v-if="setting">
|
||||
<span>布局设置</span>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided @click.native="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting">
|
||||
<svg-icon icon-class="more-up" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -177,7 +178,6 @@ export default {
|
|||
|
||||
.avatar-wrapper {
|
||||
margin-top: 10px;
|
||||
right: 8px;
|
||||
position: relative;
|
||||
|
||||
.user-avatar {
|
||||
|
|
@ -190,7 +190,6 @@ export default {
|
|||
.user-nickname{
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
left: 2px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,11 +77,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.main-container:has(.fixed-header) {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.drawer-bg {
|
||||
background: #000;
|
||||
opacity: 0.3;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ const mutations = {
|
|||
if (state.hasOwnProperty(key)) {
|
||||
state[key] = value
|
||||
}
|
||||
},
|
||||
SET_TITLE: (state, title) => {
|
||||
state.title = title
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +33,7 @@ const actions = {
|
|||
},
|
||||
// 设置网页标题
|
||||
setTitle({ commit }, title) {
|
||||
commit('SET_TITLE', title)
|
||||
state.title = title
|
||||
useDynamicTitle()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,29 @@
|
|||
export const drawingDefaultValue = []
|
||||
|
||||
export function initDrawingDefaultValue() {
|
||||
if (drawingDefaultValue.length === 0) {
|
||||
drawingDefaultValue.push({
|
||||
layout: 'colFormItem',
|
||||
tagIcon: 'input',
|
||||
label: '手机号',
|
||||
vModel: 'mobile',
|
||||
formId: 6,
|
||||
tag: 'el-input',
|
||||
placeholder: '请输入手机号',
|
||||
defaultValue: '',
|
||||
span: 24,
|
||||
style: {width: '100%'},
|
||||
clearable: true,
|
||||
prepend: '',
|
||||
append: '',
|
||||
'prefix-icon': 'el-icon-mobile',
|
||||
'suffix-icon': '',
|
||||
maxlength: 11,
|
||||
'show-word-limit': true,
|
||||
readonly: false,
|
||||
disabled: false,
|
||||
required: true,
|
||||
changeTag: true,
|
||||
regList: [{
|
||||
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
|
||||
message: '手机号格式错误'
|
||||
}]
|
||||
})
|
||||
export default [
|
||||
{
|
||||
layout: 'colFormItem',
|
||||
tagIcon: 'input',
|
||||
label: '手机号',
|
||||
vModel: 'mobile',
|
||||
formId: 6,
|
||||
tag: 'el-input',
|
||||
placeholder: '请输入手机号',
|
||||
defaultValue: '',
|
||||
span: 24,
|
||||
style: { width: '100%' },
|
||||
clearable: true,
|
||||
prepend: '',
|
||||
append: '',
|
||||
'prefix-icon': 'el-icon-mobile',
|
||||
'suffix-icon': '',
|
||||
maxlength: 11,
|
||||
'show-word-limit': true,
|
||||
readonly: false,
|
||||
disabled: false,
|
||||
required: true,
|
||||
changeTag: true,
|
||||
regList: [{
|
||||
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
|
||||
message: '手机号格式错误'
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
export function cleanDrawingDefaultValue() {
|
||||
drawingDefaultValue.splice(0, drawingDefaultValue.length)
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@
|
|||
>
|
||||
</p>
|
||||
<p>
|
||||
<i class="el-icon-user-solid"></i> QQ群: <s> 满42799195 </s> <s> 满170157040 </s>
|
||||
<i class="el-icon-user-solid"></i> QQ群: <s> 满42799195 </s> <s> 满170157040 </s>
|
||||
<s> 满130643120 </s> <s> 满225920371 </s> <s> 满201705537 </s> <s> 满236543183 </s>
|
||||
<s> 满213618602 </s> <s> 满148794840 </s> <s> 满118752664 </s> <s> 满101038945 </s>
|
||||
<s> 满128355254 </s> <s> 满179219821 </s> <s> 满158753145 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=jR7HqTiLzuLocIH6aNNtTW3LlCV8UQ6d&authKey=GJZj%2Bnwmsvk6j%2FWrX7FKstAaRjgUC1WL%2F%2B8aVTaPbHX5wOimH5q9igaOSXP7cF9L&noverify=0&group_code=112869560" target="_blank">112869560</a>
|
||||
<s> 满128355254 </s> <s> 满179219821 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Z6j1amUmIPBXamuZzxpwjY8GwaP45XB6&authKey=zfSnxECfnScfY1HLCWilSqCq%2BmSVtr%2Bi%2F4oXeBcuQVwlq6XlrAfbZ0awp3%2B4Bdec&noverify=0&group_code=158753145" target="_blank">158753145</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="el-icon-chat-dot-round"></i> 微信:<a
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-login-footer">
|
||||
<span>{{ footerContent }}</span>
|
||||
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -65,14 +65,12 @@
|
|||
import { getCodeImg } from "@/api/login"
|
||||
import Cookies from "js-cookie"
|
||||
import { encrypt, decrypt } from '@/utils/jsencrypt'
|
||||
import defaultSettings from '@/settings'
|
||||
|
||||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
return {
|
||||
title: process.env.VUE_APP_TITLE,
|
||||
footerContent: defaultSettings.footerContent,
|
||||
codeUrl: "",
|
||||
loginForm: {
|
||||
username: "admin",
|
||||
|
|
@ -158,7 +156,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
.login {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
|||
|
|
@ -61,14 +61,13 @@
|
|||
</el-form>
|
||||
<!-- 底部 -->
|
||||
<div class="el-register-footer">
|
||||
<span>{{ footerContent }}</span>
|
||||
<span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCodeImg, register } from "@/api/login"
|
||||
import defaultSettings from '@/settings'
|
||||
|
||||
export default {
|
||||
name: "Register",
|
||||
|
|
@ -82,7 +81,6 @@ export default {
|
|||
}
|
||||
return {
|
||||
title: process.env.VUE_APP_TITLE,
|
||||
footerContent: defaultSettings.footerContent,
|
||||
codeUrl: "",
|
||||
registerForm: {
|
||||
username: "",
|
||||
|
|
@ -149,7 +147,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
<style rel="stylesheet/scss" lang="scss">
|
||||
.register {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
|||
|
|
@ -58,17 +58,17 @@
|
|||
|
||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns.userId.visible" />
|
||||
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns.userName.visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns.nickName.visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns.deptName.visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns.phonenumber.visible" width="120" />
|
||||
<el-table-column label="状态" align="center" key="status" v-if="columns.status.visible">
|
||||
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
|
||||
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
|
||||
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
|
||||
<template slot-scope="scope">
|
||||
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns.createTime.visible" width="160">
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
|
|
@ -277,15 +277,15 @@ export default {
|
|||
deptId: undefined
|
||||
},
|
||||
// 列信息
|
||||
columns: {
|
||||
userId: { label: '用户编号', visible: true },
|
||||
userName: { label: '用户名称', visible: true },
|
||||
nickName: { label: '用户昵称', visible: true },
|
||||
deptName: { label: '部门', visible: true },
|
||||
phonenumber: { label: '手机号码', visible: true },
|
||||
status: { label: '状态', visible: true },
|
||||
createTime: { label: '创建时间', visible: true }
|
||||
},
|
||||
columns: [
|
||||
{ key: 0, label: `用户编号`, visible: true },
|
||||
{ key: 1, label: `用户名称`, visible: true },
|
||||
{ key: 2, label: `用户昵称`, visible: true },
|
||||
{ key: 3, label: `部门`, visible: true },
|
||||
{ key: 4, label: `手机号码`, visible: true },
|
||||
{ key: 5, label: `状态`, visible: true },
|
||||
{ key: 6, label: `创建时间`, visible: true }
|
||||
],
|
||||
// 表单校验
|
||||
rules: {
|
||||
userName: [
|
||||
|
|
@ -546,11 +546,6 @@ export default {
|
|||
},
|
||||
// 提交上传文件
|
||||
submitFileForm() {
|
||||
const file = this.$refs.upload.uploadFiles
|
||||
if (!file || file.length === 0 || !file[0].name.toLowerCase().endsWith('.xls') && !file[0].name.toLowerCase().endsWith('.xlsx')) {
|
||||
this.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
|
||||
return
|
||||
}
|
||||
this.$refs.upload.submit()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,14 +146,13 @@ import { beautifierConf, titleCase } from '@/utils/index'
|
|||
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
|
||||
import { makeUpJs } from '@/utils/generator/js'
|
||||
import { makeUpCss } from '@/utils/generator/css'
|
||||
import { drawingDefaultValue, initDrawingDefaultValue, cleanDrawingDefaultValue } from '@/utils/generator/drawingDefault'
|
||||
import drawingDefault from '@/utils/generator/drawingDefault'
|
||||
import logo from '@/assets/logo/logo.png'
|
||||
import CodeTypeDialog from './CodeTypeDialog'
|
||||
import DraggableItem from './DraggableItem'
|
||||
|
||||
let oldActiveId
|
||||
let tempActiveData
|
||||
let clipboard = null
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -172,20 +171,17 @@ export default {
|
|||
selectComponents,
|
||||
layoutComponents,
|
||||
labelWidth: 100,
|
||||
drawingList: drawingDefaultValue,
|
||||
drawingList: drawingDefault,
|
||||
drawingData: {},
|
||||
activeId: drawingDefaultValue[0].formId,
|
||||
activeId: drawingDefault[0].formId,
|
||||
drawerVisible: false,
|
||||
formData: {},
|
||||
dialogVisible: false,
|
||||
generateConf: null,
|
||||
showFileName: false,
|
||||
activeData: drawingDefaultValue[0]
|
||||
activeData: drawingDefault[0]
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
initDrawingDefaultValue()
|
||||
},
|
||||
created() {
|
||||
// 防止 firefox 下 拖拽 会新打卡一个选项卡
|
||||
document.body.ondrop = event => {
|
||||
|
|
@ -212,7 +208,7 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
clipboard = new ClipboardJS('#copyNode', {
|
||||
const clipboard = new ClipboardJS('#copyNode', {
|
||||
text: trigger => {
|
||||
const codeStr = this.generateCode()
|
||||
this.$notify({
|
||||
|
|
@ -227,9 +223,6 @@ export default {
|
|||
this.$message.error('代码复制失败')
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
clipboard.destroy()
|
||||
},
|
||||
methods: {
|
||||
activeFormItem(element) {
|
||||
this.activeData = element
|
||||
|
|
@ -291,7 +284,6 @@ export default {
|
|||
this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then(
|
||||
() => {
|
||||
this.drawingList = []
|
||||
cleanDrawingDefaultValue()
|
||||
}
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -253,8 +253,7 @@ export default {
|
|||
this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath)
|
||||
})
|
||||
} else {
|
||||
const zipName = Array.isArray(tableNames) ? "ruoyi.zip" : tableNames + ".zip"
|
||||
this.$download.zip("/code/gen/batchGenCode?tables=" + tableNames, zipName)
|
||||
this.$download.zip("/code/gen/batchGenCode?tables=" + tableNames, "ruoyi.zip")
|
||||
}
|
||||
},
|
||||
/** 同步数据库操作 */
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_mod
|
|||
(5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: ruoyi\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n connectTimeout: 30000\n socketTimeout: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.system\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'系统模块接口文档\'\n # 描述\n description: \'系统模块接口描述\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','786c7daf4543411fc65c3e48dfb15243','2020-11-20 00:00:00','2024-09-02 12:14:33','nacos','0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','',''),
|
||||
(6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.gen.domain\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'代码生成接口文档\'\n # 描述\n description: \'代码生成接口描述\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n\n# 代码生成\ngen:\n # 作者\n author: ruoyi\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\n packageName: com.ruoyi.system\n # 自动去除表前缀,默认是false\n autoRemovePre: false\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\n tablePrefix: sys_\n # 是否允许生成文件覆盖到本地(自定义路径),默认不允许\n allowOverwrite: false','43d807aa0a4accbb193b6dc7e38ac8a3','2020-11-20 00:00:00','2024-12-25 08:29:33','nacos','0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','',''),
|
||||
(7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.job.domain\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'定时任务接口文档\'\n # 描述\n description: \'定时任务接口描述\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','f78483f845777335b9ed4a9f84758848','2020-11-20 00:00:00','2024-09-02 12:14:56','nacos','0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','',''),
|
||||
(8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \nfile:\n domain: http://127.0.0.1:9300\n path: D:/ruoyi/uploadPath\n prefix: /statics\n\n# FastDFS配置\nfdfs:\n domain: http://127.0.0.1\n soTimeout: 3000\n connectTimeout: 2000\n trackerList: 127.0.0.1:22122\n\n# Minio配置\nminio:\n url: http://127.0.0.1:9000\n accessKey: minioadmin\n secretKey: minioadmin\n bucketName: test\n\n # 防盗链配置\nreferer:\n # 防盗链开关\n enabled: false\n # 允许的域名列表\n allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip\n','095791a04211d6e3d294359b21357394','2020-11-20 00:00:00','2025-09-02 05:10:11','nacos','0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml','',''),
|
||||
(8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \r\nfile:\r\n domain: http://127.0.0.1:9300\r\n path: D:/ruoyi/uploadPath\r\n prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n domain: http://8.129.231.12\r\n soTimeout: 3000\r\n connectTimeout: 2000\r\n trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n url: http://8.129.231.12:9000\r\n accessKey: minioadmin\r\n secretKey: minioadmin\r\n bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''),
|
||||
(9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,'');
|
||||
|
||||
|
||||
Loading…
Reference in New Issue