框架变更
Too many changes to show.
To preserve performance only 1000 of 1000+ files are displayed.
| 1 | # http://editorconfig.org | ||
| 2 | root = true | ||
| 3 | |||
| 4 | # 空格替代Tab缩进在各种编辑工具下效果一致 | ||
| 5 | [*] | ||
| 6 | indent_style = space | ||
| 7 | indent_size = 4 | ||
| 8 | charset = utf-8 | ||
| 9 | end_of_line = lf | ||
| 10 | trim_trailing_whitespace = true | ||
| 11 | insert_final_newline = true | ||
| 12 | |||
| 13 | [*.java] | ||
| 14 | indent_style = tab | ||
| 15 | |||
| 16 | [*.{json,yml}] | ||
| 17 | indent_size = 2 | ||
| 18 | |||
| 19 | [*.md] | ||
| 20 | insert_final_newline = false | ||
| 21 | trim_trailing_whitespace = false |
| 1 | #Californium CoAP Properties file | ||
| 2 | #Tue Oct 08 10:11:32 CST 2019 | ||
| 3 | HTTP_SERVER_SOCKET_BUFFER_SIZE=8192 | ||
| 4 | UDP_CONNECTOR_OUT_CAPACITY=2147483647 | ||
| 5 | CONGESTION_CONTROL_ALGORITHM=Cocoa | ||
| 6 | USE_CONGESTION_CONTROL=false | ||
| 7 | ACK_TIMEOUT=2000 | ||
| 8 | MAX_ACTIVE_PEERS=150000 | ||
| 9 | TCP_CONNECT_TIMEOUT=10000 | ||
| 10 | NOTIFICATION_CHECK_INTERVAL_COUNT=100 | ||
| 11 | MAX_MESSAGE_SIZE=1024 | ||
| 12 | MID_TRACKER_GROUPS=16 | ||
| 13 | DEDUPLICATOR=DEDUPLICATOR_MARK_AND_SWEEP | ||
| 14 | TCP_CONNECTION_IDLE_TIMEOUT=10 | ||
| 15 | COAP_PORT=5683 | ||
| 16 | ACK_TIMEOUT_SCALE=2.0 | ||
| 17 | PREFERRED_BLOCK_SIZE=512 | ||
| 18 | NETWORK_STAGE_RECEIVER_THREAD_COUNT=1 | ||
| 19 | DTLS_AUTO_RESUME_TIMEOUT=30000 | ||
| 20 | DTLS_RESPONSE_MATCHING=STRICT | ||
| 21 | PROTOCOL_STAGE_THREAD_COUNT=4 | ||
| 22 | MAX_TRANSMIT_WAIT=93000 | ||
| 23 | UDP_CONNECTOR_RECEIVE_BUFFER=0 | ||
| 24 | EXCHANGE_LIFETIME=247000 | ||
| 25 | HTTP_SERVER_SOCKET_TIMEOUT=100000 | ||
| 26 | CROP_ROTATION_PERIOD=2000 | ||
| 27 | UDP_CONNECTOR_DATAGRAM_SIZE=2048 | ||
| 28 | MAX_RETRANSMIT=4 | ||
| 29 | MAX_PEER_INACTIVITY_PERIOD=600 | ||
| 30 | MAX_RESOURCE_BODY_SIZE=8192 | ||
| 31 | NOTIFICATION_CHECK_INTERVAL=86400000 | ||
| 32 | LEISURE=5000 | ||
| 33 | HTTP_CACHE_RESPONSE_MAX_AGE=86400 | ||
| 34 | BLOCKWISE_STATUS_LIFETIME=300000 | ||
| 35 | UDP_CONNECTOR_SEND_BUFFER=0 | ||
| 36 | MID_TACKER=GROUPED | ||
| 37 | TCP_WORKER_THREADS=1 | ||
| 38 | NETWORK_STAGE_SENDER_THREAD_COUNT=1 | ||
| 39 | NON_LIFETIME=145000 | ||
| 40 | TOKEN_SIZE_LIMIT=8 | ||
| 41 | HTTP_PORT=8080 | ||
| 42 | MARK_AND_SWEEP_INTERVAL=10000 | ||
| 43 | HEALTH_STATUS_INTERVAL=60 | ||
| 44 | ACK_RANDOM_FACTOR=1.5 | ||
| 45 | SECURE_SESSION_TIMEOUT=86400 | ||
| 46 | NSTART=1 | ||
| 47 | USE_RANDOM_MID_START=true | ||
| 48 | HTTP_CACHE_SIZE=32 | ||
| 49 | PROBING_RATE=1.0 | ||
| 50 | NOTIFICATION_REREGISTRATION_BACKOFF=2000 | ||
| 51 | COAP_SECURE_PORT=5684 |
| 1 | FROM anapsix/alpine-java:8_server-jre_unlimited | ||
| 2 | |||
| 3 | MAINTAINER smallchill@163.com | ||
| 4 | |||
| 5 | RUN mkdir -p /blade/auth | ||
| 6 | |||
| 7 | WORKDIR /blade/auth | ||
| 8 | |||
| 9 | EXPOSE 8010 | ||
| 10 | |||
| 11 | ADD ./target/blade-auth.jar ./app.jar | ||
| 12 | |||
| 13 | ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"] | ||
| 14 | |||
| 15 | CMD ["--spring.profiles.active=test"] |
| 1 | ## 目前主要支持的oauth协议 | ||
| 2 | 一、 授权码模式 | ||
| 3 | 授权码模式(authorization_code)主要针对第三方应用,是最为复杂也最为安全的一种模式,操作步骤如下 | ||
| 4 | 1. 访问地址:http://localhost:8100/oauth/authorize?client_id=blade&redirect_uri=http://example.com&code=233333&response_type=code | ||
| 5 | 2. 获取跳转后的code值(http://example.com/?code=VhYNLR)之后,调用 http://localhost/blade-auth/oauth/token 传入对应的参数 | ||
| 6 | |||
| 7 | 请求头: | ||
| 8 | Authorization : Basic YmxhZGU6YmxhZGU= ("YmxhZGU6YmxhZGU="为clientId:clientSecret串转换为的base64编码) | ||
| 9 | |||
| 10 | 表单: | ||
| 11 | grant_type:authorization_code | ||
| 12 | scope:all | ||
| 13 | code:VhYNLR | ||
| 14 | redirect_uri: http://example.com | ||
| 15 | |||
| 16 | 二、 密码模式 | ||
| 17 | 密码模式(password)主要针对自家应用,可信度较高,所以可以使用简便安全共存的模式,操作步骤如下 | ||
| 18 | 1. 直接调用 http://localhost/blade-auth/oauth/token 传入对应的参数 | ||
| 19 | |||
| 20 | 请求头: | ||
| 21 | Authorization : Basic YmxhZGU6YmxhZGU= ("YmxhZGU6YmxhZGU="为clientId:clientSecret串转换为的base64编码) | ||
| 22 | |||
| 23 | 表单: | ||
| 24 | grant_type:password | ||
| 25 | scope:all | ||
| 26 | username:admin | ||
| 27 | password:123456 | ||
| 28 | |||
| 29 | ## 获取到token后如何获取用户信息 | ||
| 30 | 1. 拼接请求头 | ||
| 31 | Authorization :bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsInVzZXJfbmFtZSI6ImFkbWluIiwic2NvcGUiOlsiYWxsIl0sImV4cCI6MTU1MzE2MTA5NSwiYXV0aG9yaXRpZXMiOlsiUk9MRV9VU0VSIl0sImp0aSI6IjE0YmMyYjAyLTgxY2UtNDFiNC04ZTI3LTA5YWE0ZmU4ZWMwYyIsImNsaWVudF9pZCI6ImJsYWRlIn0.jTmioQDq-fSNNn7YCwl3wP0JE-etSWtzLDe545mDbP4 | ||
| 32 | 2. 调用 http://localhost/blade-auth/oauth/user-info 既可获得对应用户信息 | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | |||
| 6 | <modelVersion>4.0.0</modelVersion> | ||
| 7 | |||
| 8 | <parent> | ||
| 9 | <artifactId>BladeX</artifactId> | ||
| 10 | <groupId>org.springblade</groupId> | ||
| 11 | <version>2.0.0.RELEASE</version> | ||
| 12 | </parent> | ||
| 13 | |||
| 14 | <artifactId>blade-auth</artifactId> | ||
| 15 | <name>${project.artifactId}</name> | ||
| 16 | <version>${bladex.project.version}</version> | ||
| 17 | <packaging>jar</packaging> | ||
| 18 | |||
| 19 | <dependencies> | ||
| 20 | <!--Blade--> | ||
| 21 | <dependency> | ||
| 22 | <groupId>org.springblade</groupId> | ||
| 23 | <artifactId>blade-common</artifactId> | ||
| 24 | <version>${bladex.project.version}</version> | ||
| 25 | </dependency> | ||
| 26 | <dependency> | ||
| 27 | <groupId>org.springblade</groupId> | ||
| 28 | <artifactId>blade-core-cloud</artifactId> | ||
| 29 | <version>${bladex.tool.version}</version> | ||
| 30 | <exclusions> | ||
| 31 | <exclusion> | ||
| 32 | <groupId>org.springblade</groupId> | ||
| 33 | <artifactId>blade-core-secure</artifactId> | ||
| 34 | </exclusion> | ||
| 35 | </exclusions> | ||
| 36 | </dependency> | ||
| 37 | <dependency> | ||
| 38 | <groupId>org.springblade</groupId> | ||
| 39 | <artifactId>blade-user-api</artifactId> | ||
| 40 | <version>${bladex.project.version}</version> | ||
| 41 | <exclusions> | ||
| 42 | <exclusion> | ||
| 43 | <groupId>org.springblade</groupId> | ||
| 44 | <artifactId>blade-core-secure</artifactId> | ||
| 45 | </exclusion> | ||
| 46 | </exclusions> | ||
| 47 | </dependency> | ||
| 48 | <dependency> | ||
| 49 | <groupId>org.springblade</groupId> | ||
| 50 | <artifactId>blade-system-api</artifactId> | ||
| 51 | <version>${bladex.project.version}</version> | ||
| 52 | <exclusions> | ||
| 53 | <exclusion> | ||
| 54 | <groupId>org.springblade</groupId> | ||
| 55 | <artifactId>blade-core-secure</artifactId> | ||
| 56 | </exclusion> | ||
| 57 | </exclusions> | ||
| 58 | </dependency> | ||
| 59 | <dependency> | ||
| 60 | <groupId>org.springblade</groupId> | ||
| 61 | <artifactId>blade-starter-swagger</artifactId> | ||
| 62 | <version>${bladex.tool.version}</version> | ||
| 63 | </dependency> | ||
| 64 | <dependency> | ||
| 65 | <groupId>org.springframework.cloud</groupId> | ||
| 66 | <artifactId>spring-cloud-starter-security</artifactId> | ||
| 67 | </dependency> | ||
| 68 | <dependency> | ||
| 69 | <groupId>org.springframework.security.oauth.boot</groupId> | ||
| 70 | <artifactId>spring-security-oauth2-autoconfigure</artifactId> | ||
| 71 | <version>2.1.3.RELEASE</version> | ||
| 72 | </dependency> | ||
| 73 | <dependency> | ||
| 74 | <groupId>org.springframework.boot</groupId> | ||
| 75 | <artifactId>spring-boot-starter-jdbc</artifactId> | ||
| 76 | <exclusions> | ||
| 77 | <exclusion> | ||
| 78 | <artifactId>tomcat-jdbc</artifactId> | ||
| 79 | <groupId>org.apache.tomcat</groupId> | ||
| 80 | </exclusion> | ||
| 81 | </exclusions> | ||
| 82 | </dependency> | ||
| 83 | <dependency> | ||
| 84 | <groupId>org.springframework.boot</groupId> | ||
| 85 | <artifactId>spring-boot-starter-data-redis</artifactId> | ||
| 86 | </dependency> | ||
| 87 | <dependency> | ||
| 88 | <groupId>org.springframework.security</groupId> | ||
| 89 | <artifactId>spring-security-jwt</artifactId> | ||
| 90 | </dependency> | ||
| 91 | <dependency> | ||
| 92 | <groupId>io.jsonwebtoken</groupId> | ||
| 93 | <artifactId>jjwt</artifactId> | ||
| 94 | <version>0.9.1</version> | ||
| 95 | </dependency> | ||
| 96 | <!-- MySQL --> | ||
| 97 | <dependency> | ||
| 98 | <groupId>mysql</groupId> | ||
| 99 | <artifactId>mysql-connector-java</artifactId> | ||
| 100 | <version>8.0.15</version> | ||
| 101 | </dependency> | ||
| 102 | </dependencies> | ||
| 103 | |||
| 104 | <build> | ||
| 105 | <plugins> | ||
| 106 | <plugin> | ||
| 107 | <groupId>com.spotify</groupId> | ||
| 108 | <artifactId>docker-maven-plugin</artifactId> | ||
| 109 | <version>${docker.plugin.version}</version> | ||
| 110 | <configuration> | ||
| 111 | <imageName>${docker.registry.url}/blade/${project.artifactId}:${project.version}</imageName> | ||
| 112 | <dockerDirectory>${project.basedir}</dockerDirectory> | ||
| 113 | <dockerHost>${docker.registry.host}</dockerHost> | ||
| 114 | <resources> | ||
| 115 | <resource> | ||
| 116 | <targetPath>/</targetPath> | ||
| 117 | <directory>${project.build.directory}</directory> | ||
| 118 | <include>${project.build.finalName}.jar</include> | ||
| 119 | </resource> | ||
| 120 | </resources> | ||
| 121 | <registryUrl>${docker.registry.url}</registryUrl> | ||
| 122 | <serverId>${docker.registry.url}</serverId> | ||
| 123 | <pushImage>true</pushImage> | ||
| 124 | </configuration> | ||
| 125 | </plugin> | ||
| 126 | <plugin> | ||
| 127 | <groupId>org.apache.maven.plugins</groupId> | ||
| 128 | <artifactId>maven-antrun-plugin</artifactId> | ||
| 129 | <executions> | ||
| 130 | <execution> | ||
| 131 | <phase>package</phase> | ||
| 132 | <goals> | ||
| 133 | <goal>run</goal> | ||
| 134 | </goals> | ||
| 135 | <configuration> | ||
| 136 | <tasks> | ||
| 137 | <copy overwrite="true" | ||
| 138 | tofile="${session.executionRootDirectory}/target/${project.artifactId}.jar" | ||
| 139 | file="${project.build.directory}/${project.artifactId}.jar" /> | ||
| 140 | </tasks> | ||
| 141 | </configuration> | ||
| 142 | </execution> | ||
| 143 | </executions> | ||
| 144 | </plugin> | ||
| 145 | </plugins> | ||
| 146 | </build> | ||
| 147 | |||
| 148 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth; | ||
| 18 | |||
| 19 | |||
| 20 | import org.springblade.core.cloud.feign.EnableBladeFeign; | ||
| 21 | import org.springblade.core.launch.BladeApplication; | ||
| 22 | import org.springblade.core.launch.constant.AppConstant; | ||
| 23 | import org.springframework.cloud.client.SpringCloudApplication; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 用户认证服务器 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | @EnableBladeFeign | ||
| 31 | @SpringCloudApplication | ||
| 32 | public class AuthApplication { | ||
| 33 | |||
| 34 | public static void main(String[] args) { | ||
| 35 | BladeApplication.run(AppConstant.APPLICATION_AUTH_NAME, AuthApplication.class, args); | ||
| 36 | } | ||
| 37 | |||
| 38 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.config; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.SneakyThrows; | ||
| 21 | import org.springblade.auth.constant.AuthConstant; | ||
| 22 | import org.springblade.auth.service.BladeClientDetailsServiceImpl; | ||
| 23 | import org.springframework.context.annotation.Configuration; | ||
| 24 | import org.springframework.core.annotation.Order; | ||
| 25 | import org.springframework.security.authentication.AuthenticationManager; | ||
| 26 | import org.springframework.security.core.userdetails.UserDetailsService; | ||
| 27 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; | ||
| 28 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; | ||
| 29 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; | ||
| 30 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; | ||
| 31 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; | ||
| 32 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; | ||
| 33 | import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; | ||
| 34 | import org.springframework.security.oauth2.provider.token.TokenStore; | ||
| 35 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; | ||
| 36 | |||
| 37 | import javax.sql.DataSource; | ||
| 38 | import java.util.ArrayList; | ||
| 39 | import java.util.List; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * 认证服务器配置 | ||
| 43 | * | ||
| 44 | * @author Chill | ||
| 45 | */ | ||
| 46 | @Order | ||
| 47 | @Configuration | ||
| 48 | @AllArgsConstructor | ||
| 49 | @EnableAuthorizationServer | ||
| 50 | public class BladeAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { | ||
| 51 | |||
| 52 | private final DataSource dataSource; | ||
| 53 | |||
| 54 | private AuthenticationManager authenticationManager; | ||
| 55 | |||
| 56 | private UserDetailsService userDetailsService; | ||
| 57 | |||
| 58 | private TokenStore tokenStore; | ||
| 59 | |||
| 60 | private JwtAccessTokenConverter jwtAccessTokenConverter; | ||
| 61 | |||
| 62 | private TokenEnhancer jwtTokenEnhancer; | ||
| 63 | |||
| 64 | @Override | ||
| 65 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) { | ||
| 66 | endpoints.tokenStore(tokenStore) | ||
| 67 | .authenticationManager(authenticationManager) | ||
| 68 | .userDetailsService(userDetailsService); | ||
| 69 | //扩展token返回结果 | ||
| 70 | if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) { | ||
| 71 | TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); | ||
| 72 | List<TokenEnhancer> enhancerList = new ArrayList<>(); | ||
| 73 | enhancerList.add(jwtTokenEnhancer); | ||
| 74 | enhancerList.add(jwtAccessTokenConverter); | ||
| 75 | tokenEnhancerChain.setTokenEnhancers(enhancerList); | ||
| 76 | //jwt | ||
| 77 | endpoints.tokenEnhancer(tokenEnhancerChain) | ||
| 78 | .accessTokenConverter(jwtAccessTokenConverter); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * 配置客户端信息 | ||
| 84 | */ | ||
| 85 | @Override | ||
| 86 | @SneakyThrows | ||
| 87 | public void configure(ClientDetailsServiceConfigurer clients) { | ||
| 88 | BladeClientDetailsServiceImpl clientDetailsService = new BladeClientDetailsServiceImpl(dataSource); | ||
| 89 | clientDetailsService.setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT); | ||
| 90 | clientDetailsService.setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT); | ||
| 91 | clients.withClientDetails(clientDetailsService); | ||
| 92 | } | ||
| 93 | |||
| 94 | @Override | ||
| 95 | public void configure(AuthorizationServerSecurityConfigurer oauthServer) { | ||
| 96 | oauthServer | ||
| 97 | .allowFormAuthenticationForClients() | ||
| 98 | .tokenKeyAccess("permitAll()") | ||
| 99 | .checkTokenAccess("isAuthenticated()"); | ||
| 100 | } | ||
| 101 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.config; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.SneakyThrows; | ||
| 21 | import org.springframework.context.annotation.Configuration; | ||
| 22 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 23 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; | ||
| 24 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; | ||
| 25 | import org.springframework.security.web.authentication.AuthenticationSuccessHandler; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * 自定义登录成功配置 | ||
| 29 | * | ||
| 30 | * @author Chill | ||
| 31 | */ | ||
| 32 | @Configuration | ||
| 33 | @AllArgsConstructor | ||
| 34 | @EnableResourceServer | ||
| 35 | public class BladeResourceServerConfiguration extends ResourceServerConfigurerAdapter { | ||
| 36 | |||
| 37 | /** | ||
| 38 | * 自定义登录成功处理器 | ||
| 39 | */ | ||
| 40 | private AuthenticationSuccessHandler appLoginInSuccessHandler; | ||
| 41 | |||
| 42 | @Override | ||
| 43 | @SneakyThrows | ||
| 44 | public void configure(HttpSecurity http) { | ||
| 45 | http.headers().frameOptions().disable(); | ||
| 46 | http.formLogin() | ||
| 47 | .successHandler(appLoginInSuccessHandler) | ||
| 48 | .and() | ||
| 49 | .authorizeRequests() | ||
| 50 | .antMatchers("/actuator/**", "/token/**", "/mobile/**", "/v2/api-docs", "/v2/api-docs-ext").permitAll() | ||
| 51 | .anyRequest().authenticated().and() | ||
| 52 | .csrf().disable(); | ||
| 53 | } | ||
| 54 | |||
| 55 | } |
| 1 | //package org.springblade.auth.config; | ||
| 2 | // | ||
| 3 | //import org.springblade.core.tool.api.R; | ||
| 4 | //import org.springframework.security.core.AuthenticationException; | ||
| 5 | //import org.springframework.security.web.AuthenticationEntryPoint; | ||
| 6 | //import org.springframework.stereotype.Component; | ||
| 7 | // | ||
| 8 | //import javax.servlet.http.HttpServletRequest; | ||
| 9 | //import javax.servlet.http.HttpServletResponse; | ||
| 10 | //import java.io.IOException; | ||
| 11 | //import java.io.PrintWriter; | ||
| 12 | //import java.io.Serializable; | ||
| 13 | // | ||
| 14 | ///** | ||
| 15 | // * @author: JoeTao | ||
| 16 | // * createAt: 2018/9/20 | ||
| 17 | // */ | ||
| 18 | //@Component | ||
| 19 | //public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { | ||
| 20 | // | ||
| 21 | // private static final long serialVersionUID = -8970718410437077606L; | ||
| 22 | // | ||
| 23 | // @Override | ||
| 24 | // public void commence(HttpServletRequest request, | ||
| 25 | // HttpServletResponse response, | ||
| 26 | // AuthenticationException authException) throws IOException { | ||
| 27 | // //验证为未登陆状态会进入此方法,认证错误 | ||
| 28 | // System.out.println("认证失败:" + authException.getMessage()); | ||
| 29 | // response.setStatus(200); | ||
| 30 | // response.setCharacterEncoding("UTF-8"); | ||
| 31 | // response.setContentType("application/json; charset=utf-8"); | ||
| 32 | // PrintWriter printWriter = response.getWriter(); | ||
| 33 | // String body = R.fail(401, "认证失败").toString(); | ||
| 34 | // printWriter.write(body); | ||
| 35 | // printWriter.flush(); | ||
| 36 | // } | ||
| 37 | //} |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.config; | ||
| 18 | |||
| 19 | import org.springblade.auth.support.BladeJwtTokenEnhancer; | ||
| 20 | import org.springblade.core.launch.constant.TokenConstant; | ||
| 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
| 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 23 | import org.springframework.context.annotation.Bean; | ||
| 24 | import org.springframework.context.annotation.Configuration; | ||
| 25 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; | ||
| 26 | import org.springframework.security.oauth2.provider.token.TokenStore; | ||
| 27 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; | ||
| 28 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * JwtTokenStore | ||
| 32 | * | ||
| 33 | * @author Chill | ||
| 34 | */ | ||
| 35 | @Configuration | ||
| 36 | @ConditionalOnProperty(prefix = "blade.security.oauth2", name = "storeType", havingValue = "jwt", matchIfMissing = true) | ||
| 37 | public class JwtTokenStoreConfiguration { | ||
| 38 | |||
| 39 | /** | ||
| 40 | * 使用jwtTokenStore存储token | ||
| 41 | */ | ||
| 42 | @Bean | ||
| 43 | public TokenStore jwtTokenStore() { | ||
| 44 | return new JwtTokenStore(jwtAccessTokenConverter()); | ||
| 45 | } | ||
| 46 | |||
| 47 | /** | ||
| 48 | * 用于生成jwt | ||
| 49 | */ | ||
| 50 | @Bean | ||
| 51 | public JwtAccessTokenConverter jwtAccessTokenConverter() { | ||
| 52 | JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter(); | ||
| 53 | accessTokenConverter.setSigningKey(TokenConstant.SIGN_KEY); | ||
| 54 | return accessTokenConverter; | ||
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * 用于扩展jwt | ||
| 59 | */ | ||
| 60 | @Bean | ||
| 61 | @ConditionalOnMissingBean(name = "jwtTokenEnhancer") | ||
| 62 | public TokenEnhancer jwtTokenEnhancer() { | ||
| 63 | return new BladeJwtTokenEnhancer(); | ||
| 64 | } | ||
| 65 | |||
| 66 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.config; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
| 21 | import org.springframework.context.annotation.Bean; | ||
| 22 | import org.springframework.context.annotation.Configuration; | ||
| 23 | import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
| 24 | import org.springframework.security.oauth2.provider.token.TokenStore; | ||
| 25 | import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * Redis TokenStore | ||
| 29 | * | ||
| 30 | * @author Chill | ||
| 31 | */ | ||
| 32 | @Configuration | ||
| 33 | @AllArgsConstructor | ||
| 34 | public class RedisTokenStoreConfiguration { | ||
| 35 | /** | ||
| 36 | * redis连接工厂 | ||
| 37 | */ | ||
| 38 | private RedisConnectionFactory redisConnectionFactory; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * 用于存放token | ||
| 42 | */ | ||
| 43 | @Bean | ||
| 44 | @ConditionalOnProperty(prefix = "blade.security.oauth2", name = "storeType", havingValue = "redis") | ||
| 45 | public TokenStore redisTokenStore() { | ||
| 46 | return new RedisTokenStore(redisConnectionFactory); | ||
| 47 | } | ||
| 48 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.config; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.SneakyThrows; | ||
| 21 | import org.springblade.auth.support.BladePasswordEncoderFactories; | ||
| 22 | import org.springframework.context.annotation.Bean; | ||
| 23 | import org.springframework.context.annotation.Configuration; | ||
| 24 | import org.springframework.security.authentication.AuthenticationManager; | ||
| 25 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
| 26 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||
| 27 | import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * Security配置 | ||
| 31 | * | ||
| 32 | * @author Chill | ||
| 33 | */ | ||
| 34 | @Configuration | ||
| 35 | @AllArgsConstructor | ||
| 36 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter { | ||
| 37 | |||
| 38 | @Bean | ||
| 39 | @Override | ||
| 40 | @SneakyThrows | ||
| 41 | public AuthenticationManager authenticationManagerBean() { | ||
| 42 | return super.authenticationManagerBean(); | ||
| 43 | } | ||
| 44 | |||
| 45 | @Bean | ||
| 46 | public PasswordEncoder passwordEncoder() { | ||
| 47 | return BladePasswordEncoderFactories.createDelegatingPasswordEncoder(); | ||
| 48 | } | ||
| 49 | |||
| 50 | @Override | ||
| 51 | @SneakyThrows | ||
| 52 | protected void configure(HttpSecurity http) { | ||
| 53 | http.httpBasic().and().csrf().disable(); | ||
| 54 | } | ||
| 55 | |||
| 56 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.constant; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * 授权校验常量 | ||
| 21 | * | ||
| 22 | * @author Chill | ||
| 23 | */ | ||
| 24 | public interface AuthConstant { | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 密码加密规则 | ||
| 28 | */ | ||
| 29 | String ENCRYPT = "{blade}"; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * blade_client表字段 | ||
| 33 | */ | ||
| 34 | String CLIENT_FIELDS = "client_id, CONCAT('{noop}',client_secret) as client_secret, resource_ids, scope, authorized_grant_types, " + | ||
| 35 | "web_server_redirect_uri, authorities, access_token_validity, " + | ||
| 36 | "refresh_token_validity, additional_information, autoapprove"; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * blade_client查询语句 | ||
| 40 | */ | ||
| 41 | String BASE_STATEMENT = "select " + CLIENT_FIELDS + " from blade_client"; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * blade_client查询排序 | ||
| 45 | */ | ||
| 46 | String DEFAULT_FIND_STATEMENT = BASE_STATEMENT + " order by client_id"; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * 查询client_id | ||
| 50 | */ | ||
| 51 | String DEFAULT_SELECT_STATEMENT = BASE_STATEMENT + " where client_id = ?"; | ||
| 52 | |||
| 53 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.endpoint; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springblade.core.tool.api.R; | ||
| 22 | import org.springframework.beans.factory.annotation.Autowired; | ||
| 23 | import org.springframework.beans.factory.annotation.Qualifier; | ||
| 24 | import org.springframework.security.core.Authentication; | ||
| 25 | import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpoint; | ||
| 26 | import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; | ||
| 27 | import org.springframework.web.bind.annotation.*; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * BladeEndPoint | ||
| 31 | * | ||
| 32 | * @author Chill | ||
| 33 | */ | ||
| 34 | @Slf4j | ||
| 35 | @RestController | ||
| 36 | @AllArgsConstructor | ||
| 37 | @FrameworkEndpoint | ||
| 38 | public class BladeTokenEndPoint { | ||
| 39 | |||
| 40 | @GetMapping("/oauth/user-info") | ||
| 41 | public R<Authentication> currentUser(Authentication authentication) { | ||
| 42 | return R.data(authentication); | ||
| 43 | } | ||
| 44 | |||
| 45 | @Autowired | ||
| 46 | ConsumerTokenServices consumerTokenServices; | ||
| 47 | |||
| 48 | @RequestMapping(method = RequestMethod.DELETE, value = "/oauth/token/delete") | ||
| 49 | @ResponseBody | ||
| 50 | public String revokeToken(String access_token) { | ||
| 51 | if (consumerTokenServices.revokeToken(access_token)){ | ||
| 52 | return "注销成功"; | ||
| 53 | }else{ | ||
| 54 | return "注销失败"; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.handler; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springblade.auth.utils.TokenUtil; | ||
| 22 | import org.springblade.core.tool.jackson.JsonUtil; | ||
| 23 | import org.springframework.http.MediaType; | ||
| 24 | import org.springframework.security.core.Authentication; | ||
| 25 | import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 26 | import org.springframework.security.oauth2.common.OAuth2AccessToken; | ||
| 27 | import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException; | ||
| 28 | import org.springframework.security.oauth2.provider.*; | ||
| 29 | import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; | ||
| 30 | import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; | ||
| 31 | import org.springframework.stereotype.Component; | ||
| 32 | |||
| 33 | import javax.servlet.ServletException; | ||
| 34 | import javax.servlet.http.HttpServletRequest; | ||
| 35 | import javax.servlet.http.HttpServletResponse; | ||
| 36 | import java.io.IOException; | ||
| 37 | import java.util.HashMap; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * APP登录成功处理器 | ||
| 41 | * | ||
| 42 | * @author Chill | ||
| 43 | */ | ||
| 44 | @Slf4j | ||
| 45 | @AllArgsConstructor | ||
| 46 | @Component("appLoginInSuccessHandler") | ||
| 47 | public class AppLoginInSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { | ||
| 48 | |||
| 49 | private PasswordEncoder passwordEncoder; | ||
| 50 | |||
| 51 | private ClientDetailsService clientDetailsService; | ||
| 52 | |||
| 53 | private AuthorizationServerTokenServices authorizationServerTokenServices; | ||
| 54 | |||
| 55 | @Override | ||
| 56 | public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException { | ||
| 57 | log.info("【AppLoginInSuccessHandler】 onAuthenticationSuccess authentication={}", authentication); | ||
| 58 | |||
| 59 | String[] tokens = TokenUtil.extractAndDecodeHeader(); | ||
| 60 | assert tokens.length == 2; | ||
| 61 | String clientId = tokens[0]; | ||
| 62 | String clientSecret = tokens[1]; | ||
| 63 | |||
| 64 | ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId); | ||
| 65 | if (clientDetails == null) { | ||
| 66 | throw new UnapprovedClientAuthenticationException("clientId 对应的配置信息不存在" + clientId); | ||
| 67 | } else if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) { | ||
| 68 | throw new UnapprovedClientAuthenticationException("clientSecret 不匹配" + clientId); | ||
| 69 | } | ||
| 70 | |||
| 71 | TokenRequest tokenRequest = new TokenRequest(new HashMap<>(16), clientId, clientDetails.getScope(), "app"); | ||
| 72 | OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails); | ||
| 73 | OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication); | ||
| 74 | OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(oAuth2Authentication); | ||
| 75 | |||
| 76 | response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); | ||
| 77 | response.getWriter().write(JsonUtil.toJson(token)); | ||
| 78 | } | ||
| 79 | |||
| 80 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.service; | ||
| 18 | |||
| 19 | import lombok.SneakyThrows; | ||
| 20 | import org.springframework.security.oauth2.provider.ClientDetails; | ||
| 21 | import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; | ||
| 22 | |||
| 23 | import javax.sql.DataSource; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 客户端信息 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | public class BladeClientDetailsServiceImpl extends JdbcClientDetailsService { | ||
| 31 | |||
| 32 | public BladeClientDetailsServiceImpl(DataSource dataSource) { | ||
| 33 | super(dataSource); | ||
| 34 | } | ||
| 35 | |||
| 36 | /** | ||
| 37 | * 缓存客户端信息 | ||
| 38 | * | ||
| 39 | * @param clientId 客户端id | ||
| 40 | */ | ||
| 41 | @Override | ||
| 42 | @SneakyThrows | ||
| 43 | public ClientDetails loadClientByClientId(String clientId) { | ||
| 44 | return super.loadClientByClientId(clientId); | ||
| 45 | } | ||
| 46 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.service; | ||
| 18 | |||
| 19 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
| 20 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | ||
| 21 | import lombok.Getter; | ||
| 22 | import org.springframework.security.core.GrantedAuthority; | ||
| 23 | import org.springframework.security.core.userdetails.User; | ||
| 24 | |||
| 25 | import java.util.Collection; | ||
| 26 | |||
| 27 | /** | ||
| 28 | * 用户信息拓展 | ||
| 29 | * | ||
| 30 | * @author Chill | ||
| 31 | */ | ||
| 32 | @Getter | ||
| 33 | public class BladeUserDetails extends User { | ||
| 34 | |||
| 35 | /** | ||
| 36 | * 用户id | ||
| 37 | */ | ||
| 38 | @JsonSerialize(using = ToStringSerializer.class) | ||
| 39 | private Long userId; | ||
| 40 | /** | ||
| 41 | * 租户编号 | ||
| 42 | */ | ||
| 43 | private String tenantCode; | ||
| 44 | /** | ||
| 45 | * 昵称 | ||
| 46 | */ | ||
| 47 | private String name; | ||
| 48 | /** | ||
| 49 | * 账号 | ||
| 50 | */ | ||
| 51 | private String account; | ||
| 52 | /** | ||
| 53 | * 角色id | ||
| 54 | */ | ||
| 55 | private String roleId; | ||
| 56 | /** | ||
| 57 | * 角色名 | ||
| 58 | */ | ||
| 59 | private String roleName; | ||
| 60 | /** | ||
| 61 | * 头像 | ||
| 62 | */ | ||
| 63 | private String avatar; | ||
| 64 | |||
| 65 | private Integer type; | ||
| 66 | |||
| 67 | BladeUserDetails(Long userId, String tenantCode, String name, String roleId, String roleName, String avatar, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities,Integer type) { | ||
| 68 | super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); | ||
| 69 | this.userId = userId; | ||
| 70 | this.tenantCode = tenantCode; | ||
| 71 | this.name = name; | ||
| 72 | this.account = username; | ||
| 73 | this.roleId = roleId; | ||
| 74 | this.roleName = roleName; | ||
| 75 | this.avatar = avatar; | ||
| 76 | this.type=type; | ||
| 77 | } | ||
| 78 | |||
| 79 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.service; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.SneakyThrows; | ||
| 21 | import org.springblade.auth.constant.AuthConstant; | ||
| 22 | import org.springblade.auth.utils.TokenUtil; | ||
| 23 | import org.springblade.core.tool.api.R; | ||
| 24 | import org.springblade.core.tool.utils.Func; | ||
| 25 | import org.springblade.core.tool.utils.WebUtil; | ||
| 26 | import org.springblade.system.user.entity.User; | ||
| 27 | import org.springblade.system.user.entity.UserInfo; | ||
| 28 | import org.springblade.system.user.feign.IUserClient; | ||
| 29 | import org.springframework.security.core.authority.AuthorityUtils; | ||
| 30 | import org.springframework.security.core.userdetails.UserDetails; | ||
| 31 | import org.springframework.security.core.userdetails.UserDetailsService; | ||
| 32 | import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
| 33 | import org.springframework.stereotype.Service; | ||
| 34 | |||
| 35 | import javax.servlet.http.HttpServletRequest; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * 用户信息 | ||
| 39 | * | ||
| 40 | * @author Chill | ||
| 41 | */ | ||
| 42 | @Service | ||
| 43 | @AllArgsConstructor | ||
| 44 | public class BladeUserDetailsServiceImpl implements UserDetailsService { | ||
| 45 | |||
| 46 | private IUserClient userClient; | ||
| 47 | |||
| 48 | @Override | ||
| 49 | @SneakyThrows | ||
| 50 | public UserDetails loadUserByUsername(String username) { | ||
| 51 | HttpServletRequest request = WebUtil.getRequest(); | ||
| 52 | String tenantCode = Func.toStr(request.getHeader(TokenUtil.TENANT_HEADER_KEY), TokenUtil.DEFAULT_TENANT_CODE); | ||
| 53 | R<UserInfo> result = userClient.userInfo(tenantCode, username); | ||
| 54 | if (result.isSuccess()) { | ||
| 55 | User user = result.getData().getUser(); | ||
| 56 | if (user == null) { | ||
| 57 | throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND); | ||
| 58 | } | ||
| 59 | return new BladeUserDetails(user.getId(), | ||
| 60 | user.getTenantCode(), user.getName(), user.getRoleId(), Func.join(result.getData().getRoles()), TokenUtil.DEFAULT_AVATAR, | ||
| 61 | username, AuthConstant.ENCRYPT + user.getPassword(), true, true, true, true, | ||
| 62 | AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result.getData().getRoles())),user.getType()); | ||
| 63 | } else { | ||
| 64 | throw new UsernameNotFoundException(result.getMsg()); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.support; | ||
| 18 | |||
| 19 | import org.springblade.auth.service.BladeUserDetails; | ||
| 20 | import org.springblade.auth.utils.TokenUtil; | ||
| 21 | import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; | ||
| 22 | import org.springframework.security.oauth2.common.OAuth2AccessToken; | ||
| 23 | import org.springframework.security.oauth2.provider.OAuth2Authentication; | ||
| 24 | import org.springframework.security.oauth2.provider.token.TokenEnhancer; | ||
| 25 | |||
| 26 | import java.util.HashMap; | ||
| 27 | import java.util.Map; | ||
| 28 | |||
| 29 | /** | ||
| 30 | * jwt返回参数增强 | ||
| 31 | * | ||
| 32 | * @author Chill | ||
| 33 | */ | ||
| 34 | public class BladeJwtTokenEnhancer implements TokenEnhancer { | ||
| 35 | @Override | ||
| 36 | public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { | ||
| 37 | BladeUserDetails principal = (BladeUserDetails) authentication.getUserAuthentication().getPrincipal(); | ||
| 38 | Map<String, Object> info = new HashMap<>(16); | ||
| 39 | info.put(TokenUtil.CLIENT_ID, TokenUtil.getClientIdFromHeader()); | ||
| 40 | info.put(TokenUtil.USER_ID, principal.getUserId()); | ||
| 41 | info.put(TokenUtil.ROLE_ID, principal.getRoleId()); | ||
| 42 | info.put(TokenUtil.TENANT_CODE, principal.getTenantCode()); | ||
| 43 | info.put(TokenUtil.ACCOUNT, principal.getAccount()); | ||
| 44 | info.put(TokenUtil.USER_NAME, principal.getUsername()); | ||
| 45 | info.put(TokenUtil.NICK_NAME, principal.getName()); | ||
| 46 | info.put(TokenUtil.ROLE_NAME, principal.getRoleName()); | ||
| 47 | info.put(TokenUtil.AVATAR, principal.getAvatar()); | ||
| 48 | info.put(TokenUtil.LICENSE, TokenUtil.LICENSE_NAME); | ||
| 49 | ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info); | ||
| 50 | return accessToken; | ||
| 51 | } | ||
| 52 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.support; | ||
| 18 | |||
| 19 | import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * 无密码加密 | ||
| 23 | * | ||
| 24 | * @author Chill | ||
| 25 | */ | ||
| 26 | public class BladeNoOpPasswordEncoder implements PasswordEncoder { | ||
| 27 | |||
| 28 | @Override | ||
| 29 | public String encode(CharSequence rawPassword) { | ||
| 30 | return rawPassword.toString(); | ||
| 31 | } | ||
| 32 | |||
| 33 | @Override | ||
| 34 | public boolean matches(CharSequence rawPassword, String encodedPassword) { | ||
| 35 | return rawPassword.toString().equals(encodedPassword); | ||
| 36 | } | ||
| 37 | |||
| 38 | /** | ||
| 39 | * Get the singleton {@link BladeNoOpPasswordEncoder}. | ||
| 40 | */ | ||
| 41 | public static PasswordEncoder getInstance() { | ||
| 42 | return INSTANCE; | ||
| 43 | } | ||
| 44 | |||
| 45 | private static final PasswordEncoder INSTANCE = new BladeNoOpPasswordEncoder(); | ||
| 46 | |||
| 47 | private BladeNoOpPasswordEncoder() { | ||
| 48 | } | ||
| 49 | |||
| 50 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.support; | ||
| 18 | |||
| 19 | import org.springblade.core.tool.utils.DigestUtil; | ||
| 20 | import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 21 | |||
| 22 | /** | ||
| 23 | * 自定义密码加密 | ||
| 24 | * | ||
| 25 | * @author Chill | ||
| 26 | */ | ||
| 27 | public class BladePasswordEncoder implements PasswordEncoder { | ||
| 28 | |||
| 29 | @Override | ||
| 30 | public String encode(CharSequence rawPassword) { | ||
| 31 | return DigestUtil.encrypt((String) rawPassword); | ||
| 32 | } | ||
| 33 | |||
| 34 | @Override | ||
| 35 | public boolean matches(CharSequence rawPassword, String encodedPassword) { | ||
| 36 | return encodedPassword.equals(encode(rawPassword)); | ||
| 37 | } | ||
| 38 | |||
| 39 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.support; | ||
| 18 | |||
| 19 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| 20 | import org.springframework.security.crypto.password.DelegatingPasswordEncoder; | ||
| 21 | import org.springframework.security.crypto.password.PasswordEncoder; | ||
| 22 | import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder; | ||
| 23 | import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder; | ||
| 24 | |||
| 25 | import java.util.HashMap; | ||
| 26 | import java.util.Map; | ||
| 27 | |||
| 28 | /** | ||
| 29 | * 自定义密码工厂 | ||
| 30 | * | ||
| 31 | * @author Chill | ||
| 32 | */ | ||
| 33 | public class BladePasswordEncoderFactories { | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Creates a {@link DelegatingPasswordEncoder} with default mappings. Additional | ||
| 37 | * mappings may be added and the encoding will be updated to conform with best | ||
| 38 | * practices. However, due to the nature of {@link DelegatingPasswordEncoder} the | ||
| 39 | * updates should not impact users. The mappings current are: | ||
| 40 | * | ||
| 41 | * <ul> | ||
| 42 | * <li>blade - {@link BladePasswordEncoder} (sha1(md5("password")))</li> | ||
| 43 | * <li>bcrypt - {@link BCryptPasswordEncoder} (Also used for encoding)</li> | ||
| 44 | * <li>noop - {@link BladeNoOpPasswordEncoder}</li> | ||
| 45 | * <li>pbkdf2 - {@link Pbkdf2PasswordEncoder}</li> | ||
| 46 | * <li>scrypt - {@link SCryptPasswordEncoder}</li> | ||
| 47 | * </ul> | ||
| 48 | * | ||
| 49 | * @return the {@link PasswordEncoder} to use | ||
| 50 | */ | ||
| 51 | @SuppressWarnings("deprecation") | ||
| 52 | public static PasswordEncoder createDelegatingPasswordEncoder() { | ||
| 53 | String encodingId = "blade"; | ||
| 54 | Map<String, PasswordEncoder> encoders = new HashMap<>(16); | ||
| 55 | encoders.put(encodingId, new BladePasswordEncoder()); | ||
| 56 | encoders.put("bcrypt", new BCryptPasswordEncoder()); | ||
| 57 | encoders.put("noop", BladeNoOpPasswordEncoder.getInstance()); | ||
| 58 | encoders.put("pbkdf2", new Pbkdf2PasswordEncoder()); | ||
| 59 | encoders.put("scrypt", new SCryptPasswordEncoder()); | ||
| 60 | |||
| 61 | return new DelegatingPasswordEncoder(encodingId, encoders); | ||
| 62 | } | ||
| 63 | |||
| 64 | private BladePasswordEncoderFactories() { | ||
| 65 | } | ||
| 66 | |||
| 67 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.auth.utils; | ||
| 18 | |||
| 19 | import lombok.SneakyThrows; | ||
| 20 | import org.springblade.core.launch.constant.TokenConstant; | ||
| 21 | import org.springblade.core.tool.utils.Charsets; | ||
| 22 | import org.springblade.core.tool.utils.StringPool; | ||
| 23 | import org.springblade.core.tool.utils.WebUtil; | ||
| 24 | import org.springframework.security.authentication.BadCredentialsException; | ||
| 25 | import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException; | ||
| 26 | |||
| 27 | import java.util.Base64; | ||
| 28 | import java.util.Calendar; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * 认证工具类 | ||
| 32 | * | ||
| 33 | * @author Chill | ||
| 34 | */ | ||
| 35 | public class TokenUtil { | ||
| 36 | |||
| 37 | public final static String AVATAR = TokenConstant.AVATAR; | ||
| 38 | public final static String ACCOUNT = TokenConstant.ACCOUNT; | ||
| 39 | public final static String USER_NAME = TokenConstant.USER_NAME; | ||
| 40 | public final static String NICK_NAME = TokenConstant.NICK_NAME; | ||
| 41 | public final static String USER_ID = TokenConstant.USER_ID; | ||
| 42 | public final static String ROLE_ID = TokenConstant.ROLE_ID; | ||
| 43 | public final static String ROLE_NAME = TokenConstant.ROLE_NAME; | ||
| 44 | public final static String TENANT_CODE = TokenConstant.TENANT_CODE; | ||
| 45 | public final static String CLIENT_ID = TokenConstant.CLIENT_ID; | ||
| 46 | public final static String LICENSE = TokenConstant.LICENSE; | ||
| 47 | public final static String LICENSE_NAME = TokenConstant.LICENSE_NAME; | ||
| 48 | |||
| 49 | |||
| 50 | public final static String TENANT_HEADER_KEY = "Tenant-Code"; | ||
| 51 | public final static String DEFAULT_TENANT_CODE = "000000"; | ||
| 52 | public final static String USER_NOT_FOUND = "用户名或密码错误"; | ||
| 53 | public final static String HEADER_KEY = "Authorization"; | ||
| 54 | public final static String HEADER_PREFIX = "Basic "; | ||
| 55 | public final static String DEFAULT_AVATAR = "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png"; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * 解码 | ||
| 59 | */ | ||
| 60 | @SneakyThrows | ||
| 61 | public static String[] extractAndDecodeHeader() { | ||
| 62 | String header = WebUtil.getRequest().getHeader(TokenUtil.HEADER_KEY); | ||
| 63 | if (header == null || !header.startsWith(TokenUtil.HEADER_PREFIX)) { | ||
| 64 | throw new UnapprovedClientAuthenticationException("请求头中无client信息"); | ||
| 65 | } | ||
| 66 | |||
| 67 | byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME); | ||
| 68 | |||
| 69 | byte[] decoded; | ||
| 70 | try { | ||
| 71 | decoded = Base64.getDecoder().decode(base64Token); | ||
| 72 | } catch (IllegalArgumentException var7) { | ||
| 73 | throw new BadCredentialsException("Failed to decode basic authentication token"); | ||
| 74 | } | ||
| 75 | |||
| 76 | String token = new String(decoded, Charsets.UTF_8_NAME); | ||
| 77 | int index = token.indexOf(StringPool.COLON); | ||
| 78 | if (index == -1) { | ||
| 79 | throw new BadCredentialsException("Invalid basic authentication token"); | ||
| 80 | } else { | ||
| 81 | return new String[]{token.substring(0, index), token.substring(index + 1)}; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /** | ||
| 86 | * 获取请求头中的客户端id | ||
| 87 | */ | ||
| 88 | public static String getClientIdFromHeader() { | ||
| 89 | String[] tokens = extractAndDecodeHeader(); | ||
| 90 | assert tokens.length == 2; | ||
| 91 | return tokens[0]; | ||
| 92 | } | ||
| 93 | |||
| 94 | /** | ||
| 95 | * 获取token过期时间(次日凌晨3点) | ||
| 96 | * | ||
| 97 | * @return expire | ||
| 98 | */ | ||
| 99 | public static int getTokenValiditySecond() { | ||
| 100 | Calendar cal = Calendar.getInstance(); | ||
| 101 | cal.add(Calendar.DAY_OF_YEAR, 1); | ||
| 102 | cal.set(Calendar.HOUR_OF_DAY, 3); | ||
| 103 | cal.set(Calendar.SECOND, 0); | ||
| 104 | cal.set(Calendar.MINUTE, 0); | ||
| 105 | cal.set(Calendar.MILLISECOND, 0); | ||
| 106 | return (int) (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000; | ||
| 107 | } | ||
| 108 | |||
| 109 | /** | ||
| 110 | * 获取refreshToken过期时间 | ||
| 111 | * | ||
| 112 | * @return expire | ||
| 113 | */ | ||
| 114 | public static int getRefreshTokenValiditySeconds() { | ||
| 115 | return 60 * 60 * 24 * 15; | ||
| 116 | } | ||
| 117 | |||
| 118 | } |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | <parent> | ||
| 6 | <artifactId>BladeX</artifactId> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <version>2.0.0.RELEASE</version> | ||
| 9 | </parent> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | ||
| 11 | |||
| 12 | <artifactId>blade-common</artifactId> | ||
| 13 | <name>${project.artifactId}</name> | ||
| 14 | <version>${bladex.project.version}</version> | ||
| 15 | <packaging>jar</packaging> | ||
| 16 | |||
| 17 | <dependencies> | ||
| 18 | <dependency> | ||
| 19 | <groupId>org.springblade</groupId> | ||
| 20 | <artifactId>blade-core-launch</artifactId> | ||
| 21 | <version>${bladex.tool.version}</version> | ||
| 22 | </dependency> | ||
| 23 | <dependency> | ||
| 24 | <groupId>org.springblade</groupId> | ||
| 25 | <artifactId>blade-core-auto</artifactId> | ||
| 26 | <version>${bladex.tool.version}</version> | ||
| 27 | <scope>provided</scope> | ||
| 28 | </dependency> | ||
| 29 | <!--<dependency> | ||
| 30 | <groupId>org.springblade</groupId> | ||
| 31 | <artifactId>blade-core-tool</artifactId> | ||
| 32 | <version>${bladex.tool.version}</version> | ||
| 33 | </dependency>--> | ||
| 34 | <!--<dependency>--> | ||
| 35 | <!--<groupId>com.aliyun</groupId>--> | ||
| 36 | <!--<artifactId>aliyun-java-sdk-core</artifactId>--> | ||
| 37 | <!--<version>4.1.0</version>--> | ||
| 38 | <!--</dependency>--> | ||
| 39 | </dependencies> | ||
| 40 | |||
| 41 | <build> | ||
| 42 | <plugins> | ||
| 43 | <plugin> | ||
| 44 | <groupId>org.springframework.boot</groupId> | ||
| 45 | <artifactId>spring-boot-maven-plugin</artifactId> | ||
| 46 | <configuration> | ||
| 47 | <skip>true</skip> | ||
| 48 | <finalName>${project.name}</finalName> | ||
| 49 | </configuration> | ||
| 50 | </plugin> | ||
| 51 | <plugin> | ||
| 52 | <groupId>com.spotify</groupId> | ||
| 53 | <artifactId>docker-maven-plugin</artifactId> | ||
| 54 | <version>${docker.plugin.version}</version> | ||
| 55 | <configuration> | ||
| 56 | <skipDockerBuild>true</skipDockerBuild> | ||
| 57 | </configuration> | ||
| 58 | </plugin> | ||
| 59 | </plugins> | ||
| 60 | </build> | ||
| 61 | |||
| 62 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.common.cache; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * 缓存名 | ||
| 21 | * | ||
| 22 | * @author Chill | ||
| 23 | */ | ||
| 24 | public interface CacheNames { | ||
| 25 | |||
| 26 | String NOTICE_ONE = "notice:one"; | ||
| 27 | |||
| 28 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.common.config; | ||
| 18 | |||
| 19 | |||
| 20 | import lombok.AllArgsConstructor; | ||
| 21 | import org.springframework.context.annotation.Configuration; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * 公共封装包配置类 | ||
| 25 | * | ||
| 26 | * @author Chill | ||
| 27 | */ | ||
| 28 | @Configuration | ||
| 29 | @AllArgsConstructor | ||
| 30 | public class BladeCommonConfiguration { | ||
| 31 | |||
| 32 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.common.constant; | ||
| 18 | |||
| 19 | import org.springblade.core.launch.constant.AppConstant; | ||
| 20 | |||
| 21 | /** | ||
| 22 | * 通用常量 | ||
| 23 | * | ||
| 24 | * @author Chill | ||
| 25 | */ | ||
| 26 | public interface CommonConstant { | ||
| 27 | |||
| 28 | /**118.31.247.145 | ||
| 29 | * nacos dev 地址 | ||
| 30 | */ | ||
| 31 | String NACOS_DEV_ADDR = "118.31.247.145:8848"; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * nacos prod 地址 | ||
| 35 | */ | ||
| 36 | String NACOS_PROD_ADDR = "118.31.247.145:8848"; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * nacos test 地址 | ||
| 40 | */ | ||
| 41 | String NACOS_TEST_ADDR = "118.31.247.145:8848"; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * sentinel dev 地址 | ||
| 45 | */ | ||
| 46 | String SENTINEL_DEV_ADDR = "118.31.247.145:8858"; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * sentinel prod 地址 | ||
| 50 | */ | ||
| 51 | String SENTINEL_PROD_ADDR = "118.31.247.145:8858"; | ||
| 52 | |||
| 53 | /** | ||
| 54 | * sentinel test 地址 | ||
| 55 | */ | ||
| 56 | String SENTINEL_TEST_ADDR = "118.31.247.145:8858"; | ||
| 57 | |||
| 58 | /** | ||
| 59 | * sword 系统名 | ||
| 60 | */ | ||
| 61 | String SWORD_NAME = "sword"; | ||
| 62 | |||
| 63 | /** | ||
| 64 | * saber 系统名 | ||
| 65 | */ | ||
| 66 | String SABER_NAME = "saber"; | ||
| 67 | |||
| 68 | /** | ||
| 69 | * 顶级父节点id | ||
| 70 | */ | ||
| 71 | Long TOP_PARENT_ID = 0L; | ||
| 72 | |||
| 73 | /** | ||
| 74 | * 顶级父节点名称 | ||
| 75 | */ | ||
| 76 | String TOP_PARENT_NAME = "顶级"; | ||
| 77 | |||
| 78 | |||
| 79 | /** | ||
| 80 | * 默认密码 | ||
| 81 | */ | ||
| 82 | String DEFAULT_PASSWORD = "654321"; | ||
| 83 | |||
| 84 | /** | ||
| 85 | * 动态获取nacos地址 | ||
| 86 | * | ||
| 87 | * @param profile 环境变量 | ||
| 88 | * @return addr | ||
| 89 | */ | ||
| 90 | static String nacosAddr(String profile) { | ||
| 91 | switch (profile) { | ||
| 92 | case (AppConstant.PROD_CODE): | ||
| 93 | return NACOS_PROD_ADDR; | ||
| 94 | case (AppConstant.TEST_CODE): | ||
| 95 | return NACOS_TEST_ADDR; | ||
| 96 | default: | ||
| 97 | return NACOS_DEV_ADDR; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * 动态获取sentinel地址 | ||
| 103 | * | ||
| 104 | * @param profile 环境变量 | ||
| 105 | * @return addr | ||
| 106 | */ | ||
| 107 | static String sentinelAddr(String profile) { | ||
| 108 | switch (profile) { | ||
| 109 | case (AppConstant.PROD_CODE): | ||
| 110 | return SENTINEL_PROD_ADDR; | ||
| 111 | case (AppConstant.TEST_CODE): | ||
| 112 | return SENTINEL_TEST_ADDR; | ||
| 113 | default: | ||
| 114 | return SENTINEL_DEV_ADDR; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.common.launch; | ||
| 18 | |||
| 19 | import org.springblade.common.constant.CommonConstant; | ||
| 20 | import org.springblade.core.auto.service.AutoService; | ||
| 21 | import org.springblade.core.launch.service.LauncherService; | ||
| 22 | import org.springframework.boot.builder.SpringApplicationBuilder; | ||
| 23 | |||
| 24 | import java.util.Properties; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 启动参数拓展 | ||
| 28 | * | ||
| 29 | * @author smallchil | ||
| 30 | */ | ||
| 31 | @AutoService(LauncherService.class) | ||
| 32 | public class LauncherServiceImpl implements LauncherService { | ||
| 33 | |||
| 34 | @Override | ||
| 35 | public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) { | ||
| 36 | Properties props = System.getProperties(); | ||
| 37 | props.setProperty("spring.cloud.nacos.discovery.server-addr", CommonConstant.nacosAddr(profile)); | ||
| 38 | props.setProperty("spring.cloud.nacos.config.server-addr", CommonConstant.nacosAddr(profile)); | ||
| 39 | props.setProperty("spring.cloud.sentinel.transport.dashboard", CommonConstant.sentinelAddr(profile)); | ||
| 40 | } | ||
| 41 | |||
| 42 | } |
| 1 | package org.springblade.common.utils; | ||
| 2 | |||
| 3 | public class CommonPageUtil { | ||
| 4 | /** | ||
| 5 | * 获取limit start | ||
| 6 | * @param pageIndex | ||
| 7 | * @param pageSize | ||
| 8 | * @return | ||
| 9 | */ | ||
| 10 | public static Integer startIndex(Integer pageIndex,Integer pageSize){ | ||
| 11 | if(pageIndex == null || pageIndex < 1){ | ||
| 12 | return 0; | ||
| 13 | }else if(pageSize == null || pageSize < 1){ | ||
| 14 | pageSize = 15; | ||
| 15 | } | ||
| 16 | return (pageIndex -1)*pageSize; | ||
| 17 | } | ||
| 18 | |||
| 19 | /** | ||
| 20 | * 获取limit size | ||
| 21 | * @param pageSize | ||
| 22 | * @return | ||
| 23 | */ | ||
| 24 | public static Integer pageSize(Integer pageSize){ | ||
| 25 | if(pageSize == null || pageSize < 1){ | ||
| 26 | return 15; | ||
| 27 | } | ||
| 28 | return pageSize; | ||
| 29 | } | ||
| 30 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.common.utils; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * 通用工具类 | ||
| 21 | * | ||
| 22 | * @author Chill | ||
| 23 | */ | ||
| 24 | public class CommonUtil { | ||
| 25 | |||
| 26 | } |
| 1 | package org.springblade.common.utils; | ||
| 2 | |||
| 3 | import org.springframework.util.ObjectUtils; | ||
| 4 | |||
| 5 | import java.sql.Array; | ||
| 6 | import java.text.SimpleDateFormat; | ||
| 7 | import java.util.ArrayList; | ||
| 8 | import java.util.Date; | ||
| 9 | |||
| 10 | public class OrderNoUtil { | ||
| 11 | |||
| 12 | public static String getOrderNoForRepare(){ | ||
| 13 | Date t = new Date(); | ||
| 14 | |||
| 15 | SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); | ||
| 16 | String orderNo = df.format(t)+getRandomNo(4); | ||
| 17 | return orderNo; | ||
| 18 | } | ||
| 19 | |||
| 20 | public static String getRandomNo(int length ){ | ||
| 21 | String result = ""; | ||
| 22 | java.util.Random r=new java.util.Random(); | ||
| 23 | for(int i=0;i<length;i++){ | ||
| 24 | result +=r.nextInt(); | ||
| 25 | } | ||
| 26 | return result; | ||
| 27 | } | ||
| 28 | public static String getSimNO(){ | ||
| 29 | Date t = new Date(); | ||
| 30 | |||
| 31 | SimpleDateFormat df = new SimpleDateFormat("yyMMddHHmmss"); | ||
| 32 | String orderNo = df.format(t)+getRandomNo(2).replaceAll("-",""); | ||
| 33 | for(int i=0;i<(32-orderNo.length());i++){ | ||
| 34 | orderNo += "0"; | ||
| 35 | } | ||
| 36 | return orderNo; | ||
| 37 | } | ||
| 38 | |||
| 39 | } |
| 1 | package org.springblade.common.utils.captcha; | ||
| 2 | |||
| 3 | import lombok.Data; | ||
| 4 | |||
| 5 | import java.awt.image.BufferedImage; | ||
| 6 | |||
| 7 | /** | ||
| 8 | * @author 吕鸿磊 | ||
| 9 | * @date 2019-07-30 18:39 | ||
| 10 | */ | ||
| 11 | @Data | ||
| 12 | public class CaptchaBean { | ||
| 13 | private String result; | ||
| 14 | private String[] codeArray; | ||
| 15 | private BufferedImage bufferedImage; | ||
| 16 | } |
| 1 | package org.springblade.common.utils.captcha; | ||
| 2 | |||
| 3 | import java.awt.*; | ||
| 4 | import java.awt.geom.AffineTransform; | ||
| 5 | import java.awt.image.BufferedImage; | ||
| 6 | import java.util.Random; | ||
| 7 | |||
| 8 | /** | ||
| 9 | * @author 吕鸿磊 | ||
| 10 | * @date 2019-07-30 17:52 | ||
| 11 | */ | ||
| 12 | public class CaptchaUtil { | ||
| 13 | private static char[] ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); | ||
| 14 | int codecnt=4; | ||
| 15 | Random random = new Random(); | ||
| 16 | int width = 90; | ||
| 17 | int height = 30; | ||
| 18 | int lineNum = 2; | ||
| 19 | Color color = new Color(253, 251, 255); | ||
| 20 | boolean transform=false; | ||
| 21 | |||
| 22 | public static void main(String[] args) { | ||
| 23 | CaptchaBean captchaBean = new CaptchaUtil().generateCaptcha(); | ||
| 24 | System.out.println(captchaBean.toString()); | ||
| 25 | } | ||
| 26 | public static CaptchaBean getCaptcha(){ | ||
| 27 | return new CaptchaUtil().generateCaptcha(); | ||
| 28 | } | ||
| 29 | |||
| 30 | public CaptchaBean generateCaptcha() { | ||
| 31 | // 1.build image | ||
| 32 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); | ||
| 33 | Graphics graphics = image.getGraphics(); | ||
| 34 | graphics.setColor(color); | ||
| 35 | // graphics.setColor(getRandColor(200, 250)); | ||
| 36 | graphics.fillRect(0, 0, width, height); | ||
| 37 | |||
| 38 | //2.mixSource | ||
| 39 | mixSource(image); | ||
| 40 | |||
| 41 | //3.drawCode | ||
| 42 | CaptchaBean result = drawCode(graphics); | ||
| 43 | result.setBufferedImage(image); | ||
| 44 | return result; | ||
| 45 | } | ||
| 46 | |||
| 47 | public CaptchaBean generateCode() { | ||
| 48 | CaptchaBean captchaBean = new CaptchaBean(); | ||
| 49 | String[] codeArray = new String[codecnt]; | ||
| 50 | StringBuffer builder = new StringBuffer(); | ||
| 51 | for (int i = 0; i < codecnt; i++) { | ||
| 52 | char c = ch[random.nextInt(ch.length)]; | ||
| 53 | String ch = String.valueOf(c); | ||
| 54 | codeArray[i] = ch; | ||
| 55 | builder.append(ch); | ||
| 56 | } | ||
| 57 | captchaBean.setCodeArray(codeArray); | ||
| 58 | captchaBean.setResult(builder.toString()); | ||
| 59 | return captchaBean; | ||
| 60 | } | ||
| 61 | |||
| 62 | public void mixSource(BufferedImage image) { | ||
| 63 | drawPoint(image); | ||
| 64 | drawLine(image); | ||
| 65 | } | ||
| 66 | |||
| 67 | public void drawLine(BufferedImage image) { | ||
| 68 | Graphics graphics = image.getGraphics(); | ||
| 69 | for (int i = 0; i < lineNum; i++) { | ||
| 70 | int xs = random.nextInt(width); | ||
| 71 | int ys = random.nextInt(height); | ||
| 72 | int xe = xs + random.nextInt(width); | ||
| 73 | int ye = ys + random.nextInt(height); | ||
| 74 | graphics.setColor(getRandColor(1, 255)); | ||
| 75 | graphics.drawLine(xs, ys, xe, ye); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | public void drawPoint(BufferedImage image) { | ||
| 80 | // 添加噪点 | ||
| 81 | float yawpRate = 0.05f;// 噪声率 | ||
| 82 | int area = (int) (yawpRate * width * height); | ||
| 83 | for (int i = 0; i < area; i++) { | ||
| 84 | int x = random.nextInt(width); | ||
| 85 | int y = random.nextInt(height); | ||
| 86 | image.setRGB(x, y, random.nextInt(255)); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | public CaptchaBean drawCode(Graphics graphics) { | ||
| 91 | //1.genarate code | ||
| 92 | CaptchaBean captcha = generateCode(); | ||
| 93 | |||
| 94 | //2.drapCode | ||
| 95 | Font font = getFont(16); | ||
| 96 | graphics.setFont(font); | ||
| 97 | if(captcha!=null&&captcha.getCodeArray()!=null | ||
| 98 | &&captcha.getResult()!=null&&captcha.getCodeArray().length>0) { | ||
| 99 | for(int i=0;i<captcha.getCodeArray().length;i++) { | ||
| 100 | String code = String.valueOf(captcha.getCodeArray()[i]); | ||
| 101 | |||
| 102 | // 文字变形设置 | ||
| 103 | if(transform) { | ||
| 104 | AffineTransform fontAT = new AffineTransform(); | ||
| 105 | int rotate = random.nextInt(25); | ||
| 106 | fontAT.rotate(random.nextBoolean() ? Math.toRadians(rotate) : -Math | ||
| 107 | .toRadians(rotate / 2)); | ||
| 108 | Font fx = new Font(new String[] { "Times New Roman", "Verdana", | ||
| 109 | "arial" }[random.nextInt(2)], random.nextInt(5), | ||
| 110 | 14 + random.nextInt(8)).deriveFont(fontAT); | ||
| 111 | graphics.setFont(fx); | ||
| 112 | } | ||
| 113 | |||
| 114 | // 产生随机的颜色分量来构造颜色值,这样输出的每一位数字的颜色值都不同 | ||
| 115 | // int red = random.nextInt(255); | ||
| 116 | // int green = random.nextInt(255); | ||
| 117 | // int blue = random.nextInt(255); | ||
| 118 | // 将随机产生的颜色将验证码绘制到图像中 | ||
| 119 | graphics.setColor(getRandColor(1, 255)); | ||
| 120 | // graphics.drawString(code, (i*20)+5, 10+random.nextInt(10)); | ||
| 121 | graphics.drawString(code, (i*width/5)+5, height/2+ random.nextInt(height/4)); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | return captcha; | ||
| 125 | } | ||
| 126 | |||
| 127 | // 得到随机颜色 | ||
| 128 | public Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色 | ||
| 129 | if (fc > 255) { | ||
| 130 | fc = 255; | ||
| 131 | } | ||
| 132 | if (bc > 255) { | ||
| 133 | bc = 255; | ||
| 134 | } | ||
| 135 | int r = fc + random.nextInt(bc - fc); | ||
| 136 | int g = fc + random.nextInt(bc - fc); | ||
| 137 | int b = fc + random.nextInt(bc - fc); | ||
| 138 | return new Color(r, g, b); | ||
| 139 | } | ||
| 140 | |||
| 141 | private Font getFont(int size) { | ||
| 142 | Random random = new Random(); | ||
| 143 | Font font[] = new Font[5]; | ||
| 144 | font[0] = new Font("Ravie", Font.BOLD, size); | ||
| 145 | font[1] = new Font("Antique Olive Compact", Font.BOLD, size); | ||
| 146 | font[2] = new Font("Fixedsys", Font.BOLD, size); | ||
| 147 | font[3] = new Font("Wide Latin", Font.BOLD, size); | ||
| 148 | font[4] = new Font("Gill Sans Ultra Bold", Font.BOLD, size); | ||
| 149 | return font[random.nextInt(5)]; | ||
| 150 | } | ||
| 151 | |||
| 152 | } | ||
| 153 | |||
| 154 |
| 1 | ${AnsiColor.BLUE} ______ _ _ ___ ___ | ||
| 2 | ${AnsiColor.BLUE} | ___ \| | | | \ \ / / | ||
| 3 | ${AnsiColor.BLUE} | |_/ /| | __ _ __| | ___ \ V / | ||
| 4 | ${AnsiColor.BLUE} | ___ \| | / _` | / _` | / _ \ > < | ||
| 5 | ${AnsiColor.BLUE} | |_/ /| || (_| || (_| || __/ / . \ | ||
| 6 | ${AnsiColor.BLUE} \____/ |_| \__,_| \__,_| \___|/__/ \__\ | ||
| 7 | |||
| 8 | ${AnsiColor.BLUE}:: BladeX :: ${spring.application.name}:${AnsiColor.RED}${blade.env}${AnsiColor.BLUE} :: Running SpringBoot ${spring-boot.version} :: ${AnsiColor.BRIGHT_BLACK} |
| 1 | FROM anapsix/alpine-java:8_server-jre_unlimited | ||
| 2 | |||
| 3 | MAINTAINER smallchill@163.com | ||
| 4 | |||
| 5 | RUN mkdir -p /blade/gateway | ||
| 6 | |||
| 7 | WORKDIR /blade/gateway | ||
| 8 | |||
| 9 | EXPOSE 80 | ||
| 10 | |||
| 11 | ADD ./target/blade-gateway.jar ./app.jar | ||
| 12 | |||
| 13 | ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"] | ||
| 14 | |||
| 15 | CMD ["--spring.profiles.active=test"] |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | <parent> | ||
| 6 | <artifactId>BladeX</artifactId> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <version>2.0.0.RELEASE</version> | ||
| 9 | </parent> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | ||
| 11 | |||
| 12 | <artifactId>blade-gateway</artifactId> | ||
| 13 | <name>${project.artifactId}</name> | ||
| 14 | <version>${bladex.project.version}</version> | ||
| 15 | <packaging>jar</packaging> | ||
| 16 | |||
| 17 | <dependencies> | ||
| 18 | <!--Blade--> | ||
| 19 | <dependency> | ||
| 20 | <groupId>org.springblade</groupId> | ||
| 21 | <artifactId>blade-core-launch</artifactId> | ||
| 22 | <version>${bladex.tool.version}</version> | ||
| 23 | <exclusions> | ||
| 24 | <exclusion> | ||
| 25 | <groupId>org.springframework.boot</groupId> | ||
| 26 | <artifactId>spring-boot-starter-web</artifactId> | ||
| 27 | </exclusion> | ||
| 28 | <exclusion> | ||
| 29 | <groupId>org.springframework.boot</groupId> | ||
| 30 | <artifactId>spring-boot-starter-undertow</artifactId> | ||
| 31 | </exclusion> | ||
| 32 | </exclusions> | ||
| 33 | </dependency> | ||
| 34 | <dependency> | ||
| 35 | <groupId>org.springblade</groupId> | ||
| 36 | <artifactId>blade-common</artifactId> | ||
| 37 | <version>${bladex.project.version}</version> | ||
| 38 | <exclusions> | ||
| 39 | <exclusion> | ||
| 40 | <groupId>org.springblade</groupId> | ||
| 41 | <artifactId>blade-core-launch</artifactId> | ||
| 42 | </exclusion> | ||
| 43 | </exclusions> | ||
| 44 | </dependency> | ||
| 45 | <!--Spring--> | ||
| 46 | <dependency> | ||
| 47 | <groupId>org.springframework.cloud</groupId> | ||
| 48 | <artifactId>spring-cloud-starter-gateway</artifactId> | ||
| 49 | </dependency> | ||
| 50 | <dependency> | ||
| 51 | <groupId>org.springframework.boot</groupId> | ||
| 52 | <artifactId>spring-boot-starter-data-redis-reactive</artifactId> | ||
| 53 | </dependency> | ||
| 54 | <dependency> | ||
| 55 | <groupId>de.codecentric</groupId> | ||
| 56 | <artifactId>spring-boot-admin-starter-client</artifactId> | ||
| 57 | <version>${spring.boot.admin.version}</version> | ||
| 58 | </dependency> | ||
| 59 | <!--Hystrix--> | ||
| 60 | <dependency> | ||
| 61 | <groupId>org.springframework.cloud</groupId> | ||
| 62 | <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> | ||
| 63 | <exclusions> | ||
| 64 | <exclusion> | ||
| 65 | <groupId>commons-logging</groupId> | ||
| 66 | <artifactId>commons-logging</artifactId> | ||
| 67 | </exclusion> | ||
| 68 | </exclusions> | ||
| 69 | </dependency> | ||
| 70 | <!-- Nacos --> | ||
| 71 | <dependency> | ||
| 72 | <groupId>org.springframework.cloud</groupId> | ||
| 73 | <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> | ||
| 74 | <version>${alibaba.cloud.version}</version> | ||
| 75 | </dependency> | ||
| 76 | <dependency> | ||
| 77 | <groupId>org.springframework.cloud</groupId> | ||
| 78 | <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> | ||
| 79 | <version>${alibaba.cloud.version}</version> | ||
| 80 | </dependency> | ||
| 81 | <!--Swagger--> | ||
| 82 | <dependency> | ||
| 83 | <groupId>io.springfox</groupId> | ||
| 84 | <artifactId>springfox-swagger2</artifactId> | ||
| 85 | <version>${swagger.version}</version> | ||
| 86 | <exclusions> | ||
| 87 | <exclusion> | ||
| 88 | <groupId>io.swagger</groupId> | ||
| 89 | <artifactId>swagger-models</artifactId> | ||
| 90 | </exclusion> | ||
| 91 | </exclusions> | ||
| 92 | </dependency> | ||
| 93 | <dependency> | ||
| 94 | <groupId>io.swagger</groupId> | ||
| 95 | <artifactId>swagger-models</artifactId> | ||
| 96 | <version>${swagger.models.version}</version> | ||
| 97 | </dependency> | ||
| 98 | <!--<dependency> | ||
| 99 | <groupId>io.springfox</groupId> | ||
| 100 | <artifactId>springfox-swagger-ui</artifactId> | ||
| 101 | <version>${swagger.version}</version> | ||
| 102 | </dependency>--> | ||
| 103 | <dependency> | ||
| 104 | <groupId>com.github.xiaoymin</groupId> | ||
| 105 | <artifactId>swagger-bootstrap-ui</artifactId> | ||
| 106 | <version>${swagger.bootstrapui.version}</version> | ||
| 107 | </dependency> | ||
| 108 | </dependencies> | ||
| 109 | |||
| 110 | <build> | ||
| 111 | <plugins> | ||
| 112 | <plugin> | ||
| 113 | <groupId>com.spotify</groupId> | ||
| 114 | <artifactId>docker-maven-plugin</artifactId> | ||
| 115 | <version>${docker.plugin.version}</version> | ||
| 116 | <configuration> | ||
| 117 | <imageName>${docker.registry.url}/blade/${project.artifactId}:${project.version}</imageName> | ||
| 118 | <dockerDirectory>${project.basedir}</dockerDirectory> | ||
| 119 | <dockerHost>${docker.registry.host}</dockerHost> | ||
| 120 | <resources> | ||
| 121 | <resource> | ||
| 122 | <targetPath>/</targetPath> | ||
| 123 | <directory>${project.build.directory}</directory> | ||
| 124 | <include>${project.build.finalName}.jar</include> | ||
| 125 | </resource> | ||
| 126 | </resources> | ||
| 127 | <registryUrl>${docker.registry.url}</registryUrl> | ||
| 128 | <serverId>${docker.registry.url}</serverId> | ||
| 129 | <pushImage>true</pushImage> | ||
| 130 | </configuration> | ||
| 131 | </plugin> | ||
| 132 | <plugin> | ||
| 133 | <groupId>org.apache.maven.plugins</groupId> | ||
| 134 | <artifactId>maven-antrun-plugin</artifactId> | ||
| 135 | <executions> | ||
| 136 | <execution> | ||
| 137 | <phase>package</phase> | ||
| 138 | <goals> | ||
| 139 | <goal>run</goal> | ||
| 140 | </goals> | ||
| 141 | <configuration> | ||
| 142 | <tasks> | ||
| 143 | <copy overwrite="true" | ||
| 144 | tofile="${session.executionRootDirectory}/target/${project.artifactId}.jar" | ||
| 145 | file="${project.build.directory}/${project.artifactId}.jar" /> | ||
| 146 | </tasks> | ||
| 147 | </configuration> | ||
| 148 | </execution> | ||
| 149 | </executions> | ||
| 150 | </plugin> | ||
| 151 | </plugins> | ||
| 152 | </build> | ||
| 153 | |||
| 154 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.gateway; | ||
| 18 | |||
| 19 | import org.springblade.core.launch.constant.AppConstant; | ||
| 20 | import org.springblade.core.launch.BladeApplication; | ||
| 21 | import org.springframework.cloud.client.SpringCloudApplication; | ||
| 22 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; | ||
| 23 | import org.springframework.scheduling.annotation.EnableScheduling; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 项目启动 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | @EnableHystrix | ||
| 31 | @EnableScheduling | ||
| 32 | @SpringCloudApplication | ||
| 33 | public class GateWayApplication { | ||
| 34 | |||
| 35 | public static void main(String[] args) { | ||
| 36 | BladeApplication.run(AppConstant.APPLICATION_GATEWAY_NAME, GateWayApplication.class, args); | ||
| 37 | } | ||
| 38 | |||
| 39 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.gateway.config; | ||
| 18 | |||
| 19 | |||
| 20 | import org.springblade.gateway.handler.ErrorExceptionHandler; | ||
| 21 | import org.springframework.beans.factory.ObjectProvider; | ||
| 22 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; | ||
| 23 | import org.springframework.boot.autoconfigure.web.ResourceProperties; | ||
| 24 | import org.springframework.boot.autoconfigure.web.ServerProperties; | ||
| 25 | import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; | ||
| 26 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||
| 27 | import org.springframework.boot.web.reactive.error.ErrorAttributes; | ||
| 28 | import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; | ||
| 29 | import org.springframework.context.ApplicationContext; | ||
| 30 | import org.springframework.context.annotation.Bean; | ||
| 31 | import org.springframework.context.annotation.Configuration; | ||
| 32 | import org.springframework.core.Ordered; | ||
| 33 | import org.springframework.core.annotation.Order; | ||
| 34 | import org.springframework.http.codec.ServerCodecConfigurer; | ||
| 35 | import org.springframework.web.reactive.result.view.ViewResolver; | ||
| 36 | |||
| 37 | import java.util.Collections; | ||
| 38 | import java.util.List; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * 异常处理配置类 | ||
| 42 | * | ||
| 43 | * @author Chill | ||
| 44 | */ | ||
| 45 | @Configuration | ||
| 46 | @AutoConfigureBefore(ErrorWebFluxAutoConfiguration.class) | ||
| 47 | @EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class}) | ||
| 48 | public class ErrorHandlerConfiguration { | ||
| 49 | |||
| 50 | private final ServerProperties serverProperties; | ||
| 51 | |||
| 52 | private final ApplicationContext applicationContext; | ||
| 53 | |||
| 54 | private final ResourceProperties resourceProperties; | ||
| 55 | |||
| 56 | private final List<ViewResolver> viewResolvers; | ||
| 57 | |||
| 58 | private final ServerCodecConfigurer serverCodecConfigurer; | ||
| 59 | |||
| 60 | public ErrorHandlerConfiguration(ServerProperties serverProperties, | ||
| 61 | ResourceProperties resourceProperties, | ||
| 62 | ObjectProvider<List<ViewResolver>> viewResolversProvider, | ||
| 63 | ServerCodecConfigurer serverCodecConfigurer, | ||
| 64 | ApplicationContext applicationContext) { | ||
| 65 | this.serverProperties = serverProperties; | ||
| 66 | this.applicationContext = applicationContext; | ||
| 67 | this.resourceProperties = resourceProperties; | ||
| 68 | this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); | ||
| 69 | this.serverCodecConfigurer = serverCodecConfigurer; | ||
| 70 | } | ||
| 71 | |||
| 72 | @Bean | ||
| 73 | @Order(Ordered.HIGHEST_PRECEDENCE) | ||
| 74 | public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) { | ||
| 75 | ErrorExceptionHandler exceptionHandler = new ErrorExceptionHandler( | ||
| 76 | errorAttributes, | ||
| 77 | this.resourceProperties, | ||
| 78 | this.serverProperties.getError(), | ||
| 79 | this.applicationContext); | ||
| 80 | exceptionHandler.setViewResolvers(this.viewResolvers); | ||
| 81 | exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters()); | ||
| 82 | exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders()); | ||
| 83 | return exceptionHandler; | ||
| 84 | } | ||
| 85 | |||
| 86 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.config; | ||
| 19 | |||
| 20 | import lombok.AllArgsConstructor; | ||
| 21 | import lombok.extern.slf4j.Slf4j; | ||
| 22 | import org.springblade.gateway.handler.*; | ||
| 23 | import org.springframework.context.annotation.Bean; | ||
| 24 | import org.springframework.context.annotation.Configuration; | ||
| 25 | import org.springframework.http.HttpHeaders; | ||
| 26 | import org.springframework.http.HttpMethod; | ||
| 27 | import org.springframework.http.HttpStatus; | ||
| 28 | import org.springframework.http.MediaType; | ||
| 29 | import org.springframework.http.server.reactive.ServerHttpRequest; | ||
| 30 | import org.springframework.http.server.reactive.ServerHttpResponse; | ||
| 31 | import org.springframework.web.cors.reactive.CorsUtils; | ||
| 32 | import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; | ||
| 33 | import org.springframework.web.reactive.function.server.RequestPredicates; | ||
| 34 | import org.springframework.web.reactive.function.server.RouterFunction; | ||
| 35 | import org.springframework.web.reactive.function.server.RouterFunctions; | ||
| 36 | import org.springframework.web.server.ServerWebExchange; | ||
| 37 | import org.springframework.web.server.WebFilter; | ||
| 38 | import org.springframework.web.server.WebFilterChain; | ||
| 39 | import reactor.core.publisher.Mono; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * 路由配置信息 | ||
| 43 | * | ||
| 44 | * @author Chill | ||
| 45 | */ | ||
| 46 | @Slf4j | ||
| 47 | @Configuration | ||
| 48 | @AllArgsConstructor | ||
| 49 | public class RouterFunctionConfiguration { | ||
| 50 | |||
| 51 | /** | ||
| 52 | * 这里为支持的请求头,如果有自定义的header字段请自己添加 | ||
| 53 | */ | ||
| 54 | private static final String ALLOWED_HEADERS = "x-requested-with, blade-auth, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, username, client"; | ||
| 55 | private static final String ALLOWED_METHODS = "*"; | ||
| 56 | private static final String ALLOWED_ORIGIN = "*"; | ||
| 57 | private static final String ALLOWED_EXPOSE = "*"; | ||
| 58 | private static final String MAX_AGE = "18000L"; | ||
| 59 | |||
| 60 | private final HystrixFallbackHandler hystrixFallbackHandler; | ||
| 61 | private final SwaggerResourceHandler swaggerResourceHandler; | ||
| 62 | private final SwaggerSecurityHandler swaggerSecurityHandler; | ||
| 63 | private final SwaggerUiHandler swaggerUiHandler; | ||
| 64 | |||
| 65 | @Bean | ||
| 66 | public WebFilter corsFilter() { | ||
| 67 | return (ServerWebExchange ctx, WebFilterChain chain) -> { | ||
| 68 | ServerHttpRequest request = ctx.getRequest(); | ||
| 69 | if (CorsUtils.isCorsRequest(request)) { | ||
| 70 | ServerHttpResponse response = ctx.getResponse(); | ||
| 71 | HttpHeaders headers = response.getHeaders(); | ||
| 72 | headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); | ||
| 73 | headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); | ||
| 74 | headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN); | ||
| 75 | headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE); | ||
| 76 | headers.add("Access-Control-Max-Age", MAX_AGE); | ||
| 77 | headers.add("Access-Control-Allow-Credentials", "true"); | ||
| 78 | if (request.getMethod() == HttpMethod.OPTIONS) { | ||
| 79 | response.setStatusCode(HttpStatus.OK); | ||
| 80 | return Mono.empty(); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | return chain.filter(ctx); | ||
| 84 | }; | ||
| 85 | } | ||
| 86 | |||
| 87 | @Bean | ||
| 88 | public RouterFunction routerFunction() { | ||
| 89 | return RouterFunctions.route( | ||
| 90 | RequestPredicates.path("/fallback") | ||
| 91 | .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler) | ||
| 92 | .andRoute(RequestPredicates.GET("/swagger-resources") | ||
| 93 | .and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler) | ||
| 94 | .andRoute(RequestPredicates.GET("/swagger-resources/configuration/ui") | ||
| 95 | .and(RequestPredicates.accept(MediaType.ALL)), swaggerUiHandler) | ||
| 96 | .andRoute(RequestPredicates.GET("/swagger-resources/configuration/security") | ||
| 97 | .and(RequestPredicates.accept(MediaType.ALL)), swaggerSecurityHandler); | ||
| 98 | |||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * 解决springboot2.0.5版本出现的 Only one connection receive subscriber allowed. | ||
| 103 | * 参考:https://github.com/spring-cloud/spring-cloud-gateway/issues/541 | ||
| 104 | */ | ||
| 105 | @Bean | ||
| 106 | public HiddenHttpMethodFilter hiddenHttpMethodFilter() { | ||
| 107 | return new HiddenHttpMethodFilter() { | ||
| 108 | @Override | ||
| 109 | public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { | ||
| 110 | return chain.filter(exchange); | ||
| 111 | } | ||
| 112 | }; | ||
| 113 | } | ||
| 114 | |||
| 115 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.gateway.controller; | ||
| 18 | |||
| 19 | import lombok.AllArgsConstructor; | ||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springframework.cloud.client.ServiceInstance; | ||
| 22 | import org.springframework.cloud.client.discovery.DiscoveryClient; | ||
| 23 | import org.springframework.web.bind.annotation.GetMapping; | ||
| 24 | import org.springframework.web.bind.annotation.RequestMapping; | ||
| 25 | import org.springframework.web.bind.annotation.RestController; | ||
| 26 | |||
| 27 | import java.util.HashMap; | ||
| 28 | import java.util.List; | ||
| 29 | import java.util.Map; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * 服务发现控制器 | ||
| 33 | * | ||
| 34 | * @author Chill | ||
| 35 | */ | ||
| 36 | @Slf4j | ||
| 37 | @RestController | ||
| 38 | @AllArgsConstructor | ||
| 39 | @RequestMapping("/discovery") | ||
| 40 | public class DiscoveryClientController { | ||
| 41 | |||
| 42 | private final DiscoveryClient discoveryClient; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * 获取服务实例 | ||
| 46 | */ | ||
| 47 | @GetMapping("/instances") | ||
| 48 | public Map<String, List<ServiceInstance>> instances() { | ||
| 49 | Map<String, List<ServiceInstance>> instances = new HashMap<>(16); | ||
| 50 | List<String> services = discoveryClient.getServices(); | ||
| 51 | services.forEach(s -> { | ||
| 52 | List<ServiceInstance> list = discoveryClient.getInstances(s); | ||
| 53 | instances.put(s, list); | ||
| 54 | }); | ||
| 55 | return instances; | ||
| 56 | } | ||
| 57 | |||
| 58 | } |
| 1 | package org.springblade.gateway.filter; | ||
| 2 | |||
| 3 | import org.springframework.cloud.gateway.filter.GatewayFilterChain; | ||
| 4 | import org.springframework.cloud.gateway.filter.GlobalFilter; | ||
| 5 | import org.springframework.core.Ordered; | ||
| 6 | import org.springframework.http.server.reactive.ServerHttpRequest; | ||
| 7 | import org.springframework.stereotype.Component; | ||
| 8 | import org.springframework.util.StringUtils; | ||
| 9 | import org.springframework.web.server.ServerWebExchange; | ||
| 10 | import reactor.core.publisher.Mono; | ||
| 11 | |||
| 12 | import java.util.Arrays; | ||
| 13 | import java.util.stream.Collectors; | ||
| 14 | |||
| 15 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR; | ||
| 16 | import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * <p> | ||
| 20 | * 全局拦截器,作用所有的微服务 | ||
| 21 | * <p> | ||
| 22 | * 1. 对请求头中参数进行处理 from 参数进行清洗 | ||
| 23 | * 2. 重写StripPrefix = 1,支持全局 | ||
| 24 | * | ||
| 25 | * @author lengleng | ||
| 26 | */ | ||
| 27 | @Component | ||
| 28 | public class RequestGlobalFilter implements GlobalFilter, Ordered { | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Process the Web request and (optionally) delegate to the next | ||
| 32 | * {@code WebFilter} through the given {@link GatewayFilterChain}. | ||
| 33 | * | ||
| 34 | * @param exchange the current server exchange | ||
| 35 | * @param chain provides a way to delegate to the next filter | ||
| 36 | * @return {@code Mono<Void>} to indicate when request processing is complete | ||
| 37 | */ | ||
| 38 | @Override | ||
| 39 | public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { | ||
| 40 | // 1. 清洗请求头中from 参数 | ||
| 41 | ServerHttpRequest request = exchange.getRequest().mutate() | ||
| 42 | .headers(httpHeaders -> httpHeaders.remove("X")) | ||
| 43 | .build(); | ||
| 44 | |||
| 45 | // 2. 重写StripPrefix | ||
| 46 | addOriginalRequestUrl(exchange, request.getURI()); | ||
| 47 | String rawPath = request.getURI().getRawPath(); | ||
| 48 | String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")) | ||
| 49 | .skip(1L).collect(Collectors.joining("/")); | ||
| 50 | ServerHttpRequest newRequest = request.mutate() | ||
| 51 | .path(newPath) | ||
| 52 | .build(); | ||
| 53 | exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI()); | ||
| 54 | |||
| 55 | return chain.filter(exchange.mutate().request(newRequest.mutate().build()).build()); | ||
| 56 | } | ||
| 57 | |||
| 58 | @Override | ||
| 59 | public int getOrder() { | ||
| 60 | return -1000; | ||
| 61 | } | ||
| 62 | |||
| 63 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.gateway.handler; | ||
| 18 | |||
| 19 | import org.springframework.boot.autoconfigure.web.ErrorProperties; | ||
| 20 | import org.springframework.boot.autoconfigure.web.ResourceProperties; | ||
| 21 | import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; | ||
| 22 | import org.springframework.boot.web.reactive.error.ErrorAttributes; | ||
| 23 | import org.springframework.cloud.gateway.support.NotFoundException; | ||
| 24 | import org.springframework.context.ApplicationContext; | ||
| 25 | import org.springframework.http.HttpStatus; | ||
| 26 | import org.springframework.web.reactive.function.server.*; | ||
| 27 | import org.springframework.web.server.ResponseStatusException; | ||
| 28 | |||
| 29 | import java.util.HashMap; | ||
| 30 | import java.util.Map; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * 异常处理 | ||
| 34 | * | ||
| 35 | * @author Chill | ||
| 36 | */ | ||
| 37 | public class ErrorExceptionHandler extends DefaultErrorWebExceptionHandler { | ||
| 38 | |||
| 39 | public ErrorExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, | ||
| 40 | ErrorProperties errorProperties, ApplicationContext applicationContext) { | ||
| 41 | super(errorAttributes, resourceProperties, errorProperties, applicationContext); | ||
| 42 | } | ||
| 43 | |||
| 44 | /** | ||
| 45 | * 获取异常属性 | ||
| 46 | */ | ||
| 47 | @Override | ||
| 48 | protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) { | ||
| 49 | int code = 500; | ||
| 50 | Throwable error = super.getError(request); | ||
| 51 | if (error instanceof NotFoundException) { | ||
| 52 | code = 404; | ||
| 53 | } | ||
| 54 | if (error instanceof ResponseStatusException) { | ||
| 55 | code = ((ResponseStatusException) error).getStatus().value(); | ||
| 56 | } | ||
| 57 | return response(code, this.buildMessage(request, error)); | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * 指定响应处理方法为JSON处理的方法 | ||
| 62 | * | ||
| 63 | * @param errorAttributes | ||
| 64 | */ | ||
| 65 | @Override | ||
| 66 | protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) { | ||
| 67 | return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * 根据code获取对应的HttpStatus | ||
| 72 | * | ||
| 73 | * @param errorAttributes | ||
| 74 | */ | ||
| 75 | @Override | ||
| 76 | protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) { | ||
| 77 | int statusCode = (int) errorAttributes.get("code"); | ||
| 78 | return HttpStatus.valueOf(statusCode); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * 构建异常信息 | ||
| 83 | * | ||
| 84 | * @param request | ||
| 85 | * @param ex | ||
| 86 | * @return | ||
| 87 | */ | ||
| 88 | private String buildMessage(ServerRequest request, Throwable ex) { | ||
| 89 | StringBuilder message = new StringBuilder("Failed to handle request ["); | ||
| 90 | message.append(request.methodName()); | ||
| 91 | message.append(" "); | ||
| 92 | message.append(request.uri()); | ||
| 93 | message.append("]"); | ||
| 94 | if (ex != null) { | ||
| 95 | message.append(": "); | ||
| 96 | message.append(ex.getMessage()); | ||
| 97 | } | ||
| 98 | return message.toString(); | ||
| 99 | } | ||
| 100 | |||
| 101 | /** | ||
| 102 | * 构建返回的JSON数据格式 | ||
| 103 | * | ||
| 104 | * @param status 状态码 | ||
| 105 | * @param errorMessage 异常信息 | ||
| 106 | * @return | ||
| 107 | */ | ||
| 108 | public static Map<String, Object> response(int status, String errorMessage) { | ||
| 109 | Map<String, Object> map = new HashMap<>(16); | ||
| 110 | map.put("code", status); | ||
| 111 | map.put("message", errorMessage); | ||
| 112 | map.put("data", null); | ||
| 113 | return map; | ||
| 114 | } | ||
| 115 | |||
| 116 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.handler; | ||
| 19 | |||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springframework.http.HttpStatus; | ||
| 22 | import org.springframework.http.MediaType; | ||
| 23 | import org.springframework.stereotype.Component; | ||
| 24 | import org.springframework.web.reactive.function.BodyInserters; | ||
| 25 | import org.springframework.web.reactive.function.server.HandlerFunction; | ||
| 26 | import org.springframework.web.reactive.function.server.ServerRequest; | ||
| 27 | import org.springframework.web.reactive.function.server.ServerResponse; | ||
| 28 | import reactor.core.publisher.Mono; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * Hystrix 降级处理 | ||
| 32 | * | ||
| 33 | * @author lengleng | ||
| 34 | */ | ||
| 35 | @Slf4j | ||
| 36 | @Component | ||
| 37 | public class HystrixFallbackHandler implements HandlerFunction<ServerResponse> { | ||
| 38 | @Override | ||
| 39 | public Mono<ServerResponse> handle(ServerRequest serverRequest) { | ||
| 40 | log.error("网关执行请求:{}失败,hystrix服务降级处理", serverRequest.uri()); | ||
| 41 | return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR.value()) | ||
| 42 | .contentType(MediaType.TEXT_PLAIN).body(BodyInserters.fromObject("服务异常")); | ||
| 43 | } | ||
| 44 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.handler; | ||
| 19 | |||
| 20 | import lombok.AllArgsConstructor; | ||
| 21 | import lombok.extern.slf4j.Slf4j; | ||
| 22 | import org.springframework.http.HttpStatus; | ||
| 23 | import org.springframework.http.MediaType; | ||
| 24 | import org.springframework.stereotype.Component; | ||
| 25 | import org.springframework.web.reactive.function.BodyInserters; | ||
| 26 | import org.springframework.web.reactive.function.server.HandlerFunction; | ||
| 27 | import org.springframework.web.reactive.function.server.ServerRequest; | ||
| 28 | import org.springframework.web.reactive.function.server.ServerResponse; | ||
| 29 | import reactor.core.publisher.Mono; | ||
| 30 | import springfox.documentation.swagger.web.SwaggerResourcesProvider; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * SwaggerResourceHandler | ||
| 34 | * | ||
| 35 | * @author lengleng | ||
| 36 | */ | ||
| 37 | @Slf4j | ||
| 38 | @Component | ||
| 39 | @AllArgsConstructor | ||
| 40 | public class SwaggerResourceHandler implements HandlerFunction<ServerResponse> { | ||
| 41 | private final SwaggerResourcesProvider swaggerResources; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * Handle the given request. | ||
| 45 | * | ||
| 46 | * @param request the request to handler | ||
| 47 | * @return the response | ||
| 48 | */ | ||
| 49 | @Override | ||
| 50 | public Mono<ServerResponse> handle(ServerRequest request) { | ||
| 51 | return ServerResponse.status(HttpStatus.OK) | ||
| 52 | .contentType(MediaType.APPLICATION_JSON_UTF8) | ||
| 53 | .body(BodyInserters.fromObject(swaggerResources.get())); | ||
| 54 | } | ||
| 55 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.handler; | ||
| 19 | |||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springframework.beans.factory.annotation.Autowired; | ||
| 22 | import org.springframework.http.HttpStatus; | ||
| 23 | import org.springframework.http.MediaType; | ||
| 24 | import org.springframework.stereotype.Component; | ||
| 25 | import org.springframework.web.reactive.function.BodyInserters; | ||
| 26 | import org.springframework.web.reactive.function.server.HandlerFunction; | ||
| 27 | import org.springframework.web.reactive.function.server.ServerRequest; | ||
| 28 | import org.springframework.web.reactive.function.server.ServerResponse; | ||
| 29 | import reactor.core.publisher.Mono; | ||
| 30 | import springfox.documentation.swagger.web.SecurityConfiguration; | ||
| 31 | import springfox.documentation.swagger.web.SecurityConfigurationBuilder; | ||
| 32 | |||
| 33 | import java.util.Optional; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * SwaggerSecurityHandler | ||
| 37 | * | ||
| 38 | * @author lengleng | ||
| 39 | */ | ||
| 40 | @Slf4j | ||
| 41 | @Component | ||
| 42 | public class SwaggerSecurityHandler implements HandlerFunction<ServerResponse> { | ||
| 43 | @Autowired(required = false) | ||
| 44 | private SecurityConfiguration securityConfiguration; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Handle the given request. | ||
| 48 | * | ||
| 49 | * @param request the request to handler | ||
| 50 | * @return the response | ||
| 51 | */ | ||
| 52 | @Override | ||
| 53 | public Mono<ServerResponse> handle(ServerRequest request) { | ||
| 54 | return ServerResponse.status(HttpStatus.OK) | ||
| 55 | .contentType(MediaType.APPLICATION_JSON_UTF8) | ||
| 56 | .body(BodyInserters.fromObject( | ||
| 57 | Optional.ofNullable(securityConfiguration) | ||
| 58 | .orElse(SecurityConfigurationBuilder.builder().build()))); | ||
| 59 | } | ||
| 60 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.handler; | ||
| 19 | |||
| 20 | import lombok.extern.slf4j.Slf4j; | ||
| 21 | import org.springframework.beans.factory.annotation.Autowired; | ||
| 22 | import org.springframework.http.HttpStatus; | ||
| 23 | import org.springframework.http.MediaType; | ||
| 24 | import org.springframework.stereotype.Component; | ||
| 25 | import org.springframework.web.reactive.function.BodyInserters; | ||
| 26 | import org.springframework.web.reactive.function.server.HandlerFunction; | ||
| 27 | import org.springframework.web.reactive.function.server.ServerRequest; | ||
| 28 | import org.springframework.web.reactive.function.server.ServerResponse; | ||
| 29 | import reactor.core.publisher.Mono; | ||
| 30 | import springfox.documentation.swagger.web.UiConfiguration; | ||
| 31 | import springfox.documentation.swagger.web.UiConfigurationBuilder; | ||
| 32 | |||
| 33 | import java.util.Optional; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * SwaggerUiHandler | ||
| 37 | * | ||
| 38 | * @author lengleng | ||
| 39 | */ | ||
| 40 | @Slf4j | ||
| 41 | @Component | ||
| 42 | public class SwaggerUiHandler implements HandlerFunction<ServerResponse> { | ||
| 43 | @Autowired(required = false) | ||
| 44 | private UiConfiguration uiConfiguration; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Handle the given request. | ||
| 48 | * | ||
| 49 | * @param request the request to handler | ||
| 50 | * @return the response | ||
| 51 | */ | ||
| 52 | @Override | ||
| 53 | public Mono<ServerResponse> handle(ServerRequest request) { | ||
| 54 | return ServerResponse.status(HttpStatus.OK) | ||
| 55 | .contentType(MediaType.APPLICATION_JSON_UTF8) | ||
| 56 | .body(BodyInserters.fromObject( | ||
| 57 | Optional.ofNullable(uiConfiguration) | ||
| 58 | .orElse(UiConfigurationBuilder.builder().build()))); | ||
| 59 | } | ||
| 60 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | |||
| 18 | package org.springblade.gateway.provider; | ||
| 19 | |||
| 20 | import lombok.AllArgsConstructor; | ||
| 21 | import org.springblade.core.launch.constant.AppConstant; | ||
| 22 | import org.springframework.cloud.gateway.config.GatewayProperties; | ||
| 23 | import org.springframework.cloud.gateway.route.RouteLocator; | ||
| 24 | import org.springframework.cloud.gateway.support.NameUtils; | ||
| 25 | import org.springframework.context.annotation.Primary; | ||
| 26 | import org.springframework.stereotype.Component; | ||
| 27 | import springfox.documentation.swagger.web.SwaggerResource; | ||
| 28 | import springfox.documentation.swagger.web.SwaggerResourcesProvider; | ||
| 29 | |||
| 30 | import java.util.ArrayList; | ||
| 31 | import java.util.HashMap; | ||
| 32 | import java.util.List; | ||
| 33 | import java.util.Map; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * 聚合接口文档注册 | ||
| 37 | * | ||
| 38 | * @author Sywd | ||
| 39 | */ | ||
| 40 | @Primary | ||
| 41 | @Component | ||
| 42 | @AllArgsConstructor | ||
| 43 | public class SwaggerProvider implements SwaggerResourcesProvider { | ||
| 44 | public static final String API_URI = "/v2/api-docs-ext"; | ||
| 45 | private final RouteLocator routeLocator; | ||
| 46 | private final GatewayProperties gatewayProperties; | ||
| 47 | |||
| 48 | private static Map<String, String> routeMap = new HashMap<>(); | ||
| 49 | |||
| 50 | static { | ||
| 51 | routeMap.put(AppConstant.APPLICATION_AUTH_NAME, "授权模块"); | ||
| 52 | routeMap.put(AppConstant.APPLICATION_DESK_NAME, "工作台模块"); | ||
| 53 | routeMap.put(AppConstant.APPLICATION_SYSTEM_NAME, "系统模块"); | ||
| 54 | routeMap.put(AppConstant.APPLICATION_USER_NAME, "用户模块"); | ||
| 55 | routeMap.put("blade-apartment", "智能公寓模块"); | ||
| 56 | } | ||
| 57 | |||
| 58 | @Override | ||
| 59 | public List<SwaggerResource> get() { | ||
| 60 | List<SwaggerResource> resources = new ArrayList<>(); | ||
| 61 | List<String> routes = new ArrayList<>(); | ||
| 62 | routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); | ||
| 63 | gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())) | ||
| 64 | .forEach(routeDefinition -> routeDefinition.getPredicates().stream() | ||
| 65 | .filter(predicateDefinition -> "Path".equalsIgnoreCase(predicateDefinition.getName())) | ||
| 66 | .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(), | ||
| 67 | predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") | ||
| 68 | .replace("/**", API_URI))))); | ||
| 69 | return resources; | ||
| 70 | } | ||
| 71 | |||
| 72 | private SwaggerResource swaggerResource(String name, String location) { | ||
| 73 | SwaggerResource swaggerResource = new SwaggerResource(); | ||
| 74 | swaggerResource.setName((routeMap.get(name) == null ? name : routeMap.get(name))); | ||
| 75 | swaggerResource.setLocation(location); | ||
| 76 | swaggerResource.setSwaggerVersion("2.0"); | ||
| 77 | return swaggerResource; | ||
| 78 | } | ||
| 79 | |||
| 80 | } |
| 1 | server: | ||
| 2 | port: 80 | ||
| 3 | |||
| 4 | # 需要配置的服务名 | ||
| 5 | blade: | ||
| 6 | service: | ||
| 7 | blade-auth: blade-auth | ||
| 8 | blade-desk: blade-desk | ||
| 9 | blade-system: blade-system | ||
| 10 | blade-apartment: blade-apartment | ||
| 11 | blade-user: blade-user | ||
| 12 | |||
| 13 | spring: | ||
| 14 | cloud: | ||
| 15 | gateway: | ||
| 16 | routes: | ||
| 17 | # 认证中心 | ||
| 18 | - id: ${blade.service.blade-auth} | ||
| 19 | uri: lb://${blade.service.blade-auth} | ||
| 20 | predicates: | ||
| 21 | - Path=/${blade.service.blade-auth}/** | ||
| 22 | # 首页模块 | ||
| 23 | - id: ${blade.service.blade-desk} | ||
| 24 | uri: lb://${blade.service.blade-desk} | ||
| 25 | predicates: | ||
| 26 | - Path=/${blade.service.blade-desk}/** | ||
| 27 | # 用户模块 | ||
| 28 | - id: ${blade.service.blade-user} | ||
| 29 | uri: lb://${blade.service.blade-user} | ||
| 30 | predicates: | ||
| 31 | - Path=/${blade.service.blade-user}/** | ||
| 32 | # 系统模块 | ||
| 33 | - id: ${blade.service.blade-system} | ||
| 34 | uri: lb://${blade.service.blade-system} | ||
| 35 | predicates: | ||
| 36 | - Path=/${blade.service.blade-system}/** | ||
| 37 | # 智能公寓模块 | ||
| 38 | - id: ${blade.service.blade-apartment} | ||
| 39 | uri: lb://${blade.service.blade-apartment} | ||
| 40 | predicates: | ||
| 41 | - Path=/${blade.service.blade-apartment}/** | ||
| 42 | discovery: | ||
| 43 | locator: | ||
| 44 | enabled: true | ||
| 45 | loadbalancer: | ||
| 46 | retry: | ||
| 47 | enabled: true | ||
| 48 | |||
| 49 |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | <parent> | ||
| 6 | <artifactId>blade-ops-api</artifactId> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <version>2.0.0.RELEASE</version> | ||
| 9 | </parent> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | ||
| 11 | |||
| 12 | <artifactId>blade-flow-api</artifactId> | ||
| 13 | <name>${project.artifactId}</name> | ||
| 14 | <version>${bladex.project.version}</version> | ||
| 15 | <packaging>jar</packaging> | ||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.constant; | ||
| 18 | |||
| 19 | /** | ||
| 20 | * 流程常量. | ||
| 21 | * | ||
| 22 | * @author Chill | ||
| 23 | */ | ||
| 24 | public interface ProcessConstant { | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 请假流程标识 | ||
| 28 | */ | ||
| 29 | String LEAVE_KEY = "Leave"; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * 报销流程标识 | ||
| 33 | */ | ||
| 34 | String Expense_KEY = "Expense"; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * 同意标识 | ||
| 38 | */ | ||
| 39 | String PASS_KEY = "pass"; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * 同意代号 | ||
| 43 | */ | ||
| 44 | String PASS_ALIAS = "ok"; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * 同意默认批复 | ||
| 48 | */ | ||
| 49 | String PASS_COMMENT = "同意"; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * 驳回默认批复 | ||
| 53 | */ | ||
| 54 | String NOT_PASS_COMMENT = "驳回"; | ||
| 55 | |||
| 56 | /** | ||
| 57 | * 创建人变量名 | ||
| 58 | */ | ||
| 59 | String TASK_VARIABLE_CREATE_USER = "createUser"; | ||
| 60 | |||
| 61 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.entity; | ||
| 18 | |||
| 19 | import lombok.Data; | ||
| 20 | import org.springblade.flow.core.constant.ProcessConstant; | ||
| 21 | |||
| 22 | import java.io.Serializable; | ||
| 23 | import java.util.Date; | ||
| 24 | import java.util.Map; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 工作流通用实体类 | ||
| 28 | * | ||
| 29 | * @author Chill | ||
| 30 | */ | ||
| 31 | @Data | ||
| 32 | public class BladeFlow implements Serializable { | ||
| 33 | private static final long serialVersionUID = 1L; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * 任务编号 | ||
| 37 | */ | ||
| 38 | private String taskId; | ||
| 39 | /** | ||
| 40 | * 任务名称 | ||
| 41 | */ | ||
| 42 | private String taskName; | ||
| 43 | /** | ||
| 44 | * 任务定义Key | ||
| 45 | */ | ||
| 46 | private String taskDefinitionKey; | ||
| 47 | /** | ||
| 48 | * 任务执行人编号 | ||
| 49 | */ | ||
| 50 | private String assignee; | ||
| 51 | /** | ||
| 52 | * 任务执行人名称 | ||
| 53 | */ | ||
| 54 | private String assigneeName; | ||
| 55 | /** | ||
| 56 | * 流程分类 | ||
| 57 | */ | ||
| 58 | private String category; | ||
| 59 | /** | ||
| 60 | * 流程分类名 | ||
| 61 | */ | ||
| 62 | private String categoryName; | ||
| 63 | /** | ||
| 64 | * 创建时间 | ||
| 65 | */ | ||
| 66 | private Date createTime; | ||
| 67 | /** | ||
| 68 | * 结束时间 | ||
| 69 | */ | ||
| 70 | private Date endTime; | ||
| 71 | /** | ||
| 72 | * 签收时间 | ||
| 73 | */ | ||
| 74 | private Date claimTime; | ||
| 75 | /** | ||
| 76 | * 历史任务结束时间 | ||
| 77 | */ | ||
| 78 | private Date historyTaskEndTime; | ||
| 79 | /** | ||
| 80 | * 执行ID | ||
| 81 | */ | ||
| 82 | private String executionId; | ||
| 83 | /** | ||
| 84 | * 流程实例ID | ||
| 85 | */ | ||
| 86 | private String processInstanceId; | ||
| 87 | /** | ||
| 88 | * 流程ID | ||
| 89 | */ | ||
| 90 | private String processDefinitionId; | ||
| 91 | /** | ||
| 92 | * 流程标识 | ||
| 93 | */ | ||
| 94 | private String processDefinitionKey; | ||
| 95 | /** | ||
| 96 | * 流程名 | ||
| 97 | */ | ||
| 98 | private String processDefinitionName; | ||
| 99 | /** | ||
| 100 | * 流程版本 | ||
| 101 | */ | ||
| 102 | private int processDefinitionVersion; | ||
| 103 | /** | ||
| 104 | * 流程说明 | ||
| 105 | */ | ||
| 106 | private String processDefinitionDesc; | ||
| 107 | /** | ||
| 108 | * 流程简图名 | ||
| 109 | */ | ||
| 110 | private String processDefinitionDiagramResName; | ||
| 111 | /** | ||
| 112 | * 流程重命名 | ||
| 113 | */ | ||
| 114 | private String processDefinitionResName; | ||
| 115 | /** | ||
| 116 | * 历史任务流程实例ID 查看流程图会用到 | ||
| 117 | */ | ||
| 118 | private String historyProcessInstanceId; | ||
| 119 | /** | ||
| 120 | * 流程实例是否结束 | ||
| 121 | */ | ||
| 122 | private String processIsFinished; | ||
| 123 | /** | ||
| 124 | * 历史活动流程 | ||
| 125 | */ | ||
| 126 | private String historyActivityName; | ||
| 127 | /** | ||
| 128 | * 历史活动耗时 | ||
| 129 | */ | ||
| 130 | private String historyActivityDurationTime; | ||
| 131 | /** | ||
| 132 | * 业务绑定Table | ||
| 133 | */ | ||
| 134 | private String businessTable; | ||
| 135 | /** | ||
| 136 | * 业务绑定ID | ||
| 137 | */ | ||
| 138 | private String businessId; | ||
| 139 | /** | ||
| 140 | * 任务状态 | ||
| 141 | */ | ||
| 142 | private String status; | ||
| 143 | /** | ||
| 144 | * 任务意见 | ||
| 145 | */ | ||
| 146 | private String comment; | ||
| 147 | /** | ||
| 148 | * 是否通过 | ||
| 149 | */ | ||
| 150 | private boolean isPass; | ||
| 151 | /** | ||
| 152 | * 是否通过代号 | ||
| 153 | */ | ||
| 154 | private String flag; | ||
| 155 | /** | ||
| 156 | * 开始查询日期 | ||
| 157 | */ | ||
| 158 | private Date beginDate; | ||
| 159 | /** | ||
| 160 | * 结束查询日期 | ||
| 161 | */ | ||
| 162 | private Date endDate; | ||
| 163 | /** | ||
| 164 | * 流程参数 | ||
| 165 | */ | ||
| 166 | private Map<String, Object> variables; | ||
| 167 | |||
| 168 | /** | ||
| 169 | * 获取是否通过 | ||
| 170 | */ | ||
| 171 | public boolean isPass() { | ||
| 172 | return ProcessConstant.PASS_ALIAS.equals(flag) || ProcessConstant.PASS_COMMENT.equals(comment); | ||
| 173 | } | ||
| 174 | |||
| 175 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.entity; | ||
| 18 | |||
| 19 | import com.baomidou.mybatisplus.annotation.TableField; | ||
| 20 | import lombok.Data; | ||
| 21 | import lombok.EqualsAndHashCode; | ||
| 22 | import org.springblade.core.mp.base.BaseEntity; | ||
| 23 | |||
| 24 | /** | ||
| 25 | * FlowEntity | ||
| 26 | * | ||
| 27 | * @author Chill | ||
| 28 | */ | ||
| 29 | @Data | ||
| 30 | @EqualsAndHashCode(callSuper = true) | ||
| 31 | public class FlowEntity extends BaseEntity { | ||
| 32 | |||
| 33 | @TableField(exist = false) | ||
| 34 | private BladeFlow flow; | ||
| 35 | |||
| 36 | public BladeFlow getFlow() { | ||
| 37 | if (flow == null) { | ||
| 38 | flow = new BladeFlow(); | ||
| 39 | } | ||
| 40 | return flow; | ||
| 41 | } | ||
| 42 | |||
| 43 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.feign; | ||
| 18 | |||
| 19 | import org.springblade.core.launch.constant.AppConstant; | ||
| 20 | import org.springblade.core.tool.api.R; | ||
| 21 | import org.springblade.flow.core.entity.BladeFlow; | ||
| 22 | import org.springframework.cloud.openfeign.FeignClient; | ||
| 23 | import org.springframework.web.bind.annotation.GetMapping; | ||
| 24 | import org.springframework.web.bind.annotation.PostMapping; | ||
| 25 | import org.springframework.web.bind.annotation.RequestBody; | ||
| 26 | import org.springframework.web.bind.annotation.RequestParam; | ||
| 27 | |||
| 28 | import java.util.Map; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * 工作流远程调用接口. | ||
| 32 | * | ||
| 33 | * @author Chill | ||
| 34 | */ | ||
| 35 | @FeignClient( | ||
| 36 | value = AppConstant.APPLICATION_FLOW_NAME, | ||
| 37 | fallback = IFlowClientFallback.class | ||
| 38 | ) | ||
| 39 | public interface IFlowClient { | ||
| 40 | |||
| 41 | String API_PREFIX = "/client"; | ||
| 42 | String START_PROCESS_INSTANCE_BY_ID = API_PREFIX + "start-process-instance-by-id"; | ||
| 43 | String START_PROCESS_INSTANCE_BY_KEY = API_PREFIX + "start-process-instance-by-key"; | ||
| 44 | String COMPLETE_TASK = API_PREFIX + "complete-task"; | ||
| 45 | String TASK_VARIABLE = API_PREFIX + "task-variable"; | ||
| 46 | String TASK_VARIABLES = API_PREFIX + "task-variables"; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * 开启流程 | ||
| 50 | * | ||
| 51 | * @param processDefinitionId 流程id | ||
| 52 | * @param businessKey 业务key | ||
| 53 | * @param variables 参数 | ||
| 54 | * @return BladeFlow | ||
| 55 | */ | ||
| 56 | @PostMapping(START_PROCESS_INSTANCE_BY_ID) | ||
| 57 | R<BladeFlow> startProcessInstanceById(@RequestParam("processDefinitionId") String processDefinitionId, @RequestParam("businessKey") String businessKey, @RequestBody Map<String, Object> variables); | ||
| 58 | |||
| 59 | /** | ||
| 60 | * 开启流程 | ||
| 61 | * | ||
| 62 | * @param processDefinitionKey 流程标识 | ||
| 63 | * @param businessKey 业务key | ||
| 64 | * @param variables 参数 | ||
| 65 | * @return BladeFlow | ||
| 66 | */ | ||
| 67 | @PostMapping(START_PROCESS_INSTANCE_BY_KEY) | ||
| 68 | R<BladeFlow> startProcessInstanceByKey(@RequestParam("processDefinitionKey") String processDefinitionKey, @RequestParam("businessKey") String businessKey, @RequestBody Map<String, Object> variables); | ||
| 69 | |||
| 70 | /** | ||
| 71 | * 完成任务 | ||
| 72 | * | ||
| 73 | * @param taskId 任务id | ||
| 74 | * @param processInstanceId 流程实例id | ||
| 75 | * @param comment 评论 | ||
| 76 | * @param variables 参数 | ||
| 77 | * @return R | ||
| 78 | */ | ||
| 79 | @PostMapping(COMPLETE_TASK) | ||
| 80 | R completeTask(@RequestParam("taskId") String taskId, @RequestParam("processInstanceId") String processInstanceId, @RequestParam("comment") String comment, @RequestBody Map<String, Object> variables); | ||
| 81 | |||
| 82 | /** | ||
| 83 | * 获取流程变量 | ||
| 84 | * | ||
| 85 | * @param taskId 任务id | ||
| 86 | * @param variableName 变量名 | ||
| 87 | * @return R | ||
| 88 | */ | ||
| 89 | @GetMapping(TASK_VARIABLE) | ||
| 90 | R<Object> taskVariable(@RequestParam("taskId") String taskId, @RequestParam("variableName") String variableName); | ||
| 91 | |||
| 92 | /** | ||
| 93 | * 获取流程变量集合 | ||
| 94 | * | ||
| 95 | * @param taskId 任务id | ||
| 96 | * @return R | ||
| 97 | */ | ||
| 98 | @GetMapping(TASK_VARIABLES) | ||
| 99 | R<Map<String, Object>> taskVariables(@RequestParam("taskId") String taskId); | ||
| 100 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.feign; | ||
| 18 | |||
| 19 | import org.springblade.core.tool.api.R; | ||
| 20 | import org.springblade.flow.core.entity.BladeFlow; | ||
| 21 | import org.springframework.stereotype.Component; | ||
| 22 | |||
| 23 | import java.util.Map; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 流程远程调用失败处理类 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | @Component | ||
| 31 | public class IFlowClientFallback implements IFlowClient { | ||
| 32 | |||
| 33 | @Override | ||
| 34 | public R<BladeFlow> startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables) { | ||
| 35 | return R.fail("远程调用失败"); | ||
| 36 | } | ||
| 37 | |||
| 38 | @Override | ||
| 39 | public R<BladeFlow> startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) { | ||
| 40 | return R.fail("远程调用失败"); | ||
| 41 | } | ||
| 42 | |||
| 43 | @Override | ||
| 44 | public R completeTask(String taskId, String processInstanceId, String comment, Map<String, Object> variables) { | ||
| 45 | return R.fail("远程调用失败"); | ||
| 46 | } | ||
| 47 | |||
| 48 | @Override | ||
| 49 | public R<Object> taskVariable(String taskId, String variableName) { | ||
| 50 | return R.fail("远程调用失败"); | ||
| 51 | } | ||
| 52 | |||
| 53 | @Override | ||
| 54 | public R<Map<String, Object>> taskVariables(String taskId) { | ||
| 55 | return R.fail("远程调用失败"); | ||
| 56 | } | ||
| 57 | |||
| 58 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.utils; | ||
| 18 | |||
| 19 | import org.springblade.core.tool.utils.Func; | ||
| 20 | import org.springblade.core.tool.utils.StringUtil; | ||
| 21 | import org.springblade.flow.core.constant.ProcessConstant; | ||
| 22 | |||
| 23 | import java.util.HashMap; | ||
| 24 | import java.util.Map; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 工作流工具类 | ||
| 28 | * | ||
| 29 | * @author Chill | ||
| 30 | */ | ||
| 31 | public class FlowUtil { | ||
| 32 | |||
| 33 | /** | ||
| 34 | * 定义流程key对应的表名 | ||
| 35 | */ | ||
| 36 | private final static Map<String, String> BUSINESS_TABLE = new HashMap<>(); | ||
| 37 | |||
| 38 | static { | ||
| 39 | BUSINESS_TABLE.put(ProcessConstant.LEAVE_KEY, "blade_process_leave"); | ||
| 40 | } | ||
| 41 | |||
| 42 | /** | ||
| 43 | * 通过流程key获取业务表名 | ||
| 44 | * | ||
| 45 | * @param key 流程key | ||
| 46 | */ | ||
| 47 | public static String getBusinessTable(String key) { | ||
| 48 | String businessTable = BUSINESS_TABLE.get(key); | ||
| 49 | if (Func.isEmpty(businessTable)) { | ||
| 50 | throw new RuntimeException("流程启动失败,未找到相关业务表"); | ||
| 51 | } | ||
| 52 | return businessTable; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * 获取业务标识 | ||
| 57 | * | ||
| 58 | * @param businessTable 业务表 | ||
| 59 | * @param businessId 业务表主键 | ||
| 60 | * @return businessKey | ||
| 61 | */ | ||
| 62 | public static String getBusinessKey(String businessTable, String businessId) { | ||
| 63 | return StringUtil.format("{}:{}", businessTable, businessId); | ||
| 64 | } | ||
| 65 | |||
| 66 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.flow.core.utils; | ||
| 18 | |||
| 19 | import org.springblade.core.secure.utils.SecureUtil; | ||
| 20 | import org.springblade.core.tool.utils.Func; | ||
| 21 | import org.springblade.core.tool.utils.StringUtil; | ||
| 22 | |||
| 23 | import static org.springblade.core.launch.constant.FlowConstant.TASK_USR_PREFIX; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 工作流任务工具类 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | public class TaskUtil { | ||
| 31 | |||
| 32 | /** | ||
| 33 | * 获取任务用户格式 | ||
| 34 | * | ||
| 35 | * @return taskUser | ||
| 36 | */ | ||
| 37 | public static String getTaskUser() { | ||
| 38 | return StringUtil.format("{}{}", TASK_USR_PREFIX, SecureUtil.getUserId()); | ||
| 39 | } | ||
| 40 | |||
| 41 | /** | ||
| 42 | * 获取任务用户格式 | ||
| 43 | * | ||
| 44 | * @param userId 用户id | ||
| 45 | * @return taskUser | ||
| 46 | */ | ||
| 47 | public static String getTaskUser(String userId) { | ||
| 48 | return StringUtil.format("{}{}", TASK_USR_PREFIX, userId); | ||
| 49 | } | ||
| 50 | |||
| 51 | |||
| 52 | /** | ||
| 53 | * 获取用户主键 | ||
| 54 | * | ||
| 55 | * @param taskUser 任务用户 | ||
| 56 | * @return userId | ||
| 57 | */ | ||
| 58 | public static Long getUserId(String taskUser) { | ||
| 59 | return Func.toLong(StringUtil.removePrefix(taskUser, TASK_USR_PREFIX)); | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * 获取用户组格式 | ||
| 64 | * | ||
| 65 | * @return candidateGroup | ||
| 66 | */ | ||
| 67 | public static String getCandidateGroup() { | ||
| 68 | return SecureUtil.getUserRole(); | ||
| 69 | } | ||
| 70 | |||
| 71 | } |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | <parent> | ||
| 6 | <artifactId>BladeX</artifactId> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <version>2.0.0.RELEASE</version> | ||
| 9 | </parent> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | ||
| 11 | |||
| 12 | <artifactId>blade-ops-api</artifactId> | ||
| 13 | <name>${project.artifactId}</name> | ||
| 14 | <version>2.0.0.RELEASE</version> | ||
| 15 | <packaging>pom</packaging> | ||
| 16 | <description>BladeX 微服务API集合</description> | ||
| 17 | |||
| 18 | <modules> | ||
| 19 | <module>blade-flow-api</module> | ||
| 20 | </modules> | ||
| 21 | |||
| 22 | <dependencies> | ||
| 23 | <dependency> | ||
| 24 | <groupId>org.springblade</groupId> | ||
| 25 | <artifactId>blade-starter-mybatis</artifactId> | ||
| 26 | <version>${bladex.tool.version}</version> | ||
| 27 | </dependency> | ||
| 28 | <dependency> | ||
| 29 | <groupId>org.springframework.cloud</groupId> | ||
| 30 | <artifactId>spring-cloud-starter-openfeign</artifactId> | ||
| 31 | </dependency> | ||
| 32 | <dependency> | ||
| 33 | <groupId>org.springblade</groupId> | ||
| 34 | <artifactId>blade-core-auto</artifactId> | ||
| 35 | <version>${bladex.tool.version}</version> | ||
| 36 | <scope>provided</scope> | ||
| 37 | </dependency> | ||
| 38 | </dependencies> | ||
| 39 | |||
| 40 | <build> | ||
| 41 | <plugins> | ||
| 42 | <plugin> | ||
| 43 | <groupId>org.springframework.boot</groupId> | ||
| 44 | <artifactId>spring-boot-maven-plugin</artifactId> | ||
| 45 | <configuration> | ||
| 46 | <skip>true</skip> | ||
| 47 | <finalName>${project.name}</finalName> | ||
| 48 | </configuration> | ||
| 49 | </plugin> | ||
| 50 | <plugin> | ||
| 51 | <groupId>com.spotify</groupId> | ||
| 52 | <artifactId>docker-maven-plugin</artifactId> | ||
| 53 | <version>${docker.plugin.version}</version> | ||
| 54 | <configuration> | ||
| 55 | <skipDockerBuild>true</skipDockerBuild> | ||
| 56 | </configuration> | ||
| 57 | </plugin> | ||
| 58 | </plugins> | ||
| 59 | </build> | ||
| 60 | |||
| 61 | </project> |
| 1 | FROM anapsix/alpine-java:8_server-jre_unlimited | ||
| 2 | |||
| 3 | MAINTAINER smallchill@163.com | ||
| 4 | |||
| 5 | RUN mkdir -p /blade/admin | ||
| 6 | |||
| 7 | WORKDIR /blade/admin | ||
| 8 | |||
| 9 | EXPOSE 7002 | ||
| 10 | |||
| 11 | ADD ./target/blade-admin.jar ./app.jar | ||
| 12 | |||
| 13 | ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"] | ||
| 14 | |||
| 15 | CMD ["--spring.profiles.active=test"] |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | <parent> | ||
| 6 | <artifactId>blade-ops</artifactId> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <version>2.0.0.RELEASE</version> | ||
| 9 | </parent> | ||
| 10 | <modelVersion>4.0.0</modelVersion> | ||
| 11 | |||
| 12 | <artifactId>blade-admin</artifactId> | ||
| 13 | <name>${project.artifactId}</name> | ||
| 14 | <version>${bladex.project.version}</version> | ||
| 15 | <packaging>jar</packaging> | ||
| 16 | |||
| 17 | <dependencies> | ||
| 18 | <!--Blade--> | ||
| 19 | <dependency> | ||
| 20 | <groupId>org.springblade</groupId> | ||
| 21 | <artifactId>blade-common</artifactId> | ||
| 22 | <version>${bladex.project.version}</version> | ||
| 23 | </dependency> | ||
| 24 | <dependency> | ||
| 25 | <groupId>org.springblade</groupId> | ||
| 26 | <artifactId>blade-core-launch</artifactId> | ||
| 27 | <version>${bladex.tool.version}</version> | ||
| 28 | </dependency> | ||
| 29 | <dependency> | ||
| 30 | <groupId>org.springblade</groupId> | ||
| 31 | <artifactId>blade-core-tool</artifactId> | ||
| 32 | <version>${bladex.tool.version}</version> | ||
| 33 | </dependency> | ||
| 34 | <dependency> | ||
| 35 | <groupId>org.springblade</groupId> | ||
| 36 | <artifactId>blade-core-cloud</artifactId> | ||
| 37 | <version>${bladex.tool.version}</version> | ||
| 38 | <exclusions> | ||
| 39 | <exclusion> | ||
| 40 | <groupId>org.springblade</groupId> | ||
| 41 | <artifactId>blade-core-secure</artifactId> | ||
| 42 | </exclusion> | ||
| 43 | </exclusions> | ||
| 44 | </dependency> | ||
| 45 | <!--Admin-Server--> | ||
| 46 | <dependency> | ||
| 47 | <groupId>de.codecentric</groupId> | ||
| 48 | <artifactId>spring-boot-admin-starter-server</artifactId> | ||
| 49 | <version>${spring.boot.admin.version}</version> | ||
| 50 | </dependency> | ||
| 51 | </dependencies> | ||
| 52 | |||
| 53 | <build> | ||
| 54 | <plugins> | ||
| 55 | <plugin> | ||
| 56 | <groupId>com.spotify</groupId> | ||
| 57 | <artifactId>docker-maven-plugin</artifactId> | ||
| 58 | <version>${docker.plugin.version}</version> | ||
| 59 | <configuration> | ||
| 60 | <imageName>${docker.registry.url}/blade/${project.artifactId}:${project.version}</imageName> | ||
| 61 | <dockerDirectory>${project.basedir}</dockerDirectory> | ||
| 62 | <dockerHost>${docker.registry.host}</dockerHost> | ||
| 63 | <resources> | ||
| 64 | <resource> | ||
| 65 | <targetPath>/</targetPath> | ||
| 66 | <directory>${project.build.directory}</directory> | ||
| 67 | <include>${project.build.finalName}.jar</include> | ||
| 68 | </resource> | ||
| 69 | </resources> | ||
| 70 | <registryUrl>${docker.registry.url}</registryUrl> | ||
| 71 | <serverId>${docker.registry.url}</serverId> | ||
| 72 | <pushImage>true</pushImage> | ||
| 73 | </configuration> | ||
| 74 | </plugin> | ||
| 75 | <plugin> | ||
| 76 | <groupId>org.apache.maven.plugins</groupId> | ||
| 77 | <artifactId>maven-antrun-plugin</artifactId> | ||
| 78 | <executions> | ||
| 79 | <execution> | ||
| 80 | <phase>package</phase> | ||
| 81 | <goals> | ||
| 82 | <goal>run</goal> | ||
| 83 | </goals> | ||
| 84 | <configuration> | ||
| 85 | <tasks> | ||
| 86 | <copy overwrite="true" | ||
| 87 | tofile="${session.executionRootDirectory}/target/${project.artifactId}.jar" | ||
| 88 | file="${project.build.directory}/${project.artifactId}.jar" /> | ||
| 89 | </tasks> | ||
| 90 | </configuration> | ||
| 91 | </execution> | ||
| 92 | </executions> | ||
| 93 | </plugin> | ||
| 94 | </plugins> | ||
| 95 | </build> | ||
| 96 | |||
| 97 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.admin; | ||
| 18 | |||
| 19 | import de.codecentric.boot.admin.server.config.EnableAdminServer; | ||
| 20 | import org.springblade.core.launch.BladeApplication; | ||
| 21 | import org.springblade.core.launch.constant.AppConstant; | ||
| 22 | import org.springframework.cloud.client.SpringCloudApplication; | ||
| 23 | |||
| 24 | /** | ||
| 25 | * admin启动器 | ||
| 26 | * | ||
| 27 | * @author Chill | ||
| 28 | */ | ||
| 29 | @EnableAdminServer | ||
| 30 | @SpringCloudApplication | ||
| 31 | public class AdminApplication { | ||
| 32 | |||
| 33 | public static void main(String[] args) { | ||
| 34 | BladeApplication.run(AppConstant.APPLICATION_ADMIN_NAME, AdminApplication.class, args); | ||
| 35 | } | ||
| 36 | |||
| 37 | } |
| 1 | server: | ||
| 2 | port: 7002 | ||
| 3 | undertow: | ||
| 4 | # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程 | ||
| 5 | io-threads: 4 | ||
| 6 | # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载 | ||
| 7 | worker-threads: 20 | ||
| 8 | # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理 | ||
| 9 | buffer-size: 1024 | ||
| 10 | # 是否分配的直接内存 | ||
| 11 | direct-buffers: true | ||
| 12 | |||
| 13 | spring: | ||
| 14 | boot: | ||
| 15 | admin: | ||
| 16 | discovery: | ||
| 17 | ignored-services: consul |
| 1 | <?xml version="1.0"?> | ||
| 2 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | |||
| 6 | <parent> | ||
| 7 | <groupId>org.springblade</groupId> | ||
| 8 | <artifactId>blade-ops</artifactId> | ||
| 9 | <version>2.0.0.RELEASE</version> | ||
| 10 | </parent> | ||
| 11 | |||
| 12 | <modelVersion>4.0.0</modelVersion> | ||
| 13 | |||
| 14 | <artifactId>blade-develop</artifactId> | ||
| 15 | <name>${project.artifactId}</name> | ||
| 16 | <version>${bladex.project.version}</version> | ||
| 17 | <packaging>jar</packaging> | ||
| 18 | |||
| 19 | <dependencies> | ||
| 20 | <!--Blade--> | ||
| 21 | <dependency> | ||
| 22 | <groupId>org.springblade</groupId> | ||
| 23 | <artifactId>blade-core-boot</artifactId> | ||
| 24 | <version>${bladex.tool.version}</version> | ||
| 25 | </dependency> | ||
| 26 | <dependency> | ||
| 27 | <groupId>org.springblade</groupId> | ||
| 28 | <artifactId>blade-starter-develop</artifactId> | ||
| 29 | <version>${bladex.tool.version}</version> | ||
| 30 | </dependency> | ||
| 31 | <dependency> | ||
| 32 | <groupId>org.springblade</groupId> | ||
| 33 | <artifactId>blade-common</artifactId> | ||
| 34 | <version>${bladex.project.version}</version> | ||
| 35 | </dependency> | ||
| 36 | <dependency> | ||
| 37 | <groupId>org.springblade</groupId> | ||
| 38 | <artifactId>blade-dict-api</artifactId> | ||
| 39 | <version>${bladex.project.version}</version> | ||
| 40 | </dependency> | ||
| 41 | </dependencies> | ||
| 42 | |||
| 43 | <build> | ||
| 44 | <plugins> | ||
| 45 | <plugin> | ||
| 46 | <groupId>com.spotify</groupId> | ||
| 47 | <artifactId>docker-maven-plugin</artifactId> | ||
| 48 | <version>${docker.plugin.version}</version> | ||
| 49 | <configuration> | ||
| 50 | <skipDockerBuild>true</skipDockerBuild> | ||
| 51 | </configuration> | ||
| 52 | </plugin> | ||
| 53 | <plugin> | ||
| 54 | <groupId>org.apache.maven.plugins</groupId> | ||
| 55 | <artifactId>maven-antrun-plugin</artifactId> | ||
| 56 | <executions> | ||
| 57 | <execution> | ||
| 58 | <phase>package</phase> | ||
| 59 | <goals> | ||
| 60 | <goal>run</goal> | ||
| 61 | </goals> | ||
| 62 | <configuration> | ||
| 63 | <tasks> | ||
| 64 | <copy overwrite="true" | ||
| 65 | tofile="${session.executionRootDirectory}/target/${project.artifactId}.jar" | ||
| 66 | file="${project.build.directory}/${project.artifactId}.jar" /> | ||
| 67 | </tasks> | ||
| 68 | </configuration> | ||
| 69 | </execution> | ||
| 70 | </executions> | ||
| 71 | </plugin> | ||
| 72 | </plugins> | ||
| 73 | </build> | ||
| 74 | |||
| 75 | </project> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop; | ||
| 18 | |||
| 19 | import org.springblade.core.cloud.feign.EnableBladeFeign; | ||
| 20 | import org.springblade.core.launch.BladeApplication; | ||
| 21 | import org.springblade.core.launch.constant.AppConstant; | ||
| 22 | import org.springframework.cloud.client.SpringCloudApplication; | ||
| 23 | |||
| 24 | /** | ||
| 25 | * Develop启动器 | ||
| 26 | * | ||
| 27 | * @author Chill | ||
| 28 | */ | ||
| 29 | @EnableBladeFeign | ||
| 30 | @SpringCloudApplication | ||
| 31 | public class DevelopApplication { | ||
| 32 | |||
| 33 | public static void main(String[] args) { | ||
| 34 | BladeApplication.run(AppConstant.APPLICATION_DEVELOP_NAME, DevelopApplication.class, args); | ||
| 35 | } | ||
| 36 | |||
| 37 | } | ||
| 38 |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop.controller; | ||
| 18 | |||
| 19 | import com.baomidou.mybatisplus.core.metadata.IPage; | ||
| 20 | import io.swagger.annotations.*; | ||
| 21 | import lombok.AllArgsConstructor; | ||
| 22 | import org.springblade.core.boot.ctrl.BladeController; | ||
| 23 | import org.springblade.core.mp.support.Condition; | ||
| 24 | import org.springblade.core.mp.support.Query; | ||
| 25 | import org.springblade.core.secure.annotation.PreAuth; | ||
| 26 | import org.springblade.core.tool.api.R; | ||
| 27 | import org.springblade.core.tool.constant.RoleConstant; | ||
| 28 | import org.springblade.core.tool.utils.Func; | ||
| 29 | import org.springblade.develop.entity.Code; | ||
| 30 | import org.springblade.develop.service.ICodeService; | ||
| 31 | import org.springblade.develop.support.BladeCodeGenerator; | ||
| 32 | import org.springframework.data.redis.core.RedisTemplate; | ||
| 33 | import org.springframework.web.bind.annotation.*; | ||
| 34 | import springfox.documentation.annotations.ApiIgnore; | ||
| 35 | |||
| 36 | import javax.validation.Valid; | ||
| 37 | import java.util.Collection; | ||
| 38 | import java.util.Map; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * 控制器 | ||
| 42 | * | ||
| 43 | * @author Chill | ||
| 44 | */ | ||
| 45 | @RestController | ||
| 46 | @AllArgsConstructor | ||
| 47 | @RequestMapping("/code") | ||
| 48 | @Api(value = "代码生成", tags = "代码生成") | ||
| 49 | @PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR) | ||
| 50 | public class CodeController extends BladeController { | ||
| 51 | |||
| 52 | private ICodeService codeService; | ||
| 53 | |||
| 54 | /** | ||
| 55 | * 详情 | ||
| 56 | */ | ||
| 57 | @GetMapping("/detail") | ||
| 58 | @ApiOperation(value = "详情", notes = "传入code", position = 1) | ||
| 59 | public R<Code> detail(Code code) { | ||
| 60 | Code detail = codeService.getOne(Condition.getQueryWrapper(code)); | ||
| 61 | return R.data(detail); | ||
| 62 | } | ||
| 63 | |||
| 64 | /** | ||
| 65 | * 分页 | ||
| 66 | */ | ||
| 67 | @GetMapping("/list") | ||
| 68 | @ApiImplicitParams({ | ||
| 69 | @ApiImplicitParam(name = "codeName", value = "模块名", paramType = "query", dataType = "string"), | ||
| 70 | @ApiImplicitParam(name = "tableName", value = "表名", paramType = "query", dataType = "string"), | ||
| 71 | @ApiImplicitParam(name = "modelName", value = "实体名", paramType = "query", dataType = "string") | ||
| 72 | }) | ||
| 73 | @ApiOperation(value = "分页", notes = "传入code", position = 2) | ||
| 74 | public R<IPage<Code>> list(@ApiIgnore @RequestParam Map<String, Object> code, Query query) { | ||
| 75 | IPage<Code> pages = codeService.page(Condition.getPage(query), Condition.getQueryWrapper(code, Code.class)); | ||
| 76 | return R.data(pages); | ||
| 77 | } | ||
| 78 | |||
| 79 | /** | ||
| 80 | * 新增或修改 | ||
| 81 | */ | ||
| 82 | @PostMapping("/submit") | ||
| 83 | @ApiOperation(value = "新增或修改", notes = "传入code", position = 6) | ||
| 84 | public R submit(@Valid @RequestBody Code code) { | ||
| 85 | return R.status(codeService.saveOrUpdate(code)); | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | /** | ||
| 90 | * 删除 | ||
| 91 | */ | ||
| 92 | @PostMapping("/remove") | ||
| 93 | @ApiOperation(value = "删除", notes = "传入ids", position = 7) | ||
| 94 | public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) { | ||
| 95 | return R.status(codeService.removeByIds(Func.toLongList(ids))); | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * 代码生成 | ||
| 100 | */ | ||
| 101 | @PostMapping("/gen-code") | ||
| 102 | @ApiOperation(value = "代码生成", notes = "传入ids", position = 8) | ||
| 103 | public R genCode(@ApiParam(value = "主键集合", required = true) @RequestParam String ids, @RequestParam(defaultValue = "sword") String system) { | ||
| 104 | Collection<Code> codes = codeService.listByIds(Func.toLongList(ids)); | ||
| 105 | codes.forEach(code -> { | ||
| 106 | BladeCodeGenerator generator = new BladeCodeGenerator(); | ||
| 107 | generator.setSystemName(system); | ||
| 108 | generator.setServiceName(code.getServiceName()); | ||
| 109 | generator.setCodeName(code.getCodeName()); | ||
| 110 | generator.setPackageName(code.getPackageName()); | ||
| 111 | generator.setPackageDir(code.getApiPath()); | ||
| 112 | generator.setPackageWebDir(code.getWebPath()); | ||
| 113 | generator.setTablePrefix(Func.toStrArray(code.getTablePrefix())); | ||
| 114 | generator.setIncludeTables(Func.toStrArray(code.getTableName())); | ||
| 115 | // 设置是否继承基础业务字段 | ||
| 116 | generator.setHasSuperEntity(false); | ||
| 117 | generator.run(); | ||
| 118 | }); | ||
| 119 | return R.success("代码生成成功"); | ||
| 120 | } | ||
| 121 | |||
| 122 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop.entity; | ||
| 18 | |||
| 19 | import com.baomidou.mybatisplus.annotation.IdType; | ||
| 20 | import com.baomidou.mybatisplus.annotation.TableId; | ||
| 21 | import com.baomidou.mybatisplus.annotation.TableLogic; | ||
| 22 | import com.baomidou.mybatisplus.annotation.TableName; | ||
| 23 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
| 24 | import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | ||
| 25 | import io.swagger.annotations.ApiModel; | ||
| 26 | import io.swagger.annotations.ApiModelProperty; | ||
| 27 | import lombok.Data; | ||
| 28 | |||
| 29 | import java.io.Serializable; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * 实体类 | ||
| 33 | * | ||
| 34 | * @author Chill | ||
| 35 | */ | ||
| 36 | @Data | ||
| 37 | @TableName("blade_code") | ||
| 38 | @ApiModel(value = "Code对象", description = "Code对象") | ||
| 39 | public class Code implements Serializable { | ||
| 40 | |||
| 41 | private static final long serialVersionUID = 1L; | ||
| 42 | |||
| 43 | /** | ||
| 44 | * 主键 | ||
| 45 | */ | ||
| 46 | @JsonSerialize(using = ToStringSerializer.class) | ||
| 47 | @ApiModelProperty(value = "主键") | ||
| 48 | @TableId(value = "id", type = IdType.ID_WORKER) | ||
| 49 | private Long id; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * 模块名称 | ||
| 53 | */ | ||
| 54 | @ApiModelProperty(value = "服务名称") | ||
| 55 | private String serviceName; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * 模块名称 | ||
| 59 | */ | ||
| 60 | @ApiModelProperty(value = "模块名称") | ||
| 61 | private String codeName; | ||
| 62 | |||
| 63 | /** | ||
| 64 | * 表名 | ||
| 65 | */ | ||
| 66 | @ApiModelProperty(value = "表名") | ||
| 67 | private String tableName; | ||
| 68 | |||
| 69 | /** | ||
| 70 | * 实体名 | ||
| 71 | */ | ||
| 72 | @ApiModelProperty(value = "表前缀") | ||
| 73 | private String tablePrefix; | ||
| 74 | |||
| 75 | /** | ||
| 76 | * 主键名 | ||
| 77 | */ | ||
| 78 | @ApiModelProperty(value = "主键名") | ||
| 79 | private String pkName; | ||
| 80 | |||
| 81 | /** | ||
| 82 | * 后端包名 | ||
| 83 | */ | ||
| 84 | @ApiModelProperty(value = "后端包名") | ||
| 85 | private String packageName; | ||
| 86 | |||
| 87 | /** | ||
| 88 | * 后端路径 | ||
| 89 | */ | ||
| 90 | @ApiModelProperty(value = "后端路径") | ||
| 91 | private String apiPath; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * 前端路径 | ||
| 95 | */ | ||
| 96 | @ApiModelProperty(value = "前端路径") | ||
| 97 | private String webPath; | ||
| 98 | |||
| 99 | /** | ||
| 100 | * 是否已删除 | ||
| 101 | */ | ||
| 102 | @TableLogic | ||
| 103 | @ApiModelProperty(value = "是否已删除") | ||
| 104 | private Integer isDeleted; | ||
| 105 | |||
| 106 | |||
| 107 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop.mapper; | ||
| 18 | |||
| 19 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 20 | import org.springblade.develop.entity.Code; | ||
| 21 | |||
| 22 | /** | ||
| 23 | * Mapper 接口 | ||
| 24 | * | ||
| 25 | * @author Chill | ||
| 26 | */ | ||
| 27 | public interface CodeMapper extends BaseMapper<Code> { | ||
| 28 | |||
| 29 | } |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 3 | <mapper namespace="org.springblade.develop.mapper.CodeMapper"> | ||
| 4 | |||
| 5 | <!-- 通用查询映射结果 --> | ||
| 6 | <resultMap id="codeResultMap" type="org.springblade.develop.entity.Code"> | ||
| 7 | <id column="id" property="id"/> | ||
| 8 | <result column="service_name" property="serviceName"/> | ||
| 9 | <result column="code_name" property="codeName"/> | ||
| 10 | <result column="table_name" property="tableName"/> | ||
| 11 | <result column="pk_name" property="pkName"/> | ||
| 12 | <result column="table_prefix" property="tablePrefix"/> | ||
| 13 | <result column="package_name" property="packageName"/> | ||
| 14 | <result column="api_path" property="apiPath"/> | ||
| 15 | <result column="web_path" property="webPath"/> | ||
| 16 | <result column="is_deleted" property="isDeleted"/> | ||
| 17 | </resultMap> | ||
| 18 | |||
| 19 | <!-- 通用查询结果列 --> | ||
| 20 | <sql id="baseColumnList"> | ||
| 21 | select | ||
| 22 | id, service_name, code_name, table_name, pk_name, model_name, package_name, api_path, web_path, is_deleted | ||
| 23 | </sql> | ||
| 24 | |||
| 25 | </mapper> |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop.service; | ||
| 18 | |||
| 19 | |||
| 20 | import com.baomidou.mybatisplus.extension.service.IService; | ||
| 21 | import org.springblade.develop.entity.Code; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * 服务类 | ||
| 25 | * | ||
| 26 | * @author Chill | ||
| 27 | */ | ||
| 28 | public interface ICodeService extends IService<Code> { | ||
| 29 | |||
| 30 | } |
| 1 | /* | ||
| 2 | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. | ||
| 3 | * | ||
| 4 | * Redistribution and use in source and binary forms, with or without | ||
| 5 | * modification, are permitted provided that the following conditions are met: | ||
| 6 | * | ||
| 7 | * Redistributions of source code must retain the above copyright notice, | ||
| 8 | * this list of conditions and the following disclaimer. | ||
| 9 | * Redistributions in binary form must reproduce the above copyright | ||
| 10 | * notice, this list of conditions and the following disclaimer in the | ||
| 11 | * documentation and/or other materials provided with the distribution. | ||
| 12 | * Neither the name of the dreamlu.net developer nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived from | ||
| 14 | * this software without specific prior written permission. | ||
| 15 | * Author: Chill 庄骞 (smallchill@163.com) | ||
| 16 | */ | ||
| 17 | package org.springblade.develop.service.impl; | ||
| 18 | |||
| 19 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||
| 20 | import org.springblade.develop.entity.Code; | ||
| 21 | import org.springblade.develop.mapper.CodeMapper; | ||
| 22 | import org.springblade.develop.service.ICodeService; | ||
| 23 | import org.springframework.stereotype.Service; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 服务实现类 | ||
| 27 | * | ||
| 28 | * @author Chill | ||
| 29 | */ | ||
| 30 | @Service | ||
| 31 | public class CodeServiceImpl extends ServiceImpl<CodeMapper, Code> implements ICodeService { | ||
| 32 | |||
| 33 | } |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'address', '智能公寓管理', 'menu', '/store/address', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'address_add', '新增', 'add', '/store/address/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'address_edit', '修改', 'edit', '/store/address/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'address_delete', '删除', 'delete', '/api/blade-store/address/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'address_view', '查看', 'view', '/store/address/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'agentprofile', '智能公寓管理', 'menu', '/user/agentprofile', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'agentprofile_add', '新增', 'add', '/user/agentprofile/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'agentprofile_edit', '修改', 'edit', '/user/agentprofile/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'agentprofile_delete', '删除', 'delete', '/api/blade-user/agentprofile/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'agentprofile_view', '查看', 'view', '/user/agentprofile/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'apartmentroom', '智能公寓管理', 'menu', '/user/apartmentroom', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'apartmentroom_add', '新增', 'add', '/user/apartmentroom/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'apartmentroom_edit', '修改', 'edit', '/user/apartmentroom/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'apartmentroom_delete', '删除', 'delete', '/api/blade-user/apartmentroom/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'apartmentroom_view', '查看', 'view', '/user/apartmentroom/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'apartmentuser', '智能公寓管理', 'menu', '/user/apartmentuser', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'apartmentuser_add', '新增', 'add', '/user/apartmentuser/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'apartmentuser_edit', '修改', 'edit', '/user/apartmentuser/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'apartmentuser_delete', '删除', 'delete', '/api/blade-user/apartmentuser/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'apartmentuser_view', '查看', 'view', '/user/apartmentuser/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'blockauth', '智能公寓管理', 'menu', '/user/blockauth', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'blockauth_add', '新增', 'add', '/user/blockauth/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'blockauth_edit', '修改', 'edit', '/user/blockauth/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'blockauth_delete', '删除', 'delete', '/api/blade-user/blockauth/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'blockauth_view', '查看', 'view', '/user/blockauth/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'category', '智能公寓管理', 'menu', '/store/category', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'category_add', '新增', 'add', '/store/category/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'category_edit', '修改', 'edit', '/store/category/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'category_delete', '删除', 'delete', '/api/blade-store/category/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'category_view', '查看', 'view', '/store/category/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'coupon', '智能公寓管理', 'menu', '/store/coupon', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'coupon_add', '新增', 'add', '/store/coupon/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'coupon_edit', '修改', 'edit', '/store/coupon/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'coupon_delete', '删除', 'delete', '/api/blade-store/coupon/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'coupon_view', '查看', 'view', '/store/coupon/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'customerservice', '智能公寓管理', 'menu', '/user/customerservice', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'customerservice_add', '新增', 'add', '/user/customerservice/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'customerservice_edit', '修改', 'edit', '/user/customerservice/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'customerservice_delete', '删除', 'delete', '/api/blade-user/customerservice/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'customerservice_view', '查看', 'view', '/user/customerservice/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'customerservicestaff', '智能公寓管理', 'menu', '/user/customerservicestaff', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'customerservicestaff_add', '新增', 'add', '/user/customerservicestaff/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'customerservicestaff_edit', '修改', 'edit', '/user/customerservicestaff/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'customerservicestaff_delete', '删除', 'delete', '/api/blade-user/customerservicestaff/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'customerservicestaff_view', '查看', 'view', '/user/customerservicestaff/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipment', '智能公寓管理', 'menu', '/user/equipment', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipment_add', '新增', 'add', '/user/equipment/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipment_edit', '修改', 'edit', '/user/equipment/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipment_delete', '删除', 'delete', '/api/blade-user/equipment/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipment_view', '查看', 'view', '/user/equipment/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentalarmlog', '智能公寓管理', 'menu', '/user/equipmentalarmlog', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentalarmlog_add', '新增', 'add', '/user/equipmentalarmlog/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentalarmlog_edit', '修改', 'edit', '/user/equipmentalarmlog/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentalarmlog_delete', '删除', 'delete', '/api/blade-user/equipmentalarmlog/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentalarmlog_view', '查看', 'view', '/user/equipmentalarmlog/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentopenlog', '智能公寓管理', 'menu', '/user/equipmentopenlog', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentopenlog_add', '新增', 'add', '/user/equipmentopenlog/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentopenlog_edit', '修改', 'edit', '/user/equipmentopenlog/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentopenlog_delete', '删除', 'delete', '/api/blade-user/equipmentopenlog/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentopenlog_view', '查看', 'view', '/user/equipmentopenlog/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentpwd', '智能公寓管理', 'menu', '/user/equipmentpwd', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentpwd_add', '新增', 'add', '/user/equipmentpwd/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentpwd_edit', '修改', 'edit', '/user/equipmentpwd/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentpwd_delete', '删除', 'delete', '/api/blade-user/equipmentpwd/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentpwd_view', '查看', 'view', '/user/equipmentpwd/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentrepair', '智能公寓管理', 'menu', '/user/equipmentrepair', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentrepair_add', '新增', 'add', '/user/equipmentrepair/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentrepair_edit', '修改', 'edit', '/user/equipmentrepair/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentrepair_delete', '删除', 'delete', '/api/blade-user/equipmentrepair/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentrepair_view', '查看', 'view', '/user/equipmentrepair/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentrepairresource', '智能公寓管理', 'menu', '/apartment/equipmentrepairresource', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentrepairresource_add', '新增', 'add', '/apartment/equipmentrepairresource/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentrepairresource_edit', '修改', 'edit', '/apartment/equipmentrepairresource/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentrepairresource_delete', '删除', 'delete', '/api/blade-apartment/equipmentrepairresource/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentrepairresource_view', '查看', 'view', '/apartment/equipmentrepairresource/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmentreset', '智能公寓管理', 'menu', '/user/equipmentreset', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmentreset_add', '新增', 'add', '/user/equipmentreset/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmentreset_edit', '修改', 'edit', '/user/equipmentreset/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmentreset_delete', '删除', 'delete', '/api/blade-user/equipmentreset/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmentreset_view', '查看', 'view', '/user/equipmentreset/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'equipmenttype', '智能公寓管理', 'menu', '/user/equipmenttype', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'equipmenttype_add', '新增', 'add', '/user/equipmenttype/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'equipmenttype_edit', '修改', 'edit', '/user/equipmenttype/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'equipmenttype_delete', '删除', 'delete', '/api/blade-user/equipmenttype/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'equipmenttype_view', '查看', 'view', '/user/equipmenttype/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'iaorder', '智能公寓管理', 'menu', '/apartment/iaorder', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'iaorder_add', '新增', 'add', '/apartment/iaorder/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'iaorder_edit', '修改', 'edit', '/apartment/iaorder/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'iaorder_delete', '删除', 'delete', '/api/blade-apartment/iaorder/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'iaorder_view', '查看', 'view', '/apartment/iaorder/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'iaorderlog', '智能公寓管理', 'menu', '/apartment/iaorderlog', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'iaorderlog_add', '新增', 'add', '/apartment/iaorderlog/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'iaorderlog_edit', '修改', 'edit', '/apartment/iaorderlog/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'iaorderlog_delete', '删除', 'delete', '/api/blade-apartment/iaorderlog/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'iaorderlog_view', '查看', 'view', '/apartment/iaorderlog/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'iaordertenant', '智能公寓管理', 'menu', '/apartment/iaordertenant', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'iaordertenant_add', '新增', 'add', '/apartment/iaordertenant/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'iaordertenant_edit', '修改', 'edit', '/apartment/iaordertenant/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'iaordertenant_delete', '删除', 'delete', '/api/blade-apartment/iaordertenant/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'iaordertenant_view', '查看', 'view', '/apartment/iaordertenant/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'lockauth', '智能公寓管理', 'menu', '/user/lockauth', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'lockauth_add', '新增', 'add', '/user/lockauth/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'lockauth_edit', '修改', 'edit', '/user/lockauth/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'lockauth_delete', '删除', 'delete', '/api/blade-user/lockauth/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'lockauth_view', '查看', 'view', '/user/lockauth/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'lockmq', '智能公寓管理', 'menu', '/user/lockmq', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'lockmq_add', '新增', 'add', '/user/lockmq/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'lockmq_edit', '修改', 'edit', '/user/lockmq/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'lockmq_delete', '删除', 'delete', '/api/blade-user/lockmq/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'lockmq_view', '查看', 'view', '/user/lockmq/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'nokeybackmsg', '智能公寓管理', 'menu', '/user/nokeybackmsg', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'nokeybackmsg_add', '新增', 'add', '/user/nokeybackmsg/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'nokeybackmsg_edit', '修改', 'edit', '/user/nokeybackmsg/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'nokeybackmsg_delete', '删除', 'delete', '/api/blade-user/nokeybackmsg/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'nokeybackmsg_view', '查看', 'view', '/user/nokeybackmsg/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
| 1 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 2 | VALUES (0, 'noticemessage', '智能公寓管理', 'menu', '/user/noticemessage', NULL, 1, 1, 0, 1, NULL, 0); | ||
| 3 | set @parentid = (SELECT LAST_INSERT_ID()); | ||
| 4 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 5 | VALUES (@parentid, 'noticemessage_add', '新增', 'add', '/user/noticemessage/add', 'plus', 1, 2, 1, 1, NULL, 0); | ||
| 6 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 7 | VALUES (@parentid, 'noticemessage_edit', '修改', 'edit', '/user/noticemessage/edit', 'form', 2, 2, 2, 2, NULL, 0); | ||
| 8 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 9 | VALUES (@parentid, 'noticemessage_delete', '删除', 'delete', '/api/blade-user/noticemessage/remove', 'delete', 3, 2, 3, 3, NULL, 0); | ||
| 10 | INSERT INTO `blade_menu`(`parent_id`, `code`, `name`, `alias`, `path`, `source`, `sort`, `category`, `action`, `is_open`, `remark`, `is_deleted`) | ||
| 11 | VALUES (@parentid, 'noticemessage_view', '查看', 'view', '/user/noticemessage/view', 'file-text', 4, 2, 2, 2, NULL, 0); |
492 Bytes
469 Bytes
778 Bytes
304 Bytes
17.1 KB
839 Bytes
450 Bytes
762 Bytes
838 Bytes
462 Bytes
374 Bytes
637 Bytes
490 Bytes
1.11 KB
1.78 KB
1.26 KB
831 Bytes
684 Bytes
802 Bytes
648 Bytes
1.7 KB
1.22 KB
1 KB
778 Bytes
1.32 KB
970 Bytes
1.14 KB
838 Bytes
2.44 KB
625 Bytes
478 Bytes
293 Bytes
309 Bytes
274 Bytes
273 Bytes
209 Bytes
608 Bytes
299 Bytes
1.24 KB
405 Bytes
705 Bytes
297 Bytes
300 Bytes
440 Bytes
530 Bytes
325 Bytes
405 Bytes
282 Bytes
255 Bytes
367 Bytes
3.17 KB
3.18 KB
698 Bytes
549 Bytes
627 Bytes
573 Bytes
413 Bytes
2.96 KB
3.05 KB
346 Bytes
3.11 KB
206 Bytes
910 Bytes
757 Bytes
467 Bytes
3.09 KB
492 Bytes
462 Bytes
432 Bytes
329 Bytes
698 Bytes
549 Bytes
450 Bytes
3.13 KB
573 Bytes
187 Bytes
189 Bytes
582 Bytes
747 Bytes
2.87 KB
230 Bytes
629 Bytes
299 Bytes
386 Bytes
1.24 KB
2.94 KB
285 Bytes
102 Bytes
300 Bytes
530 Bytes
2.92 KB
573 Bytes
2.92 KB
241 Bytes
625 Bytes
252 Bytes
3.11 KB
3.34 KB
673 Bytes
375 Bytes
282 Bytes
476 Bytes
218 Bytes
151 Bytes
365 Bytes
3.61 KB
308 Bytes
206 Bytes
278 Bytes
473 Bytes
258 Bytes
402 Bytes
277 Bytes
393 Bytes
352 Bytes
328 Bytes
169 Bytes
169 Bytes
223 Bytes
315 Bytes
250 Bytes
314 Bytes
586 Bytes
199 Bytes
574 Bytes
539 Bytes
324 Bytes
163 Bytes
165 Bytes
240 Bytes
271 Bytes
524 Bytes
419 Bytes
174 Bytes
185 Bytes
830 Bytes
4.21 KB
10.2 KB
2.72 KB
693 Bytes
996 Bytes
25.2 KB
3.1 KB
694 Bytes
764 Bytes
520 Bytes
3.1 KB
492 Bytes
1.7 KB
305 Bytes
219 Bytes
229 Bytes
161 Bytes
2.27 KB
489 Bytes
521 Bytes
1021 Bytes
789 Bytes
497 Bytes
301 Bytes
466 Bytes
434 Bytes
638 Bytes
45.6 KB
3.12 KB
147 Bytes
72.5 KB
905 Bytes
-
Please register or sign in to post a comment