diff --git a/README.md b/README.md index fd4f62c97..a7957e5e0 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼 | 功能介绍 | 使用技术 | 文档地址 | 特性注意事项 | |---|---|---|---| | 当前框架 | RuoYi-Vue-Plus | [RuoYi-Vue-Plus文档](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages) | 重写RuoYi-Vue全方位升级(不兼容原框架) | +| satoken分支 | RuoYi-Vue-Plus-satoken | [satoken分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) | 使用satoken重构权限鉴权(仅供学习不推荐上生产) | +| 单体分支 | RuoYi-Vue-Plus-fast | [fast分支地址](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) | 单体应用结构 | | 原框架 | RuoYi-Vue | [RuoYi-Vue官网](http://ruoyi.vip/) | 定期同步需要的功能 | | 前端开发框架 | Vue、Element UI | [Element UI官网](https://element.eleme.cn/#/zh-CN) | | | 后端开发框架 | SpringBoot | [SpringBoot官网](https://spring.io/projects/spring-boot/#learn) | | @@ -69,6 +71,7 @@ RuoYi-Vue-Plus 是基于 RuoYi-Vue 针对 `分布式集群` 场景升级(不兼 * 同步升级 RuoYi-Vue * GitHub 地址 [RuoYi-Vue-Plus-github](https://github.com/JavaLionLi/RuoYi-Vue-Plus) * 单模块 fast 分支 [RuoYi-Vue-Plus-fast](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/fast/) +* satoken 分支 [RuoYi-Vue-Plus-satoken](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/tree/satoken/) * 用户扩展项目 [扩展项目列表](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/wikis/pages?sort_id=4478302&doc_id=1469725) ## 加群与捐献 diff --git a/pom.xml b/pom.xml index 52ebaadbf..c6cb0242c 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ 3.1.0 - 2.5.4 + 2.5.5 UTF-8 UTF-8 1.8 @@ -26,14 +26,14 @@ 2.2.11 1.7 1.26.0 - 3.4.3.3 + 3.4.3.4 3.9.1 5.7.13 3.0.3 11.6 4.9.1 2.5.1 - 3.16.2 + 3.16.3 2.2.1 3.4.1 @@ -43,7 +43,7 @@ 7.8.0 3.13.1 - 5.6.51 + 5.6.55 8.3.0 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index b88f100a8..3d5e8dff1 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -122,6 +122,28 @@ sa-token: # 是否输出操作日志 is-log: true +# security配置 +security: + # 登出路径 + logout-url: /logout + # 匿名路径 + anonymous: + - /login + - /register + - /captchaImage + # swagger 文档配置 + - /doc.html + - /swagger-resources/** + - /webjars/** + - /*/api-docs + # druid 监控配置 + - /druid/** + # actuator 监控配置 + - /actuator + - /actuator/** + # 用户放行 + permit-all: + # 重复提交 repeat-submit: # 全局间隔时间(毫秒) @@ -237,6 +259,11 @@ swagger: name: Lion Li email: crazylionli@163.com url: https://gitee.com/JavaLionLi/RuoYi-Vue-Plus + groups: + - name: 演示案例 + basePackage: com.ruoyi.demo + - name: 系统模块 + basePackage: com.ruoyi.admin # 防止XSS攻击 xss: diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java deleted file mode 100644 index 23a25e045..000000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.ruoyi.common.core.redis; - -import com.google.common.collect.Lists; -import org.redisson.api.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -/** - * spring redis 工具类 - * - * @author shenxinquan - * @see com.ruoyi.common.utils.RedisUtils - * @deprecated 3.2.0 删除此类 - **/ -@SuppressWarnings(value = {"unchecked", "rawtypes"}) -@Component -@Deprecated -public class RedisCache { - - @Autowired - private RedissonClient redissonClient; - - /** - * 发布通道消息 - * - * @param channelKey 通道key - * @param msg 发送数据 - * @param consumer 自定义处理 - */ - public void publish(String channelKey, T msg, Consumer consumer) { - RTopic topic = redissonClient.getTopic(channelKey); - topic.publish(msg); - consumer.accept(msg); - } - - public void publish(String channelKey, T msg) { - RTopic topic = redissonClient.getTopic(channelKey); - topic.publish(msg); - } - - /** - * 订阅通道接收消息 - * - * @param channelKey 通道key - * @param clazz 消息类型 - * @param consumer 自定义处理 - */ - public void subscribe(String channelKey, Class clazz, Consumer consumer) { - RTopic topic = redissonClient.getTopic(channelKey); - topic.addListener(clazz, (channel, msg) -> consumer.accept(msg)); - } - - /** - * 缓存基本的对象,Integer、String、实体类等 - * - * @param key 缓存的键值 - * @param value 缓存的值 - */ - public void setCacheObject(final String key, final T value) { - redissonClient.getBucket(key).set(value); - } - - /** - * 缓存基本的对象,Integer、String、实体类等 - * - * @param key 缓存的键值 - * @param value 缓存的值 - * @param timeout 时间 - * @param timeUnit 时间颗粒度 - */ - public void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) { - RBucket result = redissonClient.getBucket(key); - result.set(value); - result.expire(timeout, timeUnit); - } - - /** - * 设置有效时间 - * - * @param key Redis键 - * @param timeout 超时时间 - * @return true=设置成功;false=设置失败 - */ - public boolean expire(final String key, final long timeout) { - return expire(key, timeout, TimeUnit.SECONDS); - } - - /** - * 设置有效时间 - * - * @param key Redis键 - * @param timeout 超时时间 - * @param unit 时间单位 - * @return true=设置成功;false=设置失败 - */ - public boolean expire(final String key, final long timeout, final TimeUnit unit) { - RBucket rBucket = redissonClient.getBucket(key); - return rBucket.expire(timeout, unit); - } - - /** - * 获得缓存的基本对象。 - * - * @param key 缓存键值 - * @return 缓存键值对应的数据 - */ - public T getCacheObject(final String key) { - RBucket rBucket = redissonClient.getBucket(key); - return rBucket.get(); - } - - /** - * 删除单个对象 - * - * @param key - */ - public boolean deleteObject(final String key) { - return redissonClient.getBucket(key).delete(); - } - - /* */ - - /** - * 删除集合对象 - * - * @param collection 多个对象 - * @return - */ - public void deleteObject(final Collection collection) { - RBatch batch = redissonClient.createBatch(); - collection.forEach(t->{ - batch.getBucket(t.toString()).deleteAsync(); - }); - batch.execute(); - } - - /** - * 缓存List数据 - * - * @param key 缓存的键值 - * @param dataList 待缓存的List数据 - * @return 缓存的对象 - */ - public boolean setCacheList(final String key, final List dataList) { - RList rList = redissonClient.getList(key); - return rList.addAll(dataList); - } - - /** - * 获得缓存的list对象 - * - * @param key 缓存的键值 - * @return 缓存键值对应的数据 - */ - public List getCacheList(final String key) { - RList rList = redissonClient.getList(key); - return rList.readAll(); - } - - /** - * 缓存Set - * - * @param key 缓存键值 - * @param dataSet 缓存的数据 - * @return 缓存数据的对象 - */ - public boolean setCacheSet(final String key, final Set dataSet) { - RSet rSet = redissonClient.getSet(key); - return rSet.addAll(dataSet); - } - - /** - * 获得缓存的set - * - * @param key - * @return - */ - public Set getCacheSet(final String key) { - RSet rSet = redissonClient.getSet(key); - return rSet.readAll(); - } - - /** - * 缓存Map - * - * @param key - * @param dataMap - */ - public void setCacheMap(final String key, final Map dataMap) { - if (dataMap != null) { - RMap rMap = redissonClient.getMap(key); - rMap.putAll(dataMap); - } - } - - /** - * 获得缓存的Map - * - * @param key - * @return - */ - public Map getCacheMap(final String key) { - RMap rMap = redissonClient.getMap(key); - return rMap.getAll(rMap.keySet()); - } - - /** - * 往Hash中存入数据 - * - * @param key Redis键 - * @param hKey Hash键 - * @param value 值 - */ - public void setCacheMapValue(final String key, final String hKey, final T value) { - RMap rMap = redissonClient.getMap(key); - rMap.put(hKey, value); - } - - /** - * 获取Hash中的数据 - * - * @param key Redis键 - * @param hKey Hash键 - * @return Hash中的对象 - */ - public T getCacheMapValue(final String key, final String hKey) { - RMap rMap = redissonClient.getMap(key); - return rMap.get(hKey); - } - - /** - * 获取多个Hash中的数据 - * - * @param key Redis键 - * @param hKeys Hash键集合 - * @return Hash对象集合 - */ - public Map getMultiCacheMapValue(final String key, final Set hKeys) { - RMap rMap = redissonClient.getMap(key); - return rMap.getAll(hKeys); - } - - /** - * 获得缓存的基本对象列表 - * - * @param pattern 字符串前缀 - * @return 对象列表 - */ - public Collection keys(final String pattern) { - Iterable iterable = redissonClient.getKeys().getKeysByPattern(pattern); - return Lists.newArrayList(iterable); - } -} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java index 03c608af8..bd7522c51 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java @@ -27,6 +27,9 @@ public class AddressUtils { public static String getRealAddressByIP(String ip) { String address = UNKNOWN; + if (StringUtils.isBlank(ip)){ + return address; + } // 内网不查询 ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); if (NetUtil.isInnerIP(ip)) { diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java deleted file mode 100644 index b5b7de316..000000000 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ServerConfig.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.ruoyi.framework.config; - -import javax.servlet.http.HttpServletRequest; -import org.springframework.stereotype.Component; -import com.ruoyi.common.utils.ServletUtils; - -/** - * 服务相关配置 - * - * @author ruoyi - */ -@Component -public class ServerConfig -{ - /** - * 获取完整的请求路径,包括:域名,端口,上下文访问路径 - * - * @return 服务地址 - */ - public String getUrl() - { - HttpServletRequest request = ServletUtils.getRequest(); - return getDomain(request); - } - - public static String getDomain(HttpServletRequest request) - { - StringBuffer url = request.getRequestURL(); - String contextPath = request.getServletContext().getContextPath(); - return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); - } -} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java index 2c65ac69d..4da3b9949 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SwaggerConfig.java @@ -1,11 +1,12 @@ package com.ruoyi.framework.config; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import com.ruoyi.common.properties.TokenProperties; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.framework.config.properties.SwaggerProperties; -import io.swagger.annotations.ApiOperation; import io.swagger.models.auth.In; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; @@ -15,6 +16,7 @@ import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; +import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @@ -27,82 +29,92 @@ import java.util.List; @EnableKnife4j public class SwaggerConfig { - @Autowired - private SwaggerProperties swaggerProperties; + @Autowired + private SwaggerProperties swaggerProperties; - /** - * 创建API - */ - @Bean - public Docket createRestApi() { - return new Docket(DocumentationType.OAS_30) - .enable(swaggerProperties.getEnabled()) - // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) - .apiInfo(apiInfo()) - // 设置哪些接口暴露给Swagger展示 - .select() - // 扫描所有有注解的api,用这种方式更灵活 - .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) - // 扫描指定包中的swagger注解 - // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) - // 扫描所有 .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build() - /* 设置安全模式,swagger可以设置访问token */ - .securitySchemes(securitySchemes()) - .securityContexts(securityContexts()) - .pathMapping(swaggerProperties.getPathMapping()); - } + @Autowired + private TokenProperties tokenProperties; - /** - * 安全模式,这里指定token通过Authorization头请求头传递 - */ - private List securitySchemes() { - List apiKeyList = new ArrayList(); - apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue())); - return apiKeyList; - } + /** + * 创建API + */ + @PostConstruct + public void createRestApi() { + for (SwaggerProperties.Groups group : swaggerProperties.getGroups()) { + String basePackage = group.getBasePackage(); + Docket docket = new Docket(DocumentationType.OAS_30) + .enable(swaggerProperties.getEnabled()) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + .apis(RequestHandlerSelectors.basePackage(basePackage)) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build() + .groupName(group.getName()) + // 设置安全模式,swagger可以设置访问token + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()) + .pathMapping(swaggerProperties.getPathMapping()); + String beanName = StringUtils.substringAfterLast(basePackage, ".") + "Docket"; + SpringUtils.registerBean(beanName, docket); + } + } - /** - * 安全上下文 - */ - private List securityContexts() { - List securityContexts = new ArrayList<>(); - securityContexts.add( - SecurityContext.builder() - .securityReferences(defaultAuth()) - .operationSelector(o -> o.requestMappingPattern().matches("/.*")) - .build()); - return securityContexts; - } + /** + * 安全模式,这里指定token通过Authorization头请求头传递 + */ + private List securitySchemes() { + List apiKeyList = new ArrayList(); + String header = tokenProperties.getHeader(); + apiKeyList.add(new ApiKey(header, header, In.HEADER.toValue())); + return apiKeyList; + } - /** - * 默认的安全上引用 - */ - private List defaultAuth() { - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - List securityReferences = new ArrayList<>(); - securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); - return securityReferences; - } + /** + * 安全上下文 + */ + private List securityContexts() { + List securityContexts = new ArrayList<>(); + securityContexts.add( + SecurityContext.builder() + .securityReferences(defaultAuth()) + .operationSelector(o -> o.requestMappingPattern().matches("/.*")) + .build()); + return securityContexts; + } - /** - * 添加摘要信息 - */ - private ApiInfo apiInfo() { - // 用ApiInfoBuilder进行定制 - SwaggerProperties.Contact contact = swaggerProperties.getContact(); - return new ApiInfoBuilder() - // 设置标题 - .title(swaggerProperties.getTitle()) - // 描述 - .description(swaggerProperties.getDescription()) - // 作者信息 - .contact(new Contact(contact.getName(), contact.getUrl(), contact.getEmail())) - // 版本 - .version(swaggerProperties.getVersion()) - .build(); - } + /** + * 默认的安全上引用 + */ + private List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + List securityReferences = new ArrayList<>(); + securityReferences.add(new SecurityReference(tokenProperties.getHeader(), authorizationScopes)); + return securityReferences; + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() { + // 用ApiInfoBuilder进行定制 + SwaggerProperties.Contact contact = swaggerProperties.getContact(); + return new ApiInfoBuilder() + // 设置标题 + .title(swaggerProperties.getTitle()) + // 描述 + .description(swaggerProperties.getDescription()) + // 作者信息 + .contact(new Contact(contact.getName(), contact.getUrl(), contact.getEmail())) + // 版本 + .version(swaggerProperties.getVersion()) + .build(); + } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java new file mode 100644 index 000000000..c83ffccbe --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SecurityProperties.java @@ -0,0 +1,32 @@ +package com.ruoyi.framework.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * Security 配置属性 + * + * @author Lion Li + */ +@Data +@Component +@ConfigurationProperties(prefix = "security") +public class SecurityProperties { + + /** + * 退出登录url + */ + private String logoutUrl; + + /** + * 匿名放行路径 + */ + private String[] anonymous; + + /** + * 用户任意访问放行路径 + */ + private String[] permitAll; + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java index ece75efef..9c4cd238c 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/SwaggerProperties.java @@ -5,6 +5,8 @@ import lombok.NoArgsConstructor; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; +import java.util.List; + /** * swagger 配置属性 * @@ -41,23 +43,46 @@ public class SwaggerProperties { */ private Contact contact; + /** + * 组配置 + */ + private List groups; + @Data @NoArgsConstructor - public static class Contact{ + public static class Contact { /** * 联系人 - **/ + */ private String name; + /** * 联系人url - **/ + */ private String url; + /** * 联系人email - **/ + */ private String email; } + @Data + @NoArgsConstructor + public static class Groups { + + /** + * 组名 + */ + private String name; + + /** + * 基础包路径 + */ + private String basePackage; + + } + } diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 164492943..99e05c1d6 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -557,7 +557,7 @@ export default { /** ${subTable.functionName}删除按钮操作 */ handleDelete${subClassName}() { if (this.checked${subClassName}.length == 0) { - this.msgError("请先选择要删除的${subTable.functionName}数据"); + this.#[[$modal]]#.msgError("请先选择要删除的${subTable.functionName}数据"); } else { const ${subclassName}List = this.${subclassName}List; const checked${subClassName} = this.checked${subClassName}; diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java index 6bee29f46..3207a46e3 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysLoginService.java @@ -77,9 +77,14 @@ public class SysLoginService asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"), request); throw new UserPasswordNotMatchException(); } + else + { + asyncService.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage(), request); + throw new ServiceException(e.getMessage()); + } asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request); - recordLoginInfo(user); + recordLoginInfo(user.getUserId()); // 生成token StpUtil.login(user.getUserId(), "PC"); return StpUtil.getTokenValue(); @@ -109,12 +114,15 @@ public class SysLoginService /** * 记录登录信息 + * + * @param userId 用户ID */ - public void recordLoginInfo(SysUser user) + public void recordLoginInfo(Long userId) { - user.setLoginIp(ServletUtils.getClientIP()); - user.setLoginDate(DateUtils.getNowDate()); - user.setUpdateBy(user.getUserName()); - userService.updateUserProfile(user); + SysUser sysUser = new SysUser(); + sysUser.setUserId(userId); + sysUser.setLoginIp(ServletUtils.getClientIP()); + sysUser.setLoginDate(DateUtils.getNowDate()); + userService.updateUserProfile(sysUser); } } diff --git a/ruoyi-ui/src/views/tool/gen/editTable.vue b/ruoyi-ui/src/views/tool/gen/editTable.vue index b9ad2588c..95b12cf59 100644 --- a/ruoyi-ui/src/views/tool/gen/editTable.vue +++ b/ruoyi-ui/src/views/tool/gen/editTable.vue @@ -4,8 +4,8 @@ - - + + { - this.cloumns = res.data.rows; + this.columns = res.data.rows; this.info = res.data.info; this.tables = res.data.tables; }); @@ -184,7 +184,7 @@ export default { const validateResult = res.every(item => !!item); if (validateResult) { const genTable = Object.assign({}, basicForm.model, genForm.model); - genTable.columns = this.cloumns; + genTable.columns = this.columns; genTable.params = { treeCode: genTable.treeCode, treeName: genTable.treeName, @@ -220,10 +220,10 @@ export default { const sortable = Sortable.create(el, { handle: ".allowDrag", onEnd: evt => { - const targetRow = this.cloumns.splice(evt.oldIndex, 1)[0]; - this.cloumns.splice(evt.newIndex, 0, targetRow); - for (let index in this.cloumns) { - this.cloumns[index].sort = parseInt(index) + 1; + const targetRow = this.columns.splice(evt.oldIndex, 1)[0]; + this.columns.splice(evt.newIndex, 0, targetRow); + for (let index in this.columns) { + this.columns[index].sort = parseInt(index) + 1; } } });