diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fa759f1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,293 @@ + + 4.0.0 + + com.beimi + beimi + 1.0.0 + jar + + majiang + 贝密游戏(麻将) + + + org.springframework.boot + spring-boot-starter-parent + 1.5.3.RELEASE + + + + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + org.freemarker + freemarker + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + mysql + mysql-connector-java + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-aop + + + + org.jasypt + jasypt + 1.9.2 + + + + org + jaudiotagger + 2.0.1 + + + + lt.jave + jave + 1.0.2 + + + + commons-codec + commons-codec + + + + commons-lang + commons-lang + 2.6 + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + commons-beanutils + commons-beanutils + + + + com.corundumstudio.socketio + netty-socketio + 1.6.7 + + + commons-io + commons-io + 2.4 + + + + org.springframework + spring-context-support + + + com.hazelcast + hazelcast + 3.8 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + + + com.alibaba + druid + 1.0.27 + + + + org.lionsoul.ip2region + ip2region + 1.2.3 + + + + com.lmax + disruptor + 3.3.6 + + + + org.apache.poi + poi + 3.15 + + + org.apache.poi + poi-ooxml + 3.15 + + + + com.github.binarywang + weixin-java-mp + 2.6.0 + + + + + org.jsoup + jsoup + 1.10.2 + + + + + commons-dbutils + commons-dbutils + 1.6 + + + + joda-time + joda-time + + + + de.odysseus.juel + juel-impl + 2.2.7 + + + + com.fasterxml.jackson.core + jackson-core + + + + + cglib + cglib + 3.2.5 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + maven-compiler-plugin + + 1.7 + 1.7 + UTF-8 + + + + + org.apache.maven.plugins + maven-war-plugin + + true + + + + + compile + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.maven.plugins + + + maven-dependency-plugin + + + [2.10,) + + + unpack + + + + + + + + + + + + + + + + + SPRING-LIBS-snapshot + https://repo.spring.io/libs-milestone + + + mvn_repository + MVNREPOSITORY + http://repo1.maven.org/maven2 + + + + + SPRING-LIBS-snapshot + https://repo.spring.io/libs-milestone + + + diff --git a/src/main/java/com/beimi/Application.java b/src/main/java/com/beimi/Application.java new file mode 100644 index 0000000..4ad1cf9 --- /dev/null +++ b/src/main/java/com/beimi/Application.java @@ -0,0 +1,25 @@ +package com.beimi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.scheduling.annotation.EnableAsync; + +import com.beimi.config.web.StartedEventListener; +import com.beimi.core.BMDataContext; + + +@EnableAutoConfiguration +@SpringBootApplication +@EnableAsync +@EnableJpaRepositories("com.beimi.web.service.repository") +public class Application { + + public static void main(String[] args) { + SpringApplication springApplication = new SpringApplication(Application.class) ; + springApplication.addListeners(new StartedEventListener()); + BMDataContext.setApplicationContext(springApplication.run(args)); + } + +} diff --git a/src/main/java/com/beimi/config/web/BeiMiExceptionListener.java b/src/main/java/com/beimi/config/web/BeiMiExceptionListener.java new file mode 100644 index 0000000..69cd894 --- /dev/null +++ b/src/main/java/com/beimi/config/web/BeiMiExceptionListener.java @@ -0,0 +1,53 @@ +package com.beimi.config.web; + +import io.netty.channel.ChannelHandlerContext; + +import java.io.IOException; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.corundumstudio.socketio.SocketIOClient; +import com.corundumstudio.socketio.listener.ExceptionListenerAdapter; + +public class BeiMiExceptionListener extends ExceptionListenerAdapter { + private static final Logger log = LoggerFactory.getLogger(BeiMiExceptionListener.class); + + @Override + public void onEventException(Exception e, List args, SocketIOClient client) { + if(e instanceof IOException){ + log.info(e.getMessage()); + }else{ + log.error(e.getMessage(), e); + } + } + + @Override + public void onDisconnectException(Exception e, SocketIOClient client) { + if(e instanceof IOException){ + log.info(e.getMessage()); + }else{ + log.error(e.getMessage(), e); + } + } + + @Override + public void onConnectException(Exception e, SocketIOClient client) { + if(e instanceof IOException){ + log.info(e.getMessage()); + }else{ + log.error(e.getMessage(), e); + } + } + + @Override + public boolean exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception { + if(e instanceof IOException){ + log.info(e.getMessage()); + }else{ + log.error(e.getMessage(), e); + } + return true; + } +} diff --git a/src/main/java/com/beimi/config/web/DelegateRequestMatchingFilter.java b/src/main/java/com/beimi/config/web/DelegateRequestMatchingFilter.java new file mode 100644 index 0000000..b1a49b6 --- /dev/null +++ b/src/main/java/com/beimi/config/web/DelegateRequestMatchingFilter.java @@ -0,0 +1,35 @@ +package com.beimi.config.web; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.springframework.security.web.util.matcher.RequestMatcher; + +public class DelegateRequestMatchingFilter implements Filter { + @SuppressWarnings("unused") + private RequestMatcher[] ignoredRequests; + + public DelegateRequestMatchingFilter(RequestMatcher... matcher) { + this.ignoredRequests = matcher; + } + + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { + chain.doFilter(req,resp); + } + + @Override + public void destroy() { + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/config/web/IMServerConfiguration.java b/src/main/java/com/beimi/config/web/IMServerConfiguration.java new file mode 100644 index 0000000..ef57f51 --- /dev/null +++ b/src/main/java/com/beimi/config/web/IMServerConfiguration.java @@ -0,0 +1,88 @@ +package com.beimi.config.web; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.NoSuchAlgorithmException; +import java.util.Properties; + +import javax.annotation.PreDestroy; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; + +import com.beimi.core.BMDataContext; +import com.beimi.util.UKTools; +import com.corundumstudio.socketio.AuthorizationListener; +import com.corundumstudio.socketio.Configuration; +import com.corundumstudio.socketio.HandshakeData; +import com.corundumstudio.socketio.SocketIOServer; +import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; + +@org.springframework.context.annotation.Configuration +public class IMServerConfiguration +{ + @Value("${bm.im.server.host}") + private String host; + + @Value("${bm.im.server.port}") + private Integer port; + + @Value("${web.upload-path}") + private String path; + + private SocketIOServer server ; + + @Bean(name="webimport") + public Integer getWebIMPort() { + BMDataContext.setWebIMPort(port); + return port; + } + + @Bean + public SocketIOServer socketIOServer() throws NoSuchAlgorithmException, IOException + { + Configuration config = new Configuration(); +// config.setHostname("localhost"); + config.setPort(port); +// config.setSocketConfig(new SocketConfig()); + config.setOrigin("*"); + config.setExceptionListener(new BeiMiExceptionListener()); + File sslFile = new File(path , "ssl/https.properties") ; + if(sslFile.exists()){ + Properties sslProperties = new Properties(); + FileInputStream in = new FileInputStream(sslFile); + sslProperties.load(in); + in.close(); + if(!StringUtils.isBlank(sslProperties.getProperty("key-store")) && !StringUtils.isBlank(sslProperties.getProperty("key-store-password"))){ + config.setKeyStorePassword(UKTools.decryption(sslProperties.getProperty("key-store-password"))); + InputStream stream = new FileInputStream(new File(path , "ssl/"+sslProperties.getProperty("key-store"))); + config.setKeyStore(stream); + } + } + + +// config.setSSLProtocol("https"); + config.setWorkerThreads(100); +// config.setStoreFactory(new HazelcastStoreFactory()); + config.setAuthorizationListener(new AuthorizationListener() { + public boolean isAuthorized(HandshakeData data) { + return true; + } + }); + + return server = new SocketIOServer(config); + } + + @Bean + public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { + return new SpringAnnotationScanner(socketServer); + } + + @PreDestroy + public void destory() { + server.stop(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/config/web/StartedEventListener.java b/src/main/java/com/beimi/config/web/StartedEventListener.java new file mode 100644 index 0000000..f494f53 --- /dev/null +++ b/src/main/java/com/beimi/config/web/StartedEventListener.java @@ -0,0 +1,13 @@ +package com.beimi.config.web; + +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.stereotype.Component; + +@Component +public class StartedEventListener implements ApplicationListener { + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/config/web/WebSecurityConfig.java b/src/main/java/com/beimi/config/web/WebSecurityConfig.java new file mode 100644 index 0000000..088b0e0 --- /dev/null +++ b/src/main/java/com/beimi/config/web/WebSecurityConfig.java @@ -0,0 +1,77 @@ +package com.beimi.config.web; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.WebUtils; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.addFilterAfter(tokenInfoTokenFilterSecurityInterceptor() , BasicAuthenticationFilter.class) + .antMatcher("*/*").authorizeRequests() + .anyRequest().permitAll() + .and().addFilterAfter(csrfHeaderFilter(), BasicAuthenticationFilter.class); + } + @Bean + public Filter tokenInfoTokenFilterSecurityInterceptor() throws Exception + { + RequestMatcher autconfig = new AntPathRequestMatcher("/autoconfig/**"); + RequestMatcher configprops = new AntPathRequestMatcher("/configprops/**"); + RequestMatcher beans = new AntPathRequestMatcher("/beans/**"); + RequestMatcher dump = new AntPathRequestMatcher("/dump/**"); + RequestMatcher env = new AntPathRequestMatcher("/env/**"); + RequestMatcher health = new AntPathRequestMatcher("/health/**"); + RequestMatcher info = new AntPathRequestMatcher("/info/**"); + RequestMatcher mappings = new AntPathRequestMatcher("/mappings/**"); + RequestMatcher metrics = new AntPathRequestMatcher("/metrics/**"); + RequestMatcher trace = new AntPathRequestMatcher("/trace/**"); + + return new DelegateRequestMatchingFilter(autconfig , configprops , beans , dump , env , health , info , mappings , metrics , trace); + } + + private Filter csrfHeaderFilter() { + return new OncePerRequestFilter() { + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); + if (csrf != null) { + Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN"); + String token = csrf.getToken(); + if (cookie == null || token != null + && !token.equals(cookie.getValue())) { + + // Token is being added to the XSRF-TOKEN cookie. + cookie = new Cookie("XSRF-TOKEN", token); + cookie.setPath("/"); + response.addCookie(cookie); + } + } + filterChain.doFilter(request, response); + } + }; + } +} diff --git a/src/main/java/com/beimi/core/BMDataContext.java b/src/main/java/com/beimi/core/BMDataContext.java new file mode 100644 index 0000000..760d5cf --- /dev/null +++ b/src/main/java/com/beimi/core/BMDataContext.java @@ -0,0 +1,75 @@ +package com.beimi.core; + +import org.springframework.context.ApplicationContext; + +public class BMDataContext { + public static final String USER_SESSION_NAME = "user"; + public static final String GUEST_USER = "guest"; + public static final String IM_USER_SESSION_NAME = "im_user"; + public static final String GUEST_USER_ID_CODE = "BEIMIGUESTUSEKEY" ; + public static final String SERVICE_QUENE_NULL_STR = "service_quene_null" ; + public static final String DEFAULT_TYPE = "default" ; //默认分类代码 + + private static int WebIMPort = 8081 ; + + private static boolean imServerRunning = false ; //IM服务状态 + + private static ApplicationContext applicationContext ; + + public static int getWebIMPort() { + return WebIMPort; + } + + public static void setWebIMPort(int webIMPort) { + WebIMPort = webIMPort; + } + + public static void setApplicationContext(ApplicationContext context){ + applicationContext = context ; + } + + public static ApplicationContext getContext(){ + return applicationContext ; + } + /** + * 系统级的加密密码 , 从CA获取 + * @return + */ + public static String getSystemSecrityPassword(){ + return "BEIMI" ; + } + +public enum NameSpaceEnum{ + + IM("/im/user") , + AGENT("/im/agent"), + ENTIM("/im/ent") , + AIIM("/im/ai") ; + + private String namespace ; + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + NameSpaceEnum(String namespace){ + this.namespace = namespace ; + } + + public String toString(){ + return super.toString().toLowerCase() ; + } + } + + public static void setIMServerStatus(boolean running){ + imServerRunning = running ; + } + public static boolean getIMServerStatus(){ + return imServerRunning; + } + +} diff --git a/src/main/java/com/beimi/util/Base62.java b/src/main/java/com/beimi/util/Base62.java new file mode 100644 index 0000000..d6f8cbf --- /dev/null +++ b/src/main/java/com/beimi/util/Base62.java @@ -0,0 +1,49 @@ +package com.beimi.util; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang.StringUtils; + +public class Base62 { + private static final int BINARY = 0x2; + + private static final int NUMBER_61 = 0x0000003d; + + static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', + 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z' }; + + + public static String encode(long value){ + return encode(String.valueOf(value)).toLowerCase() ; + } + + public static String encode(String str){ + String md5Hex = DigestUtils.md5Hex(str); + // 6 digit binary can indicate 62 letter & number from 0-9a-zA-Z + int binaryLength = 6 * 6; + long binaryLengthFixer = Long.valueOf(StringUtils.repeat("1", binaryLength), BINARY); + for (int i = 0; i < 4;) { + String subString = StringUtils.substring(md5Hex, i * 8, (i + 1) * 8); + subString = Long.toBinaryString(Long.valueOf(subString, 16) & binaryLengthFixer); + subString = StringUtils.leftPad(subString, binaryLength, "0"); + StringBuilder sbBuilder = new StringBuilder(); + for (int j = 0; j < 6; j++) { + String subString2 = StringUtils.substring(subString, j * 6, (j + 1) * 6); + int charIndex = Integer.valueOf(subString2, BINARY) & NUMBER_61; + sbBuilder.append(DIGITS[charIndex]); + } + String shortUrl = sbBuilder.toString(); + if(shortUrl!=null){ + return shortUrl; + } + } + // if all 4 possibilities are already exists + return null; + } + + @SuppressWarnings("unused") + private static void print(Object messagr){ + System.out.println(messagr); + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/util/MD5.java b/src/main/java/com/beimi/util/MD5.java new file mode 100644 index 0000000..0cf8994 --- /dev/null +++ b/src/main/java/com/beimi/util/MD5.java @@ -0,0 +1,263 @@ +package com.beimi.util; + +public class MD5 { + + public String getMD5ofStr(String inbuf) { + md5Init(); + md5Update(inbuf.getBytes(), inbuf.length()); + md5Final(); + digestHexStr = ""; + for (int i = 0; i < 16; i++) + digestHexStr += byteHEX(digest[i]); + + return digestHexStr; + } + + public String getMD5ofByte(byte[] inbuf) { + md5Init(); + md5Update(inbuf, inbuf.length); + md5Final(); + digestHexStr = ""; + for (int i = 0; i < 16; i++) + digestHexStr += byteHEX(digest[i]); + + return digestHexStr; + } + + public MD5() { + state = new long[4]; + count = new long[2]; + buffer = new byte[64]; + digest = new byte[16]; + md5Init(); + } + + private void md5Init() { + count[0] = 0L; + count[1] = 0L; + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + } + + private long F(long x, long y, long z) { + return x & y | ~x & z; + } + + private long G(long x, long y, long z) { + return x & z | y & ~z; + } + + private long H(long x, long y, long z) { + return x ^ y ^ z; + } + + private long I(long x, long y, long z) { + return y ^ (x | ~z); + } + + private long FF(long a, long b, long c, long d, long x, long s, long ac) { + a += F(b, c, d) + x + ac; + a = (int) a << (int) s | (int) a >>> (int) (32L - s); + a += b; + return a; + } + + private long GG(long a, long b, long c, long d, long x, long s, long ac) { + a += G(b, c, d) + x + ac; + a = (int) a << (int) s | (int) a >>> (int) (32L - s); + a += b; + return a; + } + + private long HH(long a, long b, long c, long d, long x, long s, long ac) { + a += H(b, c, d) + x + ac; + a = (int) a << (int) s | (int) a >>> (int) (32L - s); + a += b; + return a; + } + + private long II(long a, long b, long c, long d, long x, long s, long ac) { + a += I(b, c, d) + x + ac; + a = (int) a << (int) s | (int) a >>> (int) (32L - s); + a += b; + return a; + } + + private void md5Update(byte inbuf[], int inputLen) { + byte block[] = new byte[64]; + int index = (int) (count[0] >>> 3) & 0x3f; + if ((count[0] += inputLen << 3) < (long) (inputLen << 3)) + count[1]++; + count[1] += inputLen >>> 29; + int partLen = 64 - index; + int i; + if (inputLen >= partLen) { + md5Memcpy(buffer, inbuf, index, 0, partLen); + md5Transform(buffer); + for (i = partLen; i + 63 < inputLen; i += 64) { + md5Memcpy(block, inbuf, 0, i, 64); + md5Transform(block); + } + + index = 0; + } else { + i = 0; + } + md5Memcpy(buffer, inbuf, index, i, inputLen - i); + } + + private void md5Final() { + byte bits[] = new byte[8]; + encode(bits, count, 8); + int index = (int) (count[0] >>> 3) & 0x3f; + int padLen = index >= 56 ? 120 - index : 56 - index; + md5Update(PADDING, padLen); + md5Update(bits, 8); + encode(digest, state, 16); + } + + private void md5Memcpy(byte output[], byte input[], int outpos, int inpos, int len) { + for (int i = 0; i < len; i++) + output[outpos + i] = input[inpos + i]; + + } + + private void md5Transform(byte block[]) { + long a = state[0]; + long b = state[1]; + long c = state[2]; + long d = state[3]; + long x[] = new long[16]; + decode(x, block, 64); + a = FF(a, b, c, d, x[0], 7L, 0xd76aa478L); + d = FF(d, a, b, c, x[1], 12L, 0xe8c7b756L); + c = FF(c, d, a, b, x[2], 17L, 0x242070dbL); + b = FF(b, c, d, a, x[3], 22L, 0xc1bdceeeL); + a = FF(a, b, c, d, x[4], 7L, 0xf57c0fafL); + d = FF(d, a, b, c, x[5], 12L, 0x4787c62aL); + c = FF(c, d, a, b, x[6], 17L, 0xa8304613L); + b = FF(b, c, d, a, x[7], 22L, 0xfd469501L); + a = FF(a, b, c, d, x[8], 7L, 0x698098d8L); + d = FF(d, a, b, c, x[9], 12L, 0x8b44f7afL); + c = FF(c, d, a, b, x[10], 17L, 0xffff5bb1L); + b = FF(b, c, d, a, x[11], 22L, 0x895cd7beL); + a = FF(a, b, c, d, x[12], 7L, 0x6b901122L); + d = FF(d, a, b, c, x[13], 12L, 0xfd987193L); + c = FF(c, d, a, b, x[14], 17L, 0xa679438eL); + b = FF(b, c, d, a, x[15], 22L, 0x49b40821L); + a = GG(a, b, c, d, x[1], 5L, 0xf61e2562L); + d = GG(d, a, b, c, x[6], 9L, 0xc040b340L); + c = GG(c, d, a, b, x[11], 14L, 0x265e5a51L); + b = GG(b, c, d, a, x[0], 20L, 0xe9b6c7aaL); + a = GG(a, b, c, d, x[5], 5L, 0xd62f105dL); + d = GG(d, a, b, c, x[10], 9L, 0x2441453L); + c = GG(c, d, a, b, x[15], 14L, 0xd8a1e681L); + b = GG(b, c, d, a, x[4], 20L, 0xe7d3fbc8L); + a = GG(a, b, c, d, x[9], 5L, 0x21e1cde6L); + d = GG(d, a, b, c, x[14], 9L, 0xc33707d6L); + c = GG(c, d, a, b, x[3], 14L, 0xf4d50d87L); + b = GG(b, c, d, a, x[8], 20L, 0x455a14edL); + a = GG(a, b, c, d, x[13], 5L, 0xa9e3e905L); + d = GG(d, a, b, c, x[2], 9L, 0xfcefa3f8L); + c = GG(c, d, a, b, x[7], 14L, 0x676f02d9L); + b = GG(b, c, d, a, x[12], 20L, 0x8d2a4c8aL); + a = HH(a, b, c, d, x[5], 4L, 0xfffa3942L); + d = HH(d, a, b, c, x[8], 11L, 0x8771f681L); + c = HH(c, d, a, b, x[11], 16L, 0x6d9d6122L); + b = HH(b, c, d, a, x[14], 23L, 0xfde5380cL); + a = HH(a, b, c, d, x[1], 4L, 0xa4beea44L); + d = HH(d, a, b, c, x[4], 11L, 0x4bdecfa9L); + c = HH(c, d, a, b, x[7], 16L, 0xf6bb4b60L); + b = HH(b, c, d, a, x[10], 23L, 0xbebfbc70L); + a = HH(a, b, c, d, x[13], 4L, 0x289b7ec6L); + d = HH(d, a, b, c, x[0], 11L, 0xeaa127faL); + c = HH(c, d, a, b, x[3], 16L, 0xd4ef3085L); + b = HH(b, c, d, a, x[6], 23L, 0x4881d05L); + a = HH(a, b, c, d, x[9], 4L, 0xd9d4d039L); + d = HH(d, a, b, c, x[12], 11L, 0xe6db99e5L); + c = HH(c, d, a, b, x[15], 16L, 0x1fa27cf8L); + b = HH(b, c, d, a, x[2], 23L, 0xc4ac5665L); + a = II(a, b, c, d, x[0], 6L, 0xf4292244L); + d = II(d, a, b, c, x[7], 10L, 0x432aff97L); + c = II(c, d, a, b, x[14], 15L, 0xab9423a7L); + b = II(b, c, d, a, x[5], 21L, 0xfc93a039L); + a = II(a, b, c, d, x[12], 6L, 0x655b59c3L); + d = II(d, a, b, c, x[3], 10L, 0x8f0ccc92L); + c = II(c, d, a, b, x[10], 15L, 0xffeff47dL); + b = II(b, c, d, a, x[1], 21L, 0x85845dd1L); + a = II(a, b, c, d, x[8], 6L, 0x6fa87e4fL); + d = II(d, a, b, c, x[15], 10L, 0xfe2ce6e0L); + c = II(c, d, a, b, x[6], 15L, 0xa3014314L); + b = II(b, c, d, a, x[13], 21L, 0x4e0811a1L); + a = II(a, b, c, d, x[4], 6L, 0xf7537e82L); + d = II(d, a, b, c, x[11], 10L, 0xbd3af235L); + c = II(c, d, a, b, x[2], 15L, 0x2ad7d2bbL); + b = II(b, c, d, a, x[9], 21L, 0xeb86d391L); + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + } + + private void encode(byte output[], long input[], int len) { + int i = 0; + for (int j = 0; j < len; j += 4) { + output[j] = (byte) (int) (input[i] & 255L); + output[j + 1] = (byte) (int) (input[i] >>> 8 & 255L); + output[j + 2] = (byte) (int) (input[i] >>> 16 & 255L); + output[j + 3] = (byte) (int) (input[i] >>> 24 & 255L); + i++; + } + + } + + private void decode(long output[], byte input[], int len) { + int i = 0; + for (int j = 0; j < len; j += 4) { + output[i] = b2iu(input[j]) | b2iu(input[j + 1]) << 8 | b2iu(input[j + 2]) << 16 | b2iu(input[j + 3]) << 24; + i++; + } + + } + + private long b2iu(byte b) { + return b >= 0 ? b : b & 0xff; + } + + private String byteHEX(byte ib) { + char Digit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + char ob[] = new char[2]; + ob[0] = Digit[ib >>> 4 & 0xf]; + ob[1] = Digit[ib & 0xf]; + String s = new String(ob); + return s; + } + + static final int S11 = 7; + static final int S12 = 12; + static final int S13 = 17; + static final int S14 = 22; + static final int S21 = 5; + static final int S22 = 9; + static final int S23 = 14; + static final int S24 = 20; + static final int S31 = 4; + static final int S32 = 11; + static final int S33 = 16; + static final int S34 = 23; + static final int S41 = 6; + static final int S42 = 10; + static final int S43 = 15; + static final int S44 = 21; + static final byte PADDING[] = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; + private long state[]; + private long count[]; + private byte buffer[]; + private String digestHexStr; + private byte digest[]; + +} \ No newline at end of file diff --git a/src/main/java/com/beimi/util/UKTools.java b/src/main/java/com/beimi/util/UKTools.java new file mode 100644 index 0000000..5f936ca --- /dev/null +++ b/src/main/java/com/beimi/util/UKTools.java @@ -0,0 +1,405 @@ +package com.beimi.util; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.security.NoSuchAlgorithmException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.StringUtils; +import org.jasypt.util.text.BasicTextEncryptor; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.BeansException; +import org.springframework.beans.FatalBeanException; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +import com.beimi.core.BMDataContext; + + +public class UKTools { + private static MD5 md5 = new MD5(); + + public static SimpleDateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ; + + public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") ; + + public static SimpleDateFormat timeRangeDateFormat = new SimpleDateFormat("HH:mm"); + + /** + * 当前时间+已过随机生成的 长整形数字 + * @return + */ + public static String genID(){ + return Base62.encode(getUUID()).toLowerCase() ; + } + + public static String genIDByKey(String key){ + return Base62.encode(key).toLowerCase() ; + } + + public static String getUUID(){ + return UUID.randomUUID().toString().replace("-", "") ; + } + + public static String getContextID(String session){ + return session.replaceAll("-", "") ; + } + + public static String md5(String str) { + return md5.getMD5ofStr(md5.getMD5ofStr(str)); + } + + public static String md5(byte[] bytes) { + return md5.getMD5ofByte(bytes); + } + + public static void copyProperties(Object source, Object target,String... ignoreProperties) + throws BeansException { + + Assert.notNull(source, "Source must not be null"); + Assert.notNull(target, "Target must not be null"); + + Class actualEditable = target.getClass(); + PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable); + List ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null; + + for (PropertyDescriptor targetPd : targetPds) { + Method writeMethod = targetPd.getWriteMethod(); + if (writeMethod != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) { + PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName()); + if (sourcePd != null && !targetPd.getName().equalsIgnoreCase("id")) { + Method readMethod = sourcePd.getReadMethod(); + if (readMethod != null && + ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) { + try { + if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { + readMethod.setAccessible(true); + } + Object value = readMethod.invoke(source); + if(value != null){ //只拷贝不为null的属性 by zhao + if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { + writeMethod.setAccessible(true); + } + writeMethod.invoke(target, value); + } + } + catch (Throwable ex) { + throw new FatalBeanException( + "Could not copy property '" + targetPd.getName() + "' from source to target", ex); + } + } + } + } + } + } + + public static long ipToLong(String ipAddress) { + long result = 0; + String[] ipAddressInArray = ipAddress.split("\\."); + if(ipAddressInArray!=null && ipAddressInArray.length == 4){ + for (int i = 3; i >= 0; i--) { + long ip = Long.parseLong(ipAddressInArray[3 - i]); + + // left shifting 24,16,8,0 and bitwise OR + + // 1. 192 << 24 + // 1. 168 << 16 + // 1. 1 << 8 + // 1. 2 << 0 + result |= ip << (i * 8); + + } + } + return result; + } + + public static String longToIp2(long ip) { + + return ((ip >> 24) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + + ((ip >> 8) & 0xFF) + "." + (ip & 0xFF); + } + /*** + * ID编码 , 发送对话的时候使用 + * @param id + * @param nid + * @return + */ + public static String genNewID(String id , String nid){ + StringBuffer strb = new StringBuffer(); + if(id!=null && nid!=null){ + int length = Math.max(id.length(), nid.length()); + for(int i=0 ; i i && id.length() > i){ + int cur = (id.charAt(i) + nid.charAt(i)) / 2 ; + strb.append((char)cur) ; + }else if(nid.length() > i){ + strb.append(nid.charAt(i)) ; + }else{ + strb.append(id.charAt(i)) ; + } + } + } + return strb.toString() ; + } + + /** + * + * @param request + * @return + */ + public static String getParameter(HttpServletRequest request){ + Enumeration names = request.getParameterNames() ; + StringBuffer strb = new StringBuffer(); + while(names.hasMoreElements()){ + String name = names.nextElement() ; + if(name.indexOf("password") < 0){ //不记录 任何包含 password 的参数内容 + if(strb.length() > 0){ + strb.append(",") ; + } + strb.append(name).append("=").append(request.getParameter(name)) ; + } + } + return strb.toString() ; + + } + + /** + * 获取一天的开始时间 + * @return + */ + public static Date getStartTime(){ + Calendar todayStart = Calendar.getInstance(); + todayStart.set(Calendar.HOUR_OF_DAY, 0); + todayStart.set(Calendar.MINUTE, 0); + todayStart.set(Calendar.SECOND, 0); + todayStart.set(Calendar.MILLISECOND, 0); + return todayStart.getTime(); + } + + /** + * 获取一天的开始时间 + * @return + */ + public static Date getWeekStartTime(){ + Calendar weekStart = Calendar.getInstance(); + weekStart.set(weekStart.get(Calendar.YEAR), weekStart.get(Calendar.MONDAY), weekStart.get(Calendar.DAY_OF_MONTH), 0, 0, 0); + weekStart.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + return weekStart.getTime(); + } + + /** + * 获取一天的开始时间 + * @return + */ + public static Date getLast30Day(){ + Calendar todayStart = Calendar.getInstance(); + todayStart.set(Calendar.DAY_OF_MONTH, -30); + todayStart.set(Calendar.HOUR_OF_DAY, 0); + todayStart.set(Calendar.MINUTE, 0); + todayStart.set(Calendar.SECOND, 0); + todayStart.set(Calendar.MILLISECOND, 0); + return todayStart.getTime(); + } + + /** + * 获取一天的开始时间 + * @return + */ + public static Date getLastDay(int days){ + Calendar todayStart = Calendar.getInstance(); + todayStart.set(Calendar.DAY_OF_MONTH, -days); + todayStart.set(Calendar.HOUR_OF_DAY, 0); + todayStart.set(Calendar.MINUTE, 0); + todayStart.set(Calendar.SECOND, 0); + todayStart.set(Calendar.MILLISECOND, 0); + return todayStart.getTime(); + } + + /** + * 获取一天的结束时间 + * @return + */ + public static Date getEndTime(){ + Calendar todayEnd = Calendar.getInstance(); + todayEnd.set(Calendar.HOUR_OF_DAY, 23); + todayEnd.set(Calendar.MINUTE, 59); + todayEnd.set(Calendar.SECOND, 59); + todayEnd.set(Calendar.MILLISECOND, 999); + return todayEnd.getTime(); + } + + /** + * 获取一天的结束时间 + * @return + */ + public static Date getLastTime(int secs){ + Calendar todayEnd = Calendar.getInstance(); + todayEnd.add(Calendar.SECOND, secs*-1); + return todayEnd.getTime(); + } + + public static void noCacheResponse(HttpServletResponse response){ + response.setDateHeader("Expires",0); + response.setHeader("Buffer","True"); + response.setHeader("Cache-Control","no-cache"); + response.setHeader("Cache-Control","no-store"); + response.setHeader("Expires","0"); + response.setHeader("ETag",String.valueOf(System.currentTimeMillis())); + response.setHeader("Pragma","no-cache"); + response.setHeader("Date",String.valueOf(new Date())); + response.setHeader("Last-Modified",String.valueOf(new Date())); + } + + public static Map transBean2Map(Object obj) { + + if(obj == null){ + return null; + } + Map map = new HashMap(); + try { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor property : propertyDescriptors) { + String key = property.getName(); + + // 过滤class属性 + if (!key.equals("class")) { + // 得到property对应的getter方法 + + Method readMethod = property.getReadMethod(); + + if (readMethod != null) { + Object value = readMethod.invoke(obj); + if(value instanceof Date){ + value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) value) ; + } + map.put(key, value); + } + } + } + } catch (Exception e) { + System.out.println("transBean2Map Error " + e); + } + + return map; + + } + + /** + * + * @param str + * @return + * @throws NoSuchAlgorithmException + */ + public static String encryption(String str) throws NoSuchAlgorithmException{ + BasicTextEncryptor textEncryptor = new BasicTextEncryptor (); + textEncryptor.setPassword(BMDataContext.getSystemSecrityPassword()); + return textEncryptor.encrypt(str); + } + + /** + * + * @param str + * @return + * @throws NoSuchAlgorithmException + */ + public static String decryption(String str) throws NoSuchAlgorithmException{ + BasicTextEncryptor textEncryptor = new BasicTextEncryptor (); + textEncryptor.setPassword(BMDataContext.getSystemSecrityPassword()); + return textEncryptor.decrypt(str); + } + + public static String getTopic(String snsid ,String msgtype , String eventype , String eventkey , String msg){ + StringBuffer strb = new StringBuffer() ; + strb.append(snsid) ; + strb.append(".").append(msgtype) ; + if(msgtype.equals("text")){ + strb.append(".").append(msg) ; + }else if(msgtype.equals("event")){ + strb.append(".").append(eventype.toLowerCase()) ; + if(!StringUtils.isBlank(eventkey)){ + strb.append(".").append(eventkey) ; + } + }else{ + strb.append(".").append(msgtype) ; + } + return strb.toString() ; + } + + public static String getTopic(String snsid ,String msgtype , String eventype){ + StringBuffer strb = new StringBuffer() ; + strb.append(snsid) ; + strb.append(".").append(msgtype) ; + if(msgtype.equals("text")){ + strb.append(".").append(msgtype) ; + }else if(msgtype.equals("event")){ + strb.append(".").append(eventype.toLowerCase()) ; + }else{ + strb.append(".").append(msgtype) ; + } + return strb.toString() ; + } + /** + * 处理 对话消息中的图片 + * @param message + * @return + */ + public static String filterChatMessage(String message){ + Document document = Jsoup.parse(message) ; + Elements pngs = document.select("img[src]"); + for (Element element : pngs) { + String imgUrl = element.attr("src"); + if(imgUrl.indexOf("/res/image") >= 0){ + element.attr("class", "ukefu-media-image") ; + } + } + return document.html() ; + } + + /** + * 检查当前时间是否是在 时间范围内 ,时间范围的格式为 : 08:30~11:30,13:30~17:30 + * @param timeRanges + * @return + */ + public static boolean isInWorkingHours(String timeRanges){ + boolean workintTime = true ; + String timeStr = timeRangeDateFormat.format(new Date()) ; + if(!StringUtils.isBlank(timeRanges)){ //设置了 工作时间段 + workintTime = false ; //将 检查结果设置为 False , 如果当前时间是在 时间范围内,则 置为 True + String[] timeRange = timeRanges.split(",") ; + for(String tr : timeRange){ + String[] timeGroup = tr.split("~") ; + if(timeGroup.length == 2){ + if(timeGroup[0].compareTo(timeGroup[1]) >= 0){ + if(timeStr.compareTo(timeGroup[0]) >= 0 || timeStr.compareTo(timeGroup[1]) <= 0){ + workintTime = true ; + } + }else{ + if(timeStr.compareTo(timeGroup[0]) >= 0 && timeStr.compareTo(timeGroup[1]) <= 0){ + workintTime = true ; + } + } + } + } + } + return workintTime ; + } +} diff --git a/src/main/java/com/beimi/util/client/NettyAgentClient.java b/src/main/java/com/beimi/util/client/NettyAgentClient.java new file mode 100644 index 0000000..902eb7e --- /dev/null +++ b/src/main/java/com/beimi/util/client/NettyAgentClient.java @@ -0,0 +1,32 @@ +package com.beimi.util.client; + +import java.util.List; + +import com.corundumstudio.socketio.SocketIOClient; +import com.google.common.collect.ArrayListMultimap; + +public class NettyAgentClient implements NettyClient{ + + private ArrayListMultimap agentClientsMap = ArrayListMultimap.create(); + + public List getClients(String key){ + return agentClientsMap.get(key) ; + } + + public void putClient(String key , SocketIOClient client){ + agentClientsMap.put(key, client) ; + } + + public void removeClient(String key , String id){ + List keyClients = this.getClients(key) ; + for(SocketIOClient client : keyClients){ + if(client.getSessionId().equals(id)){ + keyClients.remove(client) ; + break ; + } + } + if(keyClients.size() == 0){ + agentClientsMap.removeAll(key) ; + } + } +} diff --git a/src/main/java/com/beimi/util/client/NettyClient.java b/src/main/java/com/beimi/util/client/NettyClient.java new file mode 100644 index 0000000..530419c --- /dev/null +++ b/src/main/java/com/beimi/util/client/NettyClient.java @@ -0,0 +1,14 @@ +package com.beimi.util.client; + +import java.util.List; + +import com.corundumstudio.socketio.SocketIOClient; + +public interface NettyClient { + + public List getClients(String key) ; + + public void putClient(String key , SocketIOClient client) ; + + public void removeClient(String key , String id) ; +} diff --git a/src/main/java/com/beimi/util/client/NettyClients.java b/src/main/java/com/beimi/util/client/NettyClients.java new file mode 100644 index 0000000..8b11e1e --- /dev/null +++ b/src/main/java/com/beimi/util/client/NettyClients.java @@ -0,0 +1,70 @@ +package com.beimi.util.client; + +import java.util.List; + +import com.corundumstudio.socketio.SocketIOClient; + + +public class NettyClients { + + private static NettyClients clients = new NettyClients(); + + private NettyIMClient imClients = new NettyIMClient(); + private NettyAgentClient agentClients = new NettyAgentClient(); + private NettyIMClient entIMClients = new NettyIMClient(); + + public static NettyClients getInstance(){ + return clients ; + } + + public void setImClients(NettyIMClient imClients) { + this.imClients = imClients; + } + public void putIMEventClient(String id , SocketIOClient userClient){ + imClients.putClient(id, userClient); + } + public void removeIMEventClient(String id , String sessionid){ + imClients.removeClient(id, sessionid); + } + public void sendIMEventMessage(String id , String event , Object data){ + List userClients = imClients.getClients(id) ; + for(SocketIOClient userClient : userClients){ + userClient.sendEvent(event, data); + } + } + + public void setAgentClients(NettyAgentClient agentClients) { + this.agentClients = agentClients; + } + public void putAgentEventClient(String id , SocketIOClient agentClient){ + agentClients.putClient(id, agentClient); + } + public void removeAgentEventClient(String id , String sessionid){ + agentClients.removeClient(id, sessionid); + } + public void sendAgentEventMessage(String id , String event , Object data){ + List agents = agentClients.getClients(id) ; + for(SocketIOClient agentClient : agents){ + agentClient.sendEvent(event, data); + } + } + + public void setEntImClients(NettyIMClient entIMClients) { + this.entIMClients = entIMClients; + } + public void putEntIMEventClient(String id , SocketIOClient userClient){ + entIMClients.putClient(id, userClient); + } + public void removeEntIMEventClient(String id , String sessionid){ + entIMClients.removeClient(id, sessionid); + } + public void sendEntIMEventMessage(String id , String event , Object data){ + List entims = entIMClients.getClients(id) ; + for(SocketIOClient userClient : entims){ + userClient.sendEvent(event, data); + } + } + public int getEntIMClientsNum(String user){ + return entIMClients.getClients(user)!=null ? entIMClients.getClients(user).size() : 0; + } +} diff --git a/src/main/java/com/beimi/util/client/NettyIMClient.java b/src/main/java/com/beimi/util/client/NettyIMClient.java new file mode 100644 index 0000000..376a658 --- /dev/null +++ b/src/main/java/com/beimi/util/client/NettyIMClient.java @@ -0,0 +1,32 @@ +package com.beimi.util.client; + +import java.util.List; + +import com.corundumstudio.socketio.SocketIOClient; +import com.google.common.collect.ArrayListMultimap; + +public class NettyIMClient implements NettyClient{ + + private ArrayListMultimap imClientsMap = ArrayListMultimap.create(); + + public List getClients(String key){ + return imClientsMap.get(key) ; + } + + public void putClient(String key , SocketIOClient client){ + imClientsMap.put(key, client) ; + } + + public void removeClient(String key , String id){ + List keyClients = this.getClients(key) ; + for(SocketIOClient client : keyClients){ + if(client.getSessionId().toString().equals(id)){ + keyClients.remove(client) ; + break ; + } + } + if(keyClients.size() == 0){ + imClientsMap.removeAll(key) ; + } + } +} diff --git a/src/main/java/com/beimi/util/client/UserClient.java b/src/main/java/com/beimi/util/client/UserClient.java new file mode 100644 index 0000000..80676a0 --- /dev/null +++ b/src/main/java/com/beimi/util/client/UserClient.java @@ -0,0 +1,16 @@ +package com.beimi.util.client; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +public class UserClient { + + private static Cache userClientMap = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).build() ; + + public static ConcurrentMap getUserClientMap(){ + return userClientMap.asMap() ; + } +} diff --git a/src/main/java/com/beimi/util/server/ServerRunner.java b/src/main/java/com/beimi/util/server/ServerRunner.java new file mode 100644 index 0000000..1e770f8 --- /dev/null +++ b/src/main/java/com/beimi/util/server/ServerRunner.java @@ -0,0 +1,34 @@ +package com.beimi.util.server; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import com.beimi.core.BMDataContext; +import com.beimi.util.server.handler.IMEventHandler; +import com.corundumstudio.socketio.SocketIONamespace; +import com.corundumstudio.socketio.SocketIOServer; + +@Component +public class ServerRunner implements CommandLineRunner { + private final SocketIOServer server; + private final SocketIONamespace imSocketNameSpace ; + + @Autowired + public ServerRunner(SocketIOServer server) { + this.server = server; + imSocketNameSpace = server.addNamespace(BMDataContext.NameSpaceEnum.IM.getNamespace()) ; + } + + @Bean(name="imNamespace") + public SocketIONamespace getIMSocketIONameSpace(SocketIOServer server ){ + imSocketNameSpace.addListeners(new IMEventHandler(server)); + return imSocketNameSpace ; + } + + public void run(String... args) throws Exception { + server.start(); + BMDataContext.setIMServerStatus(true); //IMServer 启动成功 + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/util/server/handler/IMEventHandler.java b/src/main/java/com/beimi/util/server/handler/IMEventHandler.java new file mode 100644 index 0000000..fc4f36d --- /dev/null +++ b/src/main/java/com/beimi/util/server/handler/IMEventHandler.java @@ -0,0 +1,45 @@ +package com.beimi.util.server.handler; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import com.beimi.util.client.NettyClients; +import com.corundumstudio.socketio.SocketIOClient; +import com.corundumstudio.socketio.SocketIOServer; +import com.corundumstudio.socketio.annotation.OnConnect; +import com.corundumstudio.socketio.annotation.OnDisconnect; + +public class IMEventHandler +{ + protected SocketIOServer server; + + @Autowired + public IMEventHandler(SocketIOServer server) + { + this.server = server ; + } + + @OnConnect + public void onConnect(SocketIOClient client) + { + try { + String user = client.getHandshakeData().getSingleUrlParam("userid") ; + + if(!StringUtils.isBlank(user)){ + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + //添加@OnDisconnect事件,客户端断开连接时调用,刷新客户端信息 + @OnDisconnect + public void onDisconnect(SocketIOClient client) + { + String user = client.getHandshakeData().getSingleUrlParam("userid") ; + if(user!=null){ + NettyClients.getInstance().removeIMEventClient(user , client.getSessionId().toString()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beimi/web/handler/UserController.java b/src/main/java/com/beimi/web/handler/UserController.java new file mode 100644 index 0000000..b64b607 --- /dev/null +++ b/src/main/java/com/beimi/web/handler/UserController.java @@ -0,0 +1,31 @@ +package com.beimi.web.handler; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.beimi.web.model.User; +import com.beimi.web.service.repository.UserRepository; + + +@RestController +@RequestMapping("/user") +public class UserController { + + @Autowired + private UserRepository userRes; + + @RequestMapping("/{id}") + public User view(@PathVariable("id") String id) { + User user = new User(); + user.setId(id); + + userRes.save(user) ; + + System.out.println(user.getEmail()); + + return user; + } + +} diff --git a/src/main/java/com/beimi/web/model/User.java b/src/main/java/com/beimi/web/model/User.java new file mode 100644 index 0000000..24b8b51 --- /dev/null +++ b/src/main/java/com/beimi/web/model/User.java @@ -0,0 +1,427 @@ +package com.beimi.web.model; + + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.hibernate.annotations.GenericGenerator; + + +/** + * @author jaddy0302 Rivulet User.java 2010-3-17 + * + */ +@Entity +@Table(name = "uk_user") +@org.hibernate.annotations.Proxy(lazy = false) +public class User implements Serializable{ + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + @Id + private String id ; + + private String sessionid ; + + private String username ; + private String password ; + private String email ; + private String uname ; + private String firstname ; + private String midname ; + private String lastname ; + private String language ; + private String jobtitle ; + private String department ; + private String gender; + private String mobile ; + private String birthday ; + private String nickname ; + private String secureconf = "5"; + private String usertype ; // 0 Admin User : !0 Other User + private String orgi ; + private String creater; + private Date createtime = new Date(); + private Date passupdatetime = new Date(); + private Date updatetime = new Date(); + private String memo; + private String organ; + private boolean agent ; //是否开通坐席功能 + private String skill ; + private String city ; //城市 + private String province ;//省份 + private boolean login ; //是否登录 + private boolean online ; //是否在线 + private String status ; // + private boolean datastatus ;//数据状态,是否已删除 + + private Date lastlogintime = new Date(); //最后登录时间 + + private int fans ; //粉丝 + private int follows ; //关注 + private int integral ; //积分 + + public User(){} + public User(String id){ + this.id = id ; + } + + + /** + * @return the id + */ + @Id + @Column(length = 32) + @GeneratedValue(generator = "system-uuid") + @GenericGenerator(name = "system-uuid", strategy = "uuid") + public String getId() { + return id; + } + + @Transient + public String getSessionid() { + return sessionid; + } + + + public void setSessionid(String sessionid) { + this.sessionid = sessionid; + } + + + public String getUsername() { + return username; + } + + + public void setUsername(String username) { + this.username = username; + } + + + public String getPassword() { + return password; + } + + + public void setPassword(String password) { + this.password = password; + } + + + public String getEmail() { + return email; + } + + + public void setEmail(String email) { + this.email = email; + } + + + public String getUname() { + return uname; + } + + + public void setUname(String uname) { + this.uname = uname; + } + + + public String getFirstname() { + return firstname; + } + + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + + public String getMidname() { + return midname; + } + + + public void setMidname(String midname) { + this.midname = midname; + } + + + public String getLastname() { + return lastname; + } + + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + + public String getLanguage() { + return language; + } + + + public void setLanguage(String language) { + this.language = language; + } + + + public String getJobtitle() { + return jobtitle; + } + + + public void setJobtitle(String jobtitle) { + this.jobtitle = jobtitle; + } + + + public String getDepartment() { + return department; + } + + + public void setDepartment(String department) { + this.department = department; + } + + + public String getGender() { + return gender; + } + + + public void setGender(String gender) { + this.gender = gender; + } + + + public String getBirthday() { + return birthday; + } + + + public void setBirthday(String birthday) { + this.birthday = birthday; + } + + + public String getNickname() { + return nickname; + } + + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + + public String getSecureconf() { + return secureconf; + } + + + public void setSecureconf(String secureconf) { + this.secureconf = secureconf; + } + + + public String getUsertype() { + return usertype; + } + + + public void setUsertype(String usertype) { + this.usertype = usertype; + } + + + + public String getOrgi() { + return orgi; + } + + + public void setOrgi(String orgi) { + this.orgi = orgi; + } + + + public String getCreater() { + return creater; + } + + + public void setCreater(String creater) { + this.creater = creater; + } + + + public Date getCreatetime() { + return createtime; + } + + + public void setCreatetime(Date createtime) { + this.createtime = createtime; + } + + + public Date getPassupdatetime() { + return passupdatetime; + } + + + public void setPassupdatetime(Date passupdatetime) { + this.passupdatetime = passupdatetime; + } + + + public Date getUpdatetime() { + return updatetime; + } + + + public void setUpdatetime(Date updatetime) { + this.updatetime = updatetime; + } + + + public String getMemo() { + return memo; + } + + + public void setMemo(String memo) { + this.memo = memo; + } + + + public String getOrgan() { + return organ; + } + + + public void setOrgan(String organ) { + this.organ = organ; + } + + + public void setId(String id) { + this.id = id; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public boolean isAgent() { + return agent; + } + + public void setAgent(boolean agent) { + this.agent = agent; + } + + public String getSkill() { + return skill; + } + + public void setSkill(String skill) { + this.skill = skill; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + @Transient + public boolean isLogin() { + return login; + } + + public void setLogin(boolean login) { + this.login = login; + } + + public int getFans() { + return fans; + } + + public void setFans(int fans) { + this.fans = fans; + } + + public int getFollows() { + return follows; + } + + public void setFollows(int follows) { + this.follows = follows; + } + + public int getIntegral() { + return integral; + } + + public void setIntegral(int integral) { + this.integral = integral; + } + + public Date getLastlogintime() { + return lastlogintime; + } + + public void setLastlogintime(Date lastlogintime) { + this.lastlogintime = lastlogintime; + } + @Transient + public boolean isOnline() { + return online; + } + public void setOnline(boolean online) { + this.online = online; + } + public String getStatus() { + return status; + } + public void setStatus(String status) { + this.status = status; + } + public boolean isDatastatus() { + return datastatus; + } + public void setDatastatus(boolean datastatus) { + this.datastatus = datastatus; + } +} diff --git a/src/main/java/com/beimi/web/service/repository/UserRepository.java b/src/main/java/com/beimi/web/service/repository/UserRepository.java new file mode 100644 index 0000000..d38ae2e --- /dev/null +++ b/src/main/java/com/beimi/web/service/repository/UserRepository.java @@ -0,0 +1,39 @@ +package com.beimi.web.service.repository; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +import com.beimi.web.model.User; + +public abstract interface UserRepository + extends JpaRepository +{ + public abstract User findByIdAndOrgi(String paramString, String orgi); + + public abstract User findByUsernameAndOrgi(String paramString, String orgi); + + public abstract User findByEmailAndOrgi(String paramString, String orgi); + + public abstract User findByUsernameAndPassword(String paramString1, String password); + + public abstract Page findByOrgi(String orgi , Pageable paramPageable); + + public abstract Page findByDatastatusAndOrgi(boolean datastatus , String orgi, Pageable paramPageable); + + public abstract Page findByDatastatusAndOrgiAndUsernameLike(boolean datastatus , String orgi ,String username ,Pageable paramPageable); + + public abstract List findByOrganAndOrgi(String paramString, String orgi); + + public abstract List findByOrganAndDatastatusAndOrgi(String paramString , boolean datastatus, String orgi); + + public abstract List findByOrgiAndDatastatus(String orgi , boolean datastatus); + + public abstract Page findByOrgiAndAgent(String orgi , boolean agent , Pageable paramPageable); + + public abstract List findByOrgiAndAgent(String orgi , boolean agent); + + public abstract long countByOrgiAndAgent(String orgi , boolean agent) ; +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..6fd8ca3 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,68 @@ +spring.data.jpa.repositories.enabled=true + +web.upload-path=data + +server.port=80 + +server.context-path=/ + +# FREEMARKER (FreeMarkerAutoConfiguration) +spring.freemarker.allow-request-override=false +spring.freemarker.allow-session-override=false +spring.freemarker.cache=true +spring.freemarker.charset=UTF-8 +spring.freemarker.check-template-location=true +spring.freemarker.content-type=text/html +spring.freemarker.enabled=true +spring.freemarker.expose-request-attributes=false +spring.freemarker.expose-session-attributes=false +spring.freemarker.expose-spring-macro-helpers=true +spring.freemarker.prefer-file-system-access=true +spring.freemarker.suffix=.html +spring.freemarker.settings.output_format=HTMLOutputFormat +spring.freemarker.template-loader-path=classpath:/templates/ +spring.freemarker.settings.template_update_delay=0 +spring.freemarker.settings.default_encoding=UTF-8 +spring.freemarker.settings.url_escaping_charset=UTF-8 +spring.freemarker.settings.classic_compatible=true +spring.freemarker.settings.number_format=### +spring.freemarker.order=1 + + +bm.im.server.port=8081 +bm.im.server.host=localhost + +spring.hazelcast.config=classpath:config/hazelcast.xml + + +spring.datasource.type=com.alibaba.druid.pool.DruidDataSource +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.url=jdbc:mysql://localhost:3306/beixi?useUnicode=true&characterEncoding=UTF-8 +spring.datasource.username=root +spring.datasource.password=123456 + +#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver +#spring.datasource.url=jdbc:oracle:thin:@//127.0.0.1:1521/orcl +#spring.datasource.username=c##uckefu +#spring.datasource.password=123456 + + +spring.datasource.initialSize=5 +spring.datasource.minIdle=5 +spring.datasource.maxActive=20 +spring.datasource.maxWait=60000 +spring.datasource.timeBetweenEvictionRunsMillis=60000 +spring.datasource.minEvictableIdleTimeMillis=300000 +spring.datasource.validationQuery=SELECT 1 FROM DUAL +spring.datasource.testWhileIdle=true +spring.datasource.testOnBorrow=false +spring.datasource.testOnReturn=false +spring.datasource.poolPreparedStatements=true +spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 +spring.datasource.filters=stat,wall,log4j +spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 + + +management.security.enabled=false + +mybatis-plus.mapper-locations: classpath:/mapper/*Mapper.xml diff --git a/src/main/resources/config/hazelcast.xml b/src/main/resources/config/hazelcast.xml new file mode 100644 index 0000000..66b072b --- /dev/null +++ b/src/main/resources/config/hazelcast.xml @@ -0,0 +1,235 @@ + + + + + + + UCKeFu + UCKeFu-1234567890 + + + 5701 + + + 0 + + + + 127.0.0.1 + + 127.0.0.1 + + + + + + + + PBEWithMD5AndDES + + thesalt + + thepass + + 19 + + + + + 16 + + 0 + + + + 0 + + 1 + + + 0 + + -1 + + + + BINARY + + + 1 + + 0 + + 0 + + 0 + + NONE + + 0 + + 25 + + 100 + + com.hazelcast.map.merge.PutIfAbsentMapMergePolicy + + + INDEX-ONLY + + + + + 1 + SET + + + + 1 + + + + 1 + + + + 10000 + + 10000 + 0 + 1000 + true + CANCEL_RUNNING_OPERATION + + + + 0 + 1 + 0 + + + + 10 + BLOCK + true + + + + 10000 + 1 + 0 + 30 + BINARY + + + + 0 + + + + + + + \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..8d24110 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,90 @@ + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + + + ${LOG_HOME}/error/UCKeFu.error.log.%d{yyyy-MM-dd}.log + + 30 + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + 10MB + + + ERROR + ACCEPT + DENY + + + + + + + ${LOG_HOME}/info/UCKeFu.info.log.%d{yyyy-MM-dd}.log + + 30 + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + 10MB + + + + INFO + ACCEPT + DENY + + + + + + + ${LOG_HOME}/debug/UCKeFu.debug.log.%d{yyyy-MM-dd}.log + + 30 + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + 10MB + + + + DEBUG + ACCEPT + DENY + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties new file mode 100644 index 0000000..e69de29