发布 2.3.1

This commit is contained in:
疯狂的狮子li 2021-06-04 16:20:12 +08:00
parent d87eb34352
commit 801f7cd8f7
25 changed files with 331 additions and 40 deletions

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2018 RuoYi Copyright (c) 2019 RuoYi-Vue-Plus
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in
@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,4 +1,7 @@
## 平台简介 ## 平台简介
[![码云Gitee](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/badge/star.svg?theme=blue)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
基于 RuoYi-Vue 集成 Mybatis-Plus Lombok Hutool 等便捷开发工具 适配重写相关业务 便于开发 定期与 RuoYi-Vue 同步 基于 RuoYi-Vue 集成 Mybatis-Plus Lombok Hutool 等便捷开发工具 适配重写相关业务 便于开发 定期与 RuoYi-Vue 同步
* 前端开发框架 Vue、Element UI * 前端开发框架 Vue、Element UI
@ -19,7 +22,7 @@
### 依赖改动 ### 依赖改动
* ORM框架 使用 Mybatis-Plus 3.4.2 简化CRUD (不支持主子表) * ORM框架 使用 Mybatis-Plus 简化CRUD (不支持主子表)
* Bean简化 使用 Lombok 简化 get set toString 等等 * Bean简化 使用 Lombok 简化 get set toString 等等
* 容器改动 Tomcat 改为 并发性能更好的 undertow * 容器改动 Tomcat 改为 并发性能更好的 undertow
* 分页移除 pagehelper 改为 Mybatis-Plus 分页 * 分页移除 pagehelper 改为 Mybatis-Plus 分页
@ -45,10 +48,11 @@
* 同步升级 RuoYi-Vue 3.5.0 * 同步升级 RuoYi-Vue 3.5.0
* 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) * 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/)
* Oracle 模块 oracle 分支 [RuoYi-Vue-Plus-oracle](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/oracle/)
## 关注作者(扫码请备注: "加群") ## 关注作者(扫码请备注: "加群")
![](https://images.gitee.com/uploads/images/2021/0508/235345_5503356a_1766278.jpeg) ![作者图片](https://images.gitee.com/uploads/images/2021/0508/235345_5503356a_1766278.jpeg)
## 捐献作者 ## 捐献作者
作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭 作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭

View File

@ -1,6 +1,6 @@
{ {
"name": "ruoyi-vue-plus", "name": "ruoyi-vue-plus",
"version": "2.3.0", "version": "2.3.1",
"description": "RuoYi-Vue-Plus后台管理系统", "description": "RuoYi-Vue-Plus后台管理系统",
"author": "LionLi", "author": "LionLi",
"license": "MIT", "license": "MIT",

View File

@ -152,7 +152,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -168,6 +168,8 @@ export default {
}, },
data() { data() {
return { return {
//loading
buttonLoading: false,
// //
loading: true, loading: true,
// //
@ -277,9 +279,11 @@ export default {
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.loading = true;
this.reset(); this.reset();
const id = row.id || this.ids const id = row.id || this.ids
getDemo(id).then(response => { getDemo(id).then(response => {
this.loading = false;
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改测试单表"; this.title = "修改测试单表";
@ -289,14 +293,17 @@ export default {
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
this.buttonLoading = true;
if (this.form.id != null) { if (this.form.id != null) {
updateDemo(this.form).then(response => { updateDemo(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("修改成功"); this.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addDemo(this.form).then(response => { addDemo(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("新增成功"); this.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
@ -312,9 +319,11 @@ export default {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(() => {
this.loading = true;
return delDemo(ids); return delDemo(ids);
}).then(() => { }).then(() => {
this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) })

View File

@ -102,7 +102,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button> <el-button @click="cancel"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -121,6 +121,8 @@ export default {
}, },
data() { data() {
return { return {
//loading
buttonLoading: false,
// //
loading: true, loading: true,
// //
@ -233,12 +235,14 @@ export default {
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.loading = true;
this.reset(); this.reset();
this.getTreeselect(); this.getTreeselect();
if (row != null) { if (row != null) {
this.form.parentId = row.id; this.form.parentId = row.id;
} }
getTree(row.id).then(response => { getTree(row.id).then(response => {
this.loading = false;
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改测试树表"; this.title = "修改测试树表";
@ -248,14 +252,17 @@ export default {
submitForm() { submitForm() {
this.$refs["form"].validate(valid => { this.$refs["form"].validate(valid => {
if (valid) { if (valid) {
this.buttonLoading = true;
if (this.form.id != null) { if (this.form.id != null) {
updateTree(this.form).then(response => { updateTree(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("修改成功"); this.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
addTree(this.form).then(response => { addTree(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("新增成功"); this.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
@ -270,9 +277,11 @@ export default {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(() => {
this.loading = true;
return delTree(row.id); return delTree(row.id);
}).then(() => { }).then(() => {
this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) })

View File

@ -80,6 +80,18 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v2.3.1 - 2021-6-4">
<ol>
<li>add 增加 redisson 分布式锁 注解与demo案例</li>
<li>add 增加 Oracle 分支</li>
<li>update 优化 redis 空密码兼容性</li>
<li>update 优化前端代码生成按钮增加 loading</li>
<li>fix 修复 redisson 不能批量删除的bug</li>
<li>fix 修复表单构建选择下拉选择控制台报错问题</li>
<li>fix 修复 vo 代码生成 主键列表显示 重复生成bug</li>
<li>fix 修复上传路径 win 打包编译为 win 路径, linux 报错bug</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.3.0 - 2021-6-1"> <el-collapse-item title="v2.3.0 - 2021-6-1">
<ol> <ol>
<li>add 升级 luttuce redisson 性能更强 工具更全</li> <li>add 升级 luttuce redisson 性能更强 工具更全</li>
@ -195,12 +207,14 @@
</template> </template>
<script> <script>
import config from '../../package.json'
export default { export default {
name: "index", name: "index",
data() { data() {
return { return {
// //
version: "2.3.0", version: config.version,
}; };
}, },
methods: { methods: {

View File

@ -163,7 +163,7 @@
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item v-if="form.menuType != 'M'" label="权限标识"> <el-form-item v-if="form.menuType != 'M'" label="权限标识">
<el-input v-model="form.perms" placeholder="请权限标识" maxlength="50" /> <el-input v-model="form.perms" placeholder="请权限标识" maxlength="100" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">

View File

@ -573,6 +573,7 @@
<script> <script>
import { isArray } from 'util' import { isArray } from 'util'
import draggable from 'vuedraggable'
import TreeNodeDialog from './TreeNodeDialog' import TreeNodeDialog from './TreeNodeDialog'
import { isNumberStr } from '@/utils/index' import { isNumberStr } from '@/utils/index'
import IconsDialog from './IconsDialog' import IconsDialog from './IconsDialog'
@ -595,6 +596,7 @@ const dateTimeFormat = {
export default { export default {
components: { components: {
draggable,
TreeNodeDialog, TreeNodeDialog,
IconsDialog IconsDialog
}, },

View File

@ -0,0 +1,27 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 分布式锁注解模式不推荐使用最好用锁的工具类
*
* @author shenxinquan
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RedisLock {
/**
* 锁过期时间 默认30秒
*/
int expireTime() default 30;
/**
* 锁key值
*/
String key() default "redisLockKey";
}

View File

@ -13,7 +13,7 @@ import java.util.Date;
/** /**
* web层通用数据处理 * web层通用数据处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseController public class BaseController
@ -39,7 +39,7 @@ public class BaseController
/** /**
* 响应返回结果 * 响应返回结果
* *
* @param rows 影响行数 * @param rows 影响行数
* @return 操作结果 * @return 操作结果
*/ */

View File

@ -96,8 +96,12 @@ public class RedisCache {
* @param collection 多个对象 * @param collection 多个对象
* @return * @return
*/ */
public long deleteObject(final Collection collection) { public void deleteObject(final Collection collection) {
return redissonClient.getKeys().delete(Arrays.toString(collection.toArray())); RBatch batch = redissonClient.createBatch();
collection.forEach(t->{
batch.getBucket(t.toString()).deleteAsync();
});
batch.execute();
} }
/** /**

View File

@ -43,9 +43,9 @@ public class PageUtils {
public static final int DEFAULT_PAGE_NUM = 1; public static final int DEFAULT_PAGE_NUM = 1;
/** /**
* 每页显示记录数 默认值 * 每页显示记录数 默认值 默认查全部
*/ */
public static final int DEFAULT_PAGE_SIZE = 10; public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
/** /**
* 构建 plus 分页对象 * 构建 plus 分页对象

View File

@ -95,6 +95,7 @@ public class ImageUtils
} }
finally finally
{ {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(baos); IOUtils.closeQuietly(baos);
} }
} }

View File

@ -0,0 +1,35 @@
package com.ruoyi.demo.controller;
import com.ruoyi.common.annotation.RedisLock;
import com.ruoyi.common.core.domain.AjaxResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试分布式锁的样例
*
* @author shenxinquan
*/
@RestController
@RequestMapping("/demo/redisLock")
public class RedisLockController {
/**
* #p0 标识取第一个参数为redis锁的key
*/
@GetMapping("/getLock")
@RedisLock(expireTime = 10, key = "#p0")
public AjaxResult<String> getLock(String key, String value) {
try {
// 同时请求排队
// Thread.sleep(5000);
// 锁超时测试
Thread.sleep(11000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return AjaxResult.success("操作成功",value);
}
}

View File

@ -8,6 +8,7 @@ import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.TokenService;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
@ -166,13 +167,8 @@ public class DataScopeAspect {
BaseEntity baseEntity = (BaseEntity) params; BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, sql); baseEntity.getParams().put(DATA_SCOPE, sql);
} else { } else {
try { Map<String, Object> invoke = ReflectUtils.invokeGetter(params, "params");
Method getParams = params.getClass().getDeclaredMethod("getParams", null); invoke.put(DATA_SCOPE, sql);
Map<String, Object> invoke = (Map<String, Object>) getParams.invoke(params, null);
invoke.put(DATA_SCOPE, sql);
} catch (Exception e) {
// 方法未找到 不处理
}
} }
} }
} }

View File

@ -0,0 +1,167 @@
package com.ruoyi.framework.aspectj;
import com.ruoyi.common.annotation.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁注解实现版本
*
* @author shenxinquan
*/
@Slf4j
@Aspect
@Order(9)
@Component
public class RedisLockAspect {
@Autowired
private RedissonClient redissonClient;
private static final String LOCK_TITLE = "RedisLock_";
@Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)")
public void annotationPointcut() {
}
@Around("annotationPointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
// 获得当前访问的class
Class<?> className = joinPoint.getTarget().getClass();
// 获得访问的方法名
String methodName = joinPoint.getSignature().getName();
// 得到方法的参数的类型
Class<?>[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
Object[] args = joinPoint.getArgs();
String key = "";
// 默认30秒过期时间
int expireTime = 30;
try {
// 得到访问的方法对象
Method method = className.getMethod(methodName, argClass);
method.setAccessible(true);
// 判断是否存在@RedisLock注解
if (method.isAnnotationPresent(RedisLock.class)) {
RedisLock annotation = method.getAnnotation(RedisLock.class);
key = getRedisKey(args, annotation.key());
expireTime = getExpireTime(annotation);
}
} catch (Exception e) {
throw new RuntimeException("redis分布式锁注解参数异常", e);
}
Object res;
try {
if (acquire(key, expireTime, TimeUnit.SECONDS)) {
try {
res = joinPoint.proceed();
return res;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
release(key);
}
} else {
throw new RuntimeException("redis分布式锁注解参数异常");
}
} catch (IllegalMonitorStateException e) {
log.error("lock timeout => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
throw new RuntimeException("lock timeout => key : " + key);
} catch (Exception e) {
throw new Exception("redis分布式未知异常", e);
}
}
private int getExpireTime(RedisLock annotation) {
return annotation.expireTime();
}
private String getRedisKey(Object[] args, String primalKey) {
if (args.length == 0) {
return primalKey;
}
// 获取#p0...集合
List<String> keyList = getKeyParsList(primalKey);
for (String keyName : keyList) {
int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", ""));
Object parValue = args[keyIndex];
primalKey = primalKey.replace(keyName, String.valueOf(parValue));
}
return primalKey.replace("+", "").replace("'", "");
}
/**
* 获取key中#p0中的参数名称
*/
private static List<String> getKeyParsList(String key) {
List<String> listPar = new ArrayList<>();
if (key.contains("#")) {
int plusIndex = key.substring(key.indexOf("#")).indexOf("+");
int indexNext = 0;
String parName;
int indexPre = key.indexOf("#");
if (plusIndex > 0) {
indexNext = key.indexOf("#") + plusIndex;
parName = key.substring(indexPre, indexNext);
} else {
parName = key.substring(indexPre);
}
listPar.add(parName.trim());
key = key.substring(indexNext + 1);
if (key.contains("#")) {
listPar.addAll(getKeyParsList(key));
}
}
return listPar;
}
/**
* 加锁RLock带超时时间的
*/
private boolean acquire(String key, long expire, TimeUnit expireUnit) {
//声明key对象
key = LOCK_TITLE + key;
try {
//获取锁对象
RLock mylock = redissonClient.getLock(key);
//加锁并且设置锁过期时间防止死锁的产生
mylock.tryLock(expire, expire, expireUnit);
} catch (InterruptedException e) {
return false;
}
log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
//加锁成功
return true;
}
/**
* 锁的释放
*/
private void release(String lockName) {
//必须是和加锁时的同一个key
String key = LOCK_TITLE + lockName;
//获取所对象
RLock mylock = redissonClient.getLock(key);
//释放锁解锁
mylock.unlock();
log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.framework.config.properties.RedissonProperties; import com.ruoyi.framework.config.properties.RedissonProperties;
import org.redisson.Redisson; import org.redisson.Redisson;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
@ -52,7 +53,7 @@ public class RedisConfig extends CachingConfigurerSupport {
.setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()) .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort())
.setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue()) .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue())
.setDatabase(redisProperties.getDatabase()) .setDatabase(redisProperties.getDatabase())
.setPassword(redisProperties.getPassword()) .setPassword(StrUtil.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null)
.setTimeout(singleServerConfig.getTimeout()) .setTimeout(singleServerConfig.getTimeout())
.setRetryAttempts(singleServerConfig.getRetryAttempts()) .setRetryAttempts(singleServerConfig.getRetryAttempts())
.setRetryInterval(singleServerConfig.getRetryInterval()) .setRetryInterval(singleServerConfig.getRetryInterval())

View File

@ -81,7 +81,7 @@ redisson:
# 单节点配置 # 单节点配置
singleServerConfig: singleServerConfig:
# 客户端名称 # 客户端名称
clientName: ${ruoyi-vue-plus.name} clientName: ${ruoyi.name}
# 最小空闲连接数 # 最小空闲连接数
connectionMinimumIdleSize: 32 connectionMinimumIdleSize: 32
# 连接池大小 # 连接池大小

View File

@ -81,7 +81,7 @@ redisson:
# 单节点配置 # 单节点配置
singleServerConfig: singleServerConfig:
# 客户端名称 # 客户端名称
clientName: ${ruoyi-vue-plus.name} clientName: ${ruoyi.name}
# 最小空闲连接数 # 最小空闲连接数
connectionMinimumIdleSize: 32 connectionMinimumIdleSize: 32
# 连接池大小 # 连接池大小

View File

@ -8,8 +8,8 @@ ruoyi:
copyrightYear: 2021 copyrightYear: 2021
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径,使用jvm系统变量,兼容windows和linux; # 文件路径
profile: ${user.dir}/ruoyi/uploadPath profile: ./ruoyi/uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: false addressEnabled: false

View File

@ -29,7 +29,7 @@ public class ${ClassName}Vo {
private ${pkColumn.javaType} ${pkColumn.javaField}; private ${pkColumn.javaType} ${pkColumn.javaField};
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.isList) #if($column.isList && $column.isPk!=1)
/** $column.columnComment */ /** $column.columnComment */
#set($parentheseIndex=$column.columnComment.indexOf("")) #set($parentheseIndex=$column.columnComment.indexOf(""))
#if($parentheseIndex != -1) #if($parentheseIndex != -1)

View File

@ -247,7 +247,7 @@
#end #end
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -302,6 +302,8 @@ export default {
}, },
data() { data() {
return { return {
//按钮loading
buttonLoading: false,
// 遮罩层 // 遮罩层
loading: true, loading: true,
// 显示搜索条件 // 显示搜索条件
@ -480,12 +482,14 @@ export default {
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.loading = true;
this.reset(); this.reset();
this.getTreeselect(); this.getTreeselect();
if (row != null) { if (row != null) {
this.form.${treeParentCode} = row.${treeCode}; this.form.${treeParentCode} = row.${treeCode};
} }
get${BusinessName}(row.${pkColumn.javaField}).then(response => { get${BusinessName}(row.${pkColumn.javaField}).then(response => {
this.loading = false;
this.form = response.data; this.form = response.data;
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "checkbox") #if($column.htmlType == "checkbox")
@ -500,6 +504,7 @@ export default {
submitForm() { submitForm() {
this.#[[$]]#refs["form"].validate(valid => { this.#[[$]]#refs["form"].validate(valid => {
if (valid) { if (valid) {
this.buttonLoading = true;
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "checkbox") #if($column.htmlType == "checkbox")
this.form.$column.javaField = this.form.${column.javaField}.join(","); this.form.$column.javaField = this.form.${column.javaField}.join(",");
@ -507,12 +512,14 @@ export default {
#end #end
if (this.form.${pkColumn.javaField} != null) { if (this.form.${pkColumn.javaField} != null) {
update${BusinessName}(this.form).then(response => { update${BusinessName}(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("修改成功"); this.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
add${BusinessName}(this.form).then(response => { add${BusinessName}(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("新增成功"); this.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
@ -527,9 +534,11 @@ export default {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(() => {
this.loading = true;
return del${BusinessName}(row.${pkColumn.javaField}); return del${BusinessName}(row.${pkColumn.javaField});
}).then(() => { }).then(() => {
this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) })

View File

@ -301,7 +301,7 @@
#end #end
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button> <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button> <el-button @click="cancel">取 消</el-button>
</div> </div>
</el-dialog> </el-dialog>
@ -353,6 +353,8 @@ export default {
}, },
data() { data() {
return { return {
//按钮loading
buttonLoading: false,
// 遮罩层 // 遮罩层
loading: true, loading: true,
// 导出遮罩层 // 导出遮罩层
@ -534,9 +536,11 @@ export default {
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.loading = true;
this.reset(); this.reset();
const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids const ${pkColumn.javaField} = row.${pkColumn.javaField} || this.ids
get${BusinessName}(${pkColumn.javaField}).then(response => { get${BusinessName}(${pkColumn.javaField}).then(response => {
this.loading = false;
this.form = response.data; this.form = response.data;
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "checkbox") #if($column.htmlType == "checkbox")
@ -554,6 +558,7 @@ export default {
submitForm() { submitForm() {
this.#[[$]]#refs["form"].validate(valid => { this.#[[$]]#refs["form"].validate(valid => {
if (valid) { if (valid) {
this.buttonLoading = true;
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "checkbox") #if($column.htmlType == "checkbox")
this.form.$column.javaField = this.form.${column.javaField}.join(","); this.form.$column.javaField = this.form.${column.javaField}.join(",");
@ -564,12 +569,14 @@ export default {
#end #end
if (this.form.${pkColumn.javaField} != null) { if (this.form.${pkColumn.javaField} != null) {
update${BusinessName}(this.form).then(response => { update${BusinessName}(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("修改成功"); this.msgSuccess("修改成功");
this.open = false; this.open = false;
this.getList(); this.getList();
}); });
} else { } else {
add${BusinessName}(this.form).then(response => { add${BusinessName}(this.form).then(response => {
this.buttonLoading = false;
this.msgSuccess("新增成功"); this.msgSuccess("新增成功");
this.open = false; this.open = false;
this.getList(); this.getList();
@ -585,9 +592,11 @@ export default {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning" type: "warning"
}).then(function() { }).then(() => {
this.loading = true;
return del${BusinessName}(${pkColumn.javaField}s); return del${BusinessName}(${pkColumn.javaField}s);
}).then(() => { }).then(() => {
this.loading = false;
this.getList(); this.getList();
this.msgSuccess("删除成功"); this.msgSuccess("删除成功");
}) })

12
ry.sh
View File

@ -1,8 +1,12 @@
#!/bin/bash #!/bin/sh
# author ruoyi
# ./ry.sh start 启动
# ./ry.sh stop 停止
# ./ry.sh restart 重启
# ./ry.sh start 状态
AppName=ruoyi-admin.jar AppName=ruoyi-admin.jar
#JVM参数 # JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
APP_HOME=`pwd` APP_HOME=`pwd`
LOG_PATH=$APP_HOME/logs/$AppName.log LOG_PATH=$APP_HOME/logs/$AppName.log
@ -34,7 +38,7 @@ function start()
function stop() function stop()
{ {
echo "Stop $AppName" echo "Stop $AppName"
PID="" PID=""
query(){ query(){
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`

View File

@ -12,7 +12,7 @@ CREATE TABLE test_demo
create_by varchar(64) NULL DEFAULT NULL COMMENT '创建人', create_by varchar(64) NULL DEFAULT NULL COMMENT '创建人',
update_time datetime(0) NULL DEFAULT NULL COMMENT '更新时间', update_time datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
update_by varchar(64) NULL DEFAULT NULL COMMENT '更新人', update_by varchar(64) NULL DEFAULT NULL COMMENT '更新人',
del_flag int(0) NULL DEFAULT NULL COMMENT '删除标志', del_flag int(0) NULL DEFAULT 0 COMMENT '删除标志',
PRIMARY KEY (id) USING BTREE PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB COMMENT = '测试单表'; ) ENGINE = InnoDB COMMENT = '测试单表';
@ -29,7 +29,7 @@ CREATE TABLE test_tree
create_by varchar(64) NULL DEFAULT NULL COMMENT '创建人', create_by varchar(64) NULL DEFAULT NULL COMMENT '创建人',
update_time datetime(0) NULL DEFAULT NULL COMMENT '更新时间', update_time datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
update_by varchar(64) NULL DEFAULT NULL COMMENT '更新人', update_by varchar(64) NULL DEFAULT NULL COMMENT '更新人',
del_flag int(0) NULL DEFAULT NULL COMMENT '删除标志', del_flag int(0) NULL DEFAULT 0 COMMENT '删除标志',
PRIMARY KEY (id) USING BTREE PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB COMMENT = '测试树表'; ) ENGINE = InnoDB COMMENT = '测试树表';