mirror of
https://gitee.com/y_project/RuoYi-Cloud.git
synced 2026-01-26 11:51:55 +08:00
Compare commits
17 Commits
548808d2eb
...
v3.6.6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8aca11c2a2 | ||
|
|
725033e361 | ||
|
|
d29e49e23b | ||
|
|
706c3bb69b | ||
|
|
cd0ee95b9c | ||
|
|
3293e2fb56 | ||
|
|
924ec0eb6e | ||
|
|
135b1204a9 | ||
|
|
cb566a704b | ||
|
|
aadba0382e | ||
|
|
a0ce1cf33b | ||
|
|
3915c77391 | ||
|
|
b80932ceb4 | ||
|
|
056cf94082 | ||
|
|
0dcd3e6183 | ||
|
|
07be5ceb26 | ||
|
|
cc59502d7c |
@@ -1,11 +1,11 @@
|
||||
<p align="center">
|
||||
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
|
||||
</p>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.5</h1>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.6</h1>
|
||||
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
|
||||
<p align="center">
|
||||
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.5-brightgreen.svg"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.6-brightgreen.svg"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
echo.
|
||||
echo [信息] 清理工程target生成路径。
|
||||
echo [信息] 清理工程target生成路径。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
复制项目的文件到对应docker路径,便于一键生成镜像。
|
||||
#>
|
||||
|
||||
# 复制SQL文件
|
||||
Write-Host "begin copy sql"
|
||||
Copy-Item -Path "../sql/ry_20250425.sql" -Destination "./mysql/db" -Force
|
||||
Copy-Item -Path "../sql/ry_config_20250224.sql" -Destination "./mysql/db" -Force
|
||||
|
||||
# 复制HTML文件
|
||||
Write-Host "begin copy html"
|
||||
if (Test-Path "../ruoyi-ui/dist") {
|
||||
Remove-Item -Path "./nginx/html/dist" -Recurse -Force -ErrorAction SilentlyContinue
|
||||
New-Item -ItemType Directory -Path "./nginx/html/dist" -Force | Out-Null
|
||||
Copy-Item -Path "../ruoyi-ui/dist/*" -Destination "./nginx/html/dist" -Recurse -Force
|
||||
} else {
|
||||
Write-Host "Warning: ../ruoyi-ui/dist directory not found"
|
||||
}
|
||||
|
||||
# 复制JAR文件
|
||||
Write-Host "begin copy ruoyi-gateway"
|
||||
Copy-Item -Path "../ruoyi-gateway/target/ruoyi-gateway.jar" -Destination "./ruoyi/gateway/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-auth"
|
||||
Copy-Item -Path "../ruoyi-auth/target/ruoyi-auth.jar" -Destination "./ruoyi/auth/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-visual"
|
||||
Copy-Item -Path "../ruoyi-visual/ruoyi-monitor/target/ruoyi-visual-monitor.jar" -Destination "./ruoyi/visual/monitor/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-modules-system"
|
||||
Copy-Item -Path "../ruoyi-modules/ruoyi-system/target/ruoyi-modules-system.jar" -Destination "./ruoyi/modules/system/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-modules-file"
|
||||
Copy-Item -Path "../ruoyi-modules/ruoyi-file/target/ruoyi-modules-file.jar" -Destination "./ruoyi/modules/file/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-modules-job"
|
||||
Copy-Item -Path "../ruoyi-modules/ruoyi-job/target/ruoyi-modules-job.jar" -Destination "./ruoyi/modules/job/jar" -Force
|
||||
|
||||
Write-Host "begin copy ruoyi-modules-gen"
|
||||
Copy-Item -Path "../ruoyi-modules/ruoyi-gen/target/ruoyi-modules-gen.jar" -Destination "./ruoyi/modules/gen/jar" -Force
|
||||
|
||||
Write-Host "copy completed"
|
||||
@@ -9,7 +9,7 @@ usage() {
|
||||
|
||||
# copy sql
|
||||
echo "begin copy sql "
|
||||
cp ../sql/ry_20240629.sql ./mysql/db
|
||||
cp ../sql/ry_20250523.sql ./mysql/db
|
||||
cp ../sql/ry_config_20250224.sql ./mysql/db
|
||||
|
||||
# copy html
|
||||
|
||||
@@ -2,6 +2,7 @@ version : '3.8'
|
||||
services:
|
||||
ruoyi-nacos:
|
||||
container_name: ruoyi-nacos
|
||||
image: nacos/nacos-server
|
||||
build:
|
||||
context: ./nacos
|
||||
environment:
|
||||
@@ -17,6 +18,7 @@ services:
|
||||
- ruoyi-mysql
|
||||
ruoyi-mysql:
|
||||
container_name: ruoyi-mysql
|
||||
image: mysql:5.7
|
||||
build:
|
||||
context: ./mysql
|
||||
ports:
|
||||
@@ -38,6 +40,7 @@ services:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
ruoyi-redis:
|
||||
container_name: ruoyi-redis
|
||||
image: redis
|
||||
build:
|
||||
context: ./redis
|
||||
ports:
|
||||
|
||||
@@ -1 +1 @@
|
||||
存放sql目录下的所有脚本,用于docker自动执行。
|
||||
存放sql目录下的所有脚本,用于docker自动执行。
|
||||
@@ -1,7 +1,7 @@
|
||||
# 基础镜像
|
||||
FROM mysql:5.7
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 执行sql脚本
|
||||
ADD ./db/*.sql /docker-entrypoint-initdb.d/
|
||||
# 基础镜像
|
||||
FROM mysql:5.7
|
||||
# author
|
||||
MAINTAINER ruoyi
|
||||
|
||||
# 执行sql脚本
|
||||
ADD ./db/*.sql /docker-entrypoint-initdb.d/
|
||||
1
docker/nginx/html/dist/readme.txt
vendored
Normal file
1
docker/nginx/html/dist/readme.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
存放前端ruoyi-ui构建好的静态文件,用于nginx请求访问。
|
||||
@@ -1 +1 @@
|
||||
存放认证中心打包好的jar文件,用于docker启动应用。
|
||||
存放认证中心打包好的jar文件,用于docker启动应用。
|
||||
@@ -1 +1 @@
|
||||
存放网关模块打包好的jar文件,用于docker启动应用。
|
||||
存放网关模块打包好的jar文件,用于docker启动应用。
|
||||
@@ -1 +1 @@
|
||||
存放监控中心打包好的jar文件,用于docker启动应用。
|
||||
存放监控中心打包好的jar文件,用于docker启动应用。
|
||||
11
pom.xml
11
pom.xml
@@ -6,14 +6,14 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依微服务系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>3.6.5</ruoyi.version>
|
||||
<ruoyi.version>3.6.6</ruoyi.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
@@ -26,17 +26,16 @@
|
||||
<pagehelper.boot.version>2.0.0</pagehelper.boot.version>
|
||||
<druid.version>1.2.23</druid.version>
|
||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||
<commons.io.version>2.13.0</commons.io.version>
|
||||
<commons.io.version>2.19.0</commons.io.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<fastjson.version>2.0.53</fastjson.version>
|
||||
<fastjson.version>2.0.57</fastjson.version>
|
||||
<jjwt.version>0.9.1</jjwt.version>
|
||||
<minio.version>8.2.2</minio.version>
|
||||
<poi.version>4.1.2</poi.version>
|
||||
<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.102</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>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-api</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ public class SysUser extends BaseEntity
|
||||
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
|
||||
private Date loginDate;
|
||||
|
||||
/** 密码最后更新时间 */
|
||||
private Date pwdUpdateDate;
|
||||
|
||||
/** 部门对象 */
|
||||
@Excels({
|
||||
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
|
||||
@@ -248,6 +251,16 @@ public class SysUser extends BaseEntity
|
||||
this.loginDate = loginDate;
|
||||
}
|
||||
|
||||
public Date getPwdUpdateDate()
|
||||
{
|
||||
return pwdUpdateDate;
|
||||
}
|
||||
|
||||
public void setPwdUpdateDate(Date pwdUpdateDate)
|
||||
{
|
||||
this.pwdUpdateDate = pwdUpdateDate;
|
||||
}
|
||||
|
||||
public SysDept getDept()
|
||||
{
|
||||
return dept;
|
||||
@@ -314,6 +327,7 @@ public class SysUser extends BaseEntity
|
||||
.append("delFlag", getDelFlag())
|
||||
.append("loginIp", getLoginIp())
|
||||
.append("loginDate", getLoginDate())
|
||||
.append("pwdUpdateDate", getPwdUpdateDate())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@ public class SysLoginService
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserName(username);
|
||||
sysUser.setNickName(username);
|
||||
sysUser.setPwdUpdateDate(DateUtils.getNowDate());
|
||||
sysUser.setPassword(SecurityUtils.encryptPassword(password));
|
||||
R<?> registerResult = remoteUserService.registerUserInfo(sysUser, SecurityConstants.INNER);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -136,6 +136,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算相差天数
|
||||
*/
|
||||
public static int differentDaysByMillisecond(Date date1, Date date2)
|
||||
{
|
||||
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算时间差
|
||||
*
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-modules</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
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.DateUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.file.FileTypeUtils;
|
||||
import com.ruoyi.common.core.utils.file.MimeTypeUtils;
|
||||
@@ -112,7 +113,8 @@ public class SysProfileController extends BaseController
|
||||
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||
if (userService.resetUserPwd(userName, newPassword) > 0)
|
||||
{
|
||||
// 更新缓存用户密码
|
||||
// 更新缓存用户密码&密码最后更新时间
|
||||
loginUser.getSysUser().setPwdUpdateDate(DateUtils.getNowDate());
|
||||
loginUser.getSysUser().setPassword(newPassword);
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return success();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.system.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -18,6 +19,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
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.text.Convert;
|
||||
import com.ruoyi.common.core.utils.DateUtils;
|
||||
import com.ruoyi.common.core.utils.StringUtils;
|
||||
import com.ruoyi.common.core.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.common.core.web.controller.BaseController;
|
||||
@@ -186,9 +189,35 @@ public class SysUserController extends BaseController
|
||||
ajax.put("user", user);
|
||||
ajax.put("roles", roles);
|
||||
ajax.put("permissions", permissions);
|
||||
ajax.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
|
||||
ajax.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
|
||||
return ajax;
|
||||
}
|
||||
|
||||
// 检查初始密码是否提醒修改
|
||||
public boolean initPasswordIsModify(Date pwdUpdateDate)
|
||||
{
|
||||
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
|
||||
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
|
||||
}
|
||||
|
||||
// 检查密码是否过期
|
||||
public boolean passwordIsExpiration(Date pwdUpdateDate)
|
||||
{
|
||||
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
|
||||
if (passwordValidateDays != null && passwordValidateDays > 0)
|
||||
{
|
||||
if (StringUtils.isNull(pwdUpdateDate))
|
||||
{
|
||||
// 如果从未修改过初始密码,直接提醒过期
|
||||
return true;
|
||||
}
|
||||
Date nowDate = DateUtils.getNowDate();
|
||||
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户编号获取详细信息
|
||||
*/
|
||||
|
||||
@@ -5,24 +5,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<mapper namespace="com.ruoyi.system.mapper.SysUserMapper">
|
||||
|
||||
<resultMap type="SysUser" id="SysUserResult">
|
||||
<id property="userId" column="user_id" />
|
||||
<result property="deptId" column="dept_id" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="nickName" column="nick_name" />
|
||||
<result property="email" column="email" />
|
||||
<result property="phonenumber" column="phonenumber" />
|
||||
<result property="sex" column="sex" />
|
||||
<result property="avatar" column="avatar" />
|
||||
<result property="password" column="password" />
|
||||
<result property="status" column="status" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="loginIp" column="login_ip" />
|
||||
<result property="loginDate" column="login_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" />
|
||||
<id property="userId" column="user_id" />
|
||||
<result property="deptId" column="dept_id" />
|
||||
<result property="userName" column="user_name" />
|
||||
<result property="nickName" column="nick_name" />
|
||||
<result property="email" column="email" />
|
||||
<result property="phonenumber" column="phonenumber" />
|
||||
<result property="sex" column="sex" />
|
||||
<result property="avatar" column="avatar" />
|
||||
<result property="password" column="password" />
|
||||
<result property="status" column="status" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<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" />
|
||||
</resultMap>
|
||||
@@ -47,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUserVo">
|
||||
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark,
|
||||
select u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.pwd_update_date, u.create_by, u.create_time, u.remark,
|
||||
d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status,
|
||||
r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
|
||||
from sys_user u
|
||||
@@ -154,6 +155,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="sex != null and sex != ''">sex,</if>
|
||||
<if test="password != null and password != ''">password,</if>
|
||||
<if test="status != null and status != ''">status,</if>
|
||||
<if test="pwdUpdateDate != null">pwd_update_date,</if>
|
||||
<if test="createBy != null and createBy != ''">create_by,</if>
|
||||
<if test="remark != null and remark != ''">remark,</if>
|
||||
create_time
|
||||
@@ -168,6 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="sex != null and sex != ''">#{sex},</if>
|
||||
<if test="password != null and password != ''">#{password},</if>
|
||||
<if test="status != null and status != ''">#{status},</if>
|
||||
<if test="pwdUpdateDate != null">#{pwdUpdateDate},</if>
|
||||
<if test="createBy != null and createBy != ''">#{createBy},</if>
|
||||
<if test="remark != null and remark != ''">#{remark},</if>
|
||||
sysdate()
|
||||
@@ -203,7 +206,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</update>
|
||||
|
||||
<update id="resetUserPwd" parameterType="SysUser">
|
||||
update sys_user set password = #{password} where user_name = #{userName}
|
||||
update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName}
|
||||
</update>
|
||||
|
||||
<delete id="deleteUserById" parameterType="Long">
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# 忽略build目录下类型为js的文件的语法检查
|
||||
build/*.js
|
||||
# 忽略src/assets目录下文件的语法检查
|
||||
src/assets
|
||||
# 忽略public目录下文件的语法检查
|
||||
public
|
||||
# 忽略当前目录下为js的文件的语法检查
|
||||
*.js
|
||||
# 忽略当前目录下为vue的文件的语法检查
|
||||
*.vue
|
||||
@@ -1,199 +0,0 @@
|
||||
// ESlint 检查配置
|
||||
module.exports = {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
sourceType: 'module'
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
extends: ['plugin:vue/recommended', 'eslint:recommended'],
|
||||
|
||||
// add your custom rules here
|
||||
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||
rules: {
|
||||
"vue/max-attributes-per-line": [2, {
|
||||
"singleline": 10,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}],
|
||||
"vue/singleline-html-element-content-newline": "off",
|
||||
"vue/multiline-html-element-content-newline":"off",
|
||||
"vue/name-property-casing": ["error", "PascalCase"],
|
||||
"vue/no-v-html": "off",
|
||||
'accessor-pairs': 2,
|
||||
'arrow-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'block-spacing': [2, 'always'],
|
||||
'brace-style': [2, '1tbs', {
|
||||
'allowSingleLine': true
|
||||
}],
|
||||
'camelcase': [0, {
|
||||
'properties': 'always'
|
||||
}],
|
||||
'comma-dangle': [2, 'never'],
|
||||
'comma-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'comma-style': [2, 'last'],
|
||||
'constructor-super': 2,
|
||||
'curly': [2, 'multi-line'],
|
||||
'dot-location': [2, 'property'],
|
||||
'eol-last': 2,
|
||||
'eqeqeq': ["error", "always", {"null": "ignore"}],
|
||||
'generator-star-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'handle-callback-err': [2, '^(err|error)$'],
|
||||
'indent': [2, 2, {
|
||||
'SwitchCase': 1
|
||||
}],
|
||||
'jsx-quotes': [2, 'prefer-single'],
|
||||
'key-spacing': [2, {
|
||||
'beforeColon': false,
|
||||
'afterColon': true
|
||||
}],
|
||||
'keyword-spacing': [2, {
|
||||
'before': true,
|
||||
'after': true
|
||||
}],
|
||||
'new-cap': [2, {
|
||||
'newIsCap': true,
|
||||
'capIsNew': false
|
||||
}],
|
||||
'new-parens': 2,
|
||||
'no-array-constructor': 2,
|
||||
'no-caller': 2,
|
||||
'no-console': 'off',
|
||||
'no-class-assign': 2,
|
||||
'no-cond-assign': 2,
|
||||
'no-const-assign': 2,
|
||||
'no-control-regex': 0,
|
||||
'no-delete-var': 2,
|
||||
'no-dupe-args': 2,
|
||||
'no-dupe-class-members': 2,
|
||||
'no-dupe-keys': 2,
|
||||
'no-duplicate-case': 2,
|
||||
'no-empty-character-class': 2,
|
||||
'no-empty-pattern': 2,
|
||||
'no-eval': 2,
|
||||
'no-ex-assign': 2,
|
||||
'no-extend-native': 2,
|
||||
'no-extra-bind': 2,
|
||||
'no-extra-boolean-cast': 2,
|
||||
'no-extra-parens': [2, 'functions'],
|
||||
'no-fallthrough': 2,
|
||||
'no-floating-decimal': 2,
|
||||
'no-func-assign': 2,
|
||||
'no-implied-eval': 2,
|
||||
'no-inner-declarations': [2, 'functions'],
|
||||
'no-invalid-regexp': 2,
|
||||
'no-irregular-whitespace': 2,
|
||||
'no-iterator': 2,
|
||||
'no-label-var': 2,
|
||||
'no-labels': [2, {
|
||||
'allowLoop': false,
|
||||
'allowSwitch': false
|
||||
}],
|
||||
'no-lone-blocks': 2,
|
||||
'no-mixed-spaces-and-tabs': 2,
|
||||
'no-multi-spaces': 2,
|
||||
'no-multi-str': 2,
|
||||
'no-multiple-empty-lines': [2, {
|
||||
'max': 1
|
||||
}],
|
||||
'no-native-reassign': 2,
|
||||
'no-negated-in-lhs': 2,
|
||||
'no-new-object': 2,
|
||||
'no-new-require': 2,
|
||||
'no-new-symbol': 2,
|
||||
'no-new-wrappers': 2,
|
||||
'no-obj-calls': 2,
|
||||
'no-octal': 2,
|
||||
'no-octal-escape': 2,
|
||||
'no-path-concat': 2,
|
||||
'no-proto': 2,
|
||||
'no-redeclare': 2,
|
||||
'no-regex-spaces': 2,
|
||||
'no-return-assign': [2, 'except-parens'],
|
||||
'no-self-assign': 2,
|
||||
'no-self-compare': 2,
|
||||
'no-sequences': 2,
|
||||
'no-shadow-restricted-names': 2,
|
||||
'no-spaced-func': 2,
|
||||
'no-sparse-arrays': 2,
|
||||
'no-this-before-super': 2,
|
||||
'no-throw-literal': 2,
|
||||
'no-trailing-spaces': 2,
|
||||
'no-undef': 2,
|
||||
'no-undef-init': 2,
|
||||
'no-unexpected-multiline': 2,
|
||||
'no-unmodified-loop-condition': 2,
|
||||
'no-unneeded-ternary': [2, {
|
||||
'defaultAssignment': false
|
||||
}],
|
||||
'no-unreachable': 2,
|
||||
'no-unsafe-finally': 2,
|
||||
'no-unused-vars': [2, {
|
||||
'vars': 'all',
|
||||
'args': 'none'
|
||||
}],
|
||||
'no-useless-call': 2,
|
||||
'no-useless-computed-key': 2,
|
||||
'no-useless-constructor': 2,
|
||||
'no-useless-escape': 0,
|
||||
'no-whitespace-before-property': 2,
|
||||
'no-with': 2,
|
||||
'one-var': [2, {
|
||||
'initialized': 'never'
|
||||
}],
|
||||
'operator-linebreak': [2, 'after', {
|
||||
'overrides': {
|
||||
'?': 'before',
|
||||
':': 'before'
|
||||
}
|
||||
}],
|
||||
'padded-blocks': [2, 'never'],
|
||||
'quotes': [2, 'single', {
|
||||
'avoidEscape': true,
|
||||
'allowTemplateLiterals': true
|
||||
}],
|
||||
'semi': [2, 'never'],
|
||||
'semi-spacing': [2, {
|
||||
'before': false,
|
||||
'after': true
|
||||
}],
|
||||
'space-before-blocks': [2, 'always'],
|
||||
'space-before-function-paren': [2, 'never'],
|
||||
'space-in-parens': [2, 'never'],
|
||||
'space-infix-ops': 2,
|
||||
'space-unary-ops': [2, {
|
||||
'words': true,
|
||||
'nonwords': false
|
||||
}],
|
||||
'spaced-comment': [2, 'always', {
|
||||
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
||||
}],
|
||||
'template-curly-spacing': [2, 'never'],
|
||||
'use-isnan': 2,
|
||||
'valid-typeof': 2,
|
||||
'wrap-iife': [2, 'any'],
|
||||
'yield-star-spacing': [2, 'both'],
|
||||
'yoda': [2, 'never'],
|
||||
'prefer-const': 2,
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||
'object-curly-spacing': [2, 'always', {
|
||||
objectsInObjects: false
|
||||
}],
|
||||
'array-bracket-spacing': [2, 'never']
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ruoyi",
|
||||
"version": "3.6.5",
|
||||
"version": "3.6.6",
|
||||
"description": "若依管理系统",
|
||||
"author": "若依",
|
||||
"license": "MIT",
|
||||
@@ -8,19 +8,7 @@
|
||||
"dev": "vue-cli-service serve",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
"lint": "eslint --ext .js,.vue src"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
"preview": "node build/index.js --preview"
|
||||
},
|
||||
"keywords": [
|
||||
"vue",
|
||||
@@ -56,23 +44,17 @@
|
||||
"vue": "2.6.12",
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-cropper": "0.5.5",
|
||||
"vue-meta": "2.4.0",
|
||||
"vue-router": "3.4.9",
|
||||
"vuedraggable": "2.24.3",
|
||||
"vuex": "3.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "4.4.6",
|
||||
"@vue/cli-plugin-eslint": "4.4.6",
|
||||
"@vue/cli-service": "4.4.6",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||
"chalk": "4.1.0",
|
||||
"compression-webpack-plugin": "6.1.2",
|
||||
"connect": "3.6.6",
|
||||
"eslint": "7.15.0",
|
||||
"eslint-plugin-vue": "7.2.0",
|
||||
"lint-staged": "10.5.3",
|
||||
"sass": "1.32.13",
|
||||
"sass-loader": "10.1.1",
|
||||
"script-ext-html-webpack-plugin": "2.1.5",
|
||||
|
||||
@@ -10,15 +10,7 @@ import ThemePicker from "@/components/ThemePicker"
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: { ThemePicker },
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
|
||||
titleTemplate: title => {
|
||||
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
|
||||
}
|
||||
}
|
||||
}
|
||||
components: { ThemePicker }
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
1
ruoyi-ui/src/assets/icons/svg/enter.svg
Normal file
1
ruoyi-ui/src/assets/icons/svg/enter.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746590936918" class="icon" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5378" xmlns:xlink="http://www.w3.org/1999/xlink" width="233.203125" height="200"><path d="M1151.9144 325.11999969V89.12a57.04000031 57.04000031 0 0 0-28.8-49.44 58.15999969 58.15999969 0 0 0-57.76000031 0 57.04000031 57.04000031 0 0 0-28.8 49.44v235.99999969c0.24 84.31999969-33.6 152.56000031-94.08 212.00000062-60.07999969 59.83999969-141.84 80.64-227.04 80.4H225.91440031L388.07439969 457.11999969a56.80000031 56.80000031 0 0 0 12.40000031-62.16 57.76000031 57.76000031 0 0 0-94.00000031-18.63999938L48.8744 631.20000031a56.88 56.88 0 0 0 0 80.79999938l264.96 262.56a58.08 58.08 0 0 0 96.55999969-25.59999938 56.80000031 56.80000031 0 0 0-14.95999969-55.2L232.07439969 731.67999969h483.44000062c116.56000031 0 226.15999969-32.08000031 308.64-113.76 82.15999969-80.80000031 128.23999969-178.15999969 127.83999938-292.87999969" p-id="5379"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
ruoyi-ui/src/assets/icons/svg/more-up.svg
Normal file
1
ruoyi-ui/src/assets/icons/svg/more-up.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746760911144" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12537" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M395.21211 182.914448c0 62.669318 49.541323 113.472378 110.642936 113.472378 61.093427 0 110.652146-50.80306 110.65214601-113.472378 0-62.685691-49.559742-113.487727-110.65214601-113.487727C444.75241 69.426721 395.21211 120.22978 395.21211 182.914448zM395.21211 523.34693101c0 62.668295 49.541323 113.487727 110.642936 113.48772699 61.093427 0 110.652146-50.820456 110.652146-113.487727 0-62.669318-49.559742-113.472378-110.652146-113.472378C444.75241 409.874553 395.21211 460.67761301 395.21211 523.34693101zM395.21211 841.084529c0 62.686714 49.541323 113.488751 110.642936 113.488751 61.093427 0 110.652146-50.80203599 110.65214601-113.488751 0-62.669318-49.559742-113.471354-110.65214601-113.471354C444.75241 727.614198 395.21211 778.416234 395.21211 841.084529z" p-id="12538"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -28,7 +28,7 @@
|
||||
</el-upload>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<transition-group ref="uploadFileList" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||
<el-link :href="file.url" :underline="false" target="_blank">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
@@ -84,7 +84,7 @@ export default {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 拖动排序
|
||||
// 拖动排序
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -102,9 +102,9 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.drag) {
|
||||
if (this.drag && !this.disabled) {
|
||||
this.$nextTick(() => {
|
||||
const element = document.querySelector('.upload-file-list')
|
||||
const element = this.$refs.uploadFileList?.$el || this.$refs.uploadFileList
|
||||
Sortable.create(element, {
|
||||
ghostClass: 'file-upload-darg',
|
||||
onEnd: (evt) => {
|
||||
|
||||
@@ -13,14 +13,17 @@
|
||||
ref="headerSearchSelectRef"
|
||||
size="large"
|
||||
@input="querySearch"
|
||||
prefix-icon="Search"
|
||||
prefix-icon="el-icon-search"
|
||||
placeholder="菜单搜索,支持标题、URL模糊查询"
|
||||
clearable
|
||||
@keyup.enter.native="selectActiveResult"
|
||||
@keydown.up.native="navigateResult('up')"
|
||||
@keydown.down.native="navigateResult('down')"
|
||||
>
|
||||
</el-input>
|
||||
<el-scrollbar wrap-class="right-scrollbar-wrapper">
|
||||
<div class="result-wrap">
|
||||
<div class="search-item" v-for="item in options" :key="item.path">
|
||||
<div class="search-item" v-for="(item, index) in options" :key="item.path" :style="activeStyle(index)" @mouseenter="activeIndex = index" @mouseleave="activeIndex = -1">
|
||||
<div class="left">
|
||||
<svg-icon class="menu-icon" :icon-class="item.icon" />
|
||||
</div>
|
||||
@@ -32,6 +35,7 @@
|
||||
{{ item.path }}
|
||||
</div>
|
||||
</div>
|
||||
<svg-icon icon-class="enter" v-show="index === activeIndex"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
@@ -51,11 +55,15 @@ export default {
|
||||
search: '',
|
||||
options: [],
|
||||
searchPool: [],
|
||||
activeIndex: -1,
|
||||
show: false,
|
||||
fuse: undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
theme() {
|
||||
return this.$store.state.settings.theme
|
||||
},
|
||||
routes() {
|
||||
return this.$store.getters.defaultRoutes
|
||||
}
|
||||
@@ -84,6 +92,7 @@ export default {
|
||||
this.search = ''
|
||||
this.options = []
|
||||
this.show = false
|
||||
this.activeIndex = -1
|
||||
},
|
||||
change(val) {
|
||||
const path = val.path
|
||||
@@ -162,11 +171,31 @@ export default {
|
||||
return res
|
||||
},
|
||||
querySearch(query) {
|
||||
this.activeIndex = -1
|
||||
if (query !== '') {
|
||||
this.options = this.fuse.search(query).map((item) => item.item) ?? this.searchPool
|
||||
} else {
|
||||
this.options = this.searchPool
|
||||
}
|
||||
},
|
||||
activeStyle(index) {
|
||||
if (index !== this.activeIndex) return {}
|
||||
return {
|
||||
"background-color": this.theme,
|
||||
"color": "#fff"
|
||||
}
|
||||
},
|
||||
navigateResult(direction) {
|
||||
if (direction === "up") {
|
||||
this.activeIndex = this.activeIndex <= 0 ? this.options.length - 1 : this.activeIndex - 1
|
||||
} else if (direction === "down") {
|
||||
this.activeIndex = this.activeIndex >= this.options.length - 1 ? 0 : this.activeIndex + 1
|
||||
}
|
||||
},
|
||||
selectActiveResult() {
|
||||
if (this.options.length > 0 && this.activeIndex >= 0) {
|
||||
this.change(this.options[this.activeIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,11 +218,13 @@ export default {
|
||||
|
||||
.result-wrap {
|
||||
height: 280px;
|
||||
margin: 12px 0;
|
||||
margin: 6px 0;
|
||||
|
||||
.search-item {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
align-items: center;
|
||||
padding-right: 10px;
|
||||
|
||||
.left {
|
||||
width: 60px;
|
||||
@@ -202,16 +233,17 @@ export default {
|
||||
.menu-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-info {
|
||||
padding-left: 5px;
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
flex: 1;
|
||||
|
||||
.menu-title,
|
||||
.menu-path {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
multiple
|
||||
:disabled="disabled"
|
||||
:action="uploadImgUrl"
|
||||
list-type="picture-card"
|
||||
:on-success="handleUploadSuccess"
|
||||
@@ -22,7 +23,7 @@
|
||||
</el-upload>
|
||||
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip && !disabled">
|
||||
请上传
|
||||
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||
@@ -79,7 +80,12 @@ export default {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 拖动排序
|
||||
// 禁用组件(仅查看图片)
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 拖动排序
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
@@ -100,9 +106,9 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.drag) {
|
||||
if (this.drag && !this.disabled) {
|
||||
this.$nextTick(() => {
|
||||
const element = document.querySelector('.el-upload-list')
|
||||
const element = this.$refs.imageUpload?.$el?.querySelector('.el-upload-list')
|
||||
Sortable.create(element, {
|
||||
onEnd: (evt) => {
|
||||
const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]
|
||||
@@ -239,12 +245,17 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
// .el-upload--picture-card 控制加号部分
|
||||
::v-deep.hide .el-upload--picture-card {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep .el-upload-list--picture-card.is-disabled + .el-upload--picture-card {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// 去掉动画效果
|
||||
::v-deep .el-list-enter-active,
|
||||
::v-deep .el-list-leave-active {
|
||||
transition: all 0s;
|
||||
transition: all 0s;
|
||||
}
|
||||
|
||||
::v-deep .el-list-enter, .el-list-leave-active {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line -->
|
||||
<div :style="{backgroundImage: `url(${image})`}" class="pan-thumb"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
<template>
|
||||
<div ref="rightPanel" class="rightPanel-container">
|
||||
<div class="rightPanel-background" />
|
||||
<div class="rightPanel">
|
||||
<div class="rightPanel-items">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RightPanel',
|
||||
props: {
|
||||
clickNotClose: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
show: {
|
||||
get() {
|
||||
return this.$store.state.settings.showSettings
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch('settings/changeSetting', {
|
||||
key: 'showSettings',
|
||||
value: val
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(value) {
|
||||
if (value && !this.clickNotClose) {
|
||||
this.addEventClick()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.addEventClick()
|
||||
},
|
||||
beforeDestroy() {
|
||||
const elx = this.$refs.rightPanel
|
||||
elx.remove()
|
||||
},
|
||||
methods: {
|
||||
addEventClick() {
|
||||
window.addEventListener('click', this.closeSidebar)
|
||||
},
|
||||
closeSidebar(evt) {
|
||||
const parent = evt.target.closest('.el-drawer__body')
|
||||
if (!parent) {
|
||||
this.show = false
|
||||
window.removeEventListener('click', this.closeSidebar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rightPanel-background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
|
||||
background: rgba(0, 0, 0, .2);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
width: 100%;
|
||||
max-width: 260px;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
|
||||
transition: all .25s cubic-bezier(.7, .3, .1, 1);
|
||||
transform: translate(100%);
|
||||
background: #fff;
|
||||
z-index: 40000;
|
||||
}
|
||||
|
||||
.handle-button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: absolute;
|
||||
left: -48px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
border-radius: 6px 0 0 6px !important;
|
||||
z-index: 0;
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
line-height: 48px;
|
||||
i {
|
||||
font-size: 24px;
|
||||
line-height: 48px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -17,7 +17,7 @@ const install = function(Vue) {
|
||||
if (window.Vue) {
|
||||
window['hasRole'] = hasRole
|
||||
window['hasPermi'] = hasPermi
|
||||
Vue.use(install) // eslint-disable-line
|
||||
Vue.use(install)
|
||||
}
|
||||
|
||||
export default install
|
||||
|
||||
@@ -6,15 +6,17 @@
|
||||
</keep-alive>
|
||||
</transition>
|
||||
<iframe-toggle />
|
||||
<copyright />
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import copyright from "./Copyright/index"
|
||||
import iframeToggle from "./IframeToggle/index"
|
||||
|
||||
export default {
|
||||
name: 'AppMain',
|
||||
components: { iframeToggle },
|
||||
components: { iframeToggle, copyright },
|
||||
computed: {
|
||||
cachedViews() {
|
||||
return this.$store.state.tagsView.cachedViews
|
||||
@@ -33,7 +35,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
addIframe() {
|
||||
const {name} = this.$route
|
||||
const { name } = this.$route
|
||||
if (name && this.$route.meta.link) {
|
||||
this.$store.dispatch('tagsView/addIframeView', this.$route)
|
||||
}
|
||||
@@ -51,6 +53,10 @@ export default {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-main:has(.copyright) {
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
|
||||
.fixed-header + .app-main {
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
35
ruoyi-ui/src/layout/components/Copyright/index.vue
Normal file
35
ruoyi-ui/src/layout/components/Copyright/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<footer v-if="visible" class="copyright">
|
||||
<span>{{ content }}</span>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
visible() {
|
||||
return this.$store.state.settings.footerVisible
|
||||
},
|
||||
content() {
|
||||
return this.$store.state.settings.footerContent
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.copyright {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 36px;
|
||||
padding: 10px 20px;
|
||||
text-align: right;
|
||||
background-color: #f8f8f8;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
border-top: 1px solid #e7e7e7;
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
||||
@@ -25,23 +25,24 @@
|
||||
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="hover">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="avatar" class="user-avatar">
|
||||
<i class="el-icon-caret-bottom" />
|
||||
<span class="user-nickname"> {{ nickName }} </span>
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
<el-dropdown-item @click.native="setting = true">
|
||||
<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>
|
||||
@@ -58,6 +59,7 @@ import RuoYiGit from '@/components/RuoYi/Git'
|
||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||
|
||||
export default {
|
||||
emits: ['setLayout'],
|
||||
components: {
|
||||
Breadcrumb,
|
||||
TopNav,
|
||||
@@ -72,17 +74,12 @@ export default {
|
||||
...mapGetters([
|
||||
'sidebar',
|
||||
'avatar',
|
||||
'device'
|
||||
'device',
|
||||
'nickName'
|
||||
]),
|
||||
setting: {
|
||||
get() {
|
||||
return this.$store.state.settings.showSettings
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch('settings/changeSetting', {
|
||||
key: 'showSettings',
|
||||
value: val
|
||||
})
|
||||
}
|
||||
},
|
||||
topNav: {
|
||||
@@ -95,6 +92,9 @@ export default {
|
||||
toggleSideBar() {
|
||||
this.$store.dispatch('app/toggleSideBar')
|
||||
},
|
||||
setLayout(event) {
|
||||
this.$emit('setLayout')
|
||||
},
|
||||
logout() {
|
||||
this.$confirm('确定注销并退出系统吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -173,17 +173,25 @@ export default {
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 30px;
|
||||
margin-right: 0px;
|
||||
padding-right: 0px;
|
||||
|
||||
.avatar-wrapper {
|
||||
margin-top: 5px;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
|
||||
.user-avatar {
|
||||
cursor: pointer;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-nickname{
|
||||
position: relative;
|
||||
bottom: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-icon-caret-bottom {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-drawer size="280px" :visible="visible" :with-header="false" :append-to-body="true" :show-close="false">
|
||||
<el-drawer size="280px" :visible="showSettings" :with-header="false" :append-to-body="true" :before-close="closeSetting" :lock-scroll="false">
|
||||
<div class="drawer-container">
|
||||
<div>
|
||||
<div class="setting-drawer-content">
|
||||
@@ -49,6 +49,11 @@
|
||||
<el-switch v-model="tagsView" class="drawer-switch" />
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示页签图标</span>
|
||||
<el-switch v-model="tagsIcon" :disabled="!tagsView" class="drawer-switch" />
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>固定 Header</span>
|
||||
<el-switch v-model="fixedHeader" class="drawer-switch" />
|
||||
@@ -64,6 +69,11 @@
|
||||
<el-switch v-model="dynamicTitle" class="drawer-switch" />
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>底部版权</span>
|
||||
<el-switch v-model="footerVisible" class="drawer-switch" />
|
||||
</div>
|
||||
|
||||
<el-divider/>
|
||||
|
||||
<el-button size="small" type="primary" plain icon="el-icon-document-add" @click="saveSetting">保存配置</el-button>
|
||||
@@ -78,18 +88,15 @@ import ThemePicker from '@/components/ThemePicker'
|
||||
|
||||
export default {
|
||||
components: { ThemePicker },
|
||||
expose: ['openSetting'],
|
||||
data() {
|
||||
return {
|
||||
theme: this.$store.state.settings.theme,
|
||||
sideTheme: this.$store.state.settings.sideTheme
|
||||
sideTheme: this.$store.state.settings.sideTheme,
|
||||
showSettings: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get() {
|
||||
return this.$store.state.settings.showSettings
|
||||
}
|
||||
},
|
||||
fixedHeader: {
|
||||
get() {
|
||||
return this.$store.state.settings.fixedHeader
|
||||
@@ -127,6 +134,17 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
tagsIcon: {
|
||||
get() {
|
||||
return this.$store.state.settings.tagsIcon
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch('settings/changeSetting', {
|
||||
key: 'tagsIcon',
|
||||
value: val
|
||||
})
|
||||
}
|
||||
},
|
||||
sidebarLogo: {
|
||||
get() {
|
||||
return this.$store.state.settings.sidebarLogo
|
||||
@@ -147,8 +165,20 @@ export default {
|
||||
key: 'dynamicTitle',
|
||||
value: val
|
||||
})
|
||||
this.$store.dispatch('settings/setTitle', this.$store.state.settings.title)
|
||||
}
|
||||
},
|
||||
footerVisible: {
|
||||
get() {
|
||||
return this.$store.state.settings.footerVisible
|
||||
},
|
||||
set(val) {
|
||||
this.$store.dispatch('settings/changeSetting', {
|
||||
key: 'footerVisible',
|
||||
value: val
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
themeChange(val) {
|
||||
@@ -165,6 +195,12 @@ export default {
|
||||
})
|
||||
this.sideTheme = val
|
||||
},
|
||||
openSetting() {
|
||||
this.showSettings = true
|
||||
},
|
||||
closeSetting(){
|
||||
this.showSettings = false
|
||||
},
|
||||
saveSetting() {
|
||||
this.$modal.loading("正在保存到本地,请稍候...")
|
||||
this.$cache.local.set(
|
||||
@@ -172,9 +208,11 @@ export default {
|
||||
`{
|
||||
"topNav":${this.topNav},
|
||||
"tagsView":${this.tagsView},
|
||||
"tagsIcon":${this.tagsIcon},
|
||||
"fixedHeader":${this.fixedHeader},
|
||||
"sidebarLogo":${this.sidebarLogo},
|
||||
"dynamicTitle":${this.dynamicTitle},
|
||||
"footerVisible":${this.footerVisible},
|
||||
"sideTheme":"${this.sideTheme}",
|
||||
"theme":"${this.theme}"
|
||||
}`
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
v-for="tag in visitedViews"
|
||||
ref="tag"
|
||||
:key="tag.path"
|
||||
:class="isActive(tag)?'active':''"
|
||||
:class="{ 'active': isActive(tag), 'has-icon': tagsIcon }"
|
||||
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||
tag="span"
|
||||
class="tags-view-item"
|
||||
@@ -13,6 +13,7 @@
|
||||
@click.middle.native="!isAffix(tag)?closeSelectedTag(tag):''"
|
||||
@contextmenu.prevent.native="openMenu(tag,$event)"
|
||||
>
|
||||
<svg-icon v-if="tagsIcon && tag.meta && tag.meta.icon && tag.meta.icon !== '#'" :icon-class="tag.meta.icon" />
|
||||
{{ tag.title }}
|
||||
<span v-if="!isAffix(tag)" class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||
</router-link>
|
||||
@@ -52,6 +53,9 @@ export default {
|
||||
},
|
||||
theme() {
|
||||
return this.$store.state.settings.theme
|
||||
},
|
||||
tagsIcon() {
|
||||
return this.$store.state.settings.tagsIcon
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -277,6 +281,11 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tags-view-item.active.has-icon::before {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
|
||||
@@ -4,19 +4,16 @@
|
||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||||
<div :class="{'fixed-header':fixedHeader}">
|
||||
<navbar/>
|
||||
<navbar @setLayout="setLayout"/>
|
||||
<tags-view v-if="needTagsView"/>
|
||||
</div>
|
||||
<app-main/>
|
||||
<right-panel>
|
||||
<settings/>
|
||||
</right-panel>
|
||||
<settings ref="settingRef"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RightPanel from '@/components/RightPanel'
|
||||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
||||
import ResizeMixin from './mixin/ResizeHandler'
|
||||
import { mapState } from 'vuex'
|
||||
@@ -27,7 +24,6 @@ export default {
|
||||
components: {
|
||||
AppMain,
|
||||
Navbar,
|
||||
RightPanel,
|
||||
Settings,
|
||||
Sidebar,
|
||||
TagsView
|
||||
@@ -57,6 +53,9 @@ export default {
|
||||
methods: {
|
||||
handleClickOutside() {
|
||||
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
||||
},
|
||||
setLayout() {
|
||||
this.$refs.settingRef.openSetting()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ import ImageUpload from "@/components/ImageUpload"
|
||||
import ImagePreview from "@/components/ImagePreview"
|
||||
// 字典标签组件
|
||||
import DictTag from '@/components/DictTag'
|
||||
// 头部标签组件
|
||||
import VueMeta from 'vue-meta'
|
||||
// 字典数据组件
|
||||
import DictData from '@/components/DictData'
|
||||
|
||||
@@ -60,7 +58,6 @@ Vue.component('ImagePreview', ImagePreview)
|
||||
|
||||
Vue.use(directive)
|
||||
Vue.use(plugins)
|
||||
Vue.use(VueMeta)
|
||||
DictData.install()
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
module.exports = {
|
||||
/**
|
||||
* 网页标题
|
||||
*/
|
||||
title: process.env.VUE_APP_TITLE,
|
||||
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
* 系统布局配置
|
||||
*/
|
||||
showSettings: false,
|
||||
showSettings: true,
|
||||
|
||||
/**
|
||||
* 是否显示顶部导航
|
||||
@@ -18,6 +23,11 @@ module.exports = {
|
||||
* 是否显示 tagsView
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 显示页签图标
|
||||
*/
|
||||
tagsIcon: false,
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
@@ -35,10 +45,12 @@ module.exports = {
|
||||
dynamicTitle: false,
|
||||
|
||||
/**
|
||||
* @type {string | array} 'production' | ['production', 'development']
|
||||
* @description Need show err logs component.
|
||||
* The default is only used in the production env
|
||||
* If you want to also use it in dev, you can pass ['production', 'development']
|
||||
* 是否显示底部版权
|
||||
*/
|
||||
errorLog: 'production'
|
||||
footerVisible: false,
|
||||
|
||||
/**
|
||||
* 底部版权文本内容
|
||||
*/
|
||||
footerContent: 'Copyright © 2018-2025 RuoYi. All Rights Reserved.'
|
||||
}
|
||||
|
||||
@@ -7,13 +7,15 @@ const getters = {
|
||||
cachedViews: state => state.tagsView.cachedViews,
|
||||
token: state => state.user.token,
|
||||
avatar: state => state.user.avatar,
|
||||
id: state => state.user.id,
|
||||
name: state => state.user.name,
|
||||
nickName: state => state.user.nickName,
|
||||
introduction: state => state.user.introduction,
|
||||
roles: state => state.user.roles,
|
||||
permissions: state => state.user.permissions,
|
||||
permission_routes: state => state.permission.routes,
|
||||
topbarRouters:state => state.permission.topbarRouters,
|
||||
defaultRoutes:state => state.permission.defaultRoutes,
|
||||
sidebarRouters:state => state.permission.sidebarRouters
|
||||
topbarRouters: state => state.permission.topbarRouters,
|
||||
defaultRoutes: state => state.permission.defaultRoutes,
|
||||
sidebarRouters: state => state.permission.sidebarRouters
|
||||
}
|
||||
export default getters
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import defaultSettings from '@/settings'
|
||||
import { useDynamicTitle } from '@/utils/dynamicTitle'
|
||||
|
||||
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
|
||||
const { sideTheme, showSettings, topNav, tagsView, tagsIcon, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
|
||||
|
||||
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
|
||||
const state = {
|
||||
@@ -10,9 +11,12 @@ const state = {
|
||||
showSettings: showSettings,
|
||||
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
||||
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
|
||||
tagsIcon: storageSetting.tagsIcon === undefined ? tagsIcon : storageSetting.tagsIcon,
|
||||
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
|
||||
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
|
||||
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
|
||||
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle,
|
||||
footerVisible: storageSetting.footerVisible === undefined ? footerVisible : storageSetting.footerVisible,
|
||||
footerContent: footerContent
|
||||
}
|
||||
const mutations = {
|
||||
CHANGE_SETTING: (state, { key, value }) => {
|
||||
@@ -30,6 +34,7 @@ const actions = {
|
||||
// 设置网页标题
|
||||
setTitle({ commit }, title) {
|
||||
state.title = title
|
||||
useDynamicTitle()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import router from '@/router'
|
||||
import { MessageBox, } from 'element-ui'
|
||||
import { login, logout, getInfo, refreshToken } from '@/api/login'
|
||||
import { getToken, setToken, setExpiresIn, removeToken } from '@/utils/auth'
|
||||
import { isEmpty } from "@/utils/validate"
|
||||
@@ -8,6 +10,7 @@ const user = {
|
||||
token: getToken(),
|
||||
id: '',
|
||||
name: '',
|
||||
nickName: '',
|
||||
avatar: '',
|
||||
roles: [],
|
||||
permissions: []
|
||||
@@ -26,6 +29,9 @@ const user = {
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name
|
||||
},
|
||||
SET_NICK_NAME: (state, nickName) => {
|
||||
state.nickName = nickName
|
||||
},
|
||||
SET_AVATAR: (state, avatar) => {
|
||||
state.avatar = avatar
|
||||
},
|
||||
@@ -72,7 +78,20 @@ const user = {
|
||||
}
|
||||
commit('SET_ID', user.userId)
|
||||
commit('SET_NAME', user.userName)
|
||||
commit('SET_NICK_NAME', user.nickName)
|
||||
commit('SET_AVATAR', avatar)
|
||||
/* 初始密码提示 */
|
||||
if(res.isDefaultModifyPwd) {
|
||||
MessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||
}).catch(() => {})
|
||||
}
|
||||
/* 过期密码提示 */
|
||||
if(!res.isDefaultModifyPwd && res.isPasswordExpired) {
|
||||
MessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => {
|
||||
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
|
||||
}).catch(() => {})
|
||||
}
|
||||
resolve(res)
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
|
||||
13
ruoyi-ui/src/utils/dynamicTitle.js
Normal file
13
ruoyi-ui/src/utils/dynamicTitle.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import store from '@/store'
|
||||
import defaultSettings from '@/settings'
|
||||
|
||||
/**
|
||||
* 动态修改标题
|
||||
*/
|
||||
export function useDynamicTitle() {
|
||||
if (store.state.settings.dynamicTitle) {
|
||||
document.title = store.state.settings.title + ' - ' + defaultSettings.title
|
||||
} else {
|
||||
document.title = defaultSettings.title
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable max-len */
|
||||
import { trigger } from './config'
|
||||
|
||||
let confGlobal
|
||||
|
||||
@@ -108,6 +108,53 @@
|
||||
<span>更新日志</span>
|
||||
</div>
|
||||
<el-collapse accordion>
|
||||
<el-collapse-item title="v3.6.6 - 2025-05-30">
|
||||
<ol>
|
||||
<li>优化菜单搜索查询页</li>
|
||||
<li>导航栏显示昵称&设置</li>
|
||||
<li>用户管理支持分栏拖动</li>
|
||||
<li>修改主题样式本地读取</li>
|
||||
<li>菜单管理新增路由名称</li>
|
||||
<li>添加底部版权信息&开关</li>
|
||||
<li>分配角色禁用不允许勾选</li>
|
||||
<li>添加页签图标显示开关功能</li>
|
||||
<li>用户管理过滤掉已禁用部门</li>
|
||||
<li>上传组件新增拖动排序属性</li>
|
||||
<li>显隐列组件支持全选/全不选</li>
|
||||
<li>白名单支持对通配符路径匹配</li>
|
||||
<li>初始密码支持自定义修改策略</li>
|
||||
<li>账号密码支持自定义更新周期</li>
|
||||
<li>菜单面包屑导航支持多层级显示</li>
|
||||
<li>支持富文本复制粘贴图片上传至url</li>
|
||||
<li>支持文件&图片组件自定义地址&参数</li>
|
||||
<li>更新ry-config的nacos表结构到最新版本</li>
|
||||
<li>代码生成新增配置是否允许文件覆盖到本地</li>
|
||||
<li>使用CacheRequestBody代替CacheRequestFilter</li>
|
||||
<li>升级tomcat到最新版本9.0.105</li>
|
||||
<li>升级fastjson到最新版2.0.57</li>
|
||||
<li>升级commons.io到最新版本2.19.0</li>
|
||||
<li>package.json移除runjs&eslint&vue-meta依赖</li>
|
||||
<li>修复导出子列表对象只能在最后的问题</li>
|
||||
<li>修复TopNav无法正确获取active的问题</li>
|
||||
<li>修复默认关闭Tags-Views内链页面打不开</li>
|
||||
<li>Excel注解支持wrapText是否允许内容换行</li>
|
||||
<li>优化文件上传组件新增类型</li>
|
||||
<li>优化导入带标题文件关闭清理</li>
|
||||
<li>优化参数键值更换为多行文本</li>
|
||||
<li>优化特殊字符密码修改失败问题</li>
|
||||
<li>优化代码生成列表支持按时间排序</li>
|
||||
<li>优化TopNav内链菜单点击没有高亮</li>
|
||||
<li>优化文件异常输入流未关闭的问题</li>
|
||||
<li>优化菜单管理切换Mini布局错乱问题</li>
|
||||
<li>优化空指针异常时无法获取错误信息问题</li>
|
||||
<li>优化文件&图片上传组件新增disabled属性</li>
|
||||
<li>优化isAdmin方法,避免脱敏模块security依赖</li>
|
||||
<li>优化定时任务字符包含多个括号导致数据错误</li>
|
||||
<li>优化登录&注册页表头使用VUE_APP_TITLE配置值</li>
|
||||
<li>优化导出Excel日期格式双击离开后与设定的格式不一致问题</li>
|
||||
<li>其他细节优化</li>
|
||||
</ol>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="v3.6.5 - 2024-11-13">
|
||||
<ol>
|
||||
<li>使用SpringDoc代替Swagger</li>
|
||||
@@ -909,7 +956,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
// 版本号
|
||||
version: "3.6.5"
|
||||
version: "3.6.6"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<div slot="header" class="clearfix">
|
||||
<span>基本资料</span>
|
||||
</div>
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tabs v-model="selectedTab">
|
||||
<el-tab-pane label="基本资料" name="userinfo">
|
||||
<userInfo :user="user" />
|
||||
</el-tab-pane>
|
||||
@@ -72,10 +72,14 @@ export default {
|
||||
user: {},
|
||||
roleGroup: {},
|
||||
postGroup: {},
|
||||
activeTab: "userinfo"
|
||||
selectedTab: "userinfo"
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const activeTab = this.$route.params && this.$route.params.activeTab
|
||||
if (activeTab) {
|
||||
this.selectedTab = activeTab
|
||||
}
|
||||
this.getUser()
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -115,7 +115,6 @@ export default {
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
// eslint-disable-next-line func-names
|
||||
'formData.value': function (val) {
|
||||
this.dataType = isNumberStr(val) ? 'number' : 'string'
|
||||
}
|
||||
|
||||
@@ -190,7 +190,6 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// eslint-disable-next-line func-names
|
||||
'activeData.label': function (val, oldVal) {
|
||||
if (
|
||||
this.activeData.placeholder === undefined
|
||||
|
||||
@@ -6,13 +6,8 @@
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="字段信息" name="columnInfo">
|
||||
<el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
|
||||
<el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag" />
|
||||
<el-table-column
|
||||
label="字段列名"
|
||||
prop="columnName"
|
||||
min-width="10%"
|
||||
:show-overflow-tooltip="true"
|
||||
/>
|
||||
<el-table-column label="序号" type="index" min-width="5%" class-name="allowDrag"/>
|
||||
<el-table-column label="字段列名" prop="columnName" min-width="10%" :show-overflow-tooltip="true" class-name="allowDrag"/>
|
||||
<el-table-column label="字段描述" min-width="10%">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.columnComment"></el-input>
|
||||
|
||||
@@ -23,8 +23,6 @@ module.exports = {
|
||||
outputDir: 'dist',
|
||||
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
|
||||
assetsDir: 'static',
|
||||
// 是否开启eslint保存检测,有效值:ture | false | 'error'
|
||||
lintOnSave: process.env.NODE_ENV === 'development',
|
||||
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
|
||||
productionSourceMap: false,
|
||||
transpileDependencies: ['quill'],
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-visual</artifactId>
|
||||
<version>3.6.5</version>
|
||||
<version>3.6.6</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ create table sys_user (
|
||||
del_flag char(1) default '0' comment '删除标志(0代表存在 2代表删除)',
|
||||
login_ip varchar(128) default '' comment '最后登录IP',
|
||||
login_date datetime comment '最后登录时间',
|
||||
pwd_update_date datetime comment '密码最后更新时间',
|
||||
create_by varchar(64) default '' comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by varchar(64) default '' comment '更新者',
|
||||
@@ -67,8 +68,8 @@ create table sys_user (
|
||||
-- ----------------------------
|
||||
-- 初始化-用户信息表数据
|
||||
-- ----------------------------
|
||||
insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员');
|
||||
insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员');
|
||||
insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', null, '管理员');
|
||||
insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', null, '测试员');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
@@ -544,11 +545,13 @@ create table sys_config (
|
||||
primary key (config_id)
|
||||
) engine=innodb auto_increment=100 comment = '参数配置表';
|
||||
|
||||
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
|
||||
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
|
||||
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' );
|
||||
insert into sys_config values(4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)');
|
||||
insert into sys_config values(5, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)');
|
||||
insert into sys_config values(1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', sysdate(), '', null, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow' );
|
||||
insert into sys_config values(2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', sysdate(), '', null, '初始化密码 123456' );
|
||||
insert into sys_config values(3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', sysdate(), '', null, '深色主题theme-dark,浅色主题theme-light' );
|
||||
insert into sys_config values(4, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', sysdate(), '', null, '是否开启注册用户功能(true开启,false关闭)');
|
||||
insert into sys_config values(5, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', sysdate(), '', null, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)');
|
||||
insert into sys_config values(6, '用户管理-初始密码修改策略', 'sys.account.initPasswordModify', '1', 'Y', 'admin', sysdate(), '', null, '0:初始密码修改策略关闭,没有任何提示,1:提醒用户,如果未修改初始密码,则在登录时就会提醒修改密码对话框');
|
||||
insert into sys_config values(7, '用户管理-账号密码更新周期', 'sys.account.passwordValidateDays', '0', 'Y', 'admin', sysdate(), '', null, '密码更新周期(填写数字,数据初始化值为0不限制,若修改必须为大于0小于365的正整数),如果超过这个周期登录系统时,则在登录时就会提醒修改密码对话框');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
Reference in New Issue
Block a user