initial commit: lottery 项目集(三工程统一管理)

- apps/lotteryServer, lotteryCapture, lotteryOpen 三个业务工程
- 忽略 archive/, tools/, infra/data/ 大目录与敏感配置文件
- 移除 lotteryServer 原嵌套 git,并入顶层统一管理
This commit is contained in:
feng0207
2026-09-17 19:03:32 +08:00
commit 3fc4dcc777
2251 changed files with 459578 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>lotteryOpen_sell</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
@@ -0,0 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
+272
View File
@@ -0,0 +1,272 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>lotteryOpen</groupId>
<artifactId>lotteryOpen</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>lotteryOpen</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.2.13.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.2.13.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.13.Final</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>xom</groupId>
<artifactId>xom</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.htmlparser</groupId>
<artifactId>htmlparser</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<!-- LOGGING begins -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<!-- 代码直接调用log4j会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>runtime</scope>
</dependency>
<!-- 代码直接调用common-logging会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.7</version>
<scope>runtime</scope>
</dependency>
<!-- 代码直接调用java.util.logging会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.7</version>
<scope>runtime</scope>
</dependency>
<!-- LOGGING ends -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
<dependency>
<groupId>net.contrapunctus.lzma</groupId>
<artifactId>lzma-4.63-jio-0.95.jar</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${basedir}\src\main\resources\lib\lzma-4.63-jio-0.95.jar</systemPath>
</dependency>
</dependencies>
<build>
<finalName>lotteryOpen</finalName>
<sourceDirectory>src/main/java</sourceDirectory>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.0,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- 设置源文件编码方式 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>lottery.bin.StartUp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 拷贝依赖的jar包到lib目录 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- 解决资源文件的编码问题 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
+7
View File
@@ -0,0 +1,7 @@
#!/bin/startup.sh
jarName=LotteryOpen.jar
ps -ef|grep -v grep|grep $jarName|while read u p o
do
kill -9 $p
done
exec java -jar -Xms512m -Xmx1024m $jarName &
@@ -0,0 +1,40 @@
package javautils;
public class ObjectUtil {
public static double toDouble(Object object) {
if(object != null && object instanceof Number) {
return ((Number) object).doubleValue();
}
return 0;
}
public static int toInt(Object object) {
if(object != null && object instanceof Number) {
return ((Number) object).intValue();
}
return 0;
}
public static long toLong(Object object) {
if(object != null && object instanceof Number) {
return ((Number) object).longValue();
}
return 0;
}
public static float toFloat(Object object) {
if(object != null && object instanceof Number) {
return ((Number) object).floatValue();
}
return 0;
}
public static short toShort(Object object) {
if(object != null && object instanceof Number) {
return ((Number) object).shortValue();
}
return 0;
}
}
@@ -0,0 +1,507 @@
package javautils;
import javautils.date.Moment;
import javautils.math.MathUtil;
import javautils.regex.RegexUtil;
import org.apache.commons.lang.StringUtils;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
public class StringUtil {
/**
* 判断字符串是否为空
* @param s
* @return
*/
public static boolean isNotNull(String s) {
if(s == null) return false;
if(s.trim().length() == 0) return false;
return true;
}
/**
* 判断字符串能否转成int
* @param s
* @return
*/
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 判断字符串能否转成double
* @param s
* @return
*/
public static boolean isDouble(String s) {
try {
Double.parseDouble(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 判断字符串能否转成float
* @param s
* @return
*/
public static boolean isFloat(String s) {
try {
Float.parseFloat(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 判断字符串能否转成boolean
* @param s
* @return
*/
public static boolean isBoolean(String s) {
try {
Boolean.parseBoolean(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 判断能否转成short
* @param s
* @return
*/
public static boolean isShort(String s) {
try {
Short.parseShort(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 判断能否转成long
* @param s
* @return
*/
public static boolean isLong(String s) {
try {
Long.parseLong(s);
} catch (Exception e) {
return false;
}
return true;
}
/**
* 自动转类型
* @param s
* @param clazz
* @return
*/
public static Object transObject(String s, Class<?> clazz) {
if(clazz != null) {
if(clazz == Integer.class) {
if(isInteger(s)) {
return Integer.parseInt(s);
}
return 0;
}
if(clazz == Double.class) {
if(isDouble(s)) {
return Double.parseDouble(s);
}
return 0;
}
if(clazz == Float.class) {
if(isFloat(s)) {
return Float.parseFloat(s);
}
return 0;
}
if(clazz == Boolean.class) {
if(isBoolean(s)) {
return Boolean.parseBoolean(s);
}
return true;
}
if(clazz == Short.class) {
if(isShort(s)) {
return Short.parseShort(s);
}
return 0;
}
if(clazz == Long.class) {
if(isLong(s)) {
return Long.parseLong(s);
}
return 0;
}
}
return s;
}
public static String transArrayToString(Object[] array) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = array.length; i < j; i++) {
sb.append(array[i].toString());
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
public static String transArrayToString(Object[] array, String p) {
String tempStr = new String();
for (Object value : array) {
tempStr += p + value.toString() + p + ",";
}
tempStr = tempStr.substring(0, tempStr.length() - 2);
return tempStr;
}
public static int[] transStringToIntArray(String string, String regex) {
if (isNotNull(string)) {
String[] sArray = string.split(regex);
int[] intArray = new int[sArray.length];
for (int i = 0; i < sArray.length; i++) {
if(isIntegerString(sArray[i])) {
intArray[i] = Integer.parseInt(sArray[i]);
}
}
return intArray;
}
return null;
}
/**
* 转换文件大小
* @param bytes
* @return
*/
public static String transDataLong(long b) {
StringBuffer sb = new StringBuffer();
long KB = 1024;
long MB = KB * 1024;
long GB = MB * 1024;
long TB = GB * 1024;
if(b >= TB) {
sb.append(MathUtil.doubleFormat((double)b/TB, 2) + "TB");
} else if(b >= GB) {
sb.append(MathUtil.doubleFormat((double)b/GB, 2) + "GB");
} else if(b >= MB) {
sb.append(MathUtil.doubleFormat((double)b/MB, 2) + "MB");
} else if(b >= KB) {
sb.append(MathUtil.doubleFormat((double)b/KB, 2) + "KB");
} else {
sb.append(b + "B");
}
return sb.toString();
}
/**
* 判断是否是int类型字符串
* @param str
* @return
*/
public static boolean isIntegerString(String str) {
boolean flag = false;
if(RegexUtil.isMatcher(str, RegexUtil.integer_regex)) {
flag = true;
}
return flag;
}
public static boolean isDoubleString(String str) {
boolean flag = false;
if(RegexUtil.isMatcher(str, RegexUtil.rational_numbers_regex)) {
flag = true;
}
return flag;
}
public static boolean isFloatString(String str) {
boolean flag = false;
if(RegexUtil.isMatcher(str, RegexUtil.rational_numbers_regex)) {
flag = true;
}
return flag;
}
/**
* 判断字符串是否是日期yyyy-MM-dd格式
* @param s
* @return
*/
public static boolean isDateString(String str) {
try {
if(str.length() != 10) {
return false;
}
new SimpleDateFormat("yyyy-MM-dd").parse(str);
} catch (Exception e) {
return false;
}
return true;
}
public static String markWithSymbol(Object obj, String symbol) {
return symbol + obj.toString() + symbol;
}
//123456789
public static Object[] split(String s) {
char[] carr = s.toCharArray();
Object[] arr = new Object[carr.length];
for (int i = 0; i < carr.length; i++) {
arr[i] = carr[i];
}
return arr;
}
//123456789
public static String[] splitToStr(String s) {
char[] carr = s.toCharArray();
String[] arr = new String[carr.length];
for (int i = 0; i < carr.length; i++) {
arr[i] = carr[i] + "";
}
return arr;
}
//123456789
public static String[] splitDistinct(String s) {
String[] strs = splitToStr(s);
HashSet<String> distinct = new HashSet<>();
for (String str : strs) {
distinct.add(str);
}
return distinct.toArray(new String[]{});
}
public static String substring(String s, String start, String end, boolean isInSub) {
int idx = s.indexOf(start);
int edx = s.indexOf(end);
idx = idx == -1 ? 0 : idx + (isInSub ? 0 : start.length());
edx = edx == -1 ? s.length() : edx + (isInSub ? end.length() : 0);
return s.substring(idx, edx);
}
public static String doubleFormat(double d) {
DecimalFormat decimalformat = new DecimalFormat("#0.00");
return decimalformat.format(d);
}
public static String fromInputStream(InputStream inputStream) {
try {
StringBuffer sb = new StringBuffer();
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len));
}
inputStream.close();
return sb.toString();
} catch (Exception e) {}
return null;
}
/**
* 验证是否是服务时间
* @param moment
* @param times 格式为12:00~2:00
* @return
*/
public static boolean isServiceTime(Moment moment, String times) {
int thisMins = moment.hour() * 60 + moment.minute();
String[] timeArr = times.split("~");
int startMins = Integer.parseInt(timeArr[0].split(":")[0]) * 60 + Integer.parseInt(timeArr[0].split(":")[1]);
int endMins = Integer.parseInt(timeArr[1].split(":")[0]) * 60 + Integer.parseInt(timeArr[1].split(":")[1]);
if(startMins < endMins) {
// 不在服务内的时间是 0 - start 和 end - 24
if((thisMins > 0 && thisMins < startMins) || (thisMins > endMins && thisMins < 24 * 60)) {
return false;
}
} else {
// 不在服务内的时间是 end - start
if(thisMins > endMins && thisMins < startMins) {
return false;
}
}
return true;
}
//姓名只能包含中文
public static boolean isNameChn(String name){
boolean result = true;
int num = 0;
for(int i=0;i<name.length();i++){
if(!Pattern.matches(RegexUtil.name_input_chn, name.substring(i, i + 1))){
num++;
}
}
if(num > 0){
result = false;;
}
return result;
}
public static String join(String str, String separator) {
if (isNotNull(str)) {
return StringUtils.join(split(str), separator);
}
return null;
}
/**
* 按位置进行替换,如String str = replaceAt("[√,√,√,-,-]", '√', new char[]{'1', '2'}, new int[]{1, 3});
* @param str 要替换的字符串
* @param search 查找字符
* @param withs 依次替换成指定字符
* @param ats 匹配第n次出现的时候按指定字符进行替换
* @return
*/
public static String replaceAt(String str, char search, char[] withs, int[] ats) {
if (isNotNull(str)) {
char[] chars = str.toCharArray();
int appearN = 0;
int withN = 0;
int atN = 0;
for (int i = 0; i < chars.length; i++) {
if (withN >= withs.length || atN >= ats.length) {
break;
}
char aChar = chars[i];
if (aChar == search) {
// 第n次出现
appearN++;
if (appearN == ats[atN]) {
chars[i] = withs[withN++];
atN++;
}
}
}
return new String(chars);
}
return str;
}
/**
* 统计每个字符串出现的次数,并按照从大到小进行排序
*/
public static Map<String, Integer> countChars(String str) {
char[] chars = str.toCharArray();
Map<String, Integer> map = new HashMap<>();
for (char aChar : chars) {
String _char = aChar + "";
Integer count = map.get(_char);
if (count == null) {
count = 0;
}
count++;
map.put(_char, count);
}
Map<String, Integer> sortedMap = new LinkedHashMap<>();
if (map != null && !map.isEmpty()) {
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
Iterator<Map.Entry<String, Integer>> iter = entryList.iterator();
Map.Entry<String, Integer> tmpEntry;
while (iter.hasNext()) {
tmpEntry = iter.next();
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
}
}
return sortedMap;
}
/**
* 统计每个字符串出现的次数,并按照从大到小进行排序
*/
public static Map<String, Integer> countChars(String[] str) {
Map<String, Integer> map = new HashMap<>();
for (String aChar : str) {
String _char = aChar;
Integer count = map.get(_char);
if (count == null) {
count = 0;
}
count++;
map.put(_char, count);
}
return sortByValueMap(map);
}
private static Map<String, Integer> sortByValueMap(Map<String, Integer> map) {
Map<String, Integer> sortedMap = new LinkedHashMap<>();
if (map != null && !map.isEmpty()) {
List<Map.Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
Iterator<Map.Entry<String, Integer>> iter = entryList.iterator();
Map.Entry<String, Integer> tmpEntry;
while (iter.hasNext()) {
tmpEntry = iter.next();
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
}
}
return sortedMap;
}
public static void main(String[] args) {
// String str = replaceAt("√,√,√,√,√", '√', new char[]{'1', '2', '3'}, new int[]{1, 2, 5});
// System.out.println(str);
// Map<String, Integer> stringIntegerMap = countChars("002003006007009022023026027029033036103703906606706907707910992232262272292332362372392662672692772792993363373393663673693773793996676696776796997797991");
// for (String s : stringIntegerMap.keySet()) {
// System.out.println(s + " = " + stringIntegerMap.get(s));
// }
Map<String, Integer> stringIntegerMap = countChars(new String[]{"2", "1", "2", "1", "1"});
Collection<Integer> values = stringIntegerMap.values();
Integer[] integers = values.toArray(new Integer[]{});
System.out.println(integers[0]);
System.out.println(integers[1]);
// Map<String, Integer> stringIntegerMap = countChars("0112223333555555");
// for (Map.Entry<String, Integer> stringIntegerEntry : stringIntegerMap.entrySet()) {
// System.out.println(stringIntegerEntry.getKey() + "=" + stringIntegerEntry.getValue());
// }
}
}
@@ -0,0 +1,299 @@
package javautils.array;
import java.util.*;
public class ArrayUtils {
public static boolean hasSame(String... vals) {
Set<String> set = new HashSet<>();
set.addAll(Arrays.asList(vals));
return vals.length != set.size();
}
public static int Combination(int n, int m) {
if(m < 0 || n < 0) {
return 0;
}
if(m == 0 || n == 0) {
return 1;
}
if(m > n) {
return 0;
}
if(m > n /2.0) {
m = n - m;
}
double result = 0.0;
for (int i = n; i >= (n - m + 1); i--) {
result += Math.log(i);
}
for (int i = m; i >= 1; i--) {
result -= Math.log(i);
}
result = Math.exp(result);
return (int) Math.round(result);
}
public static List<Object[]> CombinationValue(List<Object[]> source, int m, int x) {
int n = source.size();
List<Object[]> list = new ArrayList<>();
int start = 0;
while (m > 0) {
if (m == 1) {
list.add(source.get(start + x));
break;
}
for (int i = 0; i <= n - m; i++) {
int cnm = (int) Combination(n - 1 - i, m - 1);
if (x <= cnm - 1) {
list.add(source.get(start + i));
start = start + (i + 1);
n = n - (i + 1);
m--;
break;
} else {
x = x - cnm;
}
}
}
return list;
}
/**
* 针对数据库in
* @param ids
* @return
*/
public static String transInIds(int[] ids) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = ids.length; i < j; i++) {
sb.append(ids[i]);
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
public static String transInIds(Integer[] ids) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = ids.length; i < j; i++) {
sb.append(ids[i].intValue());
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
/**
* 针对数据库in
* @param ids
* @return
*/
public static String transInIds(List<Integer> ids) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = ids.size(); i < j; i++) {
sb.append(ids.get(i).intValue());
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
/**
* 存进数据库
* @param ids
* @return
*/
public static String transInsertIds(int[] ids) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = ids.length; i < j; i++) {
sb.append("[" + ids[i] + "]");
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
/**
* 获取id的时候,解析成id数组
* @param ids
* @return
*/
public static int[] transGetIds(String ids) {
String[] tmp = ids.replaceAll("\\[|\\]", "").split(",");
int[] arr = new int[tmp.length];
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(tmp[i]);
}
return arr;
}
/**
* 转换成字符串
* @param list
* @return
*/
public static String toString(List<Integer> list) {
StringBuffer sb = new StringBuffer();
for (int i = 0, j = list.size(); i < j; i++) {
sb.append(list.get(i));
if(i < j - 1) {
sb.append(",");
}
}
return sb.toString();
}
public static String toString(Object[] objs) {
StringBuffer sb = new StringBuffer();
for (Object obj : objs) {
sb.append(obj.toString());
}
return sb.toString();
}
/**
* 快速排序<br>
* 算法的思想在于分而治之:先找一个元素(一般来说都是数组头元素),把比它大的都放到右边,把比它小的都放到左边;<br>
* 然后再按照这样的思想去处理两个子数组; 下面说的子数组头元素通指用来划分数组的元素;<br>
* <br>
* 下面程序关键点就在于!forward, low0++, high0--这些运算; 这三个运算使得a[low0],a[high0]里面总有一个指向子数组头元素; <br>
* 可以用极端的情况来方便理解这三个值的运作: <br>
* 假如我的数列为0123456789, 初始时forward=false,0作为子数组划分依据,很显然第一轮的时候不会发生任何交换,low0一直指向0,<br>
* high0逐渐下降直到它指向0为止; 同理可思考9876543210这个例子;<br>
* <br>
* 时间复杂度: 平均:O(nlogn),最好:O(nlogn);最坏:O(n^2);
* 空间复杂度: O(logn);要为递归栈提供空间
* @param a 待排序数组<br>
* @param low 子数组开始的下标;<br>
* @param high 子数组结束的下标;<br>
*/
public static void quickSortDouble(Double[] a, int low, int high){
if(low>=high){
return;
}
int low0 = low;
int high0 = high;
boolean forward = false;
while(low0!=high0){
if(a[low0]>a[high0]){
double tmp = a[low0];
a[low0] = a[high0];
a[high0] = tmp;
forward = !forward;
}
if(forward){
low0++;
}
else{
high0--;
}
}
low0--;
high0++;
quickSortDouble(a, low, low0);
quickSortDouble(a, high0, high);
}
/**
* 快速排序的简单调用形式<br>
* 方便测试和调用<br>
* @param a
*/
public static void quickSortDouble(Double[] a){
quickSortDouble(a, 0, a.length-1);
}
/**
* 快速排序<br>
* 算法的思想在于分而治之:先找一个元素(一般来说都是数组头元素),把比它大的都放到右边,把比它小的都放到左边;<br>
* 然后再按照这样的思想去处理两个子数组; 下面说的子数组头元素通指用来划分数组的元素;<br>
* <br>
* 下面程序关键点就在于!forward, low0++, high0--这些运算; 这三个运算使得a[low0],a[high0]里面总有一个指向子数组头元素; <br>
* 可以用极端的情况来方便理解这三个值的运作: <br>
* 假如我的数列为0123456789, 初始时forward=false,0作为子数组划分依据,很显然第一轮的时候不会发生任何交换,low0一直指向0,<br>
* high0逐渐下降直到它指向0为止; 同理可思考9876543210这个例子;<br>
* <br>
* 时间复杂度: 平均:O(nlogn),最好:O(nlogn);最坏:O(n^2);
* 空间复杂度: O(logn);要为递归栈提供空间
* @param a 待排序数组<br>
* @param low 子数组开始的下标;<br>
* @param high 子数组结束的下标;<br>
*/
public static void quickSortString(String[] a, int low, int high){
if(low>=high){
return;
}
int low0 = low;
int high0 = high;
boolean forward = false;
while(low0!=high0){
if(a[low0].compareTo(a[high0]) > 0){
String tmp = a[low0];
a[low0] = a[high0];
a[high0] = tmp;
forward = !forward;
}
if(forward){
low0++;
}
else{
high0--;
}
}
low0--;
high0++;
quickSortString(a, low, low0);
quickSortString(a, high0, high);
}
/**
* 快速排序的简单调用形式<br>
* 方便测试和调用<br>
* @param a
*/
public static void quickSortString(String[] a){
quickSortString(a, 0, a.length-1);
}
public static void main(String[] args) {
// ConcurrentHashMap<String, Double> prizeCodes = new ConcurrentHashMap<>();
// prizeCodes.put("1000000", 2000000d);
// prizeCodes.put("0", 2d);
// for (int i = 1; i <= 100000; i++) {
// // prizeCodes.put(i + "", 0.01954);
// prizeCodes.put(i + "", Integer.valueOf(RandomUtils.nextInt(200000)+5).doubleValue());
// }
//
// long start = System.currentTimeMillis();
//
//
// // Double[] prizes = prizeCodes.values().toArray(new Double[]{});
// HashSet<Double> values = new HashSet<>(prizeCodes.values());
// Double[] prizes = values.toArray(new Double[]{});
//
// ArrayUtils.quickSortDouble(prizes);
// // Arrays.sort(prizes);
// double minPrize = prizes[0];
// double maxPrize = prizes[prizes.length-1];
//
// System.out.println("最小" + minPrize);
// System.out.println("最大" + maxPrize);
//
// long spend = System.currentTimeMillis() - start;
// System.out.println("耗时" + spend);
// System.out.println(Combination(5, 11));
// Double[] ds = {200d, 100d, 200d, 300d, 400d, 500d, 600d, 700d ,800d, 200d, 20d, 20d, 30d};
//
// quickSortDouble(ds);
//
// System.out.println(ds[0]);
}
}
@@ -0,0 +1,35 @@
package javautils.datasource;
import com.alibaba.druid.filter.logging.Log4jFilter;
import com.alibaba.druid.filter.stat.StatFilter;
/**
* Created by Nick on 2016/07/06
*/
public class ConfigDruidDataSource {
public static Log4jFilter configLog4jFilter() {
Log4jFilter filter = new Log4jFilter();
filter.setStatementExecuteQueryAfterLogEnabled(false);
filter.setStatementExecuteUpdateAfterLogEnabled(false);
filter.setStatementExecuteBatchAfterLogEnabled(false);
filter.setStatementExecuteAfterLogEnabled(false);
filter.setStatementExecutableSqlLogEnable(false);
filter.setStatementParameterSetLogEnabled(false);
filter.setStatementParameterClearLogEnable(false);
filter.setStatementCreateAfterLogEnabled(false);
filter.setStatementCloseAfterLogEnabled(false);
filter.setStatementPrepareAfterLogEnabled(false);
filter.setStatementPrepareCallAfterLogEnabled(false);
filter.setStatementLogEnabled(false);
filter.setStatementLogErrorEnabled(false);
return filter;
}
public static StatFilter configStatFilter() {
StatFilter filter = new StatFilter();
filter.setSlowSqlMillis(5000);
filter.setLogSlowSql(true);
filter.setMergeSql(true);
return filter;
}
}
@@ -0,0 +1,20 @@
package javautils.datasource;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Nick on 2016/07/06
*/
public class CustomDruidDataSource extends DruidDataSource {
@Override
public List<Filter> getProxyFilters() {
List<Filter> proxyFilters = new ArrayList<>();
proxyFilters.add(ConfigDruidDataSource.configLog4jFilter());
proxyFilters.add(ConfigDruidDataSource.configStatFilter());
return proxyFilters;
}
}
@@ -0,0 +1,36 @@
package javautils.date;
import java.util.ArrayList;
import java.util.List;
/**
* 依赖于Moment.java
*/
public class DateRangeUtil {
public static void main(String[] args) {
String[] days = listDate("2014-01-01", "2014-01-15");
for (String string : days) {
System.out.println(string);
}
}
public static String[] listDate(String sDate, String eDate) {
Moment sMoment = new Moment().fromDate(sDate);
Moment eMoment = new Moment().fromDate(eDate);
List<String> list = new ArrayList<>();
if(sMoment.le(eMoment)) {
list.add(sMoment.toSimpleDate());
int days = eMoment.difference(sMoment, "day");
for (int i = 0; i < days - 1; i++) {
list.add(sMoment.add(1, "days").toSimpleDate());
}
}
String[] array = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
}
@@ -0,0 +1,421 @@
package javautils.date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateUtil {
/**
* 获取当前时间
* @return
*/
public static String getCurrentTime() {
GregorianCalendar g = new GregorianCalendar();
return dateToString(g);
}
/**
* 获取当前日期
* @return
*/
public static String getCurrentDate() {
GregorianCalendar g = new GregorianCalendar();
return dateToStringSim(g);
}
/**
* 获取昨天日期
* @return
*/
public static String getYesterday() {
GregorianCalendar g = new GregorianCalendar();
g.set(Calendar.DATE, g.get(Calendar.DATE) - 1);
return dateToStringSim(g);
}
/**
* 获取明天日期
* @return
*/
public static String getTomorrow() {
GregorianCalendar g = new GregorianCalendar();
g.set(Calendar.DATE, g.get(Calendar.DATE) + 1);
return dateToStringSim(g);
}
/**
* 转换成时间
* @param ms
* @return
*/
public static String getTime(long ms) {
GregorianCalendar g = new GregorianCalendar();
g.setTimeInMillis(ms);
return dateToString(g);
}
/**
* 根据时间获取GregorianCalendar
* @param time
* @return
*/
private static GregorianCalendar getCalendarByTime(String time, String format) {
GregorianCalendar g = new GregorianCalendar();
try {
g.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time));
} catch (ParseException e) {
g = null;
}
return g;
}
/**
* 计算时间
* @param g
* @param seconds
* @return
*/
private static String calcDate(GregorianCalendar g, int seconds) {
if(g == null) {
g = new GregorianCalendar();
}
g.add(Calendar.SECOND, seconds);
return dateToString(g);
}
/**
* 日期转字符串
* @param date
* @return
*/
public static String dateToString(Date date) {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String s = formatter.format(date);
return s;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 字符串转日期
* @param date
* @return
*/
public static Date stringToDate(String date) {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date d = (Date) formatter.parse(date);
return d;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 字符串转日期, 自定义格式
* @param date
* @param format
* @return
*/
public static Date stringToDate(String date, String format) {
try {
DateFormat formatter = new SimpleDateFormat(format);
Date d = (Date) formatter.parse(date);
return d;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取日期相差毫秒数
* @param subDate
* @param minDate
* @return
*/
public static long calcDate(String subDate, String minDate) {
long lSubDate = getCalendarByTime(subDate, "yyyy-MM-dd HH:mm:ss").getTimeInMillis();
long lMinDate = getCalendarByTime(minDate, "yyyy-MM-dd HH:mm:ss").getTimeInMillis();
return (lSubDate - lMinDate);
}
/**
* 根据日期计算相差天数,忽略时分秒
* @param date1
* @param date2
* @return
*/
public static int calcDays(Date date1, Date date2) {
Calendar date1Calendar = Calendar.getInstance();
date1Calendar.setTime(date1);
Calendar date2Calendar = Calendar.getInstance();
date2Calendar.setTime(date2);
int day1 = date1Calendar.get(Calendar.DAY_OF_YEAR);
int day2 = date2Calendar.get(Calendar.DAY_OF_YEAR);
return day1 - day2;
}
/**
* 根据差值计算出新的时间
* @param time
* @param seconds
* @return
*/
public static String calcDateByTime(String time, int seconds) {
GregorianCalendar g = getCalendarByTime(time, "yyyy-MM-dd HH:mm:ss");
return calcDate(g, seconds);
}
/**
* 根据天数计算出新的日期
* @param date
* @param days
* @return
*/
public static String calcNewDay(String date, int days) {
GregorianCalendar g = new GregorianCalendar();
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
g.set(Calendar.DATE, g.get(Calendar.DATE) + days);
return dateToStringSim(g);
}
/**
* 下一天
* @param date
* @return
*/
public static String calcNextDay(String date) {
GregorianCalendar g = new GregorianCalendar();
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
g.set(Calendar.DATE, g.get(Calendar.DATE) + 1);
return dateToStringSim(g);
}
/**
* 上一天
* @param date
* @return
*/
public static String calcLastDay(String date) {
GregorianCalendar g = new GregorianCalendar();
g.setTimeInMillis(formatTime(date, "yyyy-MM-dd"));
g.set(Calendar.DATE, g.get(Calendar.DATE) - 1);
return dateToStringSim(g);
}
private static Calendar getDateOfMonth(Calendar date, int num, boolean flag) {
Calendar lastDate = (Calendar) date.clone();
if(flag) {
lastDate.add(Calendar.MONTH, num);
}else {
lastDate.add(Calendar.MONTH, -num);
}
return lastDate;
}
private static Calendar getDateOfLastMonth(String dateStr, int num, boolean flag) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(dateStr);
Calendar c = Calendar.getInstance();
c.setTime(date);
return getDateOfMonth(c, num, flag);
} catch (Exception e) {
throw new IllegalArgumentException(
"Invalid date format(yyyyMMdd): " + dateStr);
}
}
/**
* 获取上个月的同一天
* @param date
* @param num
* @param flag
* @return
*/
public static String getSameDateOfLastMonth(String date, int num, boolean flag) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String lastDate = sdf.format(getDateOfLastMonth(date, num, flag).getTime());
return lastDate;
}
/**
* GregorianCalendar转成字符串
* @param g
* @return
*/
private static String dateToString(GregorianCalendar g) {
String year = String.valueOf(g.get(Calendar.YEAR));
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
String day =String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
String hours = String.format("%02d", g.get(Calendar.HOUR_OF_DAY));
String minutes = String.format("%02d", g.get(Calendar.MINUTE));
String seconds = String.format("%02d", g.get(Calendar.SECOND));
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
}
/**
* 根据时间转成MS
* @param time
* @param format
* @return
*/
public static long stringToLong(String time, String format) {
return stringToDate(time, format).getTime();
}
/**
* GregorianCalendar转成日期格式
* @param g
* @return
*/
public static String dateToStringSim(GregorianCalendar g) {
String year = String.valueOf(g.get(Calendar.YEAR));
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
String day = String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
return year + "-" + month + "-" + day;
}
/**
* 获取当前时间
* @return
*/
public static String getCurTimeStr() {
GregorianCalendar g = new GregorianCalendar();
String year = String.valueOf(g.get(Calendar.YEAR));
String month = String.format("%02d", g.get(Calendar.MONTH) + 1);
String day = String.format("%02d", g.get(Calendar.DAY_OF_MONTH));
String hours = String.format("%02d", g.get(Calendar.HOUR_OF_DAY));
String minutes = String.format("%02d", g.get(Calendar.MINUTE));
String seconds = String.format("%02d", g.get(Calendar.SECOND));
return year + month + day + hours + minutes + seconds;
}
/**
* 格式化时间
* @param time
* @param oldFormat
* @param newFormat
* @return
*/
public static String formatTime(String time, String oldFormat,
String newFormat) {
return new SimpleDateFormat(newFormat).format(stringToDate(time,
oldFormat));
}
/**
* 格式化日期
* @param date
* @param format
* @return
*/
public static String formatTime(Date date, String format) {
return new SimpleDateFormat(format).format(date);
}
/**
* 格式化时间
* @param time
* @param format
* @return
*/
public static String formatTime(long time, String format) {
return formatTime(getTime(time), "yyyy-MM-dd HH:mm:ss", format);
}
/**
* 获取时间, 根据格式化参数
* @param time
* @param format
* @return
*/
public static long formatTime(String time, String format) {
return stringToDate(time, format).getTime();
}
public static String dateForm(String date, String config) {
if ("MM/dd/yyyy".equals(config)) {
String[] dateStrs = date.split("/");
return dateStrs[2] + "-" + dateStrs[0] + "-" + dateStrs[1];
}
if ("MM-dd-yyyy".equals(config)) {
String[] dateStrs = date.split("-");
return dateStrs[2] + "-" + dateStrs[0] + "-" + dateStrs[1];
}
return null;
}
public static int getYear(String time) {
return Integer.parseInt(time.substring(0, 4));
}
public static int getMonth(String time) {
return Integer.parseInt(time.substring(5, 7));
}
public static int getDay(String time) {
return Integer.parseInt(time.substring(8, 10));
}
public static int getHours(String time) {
return Integer.parseInt(time.substring(11, 13));
}
public static int getMinutes(String time) {
return Integer.parseInt(time.substring(14, 16));
}
public static int getSeconds(String time) {
return Integer.parseInt(time.substring(17));
}
public static int getYear() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.YEAR);
}
public static int getMonth() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.MONTH) + 1;
}
public static int getDay() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.DAY_OF_MONTH);
}
public static int getHours() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.HOUR_OF_DAY);
}
public static int getMinutes() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.MINUTE);
}
public static int getSeconds() {
GregorianCalendar g = new GregorianCalendar();
return g.get(Calendar.SECOND);
}
public static void main(String[] args) {
}
}
@@ -0,0 +1,846 @@
package javautils.date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class Moment {
public static void main(String[] args) {
Moment moment = new Moment();
System.out.println(moment.difference(new Moment().fromDate("2015-01-18"), "hour"));
}
static {
TimeZone china = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone.setDefault(china);
}
public GregorianCalendar gc;
public Moment() {
gc = new GregorianCalendar();
gc.setFirstDayOfWeek(Calendar.MONDAY);
}
public Moment(GregorianCalendar gc) {
this.gc = gc;
}
/**
* 根据日期获取对象
* @param date
* @return
*/
public Moment fromDate(String date) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date d = format.parse(date);
gc.setTime(d);
} catch (Exception e) {}
return this;
}
/**
* 从日期转换
* @param date
* @return
*/
public Moment fromDate(Date date) {
gc.setTime(date);
return this;
}
/**
* 根据时间获取对象
* @param time
* @return
*/
public Moment fromTime(String time) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = format.parse(time);
gc.setTime(d);
} catch (Exception e) {}
return this;
}
/**
* 根据时间+format
* @param time
* @param formatStr
* @return
*/
public Moment fromTime(String time, String formatStr) {
try {
DateFormat format = new SimpleDateFormat(formatStr);
Date d = format.parse(time);
gc.setTime(d);
} catch (Exception e) {}
return this;
}
/**
* 转换成普通时间 1900-01-01 12:00:00
* @return
*/
public String toSimpleTime() {
return year() + "-" + months() + "-" + days() + " " + hours() + ":" + minutes() + ":" + seconds();
}
/**
* 转换成完整时间1900-01-01 12:00:00.000
* @return
*/
public String toFullTime() {
return toSimpleTime() + "." + milliseconds();
}
/**
* 转成日期格式1900-01-01
* @return
*/
public String toSimpleDate() {
return year() + "-" + months() + "-" + days();
}
/**
* 获取date对象
* @return
*/
public Date toDate() {
return gc.getTime();
}
/**
* 根据参数格式化
* y年
* M月
* d日
* H时
* m分
* s秒
* @param format
* @return
*/
public String format(String format) {
return new SimpleDateFormat(format).format(toDate());
}
/**
* 获取年份
*
* @return
* @return
*/
public int year() {
return gc.get(Calendar.YEAR);
}
/**
* 设置年份
*
* @param year
*/
public Moment year(int year) {
gc.set(Calendar.YEAR, year);
return this;
}
/**
* 获取月份
*
* @return
*/
public int month() {
return gc.get(Calendar.MONTH) + 1;
}
/**
* 获取完整月份
*
* @return
*/
public String months() {
return String.format("%02d", month());
}
/**
* 设置月份
*
* @param month
* @return
*/
public Moment month(int month) {
if (month > 0 && month <= 12) {
gc.set(Calendar.MONTH, month - 1);
}
return this;
}
/**
* 设置月份
*
* @param month
* @return
*/
public Moment month(String month) {
month(Integer.parseInt(month));
return this;
}
/**
* 获取天
*
* @return
*/
public int day() {
return gc.get(Calendar.DAY_OF_MONTH);
}
/**
* 获取完整天
*
* @return
*/
public String days() {
return String.format("%02d", day());
}
/**
* 设置天
*
* @param day
* @return
*/
public Moment day(int day) {
if (day > 0 && day <= 31) {
gc.set(Calendar.DAY_OF_MONTH, day);
}
return this;
}
/**
* 设置天
*
* @param day
* @return
*/
public Moment day(String day) {
day(Integer.parseInt(day));
return this;
}
/**
* 获取小时
*
* @return
*/
public int hour() {
return gc.get(Calendar.HOUR_OF_DAY);
}
/**
* 获取小时
*
* @return
*/
public String hours() {
return String.format("%02d", hour());
}
/**
* 设置小时
*
* @param hour
* @return
*/
public Moment hour(int hour) {
if (hour >= 0 && hour < 24) {
gc.set(Calendar.HOUR_OF_DAY, hour);
}
return this;
}
/**
* 设置小时
*
* @param hour
* @return
*/
public Moment hour(String hour) {
hour(Integer.parseInt(hour));
return this;
}
/**
* 获取分钟
*
* @return
*/
public int minute() {
return gc.get(Calendar.MINUTE);
}
/**
* 获取分钟
*
* @return
*/
public String minutes() {
return String.format("%02d", minute());
}
/**
* 设置分钟
*
* @param minute
* @return
*/
public Moment minute(int minute) {
if (minute >= 0 && minute < 60) {
gc.set(Calendar.MINUTE, minute);
}
return this;
}
/**
* 设置分钟
*
* @param minute
* @return
*/
public Moment minute(String minute) {
minute(Integer.parseInt(minute));
return this;
}
/**
* 获取秒
*
* @return
*/
public int second() {
return gc.get(Calendar.SECOND);
}
/**
* 获取秒
*
* @return
*/
public String seconds() {
return String.format("%02d", second());
}
/**
* 设置秒
*
* @param second
* @return
*/
public Moment second(int second) {
if (second >= 0 && second < 60) {
gc.set(Calendar.SECOND, second);
}
return this;
}
/**
* 设置秒
*
* @param second
* @return
*/
public Moment second(String second) {
second(Integer.parseInt(second));
return this;
}
/**
* 获取毫秒
*
* @return
*/
public int millisecond() {
return gc.get(Calendar.MILLISECOND);
}
/**
* 获取毫秒
*
* @return
*/
public String milliseconds() {
return String.format("%03d", millisecond());
}
/**
* 设置毫秒
*
* @param millisecond
* @return
*/
public Moment millisecond(int millisecond) {
if (millisecond >= 0 && millisecond < 1000) {
gc.set(Calendar.MILLISECOND, millisecond);
}
return this;
}
/**
* 设置毫秒
*
* @param millisecond
* @return
*/
public Moment millisecond(String millisecond) {
millisecond(Integer.parseInt(millisecond));
return this;
}
/**
* 获取当前日期在本月的第几周
*
* @return
*/
public int weekOfMonth() {
return gc.get(Calendar.WEEK_OF_MONTH);
}
/**
* 获取当前日期在本年的第几周
*
* @return
*/
public int weekOfYear() {
return gc.get(Calendar.WEEK_OF_YEAR);
}
/**
* 获取星期几
*
* @return
*/
public int dayOfWeek() {
int field = gc.get(Calendar.DAY_OF_WEEK);
switch (field) {
case Calendar.SUNDAY:
return 7;
case Calendar.MONDAY:
return 1;
case Calendar.TUESDAY:
return 2;
case Calendar.WEDNESDAY:
return 3;
case Calendar.THURSDAY:
return 4;
case Calendar.FRIDAY:
return 5;
case Calendar.SATURDAY:
return 6;
default:
break;
}
return gc.getFirstDayOfWeek();
}
/**
* 设置星期几
* @param week
* @return
*/
public Moment dayOfWeek(int week) {
switch (week) {
case 7:
gc.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
break;
case 1:
gc.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
break;
case 2:
gc.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
break;
case 3:
gc.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
break;
case 4:
gc.set(Calendar.DAY_OF_WEEK, Calendar.THURSDAY);
break;
case 5:
gc.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
break;
case 6:
gc.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
break;
default:
break;
}
return this;
}
/**
* 获取当前日期在本年的第几天
*
* @return
*/
public int dayOfYear() {
return gc.get(Calendar.DAY_OF_YEAR);
}
/**
* 设置日期为本年的第几天
*
* @param day
* @return
*/
public Moment dayOfYear(int day) {
gc.set(Calendar.DAY_OF_YEAR, day);
return this;
}
/**
* 获取当前日期所在季度 1月~3月 第一季度 4月~6月 第二季度 7月~9月 第三季度 10月~12月 第四季度
*
* @return
*/
public int quarter() {
int month = month();
switch (month) {
case 1:
case 2:
case 3:
return 1;
case 4:
case 5:
case 6:
return 2;
case 7:
case 8:
case 9:
return 3;
case 10:
case 11:
case 12:
return 4;
default:
return 0;
}
}
/**
* 根据参数获取
*
* @param name
* @return
*/
public int get(String key) {
switch (key) {
case "year":
return year();
case "month":
return month();
case "day":
case "date":
return day();
case "hour":
return hour();
case "minute":
return minute();
case "second":
return second();
case "millisecond":
return millisecond();
default:
return 0;
}
}
/**
* 根据参数设置值
*
* @param key
* @param value
* @return
*/
public Moment set(String key, int value) {
switch (key) {
case "year":
year(value);
break;
case "month":
month(value);
break;
case "day":
case "date":
day(value);
break;
case "hour":
hour(value);
break;
case "minute":
minute(value);
break;
case "second":
second(value);
break;
case "millisecond":
millisecond(value);
break;
default:
break;
}
return this;
}
/**
* 获取millis时间
*
* @return
*/
public long millis() {
return gc.getTimeInMillis();
}
/**
* 获取其中时间最大的那个
*
* @param moment
* @return
*/
public static Moment max(final Moment... moment) {
Moment max = null;
if (moment != null && moment.length > 0) {
for (Moment tmp : moment) {
if (max == null) {
max = tmp;
}
if (max.millis() < tmp.millis()) {
max = tmp;
}
}
}
return max;
}
/**
* 获取其中时间最小的那个
*
* @param moment
* @return
*/
public static Moment min(final Moment... moment) {
Moment min = null;
if (moment != null && moment.length > 0) {
for (Moment tmp : moment) {
if (min == null) {
min = tmp;
}
if (min.millis() > tmp.millis()) {
min = tmp;
}
}
}
return min;
}
/**
* 增加指定key的时间
* @param number
* @param key
* @return
*/
public Moment add(int amount, String key) {
switch (key) {
case "years":
case "y":
gc.add(Calendar.YEAR, amount);
break;
case "quarters":
case "Q":
gc.add(Calendar.MONTH, amount * 3);
break;
case "months":
case "M":
gc.add(Calendar.MONTH, amount);
break;
case "weeks":
case "w":
gc.add(Calendar.WEEK_OF_YEAR, amount);
break;
case "days":
case "d":
gc.add(Calendar.DAY_OF_MONTH, amount);
break;
case "hours":
case "h":
gc.add(Calendar.HOUR_OF_DAY, amount);
break;
case "minutes":
case "m":
gc.add(Calendar.MINUTE, amount);
break;
case "seconds":
case "s":
gc.add(Calendar.SECOND, amount);
break;
case "milliseconds":
case "ms":
gc.add(Calendar.MILLISECOND, amount);
break;
default:
break;
}
return this;
}
/**
* 减去指定key的时间
* @param number
* @param key
* @return
*/
public Moment subtract(int amount, String key) {
return add(-amount, key);
}
/**
* 获取key的开始时间
*
* @param key
* @return
*/
public Moment startOf(String key) {
Moment moment = new Moment( (GregorianCalendar) this.gc.clone());
switch (key) {
case "year":
moment.dayOfYear(1).hour(0).minute(0).second(0).millisecond(0);
break;
case "month":
moment.day(1).hour(0).minute(0).second(0).millisecond(0);
break;
case "week":
moment.dayOfWeek(1).hour(0).minute(0).second(0).millisecond(0);
break;
case "day":
moment.hour(0).minute(0).second(0).millisecond(0);
break;
case "hour":
moment.minute(0).second(0).millisecond(0);
case "minute":
moment.second(0).millisecond(0);
break;
case "second":
moment.millisecond(0);
break;
default:
break;
}
return moment;
}
/**
* 获取key的结束时间
*
* @param key
* @return
*/
public Moment endOf(String key) {
Moment moment = new Moment();
switch (key) {
case "year":
return moment.startOf(key).add(1, "years").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
case "month":
return moment.startOf(key).add(1, "months").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
case "week":
return moment.startOf(key).add(1, "weeks").subtract(1, "days").hour(23).minute(59).second(59).millisecond(999);
case "day":
return moment.startOf(key).hour(23).minute(59).second(59).millisecond(999);
case "hour":
return moment.startOf(key).minute(59).second(59).millisecond(999);
case "minute":
return moment.startOf(key).second(59).millisecond(999);
case "second":
return moment.startOf(key).millisecond(999);
default:
break;
}
return moment;
}
/**
* 获取时间差值
* @param moment
* @param key
* @return
*/
public int difference(Moment moment, String key) {
switch (key) {
case "year":
return this.year() - moment.year();
case "month":
return difference(moment, "year") * 12 + (this.month() - moment.month());
case "day":
return (int) ((this.millis() - moment.millis()) / (24 * 60 * 60 * 1000));
case "hour":
return (int) ((this.millis() - moment.millis()) / (60 * 60 * 1000));
case "minute":
return (int) ((this.millis() - moment.millis()) / (60 * 1000));
case "second":
return (int) ((this.millis() - moment.millis()) / (1000));
default:
break;
}
return 0;
}
/**
* 大于另一个日期
* @param moment
* @return
*/
public boolean gt(Moment moment) {
return (this.millis() > moment.millis()) ? true : false;
}
/**
* 小于另一个日期
* @param moment
* @return
*/
public boolean lt(Moment moment) {
return (this.millis() < moment.millis()) ? true : false;
}
/**
* 大于或者等于另一个日期
* @param moment
* @return
*/
public boolean ge(Moment moment) {
return (this.millis() >= moment.millis()) ? true : false;
}
/**
* 小于或者等于另一个日期
* @param moment
* @return
*/
public boolean le(Moment moment) {
return (this.millis() <= moment.millis()) ? true : false;
}
/**
* 在两个日期之间
* @param sMoment
* @param eMoment
* @return
*/
public boolean between(Moment sMoment, Moment eMoment) {
return (this.ge(sMoment) && this.le(eMoment)) ? true : false;
}
}
@@ -0,0 +1,62 @@
package javautils.email;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class SpringMailUtil {
private static final Logger logger = LoggerFactory.getLogger(SpringMailUtil.class);
private String username;
private String personal;
private String password;
private String host;
private String defaultEncoding = "UTF-8";
public SpringMailUtil(String username, String personal, String password, String host) {
this.username = username;
this.personal = personal;
this.password = password;
this.host = host;
}
public boolean send(String to, String subject, String htmlText) {
return sendInternal(to, subject, htmlText);
}
public boolean sendInternal(String to, String subject, String htmlText) {
try {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setDefaultEncoding(defaultEncoding);
mailSender.setHost(host);
mailSender.setUsername(username);
mailSender.setPassword(password);
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.user", username);
properties.put("mail.smtp.password", password);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.auth", "true");
mailSender.setJavaMailProperties(properties);
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
messageHelper.setTo(to);
messageHelper.setFrom(username, personal);
messageHelper.setSubject(subject);
messageHelper.setText(htmlText, true);
mailSender.send(mimeMessage);
return true;
} catch (Exception e) {
logger.error("发送邮件失败!", e == null ? "" : e.getMessage());
}
return false;
}
}
@@ -0,0 +1,77 @@
package javautils.encrypt;
import java.security.MessageDigest;
/**
* 对密码进行加密和验证的类
*/
public class CipherUtil {
// 十六进制下数字到字符的映射数组
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
/** * 把inputString加密 */
public static String generatePassword(String inputString) {
return encodeByMD5(inputString);
}
/**
* 验证输入的密码是否正确
*
* @param password
* 加密后的密码
* @param inputString
* 输入的字符串
* @return 验证结果,TRUE:正确 FALSE:错误
*/
public static boolean validatePassword(String password, String inputString) {
if (password.equals(encodeByMD5(inputString))) {
return true;
} else {
return false;
}
}
/** 对字符串进行MD5加密 */
private static String encodeByMD5(String originString) {
if (originString != null) {
try {
// 创建具有指定算法名称的信息摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
byte[] results = md.digest(originString.getBytes());
// 将得到的字节数组变成字符串返回
String resultString = byteArrayToHexString(results);
return resultString.toUpperCase();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 转换字节数组为十六进制字符串
*
* @param 字节数组
* @return 十六进制字符串
*/
private static String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
/** 将一个字节转化成十六进制形式的字符串 */
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
}
@@ -0,0 +1,128 @@
package javautils.encrypt;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.Key;
/**
* DES加密工具类
*/
public class DESUtil {
private DESUtil() {
}
public static DESUtil getInstance() {
return new DESUtil();
}
/**
* 根据参数生成 KEY
*/
public Key getKey(String strKey) {
Key key = null;
try {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
DESKeySpec keySpec = new DESKeySpec(strKey.getBytes());
keyFactory.generateSecret(keySpec);
key = keyFactory.generateSecret(keySpec);
} catch (Exception e) {
e.printStackTrace();
}
return key;
}
/**
* 加密 String 明文输入 ,String 密文输出
*/
public String encryptStr(String strMing, String keyStr) {
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = "";
BASE64Encoder base64en = new BASE64Encoder();
try {
byteMing = strMing.getBytes("UTF8");
byteMi = encryptByte(byteMing, getKey(keyStr));
strMi = base64en.encode(byteMi);
} catch (Exception e) {
e.printStackTrace();
} finally {
base64en = null;
byteMing = null;
byteMi = null;
}
return strMi;
}
/**
* 解密 以 String 密文输入 ,String 明文输出
*
* @param strMi
* @return
*/
public String decryptStr(String strMi, String keyStr) {
byte[] byteMing = null;
byte[] byteMi = null;
String strMing = "";
BASE64Decoder base64De = new BASE64Decoder();
try {
byteMi = base64De.decodeBuffer(strMi);
byteMing = decryptByte(byteMi, getKey(keyStr));
strMing = new String(byteMing, "UTF8");
} catch (Exception e) {
e.printStackTrace();
} finally {
base64De = null;
byteMing = null;
byteMi = null;
}
return strMing;
}
/**
* 加密以 byte[] 明文输入 ,byte[] 密文输出
*
* @param byteS
* @return
*/
private byte[] encryptByte(byte[] byteS, Key key) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byteFina = cipher.doFinal(byteS);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
/**
* 解密以 byte[] 密文输入 , 以 byte[] 明文输出
*
* @param byteD
* @return
*/
private byte[] decryptByte(byte[] byteD, Key key) {
byte[] byteFina = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byteFina = cipher.doFinal(byteD);
} catch (Exception e) {
e.printStackTrace();
} finally {
cipher = null;
}
return byteFina;
}
}
@@ -0,0 +1,319 @@
package javautils.encrypt;
/**
* protect the password user inputed
*/
public class SHACode {
private static final long SH0 = 0x67452301L;
private static final long SH1 = 0xefcdab89L;
private static final long SH2 = 0x98badcfeL;
private static final long SH3 = 0x10325476L;
private static final long SH4 = 0xc3d2e1f0L;
private static final long K0 = 0x5a827999L;
private static final long K1 = 0x6ed9eba1L;
private static final long K2 = 0x8f1bbcdcL;
private static final long K3 = 0xca62c1d6L;
// df debug 12.11
private static long[] W;
private static byte[] BW;
private static int p0, p1, p2, p3, p4;
private static long A, B, C, D, E, temp;
private static long f0(long x, long y, long z) {
return (z ^ (x & (y ^ z)));
}
private static long f1(long x, long y, long z) {
return (x ^ y ^ z);
}
private static long f2(long x, long y, long z) {
return ((x & y) | (z & (x | y)));
}
private static long f3(long x, long y, long z) {
return (x ^ y ^ z);
}
private static long S(int n, long X) {
long tem = 0;
X = X & 0x00000000FFFFFFFF;
if (n == 1) {
tem = ((X >> 31) & 0x00000001);
}
if (n == 5)
tem = ((X >> 27) & 0x0000001F);
if (n == 30)
tem = ((X >> 2) & 0x3FFFFFFF);
return ((X << n) | tem);
}
private static void r0(int f, long K) {
temp = S(5, A) + f0(B, C, D) + E + W[p0++] + K;
E = D;
D = C;
C = S(30, B);
B = A;
A = temp;
}
private static void r1(int f, long K) {
temp = (W[p1++] ^ W[p2++] ^ W[p3++] ^ W[p4++]);
switch (f) {
case 0:
temp = S(5, A) + f0(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
break;
case 1:
temp = S(5, A) + f1(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
break;
case 2:
temp = S(5, A) + f2(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
break;
case 3:
temp = S(5, A) + f3(B, C, D) + E + (W[p0++] = S(1, temp)) + K;
break;
}
E = D;
D = C;
C = S(30, B);
B = A;
A = temp;
}
public static long getCode(String mem) {
int i, nread, nbits;
int length = mem.toCharArray().length;
int hi_length, lo_length;
int padded;
char[] s;
int sp = 0;
long h0, h1, h2, h3, h4;
W = new long[80];
BW = new byte[320];
padded = 0;
s = mem.toCharArray();
h0 = SH0;
h1 = SH1;
h2 = SH2;
h3 = SH3;
h4 = SH4;
for (hi_length = lo_length = 0;;) {
if (length < 64)
nread = length;
else
nread = 64;
length -= nread;
for (int m = 0; m < nread; m++)
BW[m] = (byte) s[sp++];
if (nread < 64) {
nbits = nread * 8;
if ((lo_length += nbits) < (long) nbits)
hi_length++;
if ((nread < 64) && (padded == 0)) {
BW[nread++] = (byte) 0x080;
padded = 1;
}
for (i = nread; i < 64; i++)
BW[i] = 0;
byte[] tar = new byte[4];
for (int z = 0; z < 64; z = z + 4) {
for (int y = 0; y < 4; y++)
tar[y] = BW[z + y];
W[z >> 2] = 0;
W[z >> 2] = (W[z >> 2] | tar[0]) << 8;
W[z >> 2] = (W[z >> 2] | (tar[1] & 0x00FF)) << 8;
W[z >> 2] = ((W[z >> 2] | (tar[2] & 0x00FF)) << 8)
| (tar[3] & 0x00FF);
}
if (nread <= 56) {
W[14] = hi_length;
W[15] = lo_length;
}
} else {
if ((lo_length += 512) < 512)
hi_length++;
byte[] tar = new byte[4];
for (int z = 0; z < 64; z = z + 4) {
for (int y = 0; y < 4; y++)
tar[y] = BW[z + y];
W[z >> 2] = 0;
W[z >> 2] = (W[z >> 4] | tar[0]) << 8;
W[z >> 2] = (W[z >> 2] | (tar[1] & 0x00FF)) << 8;
W[z >> 2] = ((W[z >> 2] | (tar[2] & 0x00FF)) << 8)
| (tar[3] & 0x00FF);
}
}
p0 = 0;
A = h0;
B = h1;
C = h2;
D = h3;
E = h4;
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
r0(0, K0);
p1 = 13;
p2 = 8;
p3 = 2;
p4 = 0;
r1(0, K0);
r1(0, K0);
r1(0, K0);
r1(0, K0);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(1, K1);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(2, K2);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
r1(3, K3);
h0 += A;
h1 += B;
h2 += C;
h3 += D;
h4 += E;
// System.gc();
if (nread <= 56)
break;
}
W = null;
BW = null;
s = null;
A = 0;
B = 0;
C = 0;
D = 0;
E = 0;
temp = 0;
h4 = 0;
h3 = 0;
h2 = 0;
h1 = 0;
p0 = 0;
p1 = 0;
p2 = 0;
p3 = 0;
p4 = 0;
int highBit, lowBit;
lowBit = (int) (h0 & 0x0FFFF);
highBit = (int) ((h0 >> 16) & 0x0FFFFF);
h0 = 0;
String shaHigh = new String(Integer.toHexString(highBit));
int leng = shaHigh.length();
if (leng > 4) {
shaHigh = shaHigh.substring(leng - 4);
} else if (leng < 4) {
for (int m = 0; m < 4 - leng; m++)
shaHigh = "0" + shaHigh;
}
String shaLow = new String(Integer.toHexString(lowBit));
leng = shaLow.length();
if (leng > 4) {
shaLow = shaLow.substring(leng - 4);
} else if (leng < 4) {
for (int m = 0; m < 4 - leng; m++)
shaLow = "0" + shaLow;
}
return Long.parseLong(shaHigh + shaLow, 16);
}
}
@@ -0,0 +1,58 @@
package javautils.encrypt;
import lottery.domains.content.entity.UserBetsOriginal;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
/**
* Created by Nick on 2017/1/15.
*/
public class UserBetsEncrypt {
private static final DESUtil DES = DESUtil.getInstance();
private static final String DES_KEY = "#$ddw4FFWfg#GR0(DSFW@#?!@#!@#$C$$3GhyUhb";
public static String encryptCertification(String certification) {
return DES.encryptStr(certification, DES_KEY);
}
public static String getRandomCertification() {
return RandomStringUtils.random(10, true, true);
}
public static String getIdentification(UserBetsOriginal original, String certification) {
StringBuffer sb = new StringBuffer();
int point = Double.valueOf(original.getPoint()).intValue();
int money = Double.valueOf(original.getMoney()).intValue();
sb.append(original.getId())
.append(original.getBillno())
.append(original.getUserId())
.append(original.getType())
.append(original.getLotteryId())
.append(original.getExpect())
.append(original.getRuleId())
.append(DigestUtils.md5Hex(original.getCodes()))
.append(original.getNums())
.append(original.getModel())
.append(original.getMultiple())
.append(original.getCode())
.append(point)
.append(money)
.append(original.getTime())
.append(original.getStopTime())
.append(original.getOpenTime())
.append(original.getStatus())
.append(original.getOpenCode())
.append(original.getPrizeMoney())
.append(original.getPrizeTime())
.append(original.getChaseBillno())
.append(original.getChaseBillno())
.append(original.getPlanBillno())
.append(original.getRewardMoney())
.append(certification);
String thisData = sb.toString();
return DigestUtils.md5Hex(thisData + certification);
}
}
@@ -0,0 +1,41 @@
package javautils.jdbc;
import java.util.ArrayList;
import java.util.List;
/**
* 分页类
* @author root
*
*/
public class PageList {
private List<?> list;
private int count;
public PageList() {
this.list = new ArrayList<>();
this.count = 0;
}
public PageList(List<?> list, int count) {
this.list = list;
this.count = count;
}
public List<?> getList() {
return list;
}
public void setList(List<?> list) {
this.list = list;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
@@ -0,0 +1,104 @@
package javautils.jdbc.helper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.*;
public class JDBCHelper {
public final static String MYSQL = "com.mysql.jdbc.Driver";
public static Connection openConnection(String url, String username,
String password, String type) {
Connection conn = null;
try {
Class.forName(type);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {}
return conn;
}
public static boolean executeUpdate(String sql, Connection conn) {
boolean flag = false;
if (conn != null) {
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
int count = pst.executeUpdate();
flag = count > 0 ? true : false;
} catch (Exception e) {
} finally {
try {
if (pst != null) pst.close();
if (conn != null) conn.close();
} catch (SQLException e) {}
}
}
return flag;
}
public static JSONArray executeQuery(String sql, Connection conn) {
JSONArray list = null;
if (conn != null) {
PreparedStatement pst = null;
try {
pst = conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
list = toJsonArray(rs);
} catch (Exception e) {} finally {
try {
if (pst != null) pst.close();
if (conn != null) conn.close();
} catch (SQLException e) {}
}
}
return list;
}
public static JSONArray toJsonArray(ResultSet rs) throws Exception {
JSONArray list = new JSONArray();
if (rs != null) {
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
while (rs.next()) {
JSONObject obj = new JSONObject();
for (int i = 0; i < columnCount; i++) {
String columnName = metaData.getColumnLabel(i + 1);
String value = rs.getString(columnName);
obj.put(columnName, value);
}
list.add(obj);
}
}
return list;
}
/**
* java:comp/env/jdbc/books
* @param jndi
* @return
*/
public static Connection openConnection(String jndi) {
Connection conn = null;
try {
Context context = new InitialContext();
DataSource source = (DataSource) context.lookup(jndi);
conn = source.getConnection();
} catch (Exception e) {}
return conn;
}
public static void main(String[] args) {
String url = "jdbc:mysql://192.168.1.111:3306/test?useUnicode=true&characterEncoding=utf-8";
String username = "root";
String password = "root";
Connection conn = JDBCHelper.openConnection(url, username, password, JDBCHelper.MYSQL);
String sql = "select * from user";
JDBCHelper.executeQuery(sql, conn);
}
}
@@ -0,0 +1,605 @@
package javautils.jdbc.hibernate;
import javautils.jdbc.PageList;
import javautils.jdbc.util.BatchSQLUtil;
import org.hibernate.*;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.jdbc.Work;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
@Component
@SuppressWarnings("unchecked")
public class HibernateSuperDao<T> {
private static final Logger logger = LoggerFactory.getLogger(HibernateSuperDao.class);
@Autowired
private SessionFactory sessionFactory;
public Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
/**
* 保存
* @param entity
* @return
*/
@Transactional
public boolean save(final Object entity) {
boolean flag = false;
try {
getCurrentSession().save(entity);
flag = true;
} catch (Exception e) {
logger.error("保存实体类异常", e);
throw e;
}
return flag;
}
/**
* 更新
* @param entity
* @return
*/
@Transactional
public boolean update(final Object entity) {
boolean flag = false;
try {
getCurrentSession().update(entity);
flag = true;
} catch (Exception e) {
logger.error("更新实体类异常", e);
throw e;
}
return flag;
}
/**
* 更新
* @param sql sql
* @return
*/
@Transactional
public int updateBySql(final String sql) {
try {
SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
return sqlQuery.executeUpdate();
} catch (Exception e) {
logger.error("更新实体类异常", e);
throw e;
}
}
/**
* 更新
* @param hql
* @param values
* @return
*/
@Transactional
public boolean update(final String hql, final Object[] values) {
boolean flag = false;
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
int result = query.executeUpdate();
flag = result > 0 ? true : false;
} catch (Exception e) {
logger.error("更新实体类异常", e);
throw e;
}
return flag;
}
@Transactional
public int updateByHql(final String hql) {
try {
Query query = getCurrentSession().createQuery(hql);
int result = query.executeUpdate();
return result;
} catch (Exception e) {
logger.error("更新实体类异常", e);
throw e;
}
}
/**
* 删除
* @param entity
* @return
*/
public boolean delete(final Object entity) {
boolean flag = false;
try {
getCurrentSession().delete(entity);
flag = true;
} catch (Exception e) {
logger.error("删除实体类异常", e);
throw e;
}
return flag;
}
/**
* 删除
* @param hql
* @param values
* @return
*/
@Transactional
public boolean delete(final String hql, final Object[] values) {
boolean flag = false;
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
int result = query.executeUpdate();
flag = result > 0 ? true : false;
} catch (Exception e) {
logger.error("删除实体类异常", e);
throw e;
}
return flag;
}
/**
* 查询
* @param hql
* @return
*/
@Transactional(readOnly = true)
public List<T> list(final String hql) {
try {
Query query = getCurrentSession().createQuery(hql);
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 查询
* @param hql
* @param start
* @param limit
* @return
*/
@Transactional(readOnly = true)
public List<T> list(final String hql, final int start, final int limit) {
try {
Query query = getCurrentSession().createQuery(hql);
if(start >= 0 && limit > 0) {
query.setFirstResult(start);
query.setMaxResults(limit);
}
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 唯一结果查询
* @param hql
* @return
*/
@Transactional(readOnly = true)
public Object unique(final String hql) {
try {
Query query = getCurrentSession().createQuery(hql);
return query.uniqueResult();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 唯一结果查询
* @param hql
* @param values
* @return
*/
@Transactional(readOnly = true)
public Object unique(final String hql, final Object[] values) {
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
return query.uniqueResult();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 查询
* @param hql
* @param values
* @return
*/
@Transactional(readOnly = true)
public List<T> list(final String hql, final Object[] values) {
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 查询
* @param hql
* @param values
* @return
*/
@Transactional(readOnly = true)
public List<?> listObject(final String hql, final Object[] values, final int start, final int limit) {
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
if(start >= 0 && limit > 0) {
query.setFirstResult(start);
query.setMaxResults(limit);
}
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 查询
* @param hql
* @param values
* @return
*/
@Transactional(readOnly = true)
public List<?> listObject(final String hql, final Object[] values) {
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 查询
* @param hql
* @param values
* @param start
* @param limit
* @return
*/
@Transactional(readOnly = true)
public List<T> list(final String hql, final Object[] values, final int start, final int limit) {
try {
Query query = getCurrentSession().createQuery(hql);
for (int i = 0; i < values.length; i++) {
query.setParameter(String.valueOf(i), values[i]);
}
if(start >= 0 && limit > 0) {
query.setFirstResult(start);
query.setMaxResults(limit);
}
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* SQL查询
* @param sql
* @return
*/
@Transactional(readOnly = true)
public List<?> findWithSql(final String sql) {
try {
SQLQuery query = getCurrentSession().createSQLQuery(sql);
return query.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* SQL查询
* @param sql
* @return
*/
@Transactional(readOnly = true)
public Object uniqueWithSqlCount(final String sql) {
try {
SQLQuery query = getCurrentSession().createSQLQuery(sql);
return query.uniqueResult();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 分页查询
* @param querySql
* @param countSql
* @param start
* @param limit
* @return
*/
@Transactional(readOnly = true)
public PageList findPageList(final String querySql, final String countSql, final int start, final int limit) {
try {
PageList pList = new PageList();
// 查询总数
SQLQuery countQuery = getCurrentSession().createSQLQuery(countSql);
Number result = (Number) countQuery.uniqueResult();
int count = result.intValue();
pList.setCount(count);
// 查询集合
SQLQuery listQuery = getCurrentSession().createSQLQuery(querySql);
if(start >= 0 && limit > 0) {
listQuery.setFirstResult(start);
listQuery.setMaxResults(limit);
}
List<T> list = listQuery.list();
pList.setList(list);
return pList;
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* 分页查询
* @param clazz
* @param criterions
* @param orders
* @param start
* @param limit
* @return
*/
@Transactional(readOnly = true)
public PageList findPageList(final Class<T> clazz, String propertyName, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
try {
PageList pList = new PageList();
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
// 查询总数
criteria.setProjection(Projections.count(propertyName));
Number result = (Number) criteria.uniqueResult();
int count = result.intValue();
pList.setCount(count);
criteria.setProjection(null);
// 查询集合
if(start >= 0 && limit > 0) {
criteria.setFirstResult(start);
criteria.setMaxResults(limit);
}
List<T> list = criteria.list();
pList.setList(list);
return pList;
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
@Transactional(readOnly = true)
public PageList findPageList(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
try {
PageList pList = new PageList();
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
// 查询总数
criteria.setProjection(Projections.rowCount());
Number result = (Number) criteria.uniqueResult();
int count = result.intValue();
pList.setCount(count);
criteria.setProjection(null);
// 查询集合
if(start >= 0 && limit > 0) {
criteria.setFirstResult(start);
criteria.setMaxResults(limit);
}
List<T> list = criteria.list();
pList.setList(list);
return pList;
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* Criteria查询
* @param clazz
* @param criterions
* @param orders
* @return
*/
@Transactional(readOnly = true)
public List<T> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders) {
try {
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
return criteria.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* Criteria查询
* @param clazz
* @param criterions
* @param orders
* @param limit
* @return
*/
@Transactional(readOnly = true)
public List<T> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final int start, final int limit) {
try {
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
if(start >= 0 && limit > 0) {
criteria.setFirstResult(start);
criteria.setMaxResults(limit);
}
return criteria.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* Criteria查询
* @param clazz
* @param criterions
* @param orders
* @return
*/
@Transactional(readOnly = true)
public List<?> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final Projection projection) {
try {
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
criteria.setProjection(projection);
return criteria.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
/**
* Criteria查询
* @param clazz
* @param criterions
* @param orders
* @param projection
* @param start
* @param limit
* @return
*/
@Transactional(readOnly = true)
public List<?> findByCriteria(final Class<T> clazz, final List<Criterion> criterions, final List<Order> orders, final Projection projection, final int start, final int limit) {
try {
Criteria criteria = getCurrentSession().createCriteria(clazz);
for (Criterion criterion : criterions) {
criteria.add(criterion);
}
if (orders != null && orders.size() > 0) {
for (Order order : orders) {
criteria.addOrder(order);
}
}
criteria.setProjection(projection);
if(start >= 0 && limit > 0) {
criteria.setFirstResult(start);
criteria.setMaxResults(limit);
}
return criteria.list();
} catch (Exception e) {
logger.error("查询出错", e);
}
return null;
}
@Transactional
public boolean doWork(final String sql, final List<Object[]> params) {
boolean flag = false;
try {
getCurrentSession().doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
BatchSQLUtil sqlUtil = new BatchSQLUtil(connection, sql);
for (Object[] param : params) {
sqlUtil.addCount(param);
}
sqlUtil.commit();
}
});
flag = true;
} catch (Exception e) {
logger.error("doWork出错", e);
throw e;
}
return flag;
}
}
@@ -0,0 +1,56 @@
package javautils.jdbc.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class BatchSQLUtil {
public static Logger logger = LoggerFactory.getLogger(BatchSQLUtil.class);
private Connection conn;
private PreparedStatement ps;
public BatchSQLUtil(Connection conn, String sql) {
try {
this.conn = conn;
this.conn.setAutoCommit(false);
ps = this.conn.prepareStatement(sql);
} catch (Exception e) {
logger.error("BatchSQLUtil异常", e);
}
}
public void addCount(Object[] param) {
try {
for (int i = 0; i < param.length; i++) {
ps.setObject(i + 1, param[i]);
}
ps.addBatch();
} catch (SQLException e) {
logger.error("addCount异常", e);
}
}
public void commit() {
try {
ps.executeBatch();
conn.commit();
ps.clearBatch();
} catch (SQLException e) {
logger.error("commit异常", e);
}
}
public void close() {
try {
ps.close();
conn.close();
} catch (SQLException e) {
logger.error("close异常", e);
}
}
}
@@ -0,0 +1,81 @@
package javautils.jdbc.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class SQLUtil {
public static final Logger logger = LoggerFactory.getLogger(SQLUtil.class);
// ------------------------------- 增删改通用 -------------------------------//
public boolean aduSql(Connection conn, String sql) {
boolean flag = false;
try {
if (conn != null) {
PreparedStatement ps = conn.prepareStatement(sql);
ps.executeUpdate();
ps.close();
flag = true;
}
} catch (Exception e) {
logger.error("aduSql异常", e);
flag = false;
}
return flag;
}
public static boolean aduSql(Connection conn, String sql, Object[] params) {
boolean flag = false;
try {
if (conn != null) {
PreparedStatement ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
}
ps.executeUpdate();
flag = true;
ps.close();
}
} catch (Exception e) {
logger.error("aduSql异常", e);
flag = false;
}
return flag;
}
public static List<Object[]> exList(Connection conn, String sql, Object params[]) {
ArrayList<Object[]> list = new ArrayList<Object[]>();
try {
if (conn != null) {
PreparedStatement ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
}
ResultSet rs = ps.executeQuery();
while (rs.next()) {
int columns = rs.getMetaData().getColumnCount();
Object[] objArr = new Object[columns];
for (int i = 0; i < columns; i++) {
objArr[i] = rs.getObject(i + 1);
}
list.add(objArr);
}
rs.close();
ps.close();
}
} catch (Exception e) {
logger.error("exList异常", e);
}
return list;
}
}
@@ -0,0 +1,129 @@
package javautils.list;
import javautils.StringUtil;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class ListUtil {
/**
* 高性能删除全部
*/
public static HashSet<String> transToHashSet(String[] strs){
if (strs == null || strs.length <= 0) {
return new HashSet<>();
}
HashSet<String> results = new HashSet<>();
for (int i = 0; i < strs.length; i++) {
results.add(strs[i]);
}
return results;
}
/**
* 高性能删除全部
*/
public static LinkedList removeAll(LinkedList src, LinkedList list){
if (src == null || src.isEmpty() || list == null || list.isEmpty()) {
return src;
}
HashSet oth = new HashSet(list);
return removeAll(src, oth);
}
/**
* 高性能删除全部
*/
public static LinkedList removeAll(LinkedList src, HashSet oth){
if (src == null || src.isEmpty() || oth == null || oth.isEmpty()) {
return src;
}
Iterator iter = src.iterator();//采用Iterator迭代器进行数据的操作
while(iter.hasNext()){
if(oth.contains(iter.next())){
iter.remove();
}
}
return src;
}
/**
* 高性能取交集
*/
public static LinkedList<String> retainAll(LinkedList<String> list1, LinkedList<String> list2){
if (list1 == null || list1.isEmpty()) {
return new LinkedList();
}
if (list2 == null || list2.isEmpty()) {
return new LinkedList();
}
HashSet<String> retain = new HashSet<>();
Iterator<String> iter1 = list1.iterator();//采用Iterator迭代器进行数据的操作
Iterator<String> iter2 = list2.iterator();//采用Iterator迭代器进行数据的操作
HashSet<String> oth1 = new HashSet(list1);
HashSet<String> oth2 = new HashSet(list2);
// list1在list2中有的
while (iter1.hasNext()) {
String val = iter1.next();
if (oth2.contains(val)) {
retain.add(val);
}
}
// list2在list1中有的
while (iter2.hasNext()) {
String val = iter2.next();
if (oth1.contains(val)) {
retain.add(val);
}
}
return new LinkedList(retain);
}
/**
* Object数组转int数组
* @param o
* @return
*/
public static int[] transObjectToInt(Object[] o) {
int[] t = new int[o.length];
for (int i = 0; i < o.length; i++) {
if(o[i] instanceof Integer) {
t[i] = (Integer)o[i];
}
if(o[i] instanceof String) {
String s = (String)o[i];
if(StringUtil.isIntegerString(s)) {
t[i] = Integer.parseInt(s);
}
}
}
return t;
}
/**
* 集合转成String
* @param list
* @return
*/
public static String transListToString(List<?> list) {
StringBuffer sb = new StringBuffer();
for (Object obj : list) {
sb.append(String.valueOf(obj) + ", ");
}
if(list.size() > 0) {
return sb.substring(0, sb.length() - 2);
}
return sb.toString();
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,42 @@
package javautils.map;
import java.util.*;
/**
* Created by Nick on 2017/3/6.
*/
public class MapUtil {
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueAsc(Map<K, V> map) {
List<Map.Entry<K, V>> list =
new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K,V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o1.getValue()).compareTo(o2.getValue());
}
});
Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValueDesc(Map<K, V> map) {
List<Map.Entry<K, V>> list =
new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K,V>>() {
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
return (o2.getValue()).compareTo(o1.getValue());
}
});
Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
public static void main(String[] args) {
}
}
@@ -0,0 +1,142 @@
package javautils.math;
import javautils.StringUtil;
import java.util.Arrays;
/**
* @Description:组合算法 从M个数中取出N个数,无顺序
* 二维Object数组
* @author :royoan
* @since :2014-6-12 下午10:22:22
* @version :0.0.1
*/
public class CombinationAlgorithm {
/* 原M个数据数组 */
private Object[] src;
/* src数组的长度 */
private int m;
/* 需要获取N个数 */
private int n;
//临时变量,obj的行数
private int objLineIndex;
/* 存放结果的二维数组 */
public Object[][] obj;
public CombinationAlgorithm(Object[] src, int getNum) {
this.src = src;
m = src.length;
n = getNum;
/* 初始化 */
objLineIndex = 0;
obj = new Object[combination(m,n)][n];
Object[] tmp = new Object[n];
combine(src, 0, 0, n, tmp);
}
/**
* <p>
* 计算 C(m,n)个数 = (m!)/(n!*(m-n)!)
* </p>
* 从M个数中选N个数,函数返回有多少种选法 参数 m 必须大于等于 n m = 0; n = 0; retuan 1;
*
* @param m
* @param n
* @return
* @since royoan 2014-6-13 下午8:25:33
*/
public int combination(int m, int n) {
if (m < n)
return 0; // 如果总数小于取出的数,直接返回0
int k = 1;
int j = 1;
// 该种算法约掉了分母的(m-n)!,这样分子相乘的个数就是有n个了
for (int i = n; i >= 1; i--) {
k = k * m;
j = j * n;
m--;
n--;
}
return k / j;
}
/**
* <p> 递归算法,把结果写到obj二维数组对象 </p>
* @param src
* @param srcIndex
* @param i
* @param n
* @param tmp
* @since royoan 2014-6-15 上午11:22:24
*/
private void combine(Object src[], int srcIndex, int i, int n, Object[] tmp) {
int j;
for (j = srcIndex; j < src.length - (n - 1); j++ ) {
tmp[i] = src[j];
if (n == 1) {
//System.out.println(Arrays.toString(tmp));
System.arraycopy(tmp, 0, obj[objLineIndex], 0, tmp.length);
//obj[objLineIndex] = tmp;
objLineIndex ++;
} else {
n--;
i++;
combine(src, j+1, i, n, tmp);
n++;
i--;
}
}
}
public Object[][] getResutl() {
return obj;
}
/**
* 用法实例
* @param args
* @throws Exception
* @since royoan 2014-6-15 下午8:21:05
*/
public static void main(String[] args) throws Exception {
// Integer[] a = new Integer[]{1,2,3,4,5,6};
// CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
//
// Object[][] c = ca.getResutl();
// for (int i = 0; i < c.length; i++) {
// System.out.println(Arrays.toString(c[i]));
// }
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
String[] a = new String[]{"1", "2", "3", "4", "5"};
CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
Object[][] c = ca.getResutl();
}
long spent = System.currentTimeMillis() - start;
System.out.println("10万次耗时:" + spent);
// for (int i = 0; i < c.length; i++) {
// System.out.println(Arrays.toString(c[i]));
// }
String[] a = new String[]{"1", "2", "3", "4", "5"};
CombinationAlgorithm ca = new CombinationAlgorithm(a, 3);
Object[][] c = ca.getResutl();
for (int i = 0; i < c.length; i++) {
System.out.println(StringUtil.transArrayToString(c[i]));
}
}
}
@@ -0,0 +1,104 @@
package javautils.math;
import java.math.BigDecimal;
import java.text.DecimalFormat;
public class MathUtil {
public static boolean inRound(double value, double min, double max) {
return value >= min && value <= max;
}
/**
* double 相加 +
* @param a
* @param b
* @return
*/
public static double add(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.add(b2).doubleValue();
}
/**
* double 相减 -
* @param a
* @param b
* @return
*/
public static double subtract(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.subtract(b2).doubleValue();
}
/**
* double 相乘 *
* @param a
* @param b
* @return
*/
public static double multiply(double a, double b) {
BigDecimal b1 = new BigDecimal(Double.toString(a));
BigDecimal b2 = new BigDecimal(Double.toString(b));
return b1.multiply(b2).doubleValue();
}
/**
* double 相除 /
* @param v1
* @param v2
* @param scale
* @return
*/
public static double divide(double v1, double v2, int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
}
public static void main(String[] args) {
System.out.println(divide(1.2134,2312.23456,6));
System.out.println(add(12.9, 0.101));
Double d = new Double(8.747470732E7);
DecimalFormat format = new DecimalFormat("##.0000");
System.out.println(format.format(d));
}
public static double decimalFormat(BigDecimal bd, int point) {
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
}
public static double doubleFormat(double d, int point) {
try {
BigDecimal bd = new BigDecimal(d);
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
} catch (Exception e) {
e.printStackTrace();
}
return d;
}
public static double StringFormat(String d, int point) {
try {
BigDecimal bd = new BigDecimal(d);
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).doubleValue();
} catch (Exception e) {
e.printStackTrace();
}
return 0.00;
}
public static float floatFormat(float f, int point) {
try {
BigDecimal bd = new BigDecimal(f);
return bd.setScale(point, BigDecimal.ROUND_HALF_DOWN).floatValue();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
@@ -0,0 +1,64 @@
package javautils.math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 排列算法
* Created by Nick on 2016/11/27.
*/
public class PermutationUtil {
public static void main(String args[]) throws Exception {
// String[] str = {"-", "-", "1","2","3"};
// List<Object[]> objects = permutation("799".split(""));
// for (Object[] object : objects) {
// System.out.println(Arrays.toString(object));
// }
// System.out.println(objects.size());
}
/**
* 求某一组元素的排列列表,如123,可以排成123 132 213 231 321 312,元素一般5个以内就好,不然有性能瓶颈
*/
public static List<Object[]> permutation(Object[] objs) {
if (objs.length > 5) {
System.out.println("PermutationUtil.permutation排列元素不要超过5个,会有性能瓶颈");
}
return doPermutation(objs, 0, objs.length - 1);
}
private static List<Object[]> doPermutation(Object[] objs , int first,int end) {
if (objs == null || objs.length <= 0) {
return new ArrayList<>();
}
List<Object[]> result = new ArrayList<>();
//输出str[first..end]的所有排列方式
if(first == end) { //输出一个排列方式
Object[] permuration = new Object[objs.length];
int count = 0;
for(int j=0; j<= end ;j++) {
permuration[count++] =objs[j];
}
result.add(permuration);
}
for(int i = first; i <= end ; i++) {
swap(objs, i, first);
List<Object[]> subResult = doPermutation(objs, first + 1, end);//固定好当前一位,继续排列后面的
result.addAll(subResult);
swap(objs, i, first);
}
return result;
}
private static void swap(Object[] objs, int i, int first) {
Object tmp;
tmp = objs[first];
objs[first] = objs[i];
objs[i] = tmp;
}
}
@@ -0,0 +1,45 @@
package javautils.random;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/**
* Created by Nick on 2017/3/11.
*/
public final class RandomUtil {
private RandomUtil(){}
/**
* 从min - max 里随机出n个不重复的数字
* @param min 最小数值
* @param max 最大数值
* @param n 生成多少个
*/
public static List<Integer> randomUniqueNumbers(int min, int max, int n) {
List<Integer> list = new ArrayList<>();
for (int i=min; i<=max; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
List<Integer> result = new ArrayList<>();
for (int i=0; i<n; i++) {
Integer value = list.get(i);
result.add(value);
}
return result;
}
public static void main(String[] args) {
int count = 10000;
List<Integer> result = randomUniqueNumbers(0, 99999, count);
HashSet<Integer> resultChecker = new HashSet<>(result);
System.out.println("是否是正确的结果"+ (resultChecker.size() == count));
}
}
@@ -0,0 +1,106 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis;
import javautils.redis.pool.JedisPool;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisDataException;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* 装载并执行Lua Script,
*
* 如果服务器上因为集群多台服务器或重启等原因没有装载script,会自动重新装载后重试。
*
* 因为涉及到的key未知,暂时不支持Sharding。
*/
public class JedisScriptExecutor {
private static Logger logger = LoggerFactory.getLogger(JedisScriptExecutor.class);
private JedisTemplate jedisTemplate;
private String script;
private String sha1;
public JedisScriptExecutor(JedisPool jedisPool) {
this.jedisTemplate = new JedisTemplate(jedisPool);
}
public JedisScriptExecutor(JedisTemplate jedisTemplate) {
this.jedisTemplate = jedisTemplate;
}
/**
* 装载Lua Script。
* 如果Script出错,抛出JedisDataException。
*/
public void load(final String scriptContent) throws JedisDataException {
sha1 = jedisTemplate.execute(new JedisTemplate.JedisAction<String>() {
public String action(Jedis jedis) {
return jedis.scriptLoad(scriptContent);
}
});
script = scriptContent;
logger.debug("Script \"{}\" had been loaded as {}", scriptContent, sha1);
}
/**
* 从文件加载Lua Script, 文件路径格式为Spring Resource的格式.
*/
public void loadFromFile(final String scriptPath) throws JedisDataException {
String scriptContent;
try {
Resource resource = new DefaultResourceLoader().getResource(scriptPath);
scriptContent = FileUtils.readFileToString(resource.getFile(), "UTF-8");
} catch (IOException e) {
throw new IllegalArgumentException(scriptPath + " is not exist.", e);
}
load(scriptContent);
}
/**
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
* keys与args不允许为null.
*/
public Object execute(final String[] keys, final String[] args) throws IllegalArgumentException {
Assert.notNull(keys, "keys can't be null.");
Assert.notNull(args, "args can't be null.");
return execute(Arrays.asList(keys), Arrays.asList(args));
}
/**
* 执行Lua Script, 如果Redis服务器上还没装载Script则自动装载并重试。
* keys与args不允许为null.
*/
public Object execute(final List<String> keys, final List<String> args) throws IllegalArgumentException {
Assert.notNull(keys, "keys can't be null.");
Assert.notNull(args, "args can't be null.");
return jedisTemplate.execute(new JedisTemplate.JedisAction<Object>() {
public Object action(Jedis jedis) {
try {
return jedis.evalsha(sha1, keys, args);
} catch (JedisDataException e) {
logger.warn(
"Script {} is not loaded in server yet or the script is wrong, try to reload and run it again.",
script, e);
return jedis.eval(script, keys, args);
}
}
});
}
}
@@ -0,0 +1,714 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis;
import javautils.redis.pool.JedisPool;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisException;
import redis.clients.util.Hashing;
import java.util.*;
/**
* JedisShardTemplate is the JedisTemplate, which has key sharding feature.
*
* Pass more than one JedisPool to the it, it will calculate which jedisPool will handle the key. If
* only one jedisPool passed, it won't do the calculation, so please use JedisShardedTemplate by default.
*
* But it doesn't support multi-key actions by default, like:
* 1. Pipelined and Transaction process multi-keys
* 2. Methods in @redis.clients.jedis.MultiKeyCommands like mget, rpoplpush....
*
* To support them, please use a common sharding key relate to these keys when invoke the APIs.
*/
public class JedisShardedTemplate {
private final Hashing algo = Hashing.MURMUR_HASH;
private TreeMap<Long, JedisTemplate> nodes = new TreeMap<Long, JedisTemplate>();
private JedisTemplate singleTemplate = null;
public JedisShardedTemplate(JedisPool... jedisPools) {
if (jedisPools.length == 1) {
singleTemplate = new JedisTemplate(jedisPools[0]);
} else {
initNodes(jedisPools);
}
}
public JedisShardedTemplate(List<JedisPool> jedisPools) {
this(jedisPools.toArray(new JedisPool[jedisPools.size()]));
}
private void initNodes(JedisPool... jedisPools) {
for (int i = 0; i != jedisPools.length; i++) {
// more entry the make the hash ring be more balance
for (int n = 0; n < 128; n++) {
final JedisPool jedisPool = jedisPools[i];
nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), new JedisTemplate(jedisPool));
}
}
}
/**
* Hash the key and get the jedisTemplate from the hash ring. Get idea from Jedis's Sharded.java
*/
public JedisTemplate getShard(String key) {
if (singleTemplate != null) {
return singleTemplate;
}
SortedMap<Long, JedisTemplate> tail = nodes.tailMap(algo.hash(key));
if (tail.isEmpty()) {
// the last node, back to first.
return nodes.get(nodes.firstKey());
}
return tail.get(tail.firstKey());
}
/*
* Execute the action.
*
* @key the action must process only this key, or this key is a sharding key.
*/
public <T> T execute(String key, JedisTemplate.JedisAction<T> jedisAction) throws JedisException {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.execute(jedisAction);
}
/*
* Execute the action.
*
* @key the action must process only this key, or this key is a sharding key.
*/
public void execute(String key, JedisTemplate.JedisActionNoResult jedisAction) throws JedisException {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.execute(jedisAction);
}
/*
* Execute the pipeline.
*
* @key the action must process only this key, or this key is a sharding key.
*/
public List<Object> execute(String key, JedisTemplate.PipelineAction pipelineAction) throws JedisException {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.execute(pipelineAction);
}
/*
* Execute the pipeline.
*
* @key the action must process only this key, or this key is a sharding key.
*/
public void execute(String key, JedisTemplate.PipelineActionNoResult pipelineAction) throws JedisException {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.execute(pipelineAction);
}
// / Common Actions ///
public Boolean del(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.del(key);
}
public Boolean del(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.del(key);
}
// / String Actions ///
public String get(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.get(key);
}
public String get(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.get(key);
}
public Long getAsLong(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.getAsLong(key);
}
public Long getAsLong(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.getAsLong(key);
}
public Integer getAsInt(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.getAsInt(key);
}
public Integer getAsInt(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.getAsInt(key);
}
public void set(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.set(key, value);
}
public void set(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.set(key, value);
}
public void setex(final String key, final String value, final int seconds) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.setex(key, value, seconds);
}
public void setex(final String shardingKey, final String key, final String value, final int seconds) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.setex(key, value, seconds);
}
public Boolean setnx(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.setnx(key, value);
}
public Boolean setnx(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.setnx(key, value);
}
public Boolean setnxex(final String key, final String value, final int seconds) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.setnxex(key, value, seconds);
}
public Boolean setnxex(final String shardingKey, final String key, final String value, final int seconds) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.setnxex(key, value, seconds);
}
public String getSet(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.getSet(key, value);
}
public String getSet(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.getSet(key, value);
}
public Long incr(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.incr(key);
}
public Long incr(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.incr(key);
}
public Long incrBy(final String key, final Long increment) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.incrBy(key, increment);
}
public Long incrBy(final String shardingKey, final String key, final Long increment) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.incrBy(key, increment);
}
public Double incrByFloat(final String key, final double increment) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.incrByFloat(key, increment);
}
public Double incrByFloat(final String shardingKey, final String key, final double increment) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.incrByFloat(key, increment);
}
public Long decr(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.decr(key);
}
public Long decr(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.decr(key);
}
public Long decrBy(final String key, final Long decrement) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.decrBy(key, decrement);
}
public Long decrBy(final String shardingKey, final String key, final Long decrement) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.decrBy(key, decrement);
}
// / Hash Actions ///
public String hget(final String key, final String field) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hget(key, field);
}
public String hget(final String shardingKey, final String key, final String field) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hget(key, field);
}
public List<String> hmget(final String key, final String field) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hmget(key, field);
}
public List<String> hmget(final String key, final String[] fields) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hmget(key, fields);
}
public List<String> hmget(final String shardingKey, final String key, final String field) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hmget(key, field);
}
public List<String> hmget(final String shardingKey, final String key, final String[] fields) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hmget(key, fields);
}
public Map<String, String> hgetAll(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hgetAll(key);
}
public Map<String, String> hgetAll(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hgetAll(key);
}
public void hset(final String key, final String field, final String value) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.hset(key, field, value);
}
public void hset(final String shardingKey, final String key, final String field, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.hset(key, field, value);
}
public void hmset(final String key, final Map<String, String> map) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.hmset(key, map);
}
public void hmset(final String shardingKey, final String key, final Map<String, String> map) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.hmset(key, map);
}
public Boolean hsetnx(final String key, final String fieldName, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hsetnx(key, fieldName, value);
}
public Boolean hsetnx(final String shardingKey, final String key, final String fieldName, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hsetnx(key, fieldName, value);
}
public Long hincrBy(final String key, final String fieldName, final long increment) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hincrBy(key, fieldName, increment);
}
public Long hincrBy(final String shardingKey, final String key, final String fieldName, final long increment) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hincrBy(key, fieldName, increment);
}
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hincrByFloat(key, fieldName, increment);
}
public Double hincrByFloat(final String shardingKey, final String key, final String fieldName,
final double increment) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hincrByFloat(key, fieldName, increment);
}
public Long hdel(final String key, final String fieldsName) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hdel(key, fieldsName);
}
public Long hdel(final String key, final String[] fieldsNames) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hdel(key, fieldsNames);
}
public Long hdel(final String shardingKey, final String key, final String fieldsName) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hdel(key, fieldsName);
}
public Long hdel(final String shardingKey, final String key, final String[] fieldsNames) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hdel(key, fieldsNames);
}
public Boolean hexists(final String key, final String fieldName) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hexists(key, fieldName);
}
public Boolean hexists(final String shardingKey, final String key, final String fieldName) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hexists(key, fieldName);
}
public Set<String> hkeys(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hkeys(key);
}
public Set<String> hkeys(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hkeys(key);
}
public Long hlen(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.hlen(key);
}
public Long hlen(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.hlen(key);
}
// / List Actions ///
public Long lpush(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lpush(key, value);
}
public Long lpush(final String key, final String[] values) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lpush(key, values);
}
public Long lpush(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lpush(key, value);
}
public Long lpush(final String shardingKey, final String key, final String[] values) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lpush(key, values);
}
public String rpop(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.rpop(key);
}
public String rpop(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.rpop(key);
}
public String brpop(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.brpop(key);
}
public String brpop(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.brpop(key);
}
public String brpop(final int timeout, final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.brpop(timeout, key);
}
public String brpop(final String shardingKey, final int timeout, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.brpop(timeout, key);
}
public Long llen(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.llen(key);
}
public Long llen(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.llen(key);
}
public String lindex(final String key, final long index) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lindex(key, index);
}
public String lindex(final String shardingKey, final String key, final long index) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lindex(key, index);
}
public List<String> lrange(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lrange(key, start, end);
}
public List<String> lrange(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lrange(key, start, end);
}
public void ltrim(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.ltrim(key, start, end);
}
public void ltrim(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.ltrim(key, start, end);
}
public void ltrimFromLeft(final String key, final int size) {
JedisTemplate jedisTemplate = getShard(key);
jedisTemplate.ltrimFromLeft(key, size);
}
public void ltrimFromLeft(final String shardingKey, final String key, final int size) {
JedisTemplate jedisTemplate = getShard(shardingKey);
jedisTemplate.ltrimFromLeft(key, size);
}
public Boolean lremFirst(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lremFirst(key, value);
}
public Boolean lremFirst(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lremFirst(key, value);
}
public Boolean lremAll(final String key, final String value) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.lremAll(key, value);
}
public Boolean lremAll(final String shardingKey, final String key, final String value) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.lremAll(key, value);
}
// / Set Actions ///
public Boolean sadd(final String key, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.sadd(key, member);
}
public Boolean sadd(final String shardingKey, final String key, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.sadd(key, member);
}
public Set<String> smembers(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.smembers(key);
}
public Set<String> smembers(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.smembers(key);
}
// / Sorted Set Actions ///
public Boolean zadd(final String key, final double score, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zadd(key, score, member);
}
public Boolean zadd(final String shardingKey, final String key, final double score, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zadd(key, score, member);
}
public Double zscore(final String key, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zscore(key, member);
}
public Double zscore(final String shardingKey, final String key, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zscore(key, member);
}
public Long zrank(final String key, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrank(key, member);
}
public Long zrank(final String shardingKey, final String key, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrank(key, member);
}
public Long zrevrank(final String key, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrevrank(key, member);
}
public Long zrevrank(final String shardingKey, final String key, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrevrank(key, member);
}
public Long zcount(final String key, final double start, final double end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zcount(key, start, end);
}
public Long zcount(final String shardingKey, final String key, final double start, final double end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zcount(key, start, end);
}
public Set<String> zrange(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrange(key, start, end);
}
public Set<String> zrange(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrange(key, start, end);
}
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrangeWithScores(key, start, end);
}
public Set<Tuple> zrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrangeWithScores(key, start, end);
}
public Set<String> zrevrange(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrevrange(key, start, end);
}
public Set<String> zrevrange(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrevrange(key, start, end);
}
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrevrangeWithScores(key, start, end);
}
public Set<Tuple> zrevrangeWithScores(final String shardingKey, final String key, final int start, final int end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrevrangeWithScores(key, start, end);
}
public Set<String> zrangeByScore(final String key, final double min, final double max) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrangeByScore(key, min, max);
}
public Set<String> zrangeByScore(final String shardingKey, final String key, final double min, final double max) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrangeByScore(key, min, max);
}
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
}
public Set<Tuple> zrangeByScoreWithScores(final String shardingKey, final String key, final double min,
final double max) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrangeByScoreWithScores(key, min, max);
}
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrevrangeByScore(key, max, min);
}
public Set<String> zrevrangeByScore(final String shardingKey, final String key, final double max, final double min) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrevrangeByScore(key, max, min);
}
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
}
public Set<Tuple> zrevrangeByScoreWithScores(final String shardingKey, final String key, final double max,
final double min) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrevrangeByScoreWithScores(key, max, min);
}
public Boolean zrem(final String key, final String member) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zrem(key, member);
}
public Boolean zrem(final String shardingKey, final String key, final String member) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zrem(key, member);
}
public Long zremByScore(final String key, final double min, final double max) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zremByScore(key, min, max);
}
public Long zremByScore(final String shardingKey, final String key, final double min, final double max) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zremByScore(key, min, max);
}
public Long zremByRank(final String key, final long start, final long end) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zremByRank(key, start, end);
}
public Long zremByRank(final String shardingKey, final String key, final long start, final long end) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zremByRank(key, start, end);
}
public Long zcard(final String key) {
JedisTemplate jedisTemplate = getShard(key);
return jedisTemplate.zcard(key);
}
public Long zcard(final String shardingKey, final String key) {
JedisTemplate jedisTemplate = getShard(shardingKey);
return jedisTemplate.zcard(key);
}
}
@@ -0,0 +1,893 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis;
import javautils.redis.pool.JedisPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* JedisTemplate 提供了一个template方法,负责对Jedis连接的获取与归还。
* JedisAction<T> 和 JedisActionNoResult两种回调接口,适用于有无返回值两种情况。
* PipelineAction 与 PipelineActionResult两种接口,适合于pipeline中批量传输命令的情况。
*
* 同时提供一些JedisOperation中定义的 最常用函数的封装, 如get/set/zadd等。
*/
public class JedisTemplate {
private static Logger logger = LoggerFactory.getLogger(JedisTemplate.class);
private JedisPool jedisPool;
public JedisTemplate(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
/**
* Callback interface for template.
*/
public interface JedisAction<T> {
T action(Jedis jedis);
}
/**
* Callback interface for template without result.
*/
public interface JedisActionNoResult {
void action(Jedis jedis);
}
/**
* Callback interface for template.
*/
public interface PipelineAction {
List<Object> action(Pipeline Pipeline);
}
/**
* Callback interface for template without result.
*/
public interface PipelineActionNoResult {
void action(Pipeline Pipeline);
}
/**
* Execute with a call back action with result.
*/
public <T> T execute(JedisAction<T> jedisAction) throws JedisException {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
return jedisAction.action(jedis);
} catch (JedisException e) {
broken = handleJedisException(e);
throw e;
} finally {
closeResource(jedis, broken);
}
}
/**
* Execute with a call back action without result.
*/
public void execute(JedisActionNoResult jedisAction) throws JedisException {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
jedisAction.action(jedis);
} catch (JedisException e) {
broken = handleJedisException(e);
throw e;
} finally {
closeResource(jedis, broken);
}
}
/**
* Execute with a call back action with result in pipeline.
*/
public List<Object> execute(PipelineAction pipelineAction) throws JedisException {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
Pipeline pipeline = jedis.pipelined();
pipelineAction.action(pipeline);
return pipeline.syncAndReturnAll();
} catch (JedisException e) {
broken = handleJedisException(e);
throw e;
} finally {
closeResource(jedis, broken);
}
}
/**
* Execute with a call back action without result in pipeline.
*/
public void execute(PipelineActionNoResult pipelineAction) throws JedisException {
Jedis jedis = null;
boolean broken = false;
try {
jedis = jedisPool.getResource();
Pipeline pipeline = jedis.pipelined();
pipelineAction.action(pipeline);
pipeline.sync();
} catch (JedisException e) {
broken = handleJedisException(e);
throw e;
} finally {
closeResource(jedis, broken);
}
}
/**
* Return the internal JedisPool.
*/
public JedisPool getJedisPool() {
return jedisPool;
}
/**
* Handle jedisException, write log and return whether the connection is broken.
*/
protected boolean handleJedisException(JedisException jedisException) {
if (jedisException instanceof JedisConnectionException) {
logger.error("Redis connection " + jedisPool.getAddress() + " lost.", jedisException);
} else if (jedisException instanceof JedisDataException) {
if ((jedisException.getMessage() != null) && (jedisException.getMessage().indexOf("READONLY") != -1)) {
logger.error("Redis connection " + jedisPool.getAddress() + " are read-only slave.", jedisException);
} else {
// dataException, isBroken=false
return false;
}
} else {
logger.error("Jedis exception happen.", jedisException);
}
return true;
}
/**
* Return jedis connection to the pool, call different return methods depends on the conectionBroken status.
*/
protected void closeResource(Jedis jedis, boolean conectionBroken) {
try {
if (conectionBroken) {
jedisPool.returnBrokenResource(jedis);
} else {
jedisPool.returnResource(jedis);
}
} catch (Exception e) {
logger.error("return back jedis failed, will fore close the jedis.", e);
JedisUtils.destroyJedis(jedis);
}
}
// / Common Actions ///
/**
* Remove the specified keys. If a given key does not exist no operation is
* performed for this key.
*
* return false if one of the key is not exist.
*/
public Boolean del(final String... keys) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.del(keys) == keys.length ? true : false;
}
});
}
public void flushDB() {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.flushDB();
}
});
}
// / String Actions ///
/**
* Get the value of the specified key. If the key does not exist null is
* returned. If the value stored at key is not a string an error is returned
* because GET can only handle string values.
*/
public String get(final String key) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.get(key);
}
});
}
public Set<String> keys(final String key) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.keys(key);
}
});
}
/**
* Get the value of the specified key as Long.If the key does not exist null is returned.
*/
public Long getAsLong(final String key) {
String result = get(key);
return result != null ? Long.valueOf(result) : null;
}
/**
* Get the value of the specified key as Integer.If the key does not exist null is returned.
*/
public Integer getAsInt(final String key) {
String result = get(key);
return result != null ? Integer.valueOf(result) : null;
}
/**
* Get the value of the specified key as Double.If the key does not exist null is returned.
*/
public Double getAsDouble(final String key) {
String result = get(key);
return result != null ? Double.valueOf(result) : null;
}
/**
* Get the values of all the specified keys. If one or more keys dont exist
* or is not of type String, a 'nil' value is returned instead of the value
* of the specified key, but the operation never fails.
*/
public List<String> mget(final String... keys) {
return execute(new JedisAction<List<String>>() {
@Override
public List<String> action(Jedis jedis) {
return jedis.mget(keys);
}
});
}
/**
* Set the string value as value of the key.
* The string can't be longer than 1073741824 bytes (1 GB).
*/
public void set(final String key, final String value) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.set(key, value);
}
});
}
public void expire(final String key, final int seconds) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.expire(key, seconds);
}
});
}
/**
* The command is exactly equivalent to the following group of commands: {@link #set(String, String) SET} +
* {@link #expire(String, int) EXPIRE}.
* The operation is atomic.
*/
public void setex(final String key, final String value, final int seconds) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.setex(key, seconds, value);
}
});
}
/**
* SETNX works exactly like {@link #setNX(String, String) SET} with the only
* difference that if the key already exists no operation is performed.
* SETNX actually means "SET if Not eXists".
*
* return true if the key was set.
*/
public Boolean setnx(final String key, final String value) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.setnx(key, value) == 1 ? true : false;
}
});
}
/**
* The command is exactly equivalent to the following group of commands: {@link #setex(String, String, int) SETEX} +
* {@link #sexnx(String, String) SETNX}.
* The operation is atomic.
*/
public Boolean setnxex(final String key, final String value, final int seconds) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
String result = jedis.set(key, value, "NX", "EX", seconds);
return JedisUtils.isStatusOk(result);
}
});
}
/**
* GETSET is an atomic set this value and return the old value command. Set
* key to the string value and return the old value stored at key. The
* string can't be longer than 1073741824 bytes (1 GB).
*/
public String getSet(final String key, final String value) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.getSet(key, value);
}
});
}
/**
* Increment the number stored at key by one. If the key does not exist or
* contains a value of a wrong type, set the key to the value of "0" before
* to perform the increment operation.
* <p>
* INCR commands are limited to 64 bit signed integers.
* <p>
* Note: this is actually a string operation, that is, in Redis there are not "integer" types. Simply the string
* stored at the key is parsed as a base 10 64 bit signed integer, incremented, and then converted back as a string.
*
* @return Integer reply, this commands will reply with the new value of key
* after the increment.
*/
public Long incr(final String key) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.incr(key);
}
});
}
public Long incrBy(final String key, final long increment) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.incrBy(key, increment);
}
});
}
public Double incrByFloat(final String key, final double increment) {
return execute(new JedisAction<Double>() {
@Override
public Double action(Jedis jedis) {
return jedis.incrByFloat(key, increment);
}
});
}
/**
* Decrement the number stored at key by one. If the key does not exist or
* contains a value of a wrong type, set the key to the value of "0" before
* to perform the decrement operation.
*/
public Long decr(final String key) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.decr(key);
}
});
}
public Long decrBy(final String key, final long decrement) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.decrBy(key, decrement);
}
});
}
// / Hash Actions ///
/**
* If key holds a hash, retrieve the value associated to the specified
* field.
* <p>
* If the field is not found or the key does not exist, a special 'nil' value is returned.
*/
public String hget(final String key, final String fieldName) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.hget(key, fieldName);
}
});
}
public List<String> hmget(final String key, final String... fieldsNames) {
return execute(new JedisAction<List<String>>() {
@Override
public List<String> action(Jedis jedis) {
return jedis.hmget(key, fieldsNames);
}
});
}
public Map<String, String> hgetAll(final String key) {
return execute(new JedisAction<Map<String, String>>() {
@Override
public Map<String, String> action(Jedis jedis) {
return jedis.hgetAll(key);
}
});
}
public void hset(final String key, final String fieldName, final String value) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.hset(key, fieldName, value);
}
});
}
public void hmset(final String key, final Map<String, String> map) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.hmset(key, map);
}
});
}
public Boolean hsetnx(final String key, final String fieldName, final String value) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.hsetnx(key, fieldName, value) == 1 ? true : false;
}
});
}
public Long hincrBy(final String key, final String fieldName, final long increment) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.hincrBy(key, fieldName, increment);
}
});
}
public Double hincrByFloat(final String key, final String fieldName, final double increment) {
return execute(new JedisAction<Double>() {
@Override
public Double action(Jedis jedis) {
return jedis.hincrByFloat(key, fieldName, increment);
}
});
}
public Long hdel(final String key, final String... fieldsNames) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.hdel(key, fieldsNames);
}
});
}
public Boolean hexists(final String key, final String fieldName) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.hexists(key, fieldName);
}
});
}
public Set<String> hkeys(final String key) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.hkeys(key);
}
});
}
public Long hlen(final String key) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.hlen(key);
}
});
}
// / List Actions ///
public Long lpush(final String key, final String... values) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.lpush(key, values);
}
});
}
public Long rpush(final String key, final String... values) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.rpush(key, values);
}
});
}
public String rpop(final String key) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.rpop(key);
}
});
}
public String brpop(final String key) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
List<String> nameValuePair = jedis.brpop(key);
if (nameValuePair != null) {
return nameValuePair.get(1);
} else {
return null;
}
}
});
}
public String brpop(final int timeout, final String key) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
List<String> nameValuePair = jedis.brpop(timeout, key);
if (nameValuePair != null) {
return nameValuePair.get(1);
} else {
return null;
}
}
});
}
/**
* Not support for sharding.
*/
public String rpoplpush(final String sourceKey, final String destinationKey) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.rpoplpush(sourceKey, destinationKey);
}
});
}
/**
* Not support for sharding.
*/
public String brpoplpush(final String source, final String destination, final int timeout) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.brpoplpush(source, destination, timeout);
}
});
}
public Long llen(final String key) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.llen(key);
}
});
}
public String lindex(final String key, final long index) {
return execute(new JedisAction<String>() {
@Override
public String action(Jedis jedis) {
return jedis.lindex(key, index);
}
});
}
public List<String> lrange(final String key, final int start, final int end) {
return execute(new JedisAction<List<String>>() {
@Override
public List<String> action(Jedis jedis) {
return jedis.lrange(key, start, end);
}
});
}
public void ltrim(final String key, final int start, final int end) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.ltrim(key, start, end);
}
});
}
public void ltrimFromLeft(final String key, final int size) {
execute(new JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
jedis.ltrim(key, 0, size - 1);
}
});
}
public Boolean lremFirst(final String key, final String value) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
Long count = jedis.lrem(key, 1, value);
return (count == 1);
}
});
}
public Boolean lremAll(final String key, final String value) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
Long count = jedis.lrem(key, 0, value);
return (count > 0);
}
});
}
// / Set Actions ///
public Boolean sadd(final String key, final String member) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.sadd(key, member) == 1 ? true : false;
}
});
}
public Set<String> smembers(final String key) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.smembers(key);
}
});
}
// / Ordered Set Actions ///
/**
* return true for add new element, false for only update the score.
*/
public Boolean zadd(final String key, final double score, final String member) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.zadd(key, score, member) == 1 ? true : false;
}
});
}
public Double zscore(final String key, final String member) {
return execute(new JedisAction<Double>() {
@Override
public Double action(Jedis jedis) {
return jedis.zscore(key, member);
}
});
}
public Long zrank(final String key, final String member) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zrank(key, member);
}
});
}
public Long zrevrank(final String key, final String member) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zrevrank(key, member);
}
});
}
public Long zcount(final String key, final double min, final double max) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zcount(key, min, max);
}
});
}
public Set<String> zrange(final String key, final int start, final int end) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.zrange(key, start, end);
}
});
}
public Set<Tuple> zrangeWithScores(final String key, final int start, final int end) {
return execute(new JedisAction<Set<Tuple>>() {
@Override
public Set<Tuple> action(Jedis jedis) {
return jedis.zrangeWithScores(key, start, end);
}
});
}
public Set<String> zrevrange(final String key, final int start, final int end) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.zrevrange(key, start, end);
}
});
}
public Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end) {
return execute(new JedisAction<Set<Tuple>>() {
@Override
public Set<Tuple> action(Jedis jedis) {
return jedis.zrevrangeWithScores(key, start, end);
}
});
}
public Set<String> zrangeByScore(final String key, final double min, final double max) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.zrangeByScore(key, min, max);
}
});
}
public Set<Tuple> zrangeByScoreWithScores(final String key, final double min, final double max) {
return execute(new JedisAction<Set<Tuple>>() {
@Override
public Set<Tuple> action(Jedis jedis) {
return jedis.zrangeByScoreWithScores(key, min, max);
}
});
}
public Set<String> zrevrangeByScore(final String key, final double max, final double min) {
return execute(new JedisAction<Set<String>>() {
@Override
public Set<String> action(Jedis jedis) {
return jedis.zrevrangeByScore(key, max, min);
}
});
}
public Set<Tuple> zrevrangeByScoreWithScores(final String key, final double max, final double min) {
return execute(new JedisAction<Set<Tuple>>() {
@Override
public Set<Tuple> action(Jedis jedis) {
return jedis.zrevrangeByScoreWithScores(key, max, min);
}
});
}
public Boolean zrem(final String key, final String member) {
return execute(new JedisAction<Boolean>() {
@Override
public Boolean action(Jedis jedis) {
return jedis.zrem(key, member) == 1 ? true : false;
}
});
}
public Long zremByScore(final String key, final double start, final double end) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zremrangeByScore(key, start, end);
}
});
}
public Long zremByRank(final String key, final long start, final long end) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zremrangeByRank(key, start, end);
}
});
}
public Long zcard(final String key) {
return execute(new JedisAction<Long>() {
@Override
public Long action(Jedis jedis) {
return jedis.zcard(key);
}
});
}
}
@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis;
import javautils.redis.pool.JedisPool;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisException;
public class JedisUtils {
private static final String OK_CODE = "OK";
private static final String OK_MULTI_CODE = "+OK";
/**
* 判断 返回值是否ok.
*/
public static boolean isStatusOk(String status) {
return (status != null) && (OK_CODE.equals(status) || OK_MULTI_CODE.equals(status));
}
/**
* 在Pool以外强行销毁Jedis.
*/
public static void destroyJedis(Jedis jedis) {
if ((jedis != null) && jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
/**
* Ping the jedis instance, return true is the result is PONG.
*/
public static boolean ping(JedisPool pool) {
JedisTemplate template = new JedisTemplate(pool);
try {
String result = template.execute(new JedisTemplate.JedisAction<String>() {
public String action(Jedis jedis) {
return jedis.ping();
}
});
return (result != null) && result.equals("PONG");
} catch (JedisException e) {
return false;
}
}
}
@@ -0,0 +1,68 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import redis.clients.jedis.Protocol;
/**
* All information for redis connection.
*/
public class ConnectionInfo {
public static final String DEFAULT_PASSWORD = null;
private int database = Protocol.DEFAULT_DATABASE;
private String password = DEFAULT_PASSWORD;
private int timeout = Protocol.DEFAULT_TIMEOUT;
public ConnectionInfo() {
}
public ConnectionInfo(int database, String password, int timeout) {
this.timeout = timeout;
if (password != null && password.length() > 0) {
this.password = password;
}
else {
this.password = DEFAULT_PASSWORD;
}
this.database = database;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if (password != null && password.length() > 0) {
this.password = password;
}
else {
this.password = DEFAULT_PASSWORD;
}
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
@Override
public String toString() {
return "ConnectionInfo [database=" + database + ", password=" + password + ", timeout=" + timeout + "]";
}
}
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPoolConfig;
/**
* Pool which connect to redis instance directly.
*/
public class JedisDirectPool extends JedisPool {
public JedisDirectPool(HostAndPort address, JedisPoolConfig config) {
initInternalPool(address, new ConnectionInfo(), config);
}
public JedisDirectPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
initInternalPool(address, connectionInfo, config);
}
}
@@ -0,0 +1,98 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import redis.clients.jedis.BinaryJedis;
import redis.clients.jedis.Jedis;
/**
* Copy from redis.clients.jedis.JedisFactory, because it is not a public class.
*/
public class JedisFactory implements PooledObjectFactory<Jedis> {
private final String host;
private final int port;
private final int timeout;
private final String password;
private final int database;
private final String clientName;
public JedisFactory(final String host, final int port, final int timeout, final String password, final int database) {
this(host, port, timeout, password, database, null);
}
public JedisFactory(final String host, final int port, final int timeout, final String password,
final int database, final String clientName) {
super();
this.host = host;
this.port = port;
this.timeout = timeout;
this.password = password;
this.database = database;
this.clientName = clientName;
}
@Override
public void activateObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.getDB() != database) {
jedis.select(database);
}
}
@Override
public void destroyObject(PooledObject<Jedis> pooledJedis) throws Exception {
final BinaryJedis jedis = pooledJedis.getObject();
if (jedis.isConnected()) {
try {
try {
jedis.quit();
} catch (Exception e) {
}
jedis.disconnect();
} catch (Exception e) {
}
}
}
@Override
public PooledObject<Jedis> makeObject() throws Exception {
final Jedis jedis = new Jedis(this.host, this.port, this.timeout);
jedis.connect();
if (null != this.password) {
jedis.auth(this.password);
}
if (database != 0) {
jedis.select(database);
}
if (clientName != null) {
jedis.clientSetname(clientName);
}
return new DefaultPooledObject<Jedis>(jedis);
}
@Override
public void passivateObject(PooledObject<Jedis> pooledJedis) throws Exception {
// TODO maybe should select db 0? Not sure right now.
}
@Override
public boolean validateObject(PooledObject<Jedis> pooledJedis) {
final BinaryJedis jedis = pooledJedis.getObject();
try {
return jedis.isConnected() && jedis.ping().equals("PONG");
} catch (final Exception e) {
return false;
}
}
}
@@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.util.Pool;
/**
* Jedis Pool base class.
*/
public abstract class JedisPool extends Pool<Jedis> {
protected HostAndPort address;
protected ConnectionInfo connectionInfo;
/**
* Create a JedisPoolConfig with new maxPoolSize becasuse JedisPoolConfig's default maxPoolSize is only 8.
* Also reset the idle checking time to 10 minutes, the default value is half minute.
* Also rest the max idle to zero, the default value is 8 too.
* The default idle time is 60 seconds.
*/
public static JedisPoolConfig createPoolConfig(int maxPoolSize) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxPoolSize);
config.setMaxIdle(maxPoolSize);
config.setTimeBetweenEvictionRunsMillis(600 * 1000);
return config;
}
/**
* Initialize the internal pool with connection info and pool config.
*/
protected void initInternalPool(HostAndPort address, ConnectionInfo connectionInfo, JedisPoolConfig config) {
this.address = address;
this.connectionInfo = connectionInfo;
JedisFactory factory = new JedisFactory(address.getHost(), address.getPort(), connectionInfo.getTimeout(),
connectionInfo.getPassword(), connectionInfo.getDatabase());
internalPool = new GenericObjectPool(factory, config);
}
/**
* Return a broken jedis connection back to pool.
*/
@Override
public void returnBrokenResource(final Jedis resource) {
if (resource != null) {
returnBrokenResourceObject(resource);
}
}
/**
* Return a available jedis connection back to pool.
*/
@Override
public void returnResource(final Jedis resource) {
if (resource != null) {
resource.resetState();
returnResourceObject(resource);
}
}
public HostAndPort getAddress() {
return address;
}
public ConnectionInfo getConnectionInfo() {
return connectionInfo;
}
}
@@ -0,0 +1,179 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Build JedisPool smartly。
* Depends on masterName whether prefix with "direct:", it will build JedisSentinelPool or JedisDirectPool.
*/
public class JedisPoolBuilder {
public static final String DIRECT_POOL_PREFIX = "direct:";
private static Logger logger = LoggerFactory.getLogger(JedisPoolBuilder.class);
private String[] sentinelHosts;
private int sentinelPort = Protocol.DEFAULT_SENTINEL_PORT;
private String masterName;
private String[] shardedMasterNames;
private int poolSize = -1;
private int database = Protocol.DEFAULT_DATABASE;
private String password = ConnectionInfo.DEFAULT_PASSWORD;
private int timeout = Protocol.DEFAULT_TIMEOUT;
public JedisPoolBuilder setHosts(String[] hosts) {
this.sentinelHosts = hosts;
return this;
}
public JedisPoolBuilder setHosts(String hosts) {
if (hosts != null) {
this.sentinelHosts = hosts.split(",");
}
return this;
}
public JedisPoolBuilder setPort(int port) {
this.sentinelPort = port;
return this;
}
public JedisPoolBuilder setMasterName(String masterName) {
this.masterName = masterName;
return this;
}
public JedisPoolBuilder setShardedMasterNames(String[] shardedMasterNames) {
this.shardedMasterNames = shardedMasterNames;
return this;
}
public JedisPoolBuilder setShardedMasterNames(String shardedMasterNames) {
if (shardedMasterNames != null) {
this.shardedMasterNames = shardedMasterNames.split(",");
}
return this;
}
public JedisPoolBuilder setDirectHostAndPort(String host, String port) {
this.masterName = host + ":" + port;
return this;
}
public JedisPoolBuilder setPoolSize(int poolSize) {
this.poolSize = poolSize;
return this;
}
public JedisPoolBuilder setDatabase(int database) {
this.database = database;
return this;
}
public JedisPoolBuilder setPassword(String password) {
this.password = password;
return this;
}
public JedisPoolBuilder setTimeout(int timeout) {
this.timeout = timeout;
return this;
}
public JedisPool buildPool() {
if ((masterName == null) || "".equals(masterName)) {
throw new IllegalArgumentException("masterName is null or empty");
}
if (poolSize < 1) {
throw new IllegalArgumentException("poolSize is less then one");
}
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
if (isDirect(masterName)) {
return buildDirectPool(masterName, connectionInfo, config);
} else {
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
throw new IllegalArgumentException("sentinelHosts is null or empty");
}
return buildSentinelPool(masterName, connectionInfo, config);
}
}
public List<JedisPool> buildShardedPools() {
if ((shardedMasterNames == null) || (shardedMasterNames.length == 0) || "".equals(shardedMasterNames[0])) {
throw new IllegalArgumentException("shardedMasterNames is null or empty");
}
if (poolSize < 1) {
throw new IllegalArgumentException("poolSize is less then one");
}
JedisPoolConfig config = JedisPool.createPoolConfig(poolSize);
ConnectionInfo connectionInfo = new ConnectionInfo(database, password, timeout);
List<JedisPool> jedisPools = new ArrayList<JedisPool>();
if (isDirect(shardedMasterNames[0])) {
for (String theMasterName : shardedMasterNames) {
jedisPools.add(buildDirectPool(theMasterName, connectionInfo, config));
}
} else {
if ((sentinelHosts == null) || (sentinelHosts.length == 0)) {
throw new IllegalArgumentException("sentinelHosts is null or empty");
}
for (String theMasterName : shardedMasterNames) {
jedisPools.add(buildSentinelPool(theMasterName, connectionInfo, config));
}
}
return jedisPools;
}
private JedisPool buildDirectPool(String directMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
String hostPortStr = directMasterName.substring(directMasterName.indexOf(":") + 1, directMasterName.length());
String[] hostPort = hostPortStr.split(":");
logger.info("Building JedisDirectPool, on redis server " + hostPort[0] + " ,sentinelPort is " + hostPort[1]);
HostAndPort masterAddress = new HostAndPort(hostPort[0], Integer.parseInt(hostPort[1]));
return new JedisDirectPool(masterAddress, config);
}
private JedisPool buildSentinelPool(String sentinelMasterName, ConnectionInfo connectionInfo, JedisPoolConfig config) {
logger.info("Building JedisSentinelPool, on sentinel sentinelHosts:" + Arrays.toString(sentinelHosts)
+ " ,sentinelPort is " + sentinelPort + " ,masterName is " + sentinelMasterName);
HostAndPort[] sentinelAddress = new HostAndPort[sentinelHosts.length];
for (int i = 0; i < sentinelHosts.length; i++) {
sentinelAddress[i] = new HostAndPort(sentinelHosts[i], sentinelPort);
}
return new JedisSentinelPool(sentinelAddress, sentinelMasterName, connectionInfo, config);
}
private static boolean isDirect(String masterName) {
return masterName.startsWith(DIRECT_POOL_PREFIX);
}
}
@@ -0,0 +1,323 @@
/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package javautils.redis.pool;
import javautils.redis.JedisTemplate;
import javautils.redis.JedisUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.exceptions.JedisConnectionException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Pool which to get redis master address get from sentinel instances.
*/
/**
* Pool which to get redis master address get from sentinel instances.
*/
public final class JedisSentinelPool extends JedisPool {
private static final String NO_ADDRESS_YET = "I dont know because no sentinel up";
private static Logger logger = LoggerFactory.getLogger(JedisSentinelPool.class);
private List<JedisPool> sentinelPools = new ArrayList<JedisPool>();
private MasterSwitchListener masterSwitchListener;
private String masterName;
private JedisPoolConfig masterPoolConfig;
private ConnectionInfo masterConnectionInfo;
private CountDownLatch poolInit = new CountDownLatch(1);
/**
* Creates a new instance of <code>JedisSentinelPool</code>.
*
* All parameters can be null or empty.
*
* @param sentinelAddresses Array of HostAndPort to sentinel instances.
* @param masterName One sentinel can monitor several redis master-slave pair, use master name to identify them.
* @param masterConnectionInfo The the other information like password,timeout.
* @param masterPoolConfig Configuration of redis pool.
*
*/
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, ConnectionInfo masterConnectionInfo,
JedisPoolConfig masterPoolConfig) {
// sentinelAddresses
assertArgument(((sentinelAddresses == null) || (sentinelAddresses.length == 0)), "seintinelInfos is not set");
for (HostAndPort sentinelInfo : sentinelAddresses) {
JedisPool sentinelPool = new JedisDirectPool(sentinelInfo, new JedisPoolConfig());
sentinelPools.add(sentinelPool);
}
// masterConnectionInfo
assertArgument(masterConnectionInfo == null, "masterConnectionInfo is not set");
this.masterConnectionInfo = masterConnectionInfo;
// masterName
assertArgument(((masterName == null) || masterName.isEmpty()), "masterName is not set");
this.masterName = masterName;
// poolConfig
assertArgument(masterPoolConfig == null, "masterPoolConfig is not set");
this.masterPoolConfig = masterPoolConfig;
// Start MasterSwitchListener thread ,internal poll will be start in the thread
masterSwitchListener = new MasterSwitchListener();
masterSwitchListener.start();
try {
if (!poolInit.await(5, TimeUnit.SECONDS)) {
logger.warn("the sentiel pool can't not init in 5 seconds");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public JedisSentinelPool(HostAndPort[] sentinelAddresses, String masterName, JedisPoolConfig masterPoolConfig) {
this(sentinelAddresses, masterName, new ConnectionInfo(), masterPoolConfig);
}
@Override
public void destroy() {
// shutdown the listener thread
masterSwitchListener.shutdown();
// destroy sentinel pools
for (JedisPool sentinel : sentinelPools) {
sentinel.destroy();
}
// destroy redis pool
destroyInternelPool();
// wait for the masterSwitchListener thread finish
try {
logger.info("Waiting for MasterSwitchListener thread finish");
masterSwitchListener.join();
logger.info("MasterSwitchListener thread finished");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
protected void destroyInternelPool() {
closeInternalPool();
address = null;
connectionInfo = null;
internalPool = null;
}
/**
* Assert the argurment, throw IllegalArgumentException if the expression is true.
*/
private static void assertArgument(boolean expression, String message) {
if (expression) {
throw new IllegalArgumentException(message);
}
}
// for test
public MasterSwitchListener getMasterSwitchListener() {
return masterSwitchListener;
}
/**
* Listener thread to listen master switch message from sentinel.
*/
public class MasterSwitchListener extends Thread {
public static final String THREAD_NAME_PREFIX = "MasterSwitchListener-";
private JedisPubSub subscriber;
private JedisPool sentinelPool;
private Jedis sentinelJedis;
private AtomicBoolean running = new AtomicBoolean(true);
private HostAndPort previousMasterAddress;
public MasterSwitchListener() {
super(THREAD_NAME_PREFIX + masterName);
}
// stop the blocking subscription and interrupt the thread
public void shutdown() {
// interrupt the thread
running.getAndSet(false);
this.interrupt();
// stop the blocking subscription
try {
if (subscriber != null) {
subscriber.unsubscribe();
}
} finally {
JedisUtils.destroyJedis(sentinelJedis);
}
}
@Override
public void run() {
while (running.get()) {
try {
sentinelPool = pickupSentinel();
if (sentinelPool != null) {
HostAndPort masterAddress = queryMasterAddress();
if ((internalPool != null) && isAddressChange(masterAddress)) {
logger.info("The internalPool {} had changed, destroy it now.", previousMasterAddress);
destroyInternelPool();
}
if (internalPool == null) {
logger.info("The internalPool {} is not init or the address had changed, init it now.",
masterAddress);
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
poolInit.countDown();
}
previousMasterAddress = masterAddress;
sentinelJedis = sentinelPool.getResource();
subscriber = new MasterSwitchSubscriber();
sentinelJedis.subscribe(subscriber, "+switch-master", "+redirect-to-master");
} else {
logger.info("All sentinels down, sleep 2 seconds and try to connect again.");
// When the system startup but the sentinels not yet, init a urgly address to prevent null point
// exception. change the logic later.
if (internalPool == null) {
HostAndPort masterAddress = new HostAndPort(NO_ADDRESS_YET, 6379);
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
previousMasterAddress = masterAddress;
}
sleep(2000);
}
} catch (JedisConnectionException e) {
if (sentinelJedis != null) {
sentinelPool.returnBrokenResource(sentinelJedis);
}
if (running.get()) {
logger.error("Lost connection with Sentinel " + sentinelPool.getAddress()
+ ", sleep 1 seconds and try to connect other one. ");
sleep(1000);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
sleep(1000);
}
}
}
public HostAndPort getCurrentMasterAddress() {
return previousMasterAddress;
}
/**
* Pickup the first available sentinel, if all sentinel down, return null.
*/
private JedisPool pickupSentinel() {
for (JedisPool pool : sentinelPools) {
if (JedisUtils.ping(pool)) {
return pool;
}
}
return null;
}
private boolean isAddressChange(HostAndPort currentMasterAddress) {
if (previousMasterAddress == null) {
return true;
}
return !previousMasterAddress.equals(currentMasterAddress);
}
/**
* Query master address from sentinel.
*/
private HostAndPort queryMasterAddress() {
JedisTemplate sentinelTemplate = new JedisTemplate(sentinelPool);
List<String> address = sentinelTemplate.execute(new JedisTemplate.JedisAction<List<String>>() {
@Override
public List<String> action(Jedis jedis) {
return jedis.sentinelGetMasterAddrByName(masterName);
}
});
if ((address == null) || address.isEmpty()) {
throw new IllegalArgumentException("Master name " + masterName + " is not in sentinel.conf");
}
return new HostAndPort(address.get(0), Integer.valueOf(address.get(1)));
}
private void sleep(int millseconds) {
try {
Thread.sleep(millseconds);
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
}
/**
* Subscriber for the master switch message from sentinel and init the new pool.
*/
private class MasterSwitchSubscriber extends JedisPubSub {
@Override
public void onMessage(String channel, String message) {
// message example: +switch-master: mymaster 127.0.0.1 6379 127.0.0.1 6380
// +redirect-to-master default 127.0.0.1 6380 127.0.0.1 6381 (if slave-master fail-over quick enough)
logger.info("Sentinel " + sentinelPool.getAddress() + " published: " + message);
String[] switchMasterMsg = message.split(" ");
// if the master name equals my master name, destroy the old pool and init a new pool
if (masterName.equals(switchMasterMsg[0])) {
HostAndPort masterAddress = new HostAndPort(switchMasterMsg[3],
Integer.parseInt(switchMasterMsg[4]));
logger.info("Switch master to " + masterAddress);
destroyInternelPool();
initInternalPool(masterAddress, masterConnectionInfo, masterPoolConfig);
previousMasterAddress = masterAddress;
}
}
@Override
public void onPMessage(String pattern, String channel, String message) {
}
@Override
public void onSubscribe(String channel, int subscribedChannels) {
}
@Override
public void onUnsubscribe(String channel, int subscribedChannels) {
}
@Override
public void onPUnsubscribe(String pattern, int subscribedChannels) {
}
@Override
public void onPSubscribe(String pattern, int subscribedChannels) {
}
}
}
}
@@ -0,0 +1,189 @@
package javautils.regex;
import javautils.StringUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class RegexUtil {
private RegexUtil() {
}
/**
* 匹配图象
* 格式: /相对路径/文件名.后缀 (后缀为gif,dmp,png,jpg)
* 匹配 : /forum/head_icon/admini2005111_ff.gif 或 admini2005111.dmp
* 不匹配: c:/admins4512.gif
*/
public static final String image_regex = "^(/{0,1}\\w){1,}\\.(gif|dmp|png|jpg|jpeg)$|^\\w{1,}\\.(gif|dmp|png|jpg|jpeg)$";
/**
* 匹配email地址
* 匹配 : foo@bar.com 或 foobar@foobar.com.au
* 不匹配: foo@bar 或 $$$@bar.com
*/
public static final String email_regex = "(?:\\w[-._\\w]*\\w@\\w[-._\\w]*\\w\\.\\w{2,3}$)";
/**
* 匹配匹配并提取url
* 匹配 : http://www.suncer.com 或news://www
* 提取(MatchResult matchResult=matcher.getMatch()): matchResult.group(0)=
* http://www.suncer.com:8080/index.html?login=true matchResult.group(1) =
* http matchResult.group(2) = www.suncer.com matchResult.group(3) = :8080
* matchResult.group(4) = /index.html?login=true
* 不匹配: c:\window
*/
public static final String url_regex = "(\\w+)://([^/:]+)(:\\d*)?([^\\s]*)";
/**
* 匹配并提取http
* 匹配 : http://www.suncer.com:8080/index.html?login=true
* 提取(MatchResult matchResult=matcher.getMatch()): matchResult.group(0)=
* http://www.suncer.com:8080/index.html?login=true matchResult.group(1) =
* http matchResult.group(2) = www.suncer.com matchResult.group(3) = :8080
* matchResult.group(4) = /index.html?login=true
* 不匹配: news://www
*/
public static final String http_regex = "(http|https|ftp)://([^/:]+)(:\\d*)?([^\\s]*)";
/**
* 匹配日期
* 范围:1900--2099
* 匹配 : 2005-04-04
* 不匹配: 01-01-01
*/
public static final String date_regex = "^((((19){1}|(20){1})d{2})|d{2})[-\\s]{1}[01]{1}d{1}[-\\s]{1}[0-3]{1}d{1}$";// 匹配日期
/**
* 匹配电话
* 匹配 : 0371-123456 或 (0371)1234567 或 (0371)12345678 或 010-123456 或
* 010-12345678 或 12345678912
* 不匹配: 1111-134355 或 0123456789
*/
public static final String phone_regex = "^(?:0[0-9]{2,3}[-\\s]{1}|\\(0[0-9]{2,4}\\))[0-9]{6,8}$|^[1-9]{1}[0-9]{5,7}$|^[1-9]{1}[0-9]{10}$";
/**
* 匹配身份证
* 匹配 : 0123456789123
* 不匹配: 0123456
*/
public static final String ID_card_regex = "^\\d{10}|\\d{13}|\\d{15}|\\d{18}$";
/**
* 匹配邮编代码
* 匹配 : 012345
* 不匹配: 0123456
*/
public static final String ZIP_regex = "^[0-9]{6}$";// 匹配邮编代码
/**
* 不包括特殊字符的匹配 (字符串中不包括符号 数学次方号^ 单引号' 双引号" 分号; 逗号, 帽号: 数学减号- 右尖括号> 左尖括号< 反斜杠\
* 即空格,制表符,回车符等 )
* 格式为: x 或 一个一上的字符
* 匹配 : 012345
* 不匹配: 0123456
*/
public static final String non_special_char_regex = "^[^'\"\\;,:-<>\\s].+$";// 匹配邮编代码
/**
* 匹配非负整数(正整数 + 0)
*/
public static final String non_negative_integers_regex = "^\\d+$";
/**
* 匹配不包括零的非负整数(正整数 > 0)
*/
public static final String non_zero_negative_integers_regex = "^[1-9]+\\d*$";
/**
* 匹配正整数
*/
public static final String positive_integer_regex = "^[0-9]*[1-9][0-9]*$";
/**
* 匹配非正整数(负整数 + 0)
*/
public static final String non_positive_integers_regex = "^((-\\d+)|(0+))$";
/**
* 匹配负整数
*/
public static final String negative_integers_regex = "^-[0-9]*[1-9][0-9]*$";
/**
* 匹配整数
*/
public static final String integer_regex = "^-?\\d+$";
/**
* 匹配非负浮点数(正浮点数 + 0)
*/
public static final String non_negative_rational_numbers_regex = "^\\d+(\\.\\d+)?$";
/**
* 匹配正浮点数
*/
public static final String positive_rational_numbers_regex = "^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$";
/**
* 匹配非正浮点数(负浮点数 + 0)
*/
public static final String non_positive_rational_numbers_regex = "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$";
/**
* 匹配负浮点数
*/
public static final String negative_rational_numbers_regex = "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$";
/**
* 匹配浮点数
*/
public static final String rational_numbers_regex = "^(-?\\d+)(\\.\\d+)?$";
/**
* 匹配由26个英文字母组成的字符串
*/
public static final String letter_regex = "^[A-Za-z]+$";
/**
* 匹配由26个英文字母的大写组成的字符串
*/
public static final String upward_letter_regex = "^[A-Z]+$";
/**
* 匹配由26个英文字母的小写组成的字符串
*/
public static final String lower_letter_regex = "^[a-z]+$";
/**
* 匹配由数字和26个英文字母组成的字符串
*/
public static final String letter_number_regex = "^[A-Za-z0-9]+$";
/**
* 匹配由数字、26个英文字母或者下划线组成的字符串
*/
public static final String letter_number_underline_regex = "^\\w+$";
/**
* 验证中文
*/
public static final String name_input_chn="[\u4e00-\u9fa5]";
public static boolean isMatcher(String s, String regex){
boolean flag = false;
try {
if(StringUtil.isNotNull(s)) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
flag = matcher.matches();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("匹配失败!");
}
return flag;
}
}
@@ -0,0 +1,24 @@
package javautils.spring;
import javautils.StringUtil;
import javautils.encrypt.DESUtil;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
/**
* Created by Nick on 2016/10/3.
*/
public class EncryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private static final String KEY = "#$ddw134R$#G#DSFW@#?!@#!@#$CCCREW1";
private static final DESUtil DES_UTIL = DESUtil.getInstance();
@Override
protected String convertProperty(String propertyName, String propertyValue) {
if (StringUtil.isNotNull(propertyValue) && propertyValue.endsWith("|e")) {
String tempValue = propertyValue.substring(0, propertyValue.length() - 2);
String decryptValue = DES_UTIL.decryptStr(tempValue, KEY);
return decryptValue;
} else {
return propertyValue;
}
}
}
@@ -0,0 +1,8 @@
package lottery.bin;
import org.springframework.stereotype.Component;
@Component
public class Catalina {
}
@@ -0,0 +1,8 @@
package lottery.bin;
import org.springframework.stereotype.Component;
@Component
public class ExecuteServer {
}
@@ -0,0 +1,18 @@
package lottery.bin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StartUp {
private static final Logger logger = LoggerFactory.getLogger(StartUp.class);
private static ApplicationContext applicationContext;
public static void main(String[] args) {
logger.debug("start up main method.");
String[] configLocations = { "config/spring/spring-config.xml" };
applicationContext = new ClassPathXmlApplicationContext(configLocations);
}
}
@@ -0,0 +1,46 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryOpenCode;
import java.util.List;
public interface LotteryOpenCodeService {
/**
* 修改为已开奖
*/
boolean updateOpened(LotteryOpenCode openCode);
/**
* 修改为无效已撤单
*/
boolean updateCancelled(LotteryOpenCode openCode);
/**
* 获取往期未开奖的期数
*/
List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count);
/**
* 根据彩票ID和期号获取开奖号码
*/
LotteryOpenCode getByExcept(String lottery, String except);
/**
* 根据彩票ID和期号以及用户获取开奖号码
*/
LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except);
/**
* 添加开奖号码,有则修改,没有就添加
*/
boolean add(LotteryOpenCode openCode);
/**
* 查看某个彩种彩期是否已经抓取过了
*/
boolean hasCaptured(String lotteryName, String expect);
/**
* 初始化开奖号码到redis中
*/
void initLotteryOpenCode();
}
@@ -0,0 +1,9 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryPlayRulesConfig;
import java.util.List;
public interface LotteryPlayRulesConfigService {
List<LotteryPlayRulesConfig> listAll();
}
@@ -0,0 +1,9 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
import java.util.List;
public interface LotteryPlayRulesGroupConfigService {
List<LotteryPlayRulesGroupConfig> listAll();
}
@@ -0,0 +1,9 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryPlayRulesGroup;
import java.util.List;
public interface LotteryPlayRulesGroupService {
List<LotteryPlayRulesGroup> listAll();
}
@@ -0,0 +1,9 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryPlayRules;
import java.util.List;
public interface LotteryPlayRulesService {
List<LotteryPlayRules> listAll();
}
@@ -0,0 +1,13 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.UserBets;
/**
* Created by Nick on 2017/2/27.
*/
public interface UserBetsHitRankingService {
/**
* 每天前10名
*/
void addIfNecessary(UserBets userBets);
}
@@ -0,0 +1,10 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.UserBets;
/**
* Created by Nick on 2017-05-19.
*/
public interface UserBetsPointService {
void add(UserBets userBets);
}
@@ -0,0 +1,30 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.LotteryOpenCode;
import lottery.domains.content.entity.UserBets;
import java.util.List;
public interface UserBetsService {
/**
* 取消追号订单
*/
boolean cancelChase(String chaseBillno, int userId, String winExpect);
/**
* 是否是待取消的追号单
*/
boolean isCancelChase(String chaseBillno);
/**
* 对腾讯分分彩因在线人数无变动进行撤单
*/
void cancelByTXFFCInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList);
/**
* 对腾讯龙虎斗因在线人数无变动进行撤单
*/
void cancelByTXLHDInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList);
}
@@ -0,0 +1,17 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.LotteryOpenCode;
import lottery.domains.content.entity.UserBets;
import java.util.List;
/**
* 用户注单结算service
* Created by Nick on 2016/8/29.
*/
public interface UserBetsSettleService {
void settleUserBets(List<UserBets> userBetsList, LotteryOpenCode openCode, Lottery lottery);
Object[] testUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cacheDantiao);
}
@@ -0,0 +1,29 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.UserBets;
public interface UserBillService {
/**
* 添加投注账单
*/
boolean addSpendBill(UserBets bBean);
/**
* 取消订单账单
*/
boolean addCancelOrderBill(UserBets bBean, String remarks);
/**
* 添加用户赢账单
*/
boolean addUserWinBill(UserBets userBets, double amount, String remarks);
/**
* 添加上级返点账单
*/
boolean addProxyReturnBill(UserBets userBets, int upId, double amount, String remarks);
/**
* 添加投注返水
*/
boolean addSpendReturnBill(UserBets userBets, double amount, String remarks);
}
@@ -0,0 +1,10 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.UserBets;
/**
* Created by Nick on 2017/2/27.
*/
public interface UserHighPrizeService {
void addIfNecessary(UserBets userBets);
}
@@ -0,0 +1,16 @@
package lottery.domains.content.biz;
import lottery.domains.content.entity.UserLotteryDetailsReport;
import java.util.List;
public interface UserLotteryDetailsReportService {
/**
* 批量新增或修改报表详情
*/
void addDetailsReports(List<UserLotteryDetailsReport> detailsReports);
boolean update(int userId, int lotteryId, int ruleId, int type, double amount, String time);
}
@@ -0,0 +1,5 @@
package lottery.domains.content.biz;
public interface UserLotteryReportService {
boolean update(int userId, int type, double amount, String time);
}
@@ -0,0 +1,198 @@
package lottery.domains.content.biz.impl;
import javautils.date.Moment;
import javautils.redis.JedisTemplate;
import lottery.domains.content.biz.LotteryOpenCodeService;
import lottery.domains.content.dao.LotteryDao;
import lottery.domains.content.dao.LotteryOpenCodeDao;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.LotteryOpenCode;
import lottery.domains.open.jobs.MailJob;
import lottery.domains.pool.DataFactory;
import lottery.domains.pool.play.HConstants;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.SetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import java.util.*;
@Service
public class LotteryOpenCodeServiceImpl implements LotteryOpenCodeService {
private static final Logger log = LoggerFactory.getLogger(LotteryOpenCodeServiceImpl.class);
private static final String OPEN_CODE_KEY = "OPEN_CODE:%s";
private static final int OPEN_CODE_MOST_EXPECT = 50; // 保留最近50期开奖号码
@Autowired
private LotteryOpenCodeDao lotteryOpenCodeDao;
@Autowired
private LotteryDao lotteryDao;
@Autowired
private JedisTemplate jedisTemplate;
@Autowired
private MailJob mailJob;
@Autowired
private DataFactory dataFactory;
@Override
public boolean updateOpened(LotteryOpenCode openCode) {
String updateTime = new Moment().toSimpleTime();
boolean updated = lotteryOpenCodeDao.updateOpened(openCode.getId(), updateTime);
return updated;
}
@Override
public boolean updateCancelled(LotteryOpenCode openCode) {
String updateTime = new Moment().toSimpleTime();
boolean updated = lotteryOpenCodeDao.updateCancelled(openCode.getId(), updateTime);
return updated;
}
@Override
public List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count) {
return lotteryOpenCodeDao.getBeforeNotOpen(lottery, count);
}
@Override
public LotteryOpenCode getByExcept(String lottery, String except) {
return lotteryOpenCodeDao.getByExcept(lottery, except);
}
@Override
public LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except) {
return lotteryOpenCodeDao.getByExceptAndUserId(lottery, userId, except);
}
@Override
public boolean add(LotteryOpenCode openCode) {
if (!"jsmmc".equals(openCode.getLottery())) {
boolean hasCaptured = hasCaptured(openCode.getLottery(), openCode.getExpect());
if (hasCaptured) {
return false;
}
}
boolean added = lotteryOpenCodeDao.add(openCode);
if (!added) {
return false;
}
addedToRedis(openCode);
return added;
}
@Override
public boolean hasCaptured(String lotteryName, String expect) {
String key = String.format(OPEN_CODE_KEY, lotteryName);
return jedisTemplate.hexists(key, expect);
}
private void addedToRedis(LotteryOpenCode entity) {
// 操作redis
String key = String.format(OPEN_CODE_KEY, entity.getLottery());
if ("jsmmc".equals(entity.getLottery())) {
// 急速秒秒彩直接存
String field = entity.getExpect() + ":" + entity.getUserId();
jedisTemplate.hset(key, field, entity.getCode());
}
else {
// 删除redis中多余的期数,始终保持50期
Set<String> hkeys = jedisTemplate.hkeys(key);
if (CollectionUtils.isEmpty(hkeys)) {
// 最新的设置进去
jedisTemplate.hset(key, entity.getExpect(), entity.getCode());
}
else {
TreeSet<String> sortHKeys = new TreeSet<>(hkeys);
// 先设置进去
String[] expects = sortHKeys.toArray(new String[]{});
String firstExpect = expects[0];
if (entity.getExpect().compareTo(firstExpect) > 0) {
jedisTemplate.hset(key, entity.getExpect(), entity.getCode());
sortHKeys.add(entity.getExpect());
}
if (CollectionUtils.isNotEmpty(sortHKeys) && sortHKeys.size() > OPEN_CODE_MOST_EXPECT) {
int exceedSize = sortHKeys.size() - OPEN_CODE_MOST_EXPECT;
Iterator<String> iterator = sortHKeys.iterator();
int count = 0;
List<String> delFields = new ArrayList<>();
while (iterator.hasNext()) {
if (count >= exceedSize) {
break;
}
delFields.add(iterator.next());
iterator.remove();
count++;
}
// 删除多余的
jedisTemplate.hdel(key, delFields.toArray(new String[]{}));
}
}
}
}
@Override
public void initLotteryOpenCode() {
// 加载所有彩票
List<Lottery> lotteries = lotteryDao.listAll();
for (Lottery lottery : lotteries) {
if (lottery.getId() == 117) continue; // 急速秒秒彩不设置
initLotteryOpenCodeByLottery(lottery);
// continue; // 只针对自主彩
}
}
private void initLotteryOpenCodeByLottery(final Lottery lottery) {
final List<LotteryOpenCode> openCodes = lotteryOpenCodeDao.getLatest(lottery.getShortName(), OPEN_CODE_MOST_EXPECT);
if (CollectionUtils.isEmpty(openCodes)) {
return;
}
final String key = String.format(OPEN_CODE_KEY, lottery.getShortName());
// 批量设置值
final TreeMap<String, String> values = new TreeMap<>();
for (LotteryOpenCode openCode : openCodes) {
values.put(openCode.getExpect(), openCode.getCode());
}
//
// // 倒序
// final NavigableMap<String, String> descendingMap = values.descendingMap();
// 执行pipeline是为保证最大程度减少redis中没有值的情况,比如删除后重新设置前,那么redis此时处于真空状态
jedisTemplate.execute(new JedisTemplate.JedisActionNoResult() {
@Override
public void action(Jedis jedis) {
Pipeline pipelined = jedis.pipelined();
// 删除原开奖号码
pipelined.del(key);
// 重新设置到redis
for (String expect : values.keySet()) {
pipelined.hset(key, expect, values.get(expect));
}
// 执行
pipelined.sync();
}
});
}
}
@@ -0,0 +1,23 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.LotteryPlayRulesConfigService;
import lottery.domains.content.dao.LotteryPlayRulesConfigDao;
import lottery.domains.content.entity.LotteryPlayRulesConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LotteryPlayRulesConfigServiceImpl implements LotteryPlayRulesConfigService {
@Autowired
private LotteryPlayRulesConfigDao lotteryPlayRulesConfigDao;
@Override
@Transactional(readOnly = true)
public List<LotteryPlayRulesConfig> listAll() {
return lotteryPlayRulesConfigDao.listAll();
}
}
@@ -0,0 +1,23 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.LotteryPlayRulesGroupConfigService;
import lottery.domains.content.dao.LotteryPlayRulesGroupConfigDao;
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LotteryPlayRulesGroupConfigServiceImpl implements LotteryPlayRulesGroupConfigService {
@Autowired
private LotteryPlayRulesGroupConfigDao lotteryPlayRulesGroupConfigDao;
@Override
@Transactional(readOnly = true)
public List<LotteryPlayRulesGroupConfig> listAll() {
return lotteryPlayRulesGroupConfigDao.listAll();
}
}
@@ -0,0 +1,23 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.LotteryPlayRulesGroupService;
import lottery.domains.content.dao.LotteryPlayRulesGroupDao;
import lottery.domains.content.entity.LotteryPlayRulesGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LotteryPlayRulesGroupServiceImpl implements LotteryPlayRulesGroupService {
@Autowired
private LotteryPlayRulesGroupDao lotteryPlayRulesGroupDao;
@Override
@Transactional(readOnly = true)
public List<LotteryPlayRulesGroup> listAll() {
return lotteryPlayRulesGroupDao.listAll();
}
}
@@ -0,0 +1,23 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.LotteryPlayRulesService;
import lottery.domains.content.dao.LotteryPlayRulesDao;
import lottery.domains.content.entity.LotteryPlayRules;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class LotteryPlayRulesServiceImpl implements LotteryPlayRulesService {
@Autowired
private LotteryPlayRulesDao lotteryPlayRulesDao;
@Override
@Transactional(readOnly = true)
public List<LotteryPlayRules> listAll() {
return lotteryPlayRulesDao.listAll();
}
}
@@ -0,0 +1,204 @@
package lottery.domains.content.biz.impl;
import javautils.date.Moment;
import lottery.domains.content.biz.UserBetsHitRankingService;
import lottery.domains.content.dao.DbServerSyncDao;
import lottery.domains.content.dao.UserBetsHitRankingDao;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.User;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.entity.UserBetsHitRanking;
import lottery.domains.content.global.DbServerSyncEnum;
import lottery.domains.content.global.Global;
import lottery.domains.pool.DataFactory;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
/**
* Created by Nick on 2017/2/27.
*/
@Service
public class UserBetsHitRankingServiceImpl implements UserBetsHitRankingService {
private static final Logger log = LoggerFactory.getLogger(UserBetsHitRankingServiceImpl.class);
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
@Autowired
private UserBetsHitRankingDao rankingDao;
@Autowired
private DataFactory dataFactory;
@Autowired
private UserDao uDao;
@Autowired
private DbServerSyncDao dbServerSyncDao;
private static boolean isRunning = false;
@Scheduled(cron = "0 0/5 * * * *")
// @Scheduled(cron = "0/10 * * * * *")
public void run() {
synchronized (UserBetsHitRankingServiceImpl.class) {
if (isRunning == true) {
// 任务正在运行,本次中断
return;
}
isRunning = true;
}
try {
add();
} finally {
isRunning = false;
}
}
private void add() {
if(userBetsQueue != null && userBetsQueue.size() > 0) {
try {
List<UserBets> adds = new LinkedList<>();
userBetsQueue.drainTo(adds, 50);
if (CollectionUtils.isNotEmpty(adds)) {
add(adds);
}
} catch (Exception e) {
log.error("添加中奖排行榜错误", e);
}
}
}
private void add(List<UserBets> adds) {
if (!dataFactory.getLotteryConfig().isAutoHitRanking()) {
return;
}
int hitRankingSize = dataFactory.getLotteryConfig().getHitRankingSize();
// 把奖金从大到小排序
Collections.sort(adds, new Comparator<UserBets>() {
@Override
public int compare(UserBets o1, UserBets o2) {
return o2.getPrizeTime().compareTo(o1.getPrizeTime());
}
});
String today = new Moment().toSimpleDate() + " 00:00:00";
String tomorrow = new Moment().add(1, "days").toSimpleDate() + " 00:00:00";
// 先查看当天的数据是否满了10条
List<Integer> todayIds = rankingDao.getIds(Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
// 没有满10条,把本次的数据由大到小加到数据库,但不超过最大条数
int currentSize = todayIds.size();
if (currentSize < hitRankingSize) {
for (int i = 0; i < adds.size(); i++) {
if (currentSize >= hitRankingSize) {
break;
}
else {
UserBets userBets = adds.get(i);
UserBetsHitRanking ranking = convert(userBets);
rankingDao.add(ranking);
currentSize++;
}
}
// 重新调整以往的数据
List<Integer> idsByTimeDesc = rankingDao.getIdsByTimeDesc(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY);
if (CollectionUtils.isNotEmpty(idsByTimeDesc)) {
rankingDao.delNotInIds(idsByTimeDesc, Global.BILL_ACCOUNT_LOTTERY);
}
dbServerSyncDao.update(DbServerSyncEnum.HIT_RANKING);
log.info("中奖排行榜更新完成");
}
else {
// 如果大于今天最小的奖金,那么加入该数据
UserBetsHitRanking minRanking = rankingDao.getMinRanking(Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
int addedCount = 0;
for (UserBets add : adds) {
boolean allowAdd = false;
if (minRanking == null) {
allowAdd = true;
}
else {
BigDecimal prize = BigDecimal.valueOf(add.getPrizeMoney());
int prizeMoney = prize.intValue();
if (prizeMoney > minRanking.getPrizeMoney()) {
allowAdd = true;
}
}
if (allowAdd) {
UserBetsHitRanking ranking = convert(add);
rankingDao.add(ranking);
addedCount++;
}
}
// 重新调整今天的数据
if (addedCount > 0) {
List<Integer> totalIds = rankingDao.getTotalIds(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
if (CollectionUtils.isNotEmpty(totalIds)) {
rankingDao.delNotInIds(totalIds, Global.BILL_ACCOUNT_LOTTERY, today, tomorrow);
}
// 重新调整以往的数据
List<Integer> idsByTimeDesc = rankingDao.getIdsByTimeDesc(hitRankingSize, Global.BILL_ACCOUNT_LOTTERY);
if (CollectionUtils.isNotEmpty(idsByTimeDesc)) {
rankingDao.delNotInIds(idsByTimeDesc, Global.BILL_ACCOUNT_LOTTERY);
}
dbServerSyncDao.update(DbServerSyncEnum.HIT_RANKING);
log.info("中奖排行榜更新完成");
}
}
}
private UserBetsHitRanking convert(UserBets userBets) {
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
if (lottery == null) {
return null;
}
User user = uDao.getById(userBets.getUserId());
if (user == null) {
return null;
}
UserBetsHitRanking ranking = new UserBetsHitRanking();
ranking.setName(lottery.getShowName());
ranking.setUsername(user.getUsername());
BigDecimal prize = BigDecimal.valueOf(userBets.getPrizeMoney());
ranking.setPrizeMoney(prize.intValue());
ranking.setTime(userBets.getPrizeTime());
ranking.setPlatform(Global.BILL_ACCOUNT_LOTTERY);
ranking.setCode(lottery.getShortName());
ranking.setType(lottery.getType()+"");
return ranking;
}
@Override
public void addIfNecessary(UserBets userBets) {
if (userBets.getPrizeMoney() != null && userBets.getPrizeMoney() >= 50000) {
userBetsQueue.offer(userBets);
}
}
}
@@ -0,0 +1,276 @@
package lottery.domains.content.biz.impl;
import javautils.array.ArrayUtils;
import javautils.math.MathUtil;
import lottery.domains.content.biz.UserBetsPointService;
import lottery.domains.content.biz.UserBillService;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.LotteryPlayRules;
import lottery.domains.content.entity.User;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.global.Global;
import lottery.domains.open.jobs.MailJob;
import lottery.domains.pool.DataFactory;
import lottery.domains.utils.user.UserCodePointUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
/**
* Created by Nick on 2017-05-19.
*/
@Service
public class UserBetsPointServiceImpl implements UserBetsPointService {
private static final Logger log = LoggerFactory.getLogger(UserBetsPointServiceImpl.class);
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
private static boolean isRunning = false;
@Autowired
private MailJob mailJob;
@Autowired
private UserDao uDao;
@Autowired
private UserBillService uBillService;
@Autowired
private UserCodePointUtil uCodePointUtil;
@Autowired
private DataFactory dataFactory;
@Override
public void add(UserBets userBets) {
userBets.setCodes(null); // 将号码置空,减少内存占用
userBetsQueue.offer(userBets);
}
@Scheduled(cron = "0/3 * * * * *")
public void run() {
synchronized (UserBetsPointServiceImpl.class) {
if (isRunning == true) {
// 任务正在运行,本次中断
return;
}
isRunning = true;
}
try {
calculateOrder();
} finally {
isRunning = false;
}
}
private void calculateOrder() {
if(userBetsQueue != null && userBetsQueue.size() > 0) {
try {
List<UserBets> userBetsList = new LinkedList<>();
userBetsQueue.drainTo(userBetsList, 3000); // 每次取3000条,不知道会不会太慢
if (CollectionUtils.isNotEmpty(userBetsList)) {
calculateOrders(userBetsList);
}
} catch (Exception e) {
log.error("添加用户大额中奖失败", e);
}
}
}
private void calculateOrders(List<UserBets> userBetsList) {
log.debug("正在进行注单返点,共计{}条注单", userBetsList.size());
long start = System.currentTimeMillis();
for (UserBets userBets : userBetsList) {
calculatePointMoney(userBets);
}
long spent = System.currentTimeMillis() - start;
log.debug("完成注单返点,共计{}条注单,耗时{}", userBetsList.size(), spent);
if (spent >= 60000) {
String warningMsg = String.format("返点耗时告警;对%s条注单进行返点时耗时达到%s", userBetsList.size(), spent);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
}
/**
* 增加上级返点与用户投注返点
*/
private void calculatePointMoney(UserBets userBets) {
// 上级返点
calculateUpPoint(userBets);
// 投注返点
calculateUserPoint(userBets);
}
/**
* 逐级为上级投注返点
* 用户投注额 * ((上级返点 - 用户返点 - 累计返点) / 100)
* 玩家a:12.0 -> 代理d:12.2 -> 代理c:12.4 -> 代理b:12.6 -> 代理a:13.0
*
* 玩家a投注:20,000
*
* 代理d返点:
* 返点比例: 12.2 - 12.0 - 0.0 = 0.2
* 计算比例: 0.2 / 100 = 0.002
* 实际返钱: 20,000 * 0.002 = 40
* 累计返点: 0.2
*
* 代理c返点:
* 返点比例: 12.4 - 12.0 - 0.2 = 0.2
* 计算比例: 0.2 / 100 = 0.002
* 返钱: 20,000 * 0.002 = 40
* 累计返点: 0.4
*
* 代理b返点:
* 返点比例: 12.6 - 12.0 - 0.4 = 0.2
* 计算比例: 0.2 / 100 = 0.002
* 返钱: 20,000 * 0.002 = 40
* 累计返点: 0.6
*
* 代理a返点:
* 返占比例: 13.0 - 12.0 - 0.6 = 0.4
* 计算比例: 0.4 / 100 = 0.004
* 返钱: 20,000 * 0.004 = 80
* 累计返点: 1.0
*/
private void calculateUpPoint(UserBets userBets) {
if (userBets.getCode() == dataFactory.getCodeConfig().getSysCode()) {
return; // 如果投注是最高,那么就不处理了
}
User user = uDao.getById(userBets.getUserId());
if (user == null || user.getUpid() == 0 || user.getUpid() == Global.USER_TOP_ID || StringUtils.isEmpty(user.getUpids())) {
// 没有上级代理或上级是总账号时,不做任何处理
return;
}
if (user.getCode() == dataFactory.getCodeConfig().getSysCode()) {
return; // 如果用户是最高,那么就不处理了
}
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
LotteryPlayRules rules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
boolean isLocate = rules.getIsLocate() == 0 ? false: true;
int [] upIds = ArrayUtils.transGetIds(user.getUpids()); // 上级ID
double currentPoint = 0; // 当前累计返点比例
double totalPoint; // 本次总计应该返点
if (isLocate) {
totalPoint = MathUtil.subtract(dataFactory.getCodeConfig().getSysLp(), user.getLocatePoint());
}
else {
totalPoint = MathUtil.subtract(dataFactory.getCodeConfig().getSysNlp(), user.getNotLocatePoint());
}
for (int upId : upIds) {
// 总账号不返点
if (upId == Global.USER_TOP_ID) {
continue;
}
if (currentPoint >= totalPoint) {
return; // 如果已经返完就不再返了
}
User upUser = uDao.getById(upId);
// 关联账号不返点
if (upUser == null || upUser.getType() == Global.USER_TYPE_RELATED) continue;
double upPoint = isLocate ? upUser.getLocatePoint() : upUser.getNotLocatePoint(); // 上级返点
double point = MathUtil.subtract(upPoint, isLocate ? user.getLocatePoint() : user.getNotLocatePoint()); // 返点比例:上级返点-用户返点
point = MathUtil.subtract(point, currentPoint); // 返点比例:减去累计返点
if(point <= 0) continue; // 小于0就不计算了
// 返给上级的钱:(注单金额 * (返点比例/100) )
double upPointMoney = calculateMoneyByPoint(userBets.getMoney(), point); // 返给上级的钱
if (upPointMoney <= 0 || upPointMoney <= 0.000001) continue; // 小于0.00001就不计算了
currentPoint = MathUtil.add(currentPoint, point); // 累计返点
if (upUser.getAStatus() != 0 && upUser.getAStatus() != -1) continue; // 非正常或冻结用户不返点,系统扣除
// // 如果用户有上级关联用户,则还需要返给上级
// if (upUser.getRelatedUpid() != 0 && upUser.getRelatedUpid() != Global.USER_TOP_ID && upUser.getRelatedPoint() > 0 && upUser.getRelatedPoint() <= 1) {
// double relatedMoney = MathUtil.multiply(upPointMoney, upUser.getRelatedPoint());
// if (relatedMoney > 0.0001) {
// upPointMoney = MathUtil.subtract(upPointMoney, relatedMoney);
//
// // 生成账单
// boolean succeed = uBillService.addProxyReturnBill(userBets, upUser.getRelatedUpid(), relatedMoney, "关联返点");
//
// // 修改金额
// if (succeed) {
// uDao.updateLotteryMoney(upUser.getRelatedUpid(), relatedMoney);
// }
// }
// }
if (upPointMoney <= 0) {
return;
}
// 生成账单
boolean succeed = uBillService.addProxyReturnBill(userBets, upId, upPointMoney, "上级返点");
// 修改金额
if (succeed) {
uDao.updateLotteryMoney(upId, upPointMoney);
}
if (upUser.getCode() == dataFactory.getCodeConfig().getSysCode()) {
return; // 如果上级已经是最高,那么就不处理了
}
}
}
/**
* 增加用户投注返点
*/
private void calculateUserPoint(UserBets userBets) {
// 本次投注返点
double point = userBets.getPoint();
if (point <= 0) {
return;
}
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
if (lottery != null) {
LotteryPlayRules lotteryPlayRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
// 固定奖金玩法没有投注返点
if (lotteryPlayRules != null && lotteryPlayRules.getFixed() == 0) {
double pointMoney = calculateMoneyByPoint(userBets.getMoney(), point);
if (pointMoney > 0 && pointMoney >= 0.00001) {
boolean succeed = uBillService.addSpendReturnBill(userBets, pointMoney, "投注返点");
if (succeed) {
// 修改金额
uDao.updateLotteryMoney(userBets.getUserId(), pointMoney);
}
}
}
}
}
/**
* 根据返点与金额计算返钱(金额 * (返点比例/100) )
*/
private double calculateMoneyByPoint(double money, double point) {
double percent = MathUtil.divide(point, 100, 6);
double _money = MathUtil.multiply(money, percent);
return _money;
}
}
@@ -0,0 +1,360 @@
package lottery.domains.content.biz.impl;
import javautils.date.Moment;
import javautils.redis.JedisTemplate;
import lottery.domains.content.biz.LotteryOpenCodeService;
import lottery.domains.content.biz.UserBetsService;
import lottery.domains.content.biz.UserBillService;
import lottery.domains.content.dao.UserBetsDao;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.entity.LotteryOpenCode;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.global.Global;
import lottery.domains.content.vo.bets.UserBetsAutoCancelAdapter;
import lottery.domains.content.vo.bets.UserBetsCancelAdapter;
import lottery.domains.open.jobs.MailJob;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.exceptions.JedisException;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingDeque;
@Service
public class UserBetsServiceImpl implements UserBetsService {
public static final String USER_BETS_UNOPEN_RECENT_KEY = "USER:BETS:UNOPEN:RECENT:%s"; // 用户最近未结算彩票投注ID 用户ID
public static final String USER_BETS_OPENED_RECENT_KEY = "USER:BETS:OPENED:RECENT:%s"; // 用户最近已结算彩票投注ID 用户ID
private static final Logger log = LoggerFactory.getLogger(UserBetsServiceImpl.class);
private BlockingQueue<UserBetsCancelAdapter> cancelChaseQueue = new LinkedBlockingDeque<>();
private ConcurrentHashMap<String, Boolean> cancelChaseMap = new ConcurrentHashMap<>();
private ConcurrentHashMap<String, Boolean> cancelChaseHisMap = new ConcurrentHashMap<>();
private BlockingQueue<UserBetsAutoCancelAdapter> cancelTXFFXInvalidQueue = new LinkedBlockingDeque<>();
private Set<String> cancelTXFFXInvalidSet = Collections.synchronizedSet(new HashSet<String>());
private BlockingQueue<UserBetsAutoCancelAdapter> cancelTXLHDInvalidQueue = new LinkedBlockingDeque<>();
private Set<String> cancelTXLHDInvalidSet = Collections.synchronizedSet(new HashSet<String>());
private static boolean isRunning = false;
/**
* DAO
*/
@Autowired
private UserDao uDao;
@Autowired
private UserBetsDao uBetsDao;
@Autowired
private LotteryOpenCodeService lotteryOpenCodeService;
@Autowired
private MailJob mailJob;
/**
* SERVICE
*/
@Autowired
private UserBillService uBillService;
@Autowired
private JedisTemplate jedisTemplate;
@Scheduled(cron = "0/3 * * * * *")
public void run() {
synchronized (UserBetsServiceImpl.class) {
if (isRunning == true) {
// 任务正在运行,本次中断
return;
}
isRunning = true;
}
try {
cancelChase(); // 撤单追号
cancelTXFFC(); // 撤单腾讯分分彩
cancelTXLHD(); // 撤单腾讯龙虎斗
} finally {
isRunning = false;
}
}
private void cancelChase() {
if(cancelChaseQueue != null && cancelChaseQueue.size() > 0) {
try {
List<UserBetsCancelAdapter> cancels = new LinkedList<>();
cancelChaseQueue.drainTo(cancels, 200); // 每次取200条
if (CollectionUtils.isNotEmpty(cancels)) {
cancelChase(cancels);
}
} catch (Exception e) {
log.error("撤销用户追单失败", e);
}
}
}
private void cancelChase(List<UserBetsCancelAdapter> cancels) {
log.info("正在中奖撤销追号订单,共计{}条追号单需要撤销", cancels.size());
long start = System.currentTimeMillis();
int canceledCount = 0;
for (UserBetsCancelAdapter cancel : cancels) {
List<UserBets> list = uBetsDao.getByChaseBillno(cancel.getChaseBillno(), cancel.getUserId(), cancel.getWinExpect());
for (UserBets bBean : list) {
if(bBean.getStatus() == 0) {
doCancelOrderByChase(bBean);
canceledCount++;
}
}
}
long spent = System.currentTimeMillis() - start;
log.info("完成中奖撤销追号订单,共计{}条追号单{}条注单,耗时{}", cancels.size(), canceledCount, spent);
if (spent >= 30000) {
String warningMsg = String.format("中奖撤销追号订单耗时告警;撤销%s条追号单%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
}
@Override
public boolean cancelChase(String chaseBillno, int userId, String winExpect) {
if (!cancelChaseMap.containsKey(chaseBillno) && !cancelChaseHisMap.contains(chaseBillno)) {
cancelChaseMap.put(chaseBillno, true);
cancelChaseQueue.offer(new UserBetsCancelAdapter(chaseBillno, userId, winExpect));
}
return true;
}
@Override
public boolean isCancelChase(String chaseBillno) {
return cancelChaseMap.containsKey(chaseBillno) || cancelChaseHisMap.contains(chaseBillno);
}
private boolean doCancelOrderByChase(UserBets bBean) {
try {
if(bBean.getType() == Global.USER_BETS_TYPE_CHASE && bBean.getStatus() == 0 && bBean.getChaseStop() == 1) {
boolean canceled = uBetsDao.cancel(bBean.getId());
if(canceled) {
boolean added = uBillService.addCancelOrderBill(bBean, "中奖后停止追号返款");
if(added) {
cacheUserBetsId(bBean);
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
}
}
}
return false;
} catch (Exception e) {
log.error("中奖停止追号出错,注单号:" + bBean.getId() + ",追单号:" + bBean.getChaseBillno(), e);
}
return false;
}
private void cancelTXFFC() {
if(cancelTXFFXInvalidQueue != null && cancelTXFFXInvalidQueue.size() > 0) {
try {
List<UserBetsAutoCancelAdapter> cancels = new LinkedList<>();
cancelTXFFXInvalidQueue.drainTo(cancels, 200); // 每次取200条
if (CollectionUtils.isNotEmpty(cancels)) {
cancelTXFFC(cancels);
}
} catch (Exception e) {
log.error("撤销腾讯分分彩失败", e);
}
}
}
private void cancelTXFFC(List<UserBetsAutoCancelAdapter> cancels) {
long start = System.currentTimeMillis();
int canceledCount = 0;
for (UserBetsAutoCancelAdapter cancel : cancels) {
List<UserBets> list = cancel.getUserBetsList();
log.info("正在撤销腾讯分分彩无效开奖号码,期号{}", cancel.getLotteryOpenCode().getExpect());
// 撤销注单
for (UserBets bBean : list) {
if(bBean.getStatus() == 0) {
doCancelOrderByTXFFC(bBean, cancel.getLotteryOpenCode().getCode());
canceledCount++;
}
}
// 修改开奖号码状态为无效已撤单(2)
lotteryOpenCodeService.updateCancelled(cancel.getLotteryOpenCode());
cancelTXFFXInvalidSet.remove(cancel.getLotteryOpenCode().getExpect());
}
long spent = System.currentTimeMillis() - start;
log.info("完成撤销腾讯分分彩无效开奖号码,共计{}期{}条注单,耗时{}", cancels.size(), canceledCount, spent);
if (spent >= 30000) {
String warningMsg = String.format("撤销腾讯分分彩无效开奖号码耗时告警;撤销%s期%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
}
@Override
public void cancelByTXFFCInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList) {
if (cancelTXFFXInvalidSet.contains(lotteryOpenCode.getExpect())) {
return;
}
if (!"txffc".equalsIgnoreCase(lotteryOpenCode.getLottery())) {
return;
}
cancelTXFFXInvalidSet.add(lotteryOpenCode.getExpect());
cancelTXFFXInvalidQueue.offer(new UserBetsAutoCancelAdapter(lotteryOpenCode, userBetsList));
}
private boolean doCancelOrderByTXFFC(UserBets bBean, String openCode) {
try {
Moment thisTime = new Moment();
Moment stopTime = new Moment().fromTime(bBean.getStopTime());
if (bBean.getStatus() == 0 && thisTime.ge(stopTime)) {
boolean canceled = uBetsDao.cancelAndSetOpenCode(bBean.getId(), openCode);
if(canceled) {
boolean added = uBillService.addCancelOrderBill(bBean, "腾讯分分彩重复开奖号码撤单");
if(added) {
cacheUserBetsId(bBean);
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
}
}
}
return false;
} catch (Exception e) {
log.error("腾讯分分彩无效开奖号码撤单出错,注单号:" + bBean.getId(), e);
}
return false;
}
private void cancelTXLHD() {
if(cancelTXLHDInvalidQueue != null && cancelTXLHDInvalidQueue.size() > 0) {
try {
List<UserBetsAutoCancelAdapter> cancels = new LinkedList<>();
cancelTXLHDInvalidQueue.drainTo(cancels, 200); // 每次取200条
if (CollectionUtils.isNotEmpty(cancels)) {
cancelTXLHD(cancels);
}
} catch (Exception e) {
log.error("撤销腾讯龙虎斗失败", e);
}
}
}
private void cancelTXLHD(List<UserBetsAutoCancelAdapter> cancels) {
long start = System.currentTimeMillis();
int canceledCount = 0;
for (UserBetsAutoCancelAdapter cancel : cancels) {
List<UserBets> list = cancel.getUserBetsList();
log.info("正在撤销腾讯龙虎斗无效开奖号码,期号{}", cancel.getLotteryOpenCode().getExpect());
// 撤销注单
for (UserBets bBean : list) {
if(bBean.getStatus() == 0) {
doCancelOrderByTXLHD(bBean, cancel.getLotteryOpenCode().getCode());
canceledCount++;
}
}
// 修改开奖号码状态为无效已撤单(2)
lotteryOpenCodeService.updateCancelled(cancel.getLotteryOpenCode());
cancelTXLHDInvalidSet.remove(cancel.getLotteryOpenCode().getExpect());
}
long spent = System.currentTimeMillis() - start;
log.info("完成撤销腾讯龙虎斗无效开奖号码,共计{}期{}条注单,耗时{}", cancels.size(), canceledCount, spent);
if (spent >= 30000) {
String warningMsg = String.format("撤销腾讯龙虎斗无效开奖号码耗时告警;撤销%s期%s条注单时耗时达到%s", cancels.size(), canceledCount, spent);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
}
@Override
public void cancelByTXLHDInvalid(LotteryOpenCode lotteryOpenCode, List<UserBets> userBetsList) {
if (cancelTXLHDInvalidSet.contains(lotteryOpenCode.getExpect())) {
return;
}
if (!"txlhd".equalsIgnoreCase(lotteryOpenCode.getLottery())) {
return;
}
cancelTXLHDInvalidSet.add(lotteryOpenCode.getExpect());
cancelTXLHDInvalidQueue.offer(new UserBetsAutoCancelAdapter(lotteryOpenCode, userBetsList));
}
private boolean doCancelOrderByTXLHD(UserBets bBean, String openCode) {
try {
Moment thisTime = new Moment();
Moment stopTime = new Moment().fromTime(bBean.getStopTime());
if (bBean.getStatus() == 0 && thisTime.ge(stopTime)) {
boolean canceled = uBetsDao.cancelAndSetOpenCode(bBean.getId(), openCode);
if(canceled) {
boolean added = uBillService.addCancelOrderBill(bBean, "腾讯龙虎斗重复开奖号码撤单");
if(added) {
cacheUserBetsId(bBean);
return uDao.updateLotteryMoney(bBean.getUserId(), bBean.getMoney(), -bBean.getMoney());
}
}
}
return false;
} catch (Exception e) {
log.error("腾讯龙虎斗无效开奖号码撤单出错,注单号:" + bBean.getId(), e);
}
return false;
}
@Scheduled(cron = "0 30 5 * * *")
public void clear() {
cancelChaseHisMap.clear();
cancelChaseHisMap.putAll(cancelChaseMap);
cancelChaseMap.clear();
}
private void cacheUserBetsId(UserBets userBets) {
final String unOpenCacheKey = String.format(USER_BETS_UNOPEN_RECENT_KEY, userBets.getUserId());
final String openedCacheKey = String.format(USER_BETS_OPENED_RECENT_KEY, userBets.getUserId());
final String userBetsId = userBets.getId() + "";
try {
jedisTemplate.execute(new JedisTemplate.PipelineActionNoResult() {
@Override
public void action(Pipeline pipeline) {
pipeline.lrem(unOpenCacheKey, 1, userBetsId); // 移除未结算订单ID
pipeline.lpush(openedCacheKey, userBetsId); // 设置已结算订单ID
pipeline.ltrim(openedCacheKey, 0, 10); // 最多设置10条
pipeline.expire(openedCacheKey, 60 * 60 * 12); // 12小时过期
pipeline.sync();
}
});
} catch (JedisException e) {
log.error("执行Redis缓存注单ID时出错", e);
}
}
}
@@ -0,0 +1,883 @@
package lottery.domains.content.biz.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import javautils.StringUtil;
import javautils.date.DateUtil;
import javautils.date.Moment;
import javautils.math.MathUtil;
import javautils.redis.JedisTemplate;
import lottery.domains.content.biz.LotteryOpenCodeService;
import lottery.domains.content.biz.UserBetsHitRankingService;
import lottery.domains.content.biz.UserBetsPointService;
import lottery.domains.content.biz.UserBetsService;
import lottery.domains.content.biz.UserBetsSettleService;
import lottery.domains.content.biz.UserBillService;
import lottery.domains.content.biz.UserHighPrizeService;
import lottery.domains.content.biz.UserLotteryDetailsReportService;
import lottery.domains.content.biz.UserLotteryReportService;
import lottery.domains.content.dao.UserBetsDao;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.LotteryOpenCode;
import lottery.domains.content.entity.LotteryPlayRules;
import lottery.domains.content.entity.LotteryPlayRulesGroup;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.global.Global;
import lottery.domains.content.global.NoticeSendType;
import lottery.domains.content.vo.config.LotteryConfig;
import lottery.domains.content.vo.user.UserVO;
import lottery.domains.open.jobs.MailJob;
import lottery.domains.pool.DataFactory;
import lottery.domains.pool.play.HConstants;
import lottery.domains.pool.play.ITicketPlayHandler;
import lottery.domains.pool.play.MultipleResult;
import lottery.domains.pool.play.TicketPlayHandlerContext;
import lottery.domains.pool.play.WinResult;
import lottery.domains.pool.play.impl.SSCRX3HHZXPlayHanlder;
import lottery.domains.utils.prize.PrizeUtils;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.exceptions.JedisException;
/**
*
* Created by Nick on 2016/8/29.
*/
@Service
public class UserBetsSettleServiceImpl implements UserBetsSettleService {
private static final Logger log = LoggerFactory.getLogger(UserBetsSettleServiceImpl.class);
private static final String USER_CURRENT_PRIZE_KEY = "USER:CURRENT_PRIZE:";
private static final String LOTTERY_CURRENT_PRIZE_KEY = "LOTTERY:CURRENT_PRIZE:";
private static final String USER_BETS_NOTICE_KEY = "USER:BETS_NOTICE";
/**
* 域:用户ID:注单ID:失效时间
* 值:json,彩票ID,彩票名称,彩票期号,注单ID,注单状态,投注金额,奖金,玩法名称,通知类型
*/
public static final String USER_BETS_UNOPEN_RECENT_KEY = "USER:BETS:UNOPEN:RECENT:%s"; // 用户最近未结算彩票投注ID 用户ID
public static final String USER_BETS_OPENED_RECENT_KEY = "USER:BETS:OPENED:RECENT:%s"; // 用户最近已结算彩票投注ID 用户ID
private static final int USER_BETS_NOTICE_EXPIRE_HOURS = 20; // 20小时后失效
//region services
@Autowired
private UserBetsDao userBetsDao;
@Autowired
private UserDao userDao;
@Autowired
private UserBillService userBillService;
@Autowired
private UserBetsService userBetsService;
@Autowired
private UserLotteryReportService userLotteryReportService;
@Autowired
private UserLotteryDetailsReportService userLotteryDetailsReportService;
@Autowired
private DataFactory dataFactory;
@Autowired
private LotteryOpenCodeService lotteryOpenCodeService;
@Autowired
private UserBetsHitRankingService userBetsHitRankingService;
@Autowired
private UserHighPrizeService highPrizeService;
@Autowired
private UserBetsPointService userBetsPointService;
@Autowired
private MailJob mailJob;
@Autowired
private JedisTemplate jedisTemplate;
//endregion
//region 单挑、单期奖金限制
private static ConcurrentHashMap<String, Double> expectDantiaoPrize = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, Double> expectDantiaoUnCachePrize = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, Double> userExpectPrize = new ConcurrentHashMap<>();
//endregion
@Scheduled(cron = "0 0 6 * * *")
public void clearCache() {
expectDantiaoPrize.clear();
userExpectPrize.clear();
expectDantiaoUnCachePrize.clear();
}
@Override
public void settleUserBets(List<UserBets> userBetsList, LotteryOpenCode openCode, Lottery lottery) {
try {
// 结算注单
for (UserBets userBets : userBetsList) {
if (userBets.getTime().compareTo(openCode.getTime()) >= 0) {
// 如果投注时间大于抓取时间,不开奖
continue;
}
else {
try {
if(userBets.getType() == Global.USER_BETS_TYPE_CHASE
&& userBets.getChaseStop() == 1){
boolean cancelChase = userBetsService.isCancelChase(userBets.getChaseBillno());
if (!cancelChase) {
calculateUsersBets(userBets, openCode.getCode(), lottery);
}
}
else {
calculateUsersBets(userBets, openCode.getCode(), lottery);
}
} catch (Exception e) {
log.error("开奖发生错误", e);
}
}
}
// 更新开奖状态
lotteryOpenCodeService.updateOpened(openCode);
} catch (Exception e){
throw e;
}
}
/**
* 计算用户注单
*/
private void calculateUsersBets(UserBets userBets, String openCode, Lottery lottery){
long start = System.currentTimeMillis();
// 计算注单
Object[] results = testUsersBets(userBets, openCode, lottery, true);
long spend = System.currentTimeMillis() - start;
if (spend >= 500) {
String warningMsg = String.format("开奖耗时告警;计算注单耗时较多;计算注单%s时耗时达到%s", userBets.getId(), spend);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
if (results == null || results.length <= 0) {
return;
}
int winNum = (Integer) results[0];
double prize = (Double) results[1];
start = System.currentTimeMillis();
// 计算结果
calculateResult(lottery, userBets, openCode, prize, winNum);
spend = System.currentTimeMillis() - start;
if (spend >= 1000) {
String warningMsg = String.format("开奖耗时告警;处理注单耗时较多;处理注单%s时耗时达到%s", userBets.getId(), spend);
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
}
public double getWinMoneyByCode(WinResult result,UserBets userBets, int bUnitMoney,
String [] prizeCodes){
LotteryPlayRules rules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
String tempPrize = disposeDsPlayPrize(rules,prizeCodes,result.getWinCode());
double prize = 0;
if(!tempPrize.equals("")){
//单注奖金 * 中奖注数 * 倍数
prize = MathUtil.multiply(
MathUtil.multiply(PrizeUtils.getWinMoneyByCode(rules.getFixed(),
userBets.getModel(), bUnitMoney,
userBets.getCode(),Double.parseDouble(tempPrize)),
result.getWinNum()),
userBets.getMultiple());
}
return prize;
}
public LotteryPlayRules[] getZhWinLev(int winNum, Lottery lottery){
LotteryPlayRules zuheRules1 = dataFactory.getLotteryPlayRules(lottery.getId(), "dw");//一星奖金配置
if(zuheRules1 == null){
return null;
}
if(winNum == 1){
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1};
return res;
}
else if(winNum == 2){
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
"exzhixdsq");
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2};
return res;
}
else if(winNum == 3){
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
"exzhixdsq");
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
"sxzhixdsq");
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3};
return res;
}
else if(winNum == 4){
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
"exzhixdsq");
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
"sxzhixdsq");
LotteryPlayRules zuheRules4 = dataFactory.getLotteryPlayRules(lottery.getId(),
"sixzhixzhq");
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3,zuheRules4};
return res;
}
else if(winNum == 5){
LotteryPlayRules zuheRules2 = dataFactory.getLotteryPlayRules(lottery.getId(),
"exzhixdsq");
LotteryPlayRules zuheRules3 = dataFactory.getLotteryPlayRules(lottery.getId(),
"sxzhixdsq");
LotteryPlayRules zuheRules4 = dataFactory.getLotteryPlayRules(lottery.getId(),
"sixzhixzhq");
LotteryPlayRules zuheRules5 = dataFactory.getLotteryPlayRules(lottery.getId(),
"wxzhixzh");
LotteryPlayRules [] res = new LotteryPlayRules[]{zuheRules1,zuheRules2,zuheRules3,
zuheRules4,zuheRules5};
return res;
}
return null;
}
public String disposeDsPlayPrize(LotteryPlayRules rule,String [] codeArr,String winCode){
String [] pr = rule.getPrize().split(",");
String res = "";
for (int i = 0; i < pr.length; i++) {
String [] valuearr = codeArr[i].split(",");
for (int j = 0; j < valuearr.length; j++) {
if(valuearr[j].trim().equals(winCode.trim())){
res = pr[i];
}
}
}
return res;
}
public void calculateResult(Lottery lottery, UserBets userBets, String openCode, double prize, int winNum) {
userBets.setOpenCode(openCode);
String prizeTime = new Moment().toSimpleTime();
userBets.setPrizeTime(prizeTime);
boolean succeed = false;
if(winNum >0 && prize > 0){
userBets.setPrizeMoney(prize);
userBets.setStatus(Global.USER_BETS_STATUS_WIN);
// 生成赢账单并更新中奖报表
succeed = userBillService.addUserWinBill(userBets, prize, "派奖");
if (succeed) {
// 更新注单状态
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_WIN, openCode, prize, prizeTime);
// 修改用户金额并解冻金额
userDao.updateLotteryMoney(userBets.getUserId(), prize, -userBets.getMoney());
}
}else{
userBets.setPrizeMoney(0d);
// 更新注单状态
if (winNum > 0) {
userBets.setStatus(Global.USER_BETS_STATUS_WIN);
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_WIN, openCode, 0, prizeTime);
}
else {
userBets.setStatus(Global.USER_BETS_STATUS_OPENED);
userBetsDao.updateStatus(userBets.getId(), Global.USER_BETS_STATUS_OPENED, openCode, 0, prizeTime);
}
// 解冻金额
userDao.updateFreezeMoney(userBets.getUserId(), -userBets.getMoney());
succeed = true;
}
if (succeed == false) {
String warningMsg = "结算订单出错;ID:" + userBets.getId() + ",新增赢账单时错误";
log.error(warningMsg);
mailJob.addWarning(warningMsg);
return;
}
// 更新消费报表
String time = DateUtil.formatTime(userBets.getTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
userLotteryReportService.update(userBets.getUserId(), Global.BILL_TYPE_BILLING_ORDER, userBets.getMoney(), time);
userLotteryDetailsReportService.update(userBets.getUserId(), userBets.getLotteryId(), userBets.getRuleId(), Global.BILL_TYPE_BILLING_ORDER, userBets.getMoney(), time);
// 返点
userBetsPointService.add(userBets); // 异步进行
// 中奖停止撤单
if(winNum > 0){
if(userBets.getType() == Global.USER_BETS_TYPE_CHASE
&& userBets.getChaseStop() == 1){
userBetsService.cancelChase(userBets.getChaseBillno(), userBets.getUserId(), userBets.getExpect()); // 异步进行
}
}
try {
// 发送邮件通知
if (prize >= dataFactory.getMailConfig().getOpen()) {
userBets.setPrizeMoney(prize);
mailJob.sendOpen(userBets);
}
// 发送自主彩邮件通知
if (lottery.getSelf() == 1) {
if (prize >= 200) {
UserVO user = dataFactory.getUser(userBets.getUserId());
String username = user == null ? "未知" : user.getUsername();
mailJob.addWarning("用户"+username+"在自主彩"+lottery.getShowName()+"第"+userBets.getExpect()+"中奖" + prize + "元");
}
}
}
catch (Exception e) {
log.error("发送邮件告警错误", e);
}
// // 删除用户奖金设置
// delCurrentPrize(userBets);
try {
// 新增中奖排行榜
if (dataFactory.getLotteryConfig().isAutoHitRanking()) {
userBetsHitRankingService.addIfNecessary(userBets);
}
// 通知用户
notifyUser(userBets);
// 移除未结算订单ID,设置已结算订单ID
cacheUserBetsId(userBets);
// 尝试添加大额中奖记录
highPrizeService.addIfNecessary(userBets);
} catch (Exception e) {
log.error("添加中奖通知信息时异常", e);
}
}
private void cacheUserBetsId(UserBets userBets) {
final String unOpenCacheKey = String.format(USER_BETS_UNOPEN_RECENT_KEY, userBets.getUserId());
final String openedCacheKey = String.format(USER_BETS_OPENED_RECENT_KEY, userBets.getUserId());
final String userBetsId = userBets.getId() + "";
try {
jedisTemplate.execute(new JedisTemplate.PipelineActionNoResult() {
@Override
public void action(Pipeline pipeline) {
pipeline.lrem(unOpenCacheKey, 1, userBetsId); // 移除未结算订单ID
pipeline.lpush(openedCacheKey, userBetsId); // 设置已结算订单ID
pipeline.ltrim(openedCacheKey, 0, 10); // 最多设置10条
pipeline.expire(openedCacheKey, 60 * 60 * 12); // 12小时过期
pipeline.sync();
}
});
} catch (JedisException e) {
log.error("执行Redis缓存注单ID时出错", e);
}
}
private void notifyUser(UserBets userBets) {
// 域:用户ID:注单ID:失效时间
// 值:json,彩票ID,彩票名称,彩票期号,注单ID,注单状态,投注金额,奖金,玩法名称,通知类型
long expireAt = new Moment().add(USER_BETS_NOTICE_EXPIRE_HOURS, "hours").toDate().getTime(); // 20小时后失效
Lottery lottery = dataFactory.getLottery(userBets.getLotteryId());
String field = userBets.getUserId() + ":" + userBets.getId() + ":" + expireAt; // 用户ID:注单ID:过期时间
Map<String, Object> value = new HashMap<>();
value.put("lotteryId", lottery.getId()); // 彩票ID
value.put("lottery", lottery.getShowName()); // 彩票名称
value.put("expect", userBets.getExpect()); // 彩票期号
value.put("id", userBets.getId()); // 注单ID
value.put("status", userBets.getStatus()); // 注单状态
value.put("money", userBets.getMoney()); // 投注金额
value.put("prizeMoney", userBets.getPrizeMoney()); // 奖金
String mname = "";
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
LotteryPlayRulesGroup group = dataFactory.getLotteryPlayRulesGroup(lottery.getId(), playRules.getGroupId());
if(playRules != null) {
mname = "[" + group.getName() + "_" + playRules.getName() + "]";
}
value.put("mname", mname); // 玩法名称
value.put("type", NoticeSendType.USER_BETS_NOTICE); // 彩票注单通知类型
jedisTemplate.hset(USER_BETS_NOTICE_KEY, field, JSON.toJSONString(value));
}
/**
* 计算该比投注会中多少钱
*/
public Object[] testUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cache){
LotteryConfig config = dataFactory.getLotteryConfig();
String codes = userBets.getCodes();
// 时时彩任三混合组选
LotteryPlayRules userBetsPlayRules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
if (lottery.getType() == 1 && userBetsPlayRules.getCode().equals("rx3hhzx")) {
return rx3hhzxTestUsersBets(userBets, openCode, lottery, cache);
}
// 获取玩法对应的处理类
ITicketPlayHandler handler = TicketPlayHandlerContext.getHandler(lottery.getType(), userBetsPlayRules.getCode());
if (handler == null) {
log.error("注单{}未找到对应的处理类", userBets.getId());
return null;
}
// 计算中奖结果
WinResult result = handler.calculateWinNum(userBets.getId(), codes, openCode);
/**
* 计算奖金需要注意的地方:
*时时彩:
*1、二星前、后 、大小单双玩法, 根据中奖注数计算中奖金额 ( prize * 注数) ----------
*3、不定位 前、中、三 一码不定 最多可中三注 ( prize * 注数) ----------
*4、所有任选玩法 根据中奖注数计算中奖金额 ( prize * 注数) ----------
*5、三星 混合组选在计算奖金的时候需要根据返回的对象玩法ID(playId)判断金额 -----------
*6、四、五星组合玩法 需要根据中奖注数 来判断中奖金额 (中奖注数等几星中奖) 1/2/3/4/5 中奖数字 = 对应的金额 --------
*7、定位胆 = ( prize * 注数) ----------
*11X5:
* 1、前三/前二“组选单式” 因为投注时没有去重判断,所有在中奖时需要计算注数 ----------
* 2、不 定位玩法中奖需要计算注数 ---------
* 3、定 位胆玩法中奖需要计算注数 ----------
* 4、 趣味猜中位中奖需要根据中奖号码计算奖金:winCode:为0不需要处理,----------
* 3和9 =?奖金,4和8 =?奖金,5和7=?奖金,6 =?奖金 返回03 or 09 ……
* 5、 趣味定单双中奖需要根据中奖号码计算奖金:winCode:为0不需要处理,-----------
* 5单0双 = ?奖金,4单1双 =?奖金 …… 返回 5单0双,4单1双……
* 6、任选单式、复式 X中X 都需要根据中奖注数计算奖金 -----------
*
*福彩3D、排列3:
*1、 前三混合组选 需要根据玩法ID(playId)判断奖金 ------------
*2、定位胆需要根据中奖注数计算奖金 ----------
*3、不定位需要根据中奖注数计算奖金 -----------
*
*PK10:
*1、定位胆需要根据中奖注数来计算奖金 ------------
*
*K3:
*1、二不同号标准选号计算 “单注奖金 乘以中奖注数” --------
*2、二不同号手动选号计算 “单注奖金 乘以中奖注数”(投注时没有去不同位置重复号) ---------
*3、二不同号 胆拖计算 “单注奖金 乘以中奖注数” -----------
*4、二同号手动选号 “单注奖金 乘以中奖注数” -----------
*5、快3和值 和值为3或18一等奖;4或17二等奖;5或16三等奖;6或15四等奖;7或14五等奖;8或13六等奖;9或12七等奖;10或11八等奖 ----
*
*kl8:
* 1、趣味和值大小玩法 根据中奖号码来判断奖金
* 2、趣味 奇偶盘玩法 根据中奖号码来判断奖金
* 3、趣味 上下盘 根据中奖号码来判断奖金
* 4、五行玩法 根据中奖号码来判断奖金
*/
int winNum = 0;
double prize = 0;
if(result != null && (result.getWinNum() >0 || CollectionUtils.isNotEmpty(result.getMultipleResults()))){
switch (result.getPlayId()) {
case "1_wxzhixzh": case "1_sixzhixzhh": case "1_sixzhixzhq": // 时时彩 四/五星 组合
LotteryPlayRules[] levNum = getZhWinLev(result.getWinNum(),lottery);
double zhprize = 0;
for (int i = 0; i < levNum.length; i++) {
zhprize += PrizeUtils.getBetWinMoney(levNum[i],userBets.getModel(),
config.getbUnitMoney(),userBets.getCode());
}
//单注奖金 * 倍数
prize = MathUtil.multiply(zhprize, userBets.getMultiple());
//赋值状态
winNum = result.getWinNum();
break;
case "1_sxzuxzsh":case "1_sxzuxzlh":case "1_sxzuxzsz":
case "1_sxzuxzlz":case "1_sxzuxzsq":case "1_sxzuxzlq": // 时时彩混合组选
case "4_sanxzs":case "4_sanxzl": // 3D 混合组选
case "1_sxzuxhzh":case "1_sxzuxhzz":case "1_sxzuxhzq":
String playId = result.getPlayId().substring(result.getPlayId().indexOf("_")+1,
result.getPlayId().length());
LotteryPlayRules rulezx = dataFactory.getLotteryPlayRules(lottery.getId(),playId);
double prizehh = PrizeUtils.getMoney(rulezx, userBets.getModel(), config.getbUnitMoney(), userBets.getCode());
//单注奖金 * 中奖注数 * 倍数
prize = MathUtil.multiply(MathUtil.multiply(prizehh,result.getWinNum()),
userBets.getMultiple());
//赋值状态
winNum = result.getWinNum();
break;
case "1_longhuhewq": case "1_longhuhewb": case "1_longhuhews": case "1_longhuhewg": // 时时彩龙虎和
case "1_longhuheqb": case "1_longhuheqs": case "1_longhuheqg":
case "1_longhuhebs": case "1_longhuhebg":
case "1_longhuhesg":
case "7_lhd_longhuhewq": case "7_lhd_longhuhewb": case "7_lhd_longhuhews": case "7_lhd_longhuhewg": // 龙虎斗
case "7_lhd_longhuheqb": case "7_lhd_longhuheqs": case "7_lhd_longhuheqg":
case "7_lhd_longhuhebs": case "7_lhd_longhuhebg":
case "7_lhd_longhuhesg":
winNum = result.getWinNum();
LotteryPlayRules rule = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
String calPrize = rule.getPrize().split(",")[result.getPrizeIndex()];
LotteryPlayRules calRule = new LotteryPlayRules();
calRule.setFixed(rule.getFixed());
calRule.setPrize(calPrize);
double prizelh = PrizeUtils.getBetWinMoney(calRule, userBets.getModel(),
config.getbUnitMoney(), userBets.getCode());
//单注奖金 * 中奖注数 * 倍数
prize = MathUtil.multiply(MathUtil.multiply(prizelh,result.getWinNum()),
userBets.getMultiple());
break;
case "2_dds": //11x5 定单双
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.dds11x5);
break;
case "2_czw": //11X5猜中位
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.czw11x5);
break;
case "3_hezhi":// 快3和值
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.k3hezhi);
break;
case "5_hezhidx": //快乐8 和值大小
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.kl8hezhidx);
break;
case "5_jopan": //快乐8 和值 奇偶
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.kl8jopan);
break;
case "5_sxpan": //快乐8 和值 上下
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.kl8sxpan);
break;
case "5_hezhiwx": //快乐8 和值 五行
winNum = result.getWinNum();
prize = getWinMoneyByCode(result,userBets,config.getbUnitMoney(),
HConstants.playPrize.kl8wx);
break;
case "6_pk10_dxdsgyhz":// PK10 大小单双冠亚和值
case "6_pk10_hzgyhz":// PK10 和值冠亚和值
case "6_pk10_hzqshz":// PK10 和值前三和值
if (CollectionUtils.isNotEmpty(result.getMultipleResults())) {
winNum = result.getWinNum();
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
String[] prizeArr = ruleDefault.getPrize().split(",");
double[] prizeArrDouble = new double[prizeArr.length];
for (int i = 0; i < prizeArr.length; i++) {
prizeArrDouble[i] = Double.valueOf(prizeArr[i]);
}
List<MultipleResult> multipleResults = result.getMultipleResults();
for (MultipleResult multipleResult : multipleResults) {
if (multipleResult.getNums() > 0) {
// 赔率
double odds = prizeArrDouble[multipleResult.getOddsIndex()];
// 赔率金额
double multiplePrize = PrizeUtils.getPrize(ruleDefault.getFixed(), userBets.getModel(), config.getbUnitMoney(), userBets.getCode(), odds);
//单注奖金 * 中奖注数 * 倍数
multiplePrize = MathUtil.multiply(MathUtil.multiply(multiplePrize, multipleResult.getNums()),userBets.getMultiple());
prize += multiplePrize;
}
}
}
break;
default:
if (CollectionUtils.isNotEmpty(result.getMultipleResults())) {
winNum = result.getWinNum();
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
String[] prizeArr = ruleDefault.getPrize().split(",");
double[] prizeArrDouble = new double[prizeArr.length];
for (int i = 0; i < prizeArr.length; i++) {
prizeArrDouble[i] = Double.valueOf(prizeArr[i]);
}
List<MultipleResult> multipleResults = result.getMultipleResults();
for (MultipleResult multipleResult : multipleResults) {
if (multipleResult.getNums() > 0) {
// 赔率
double odds = prizeArrDouble[multipleResult.getOddsIndex()];
// 赔率金额
double multiplePrize = PrizeUtils.getPrize(ruleDefault.getFixed(), userBets.getModel(), config.getbUnitMoney(), userBets.getCode(), odds);
//单注奖金 * 中奖注数 * 倍数
multiplePrize = MathUtil.multiply(MathUtil.multiply(multiplePrize, multipleResult.getNums()),userBets.getMultiple());
prize += multiplePrize;
}
}
}
else {
LotteryPlayRules ruleDefault = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
double prizedefailt = PrizeUtils.getBetWinMoney(ruleDefault, userBets.getModel(), config.getbUnitMoney(), userBets.getCode());
//单注奖金 * 中奖注数 * 倍数
prize = MathUtil.multiply(MathUtil.multiply(prizedefailt,result.getWinNum()), userBets.getMultiple());
//赋值状态
winNum = result.getWinNum();
}
break;
}
}
if (winNum > 0 && prize > 0) {
// 判定是否单挑模式
prize = assertDantiao(lottery, userBets, prize, cache);
// 判断是否已经超出本期奖金
prize = assertExpectPrize(lottery, userBets, prize, cache);
}
return new Object[]{winNum, prize};
}
/**
* 时时彩任三混合组选
*/
public Object[] rx3hhzxTestUsersBets(UserBets userBets, String openCode, Lottery lottery, boolean cache) {
LotteryConfig config = dataFactory.getLotteryConfig();
String codes = userBets.getCodes();
SSCRX3HHZXPlayHanlder hanlder = new SSCRX3HHZXPlayHanlder();
List<WinResult> results = hanlder.calculateWinNum(userBets.getId(), codes, openCode);
if (results == null || results.size() <= 0) {
return new Object[]{0, 0.0};
}
else {
double totalPrize = 0;
for (WinResult winResult : results) {
LotteryPlayRules rule = dataFactory.getLotteryPlayRules(lottery.getId(), winResult.getPlayId());
double rulePrize = PrizeUtils.getBetWinMoney(rule, userBets.getModel(), config.getbUnitMoney(),userBets.getCode());
// 乘注数
totalPrize += MathUtil.multiply(rulePrize, winResult.getWinNum());
}
//单注奖金 * 倍数
totalPrize = MathUtil.multiply(totalPrize, userBets.getMultiple());
// 判定是否单挑模式
totalPrize = assertDantiao(lottery, userBets, totalPrize, cache);
// 判断是否已经超出本期奖金
totalPrize = assertExpectPrize(lottery, userBets, totalPrize, cache);
return new Object[]{1, totalPrize};
}
}
/**
* 判断单挑
* 单期同用户多注单共享额度
*/
private double assertDantiao(Lottery lottery, UserBets userBets, double prize, boolean cacheDantiao) {
// 判断单挑
double finalPrize = prize;
if (lottery.getDantiaoMaxPrize() > 0) {
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(lottery.getId(), userBets.getRuleId());
if (StringUtils.isNotEmpty(playRules.getDantiao())) {
int dantiaoNum = getDantiaoNum(userBets, playRules);
if (dantiaoNum > 0 && userBets.getNums() <= dantiaoNum) {
// String expectKey = userBets.getLotteryId() + "_" + userBets.getExpect();
String expectKey = userBets.getLotteryId() + "_" + userBets.getExpect() + "_" + userBets.getUserId();
Double beforeTotalPrize = cacheDantiao ? expectDantiaoPrize.get(expectKey) : expectDantiaoUnCachePrize.get(expectKey); // 当期的累计单挑总奖金
if (beforeTotalPrize == null) beforeTotalPrize = 0d;
if (beforeTotalPrize >= lottery.getDantiaoMaxPrize()) {
finalPrize = 0;
}
else {
double expectPrize = beforeTotalPrize + prize;
if (expectPrize > lottery.getDantiaoMaxPrize()) {
finalPrize = MathUtil.subtract(lottery.getDantiaoMaxPrize(), beforeTotalPrize);
if (finalPrize < 0) {
finalPrize = 0;
}
}
if (cacheDantiao) {
expectDantiaoPrize.put(expectKey, (beforeTotalPrize + finalPrize));
}
else {
expectDantiaoUnCachePrize.put(expectKey, (beforeTotalPrize + finalPrize));
}
}
}
}
}
if (cacheDantiao && prize != finalPrize) {
String warningMsg = lottery.getShowName() + "第" + userBets.getExpect() + ",用户注单" + userBets.getBillno() + "派奖时属于单挑模式,原奖金:" + prize + ",清除后奖金:" + finalPrize;
log.warn(warningMsg);
mailJob.addWarning(warningMsg);
}
return finalPrize;
}
private int getDantiaoNum(UserBets userBets, LotteryPlayRules playRules) {
if (playRules.getTypeId() != 1) {
return Integer.valueOf(playRules.getDantiao());
}
int totalPosition = getSSCBetTotalPosition(userBets);
int minPosition;
switch (playRules.getCode()) {
case "rx2fs":
case "rx2ds":
case "rx2zx":
minPosition = 2;
break;
case "rx3fs":
case "rx3ds":
case "rx3z3":
case "rx3z6":
case "rx3hhzx":
minPosition = 3;
break;
case "rx4fs":
case "rx4ds":
minPosition = 4;
break;
// 时时彩中龙虎和玩法投注和号码就算单挑,不论注数
case "longhuhewq":
case "longhuhewb":
case "longhuhews":
case "longhuhewg":
case "longhuheqb":
case "longhuheqs":
case "longhuheqg":
case "longhuhebs":
case "longhuhebg":
case "longhuhesg":
if (userBets.getCodes().contains("和")) {
return Integer.valueOf(playRules.getDantiao());
}
else {
return 0;
}
// 时时彩中牛牛玩法投注“五条”、“炸弹”、“葫芦”号码就算单挑,不论注数
case "sscniuniu":
if (userBets.getCodes().contains("五条")) {
return Integer.valueOf(playRules.getDantiao().split(",")[0]);
}
else if (userBets.getCodes().contains("炸弹")) {
return Integer.valueOf(playRules.getDantiao().split(",")[1]);
}
else if (userBets.getCodes().contains("葫芦")) {
return Integer.valueOf(playRules.getDantiao().split(",")[2]);
}
else {
return 0;
}
default:
return Integer.valueOf(playRules.getDantiao());
}
if (minPosition > totalPosition) {
log.error("玩法{}配置错误,单挑规则配置错误[{}]", playRules.getName(), playRules.getDantiao());
return 0;
}
String[] dantiaoNums = playRules.getDantiao().split(",");
return Integer.valueOf(dantiaoNums[totalPosition - minPosition]);
}
private int getSSCBetTotalPosition(UserBets userBets) {
LotteryPlayRules playRules = dataFactory.getLotteryPlayRules(userBets.getLotteryId(), userBets.getRuleId());
int totalPosition = 0;
String[] codes;
String format;
switch (playRules.getCode()) {
case "rx2fs":
case "rx3fs":
case "rx4fs":
codes = userBets.getCodes().split(",");
for (String code : codes) {
if (NumberUtils.isDigits(code)) {
totalPosition++;
}
}
return totalPosition;
case "rx2ds":
case "rx3ds":
case "rx4ds":
case "rx3z3":
case "rx3z6":
case "rx3hhzx":
case "rx2zx":
format = StringUtil.substring(userBets.getCodes(), "[", "]", false);
return StringUtils.countMatches(format, "√");
default:
return 0;
}
}
/**
* 判断用户当期奖金是否超额,超出则清零,cacheExpect如果为false,则此处逻辑无效,直接返回参数prize
* 单期同用户多注单共享额度
*/
private double assertExpectPrize(Lottery lottery, UserBets userBets, double prize, boolean cachePrize) {
if (cachePrize == false || lottery.getExpectMaxPrize() <= 0) {
return prize;
}
String prizeKey = userBets.getLotteryId() + "_" + userBets.getExpect() + "_" + userBets.getUserId();
Double beforeTotalPrize = userExpectPrize.get(prizeKey);
if (beforeTotalPrize == null) beforeTotalPrize = 0d;
double expectTotalPrize = beforeTotalPrize + prize;
double finalPrize = prize;
if (expectTotalPrize > lottery.getExpectMaxPrize()) {
finalPrize = MathUtil.subtract(lottery.getExpectMaxPrize(), beforeTotalPrize);
if (finalPrize < 0) {
finalPrize = 0;
}
}
if (prize != finalPrize) {
mailJob.sendExpectExceedPrize(userBets, prize, finalPrize);
}
userExpectPrize.put(prizeKey, (beforeTotalPrize + finalPrize));
return finalPrize;
}
}
@@ -0,0 +1,219 @@
package lottery.domains.content.biz.impl;
import javautils.date.Moment;
import lottery.domains.content.biz.UserBillService;
import lottery.domains.content.biz.UserLotteryDetailsReportService;
import lottery.domains.content.biz.UserLotteryReportService;
import lottery.domains.content.dao.UserBillDao;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.entity.User;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.entity.UserBill;
import lottery.domains.content.global.Global;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserBillServiceImpl implements UserBillService {
private static final Logger log = LoggerFactory.getLogger(UserBillServiceImpl.class);
//region services
@Autowired
private UserBillDao uBillDao;
@Autowired
private UserDao userDao;
@Autowired
private UserLotteryReportService uLotteryReportService;
@Autowired
private UserLotteryDetailsReportService uLotteryDetailsReportService;
//endregion
/**
* 生成订单号
*/
private String billno() {
return ObjectId.get().toString();
}
@Override
public boolean addCancelOrderBill(UserBets userBets, String remarks) {
boolean flag = false;
try {
User newestUser = userDao.getById(userBets.getUserId());
String billno = billno();
int userId = newestUser.getId();
int account = Global.BILL_ACCOUNT_LOTTERY;
int type = Global.BILL_TYPE_CANCEL_ORDER;
double money = userBets.getMoney();
double beforeMoney = newestUser.getLotteryMoney();
if (beforeMoney < 0) {
beforeMoney = 0;
}
double afterMoney = newestUser.getLotteryMoney() + money;
if (afterMoney < 0) {
afterMoney = 0;
}
Integer refType = type;
String refId = String.valueOf(userBets.getId());
Moment thisTime = new Moment();
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
flag = uBillDao.add(tmpBill);
// if(flag) {
// uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
// uLotteryDetailsReportService.update(userId, bBean.getLotteryId(), bBean.getMethod(), type, money, thisTime.toSimpleDate());
// }
} catch (Exception e) {
log.error("写入彩票撤单失败!", e);
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
}
return flag;
}
@Override
public boolean addUserWinBill(UserBets userBets, double amount, String remarks) {
boolean flag = false;
try {
User newestUser = userDao.getById(userBets.getUserId());
String billno = billno();
int userId = newestUser.getId();
int type = Global.BILL_TYPE_PRIZE;
int refType = type;
int account = Global.BILL_ACCOUNT_LOTTERY;
String refId = String.valueOf(userBets.getId());
double money = amount;
double beforeMoney = newestUser.getLotteryMoney();
if (beforeMoney < 0) {
beforeMoney = 0;
}
double afterMoney = newestUser.getLotteryMoney() + money;
if (afterMoney < 0) {
afterMoney = 0;
}
Moment thisTime = new Moment();
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
flag = uBillDao.add(tmpBill);
if(flag) {
// Moment betTime = new Moment().fromTime(userBets.getTime()); // 报表计算到投注时间那边
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
}
} catch (Exception e) {
log.error("写入账单失败!", e);
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
}
return flag;
}
@Override
public boolean addProxyReturnBill(UserBets userBets, int upId, double amount, String remarks) {
boolean flag = false;
try {
User newestUser = userDao.getById(upId);
String billno = billno();
int userId = newestUser.getId();
int type = Global.BILL_TYPE_PROXY_RETURN;
int refType = type;
int account = Global.BILL_ACCOUNT_LOTTERY;
String refId = String.valueOf(userBets.getId());
double money = amount;
double beforeMoney = newestUser.getLotteryMoney();
if (beforeMoney < 0) {
beforeMoney = 0;
}
double afterMoney = newestUser.getLotteryMoney() + money;
if (afterMoney < 0) {
afterMoney = 0;
}
Moment thisTime = new Moment();
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
flag = uBillDao.add(tmpBill);
if(flag) {
// Moment betTime = new Moment().fromTime(userBets.getTime()); // 报表计算到投注时间那边
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
}
} catch (Exception e) {
log.error("写入账单失败!", e);
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
}
return flag;
}
@Override
public boolean addSpendReturnBill(UserBets userBets, double amount, String remarks) {
boolean flag = false;
try {
User newestUser = userDao.getById(userBets.getUserId());
String billno = billno();
int userId = newestUser.getId();
int type = Global.BILL_TYPE_SPEND_RETURN;
int refType = type;
int account = Global.BILL_ACCOUNT_LOTTERY;
String refId = String.valueOf(userBets.getId());
double money = amount;
double beforeMoney = newestUser.getLotteryMoney();
if (beforeMoney < 0) {
beforeMoney = 0;
}
double afterMoney = newestUser.getLotteryMoney() + money;
if (afterMoney < 0) {
afterMoney = 0;
}
Moment thisTime = new Moment();
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
flag = uBillDao.add(tmpBill);
if(flag) {
uLotteryReportService.update(userId, type, money, thisTime.toSimpleDate());
uLotteryDetailsReportService.update(userId, userBets.getLotteryId(), userBets.getRuleId(), type, amount, thisTime.toSimpleDate());
}
} catch (Exception e) {
log.error("写入账单失败!", e);
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
}
return flag;
}
@Override
public boolean addSpendBill(UserBets bBean) {
boolean flag = false;
try {
User newestUser = userDao.getById(bBean.getUserId());
String billno = billno();
int userId = newestUser.getId();
int account = Global.BILL_ACCOUNT_LOTTERY;
int type = Global.BILL_TYPE_SPEND;
double money = bBean.getMoney();
double beforeMoney = newestUser.getLotteryMoney() + money;
double afterMoney = newestUser.getLotteryMoney();
if (beforeMoney <= 0) {
beforeMoney = 0;
}
if (afterMoney <= 0) {
afterMoney = 0;
}
Integer refType = type;
String refId = String.valueOf(bBean.getId());
Moment thisTime = new Moment();
String remarks = "用户投注:" + bBean.getExpect();
UserBill tmpBill = new UserBill(billno, userId, account, type, money, beforeMoney, afterMoney, refType, refId, thisTime.toSimpleTime(), remarks);
flag = uBillDao.add(tmpBill);
if(flag) {
uLotteryDetailsReportService.update(userId, bBean.getLotteryId(), bBean.getRuleId(), type, money, thisTime.toSimpleDate());
}
} catch (Exception e) {
log.error("写入彩票消费失败!", e);
throw e;//在嵌套事物中必须抛出 不然无法触发roll-back
}
return flag;
}
}
@@ -0,0 +1,187 @@
package lottery.domains.content.biz.impl;
import com.alibaba.fastjson.JSON;
import javautils.math.MathUtil;
import javautils.redis.JedisTemplate;
import lottery.domains.content.biz.UserHighPrizeService;
import lottery.domains.content.dao.UserDao;
import lottery.domains.content.dao.UserHighPrizeDao;
import lottery.domains.content.entity.Lottery;
import lottery.domains.content.entity.User;
import lottery.domains.content.entity.UserBets;
import lottery.domains.content.entity.UserHighPrize;
import lottery.domains.pool.DataFactory;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
/**
* Created by Nick on 2017/3/13.
*/
@Service
public class UserHighPrizeServiceImpl implements UserHighPrizeService {
private static final Logger log = LoggerFactory.getLogger(UserHighPrizeServiceImpl.class);
private static final String USER_HIGH_PRIZE_NOTICE_KEY = "USER:HIGH_PRIZE:NOTICE";
private BlockingQueue<UserBets> userBetsQueue = new LinkedBlockingDeque<>();
@Autowired
private UserHighPrizeDao highTimesDao;
@Autowired
private JedisTemplate jedisTemplate;
@Autowired
private DataFactory dataFactory;
@Autowired
private UserDao uDao;
private static boolean isRunning = false;
@Scheduled(cron = "0/3 * * * * *")
public void run() {
synchronized (UserHighPrizeServiceImpl.class) {
if (isRunning == true) {
// 任务正在运行,本次中断
return;
}
isRunning = true;
}
try {
add();
} finally {
isRunning = false;
}
}
private void add() {
if(userBetsQueue != null && userBetsQueue.size() > 0) {
try {
List<UserBets> adds = new LinkedList<>();
userBetsQueue.drainTo(adds, 50);
if (CollectionUtils.isNotEmpty(adds)) {
add(adds);
}
} catch (Exception e) {
log.error("添加用户大额中奖失败", e);
}
}
}
private void add(List<UserBets> adds) {
Map<Integer, User> userMap = new HashMap<>();
for (UserBets add : adds) {
Lottery lottery = dataFactory.getLottery(add.getLotteryId());
if (lottery == null) {
continue;
}
User user = null;
if (userMap.containsKey(add.getUserId())) {
user = userMap.get(add.getUserId());
}
if (user == null) {
user = uDao.getById(add.getUserId());
}
if (user == null) {
continue;
}
UserHighPrize highTimes = convert(add, lottery, user);
// 加到数据库
highTimesDao.add(highTimes);
// // 加到redis提醒 暂时取消使用,把这句注释取消,再在global.js里把registerWebSocket()取消注释就可以启用了
// addToRedis(highTimes, user);
}
}
private UserHighPrize convert(UserBets userBets, Lottery lottery, User user) {
UserHighPrize highPrize = new UserHighPrize();
highPrize.setUserId(user.getId());
highPrize.setPlatform(2); // 类型;2:彩票;11:PT;4:AG
highPrize.setName(lottery.getShowName());
highPrize.setNameId(lottery.getId()+"");
highPrize.setSubName(userBets.getExpect());
highPrize.setRefId(userBets.getId()+"");
highPrize.setMoney(userBets.getMoney());
highPrize.setPrizeMoney(userBets.getPrizeMoney());
double times = userBets.getPrizeMoney() / userBets.getMoney();
times = MathUtil.doubleFormat(times, 3);
highPrize.setTimes(times);
highPrize.setTime(userBets.getPrizeTime());
highPrize.setStatus(0); // 状态;0:待确认;1:已锁定;2:已确认
return highPrize;
}
private void addToRedis(UserHighPrize highPrize, User user) {
// 域:数据ID
// 值:描述语言
String field = highPrize.getId()+""; // 数据ID
Map<String, Object> value = new HashMap<>();
value.put("platform", highPrize.getPlatform()); // 类型;2:彩票;11:PT;4:AG
value.put("username", user.getUsername()); // 用户名
value.put("name", highPrize.getName()); // 游戏名称
value.put("subName", highPrize.getSubName()); // 期号或桌号等
value.put("refId", highPrize.getRefId()); // 游戏记录ID,可以是user_bets的id也可能是game_bets的id
value.put("money", highPrize.getMoney()); // 投注金额
value.put("prizeMoney", highPrize.getPrizeMoney()); // 奖金
value.put("times", highPrize.getTimes()); // 倍数
value.put("type", 1); // 1:大额中奖提醒
// String money = BigDecimal.valueOf(highPrize.getMoney()).setScale(4, BigDecimal.ROUND_HALF_DOWN).toString();
// String prizeMoney = BigDecimal.valueOf(highPrize.getPrizeMoney()).setScale(5, BigDecimal.ROUND_HALF_DOWN).toString();
// if (highPrize.getTimes() >= 3) {
// value = "用户%s在%s投注¥%s元中奖¥%s元,奖金倍数:%s,请在<大额中奖查询>中确认";
// value = String.format(value, user.getUsername(), highPrize.getName(), money, prizeMoney, highPrize.getTimes());
// }
// else {
// value = "用户%s在%s投注¥%s元中奖¥%s元,请在<大额中奖查询>中确认";
// value = String.format(value, user.getUsername(), highPrize.getName(), money, prizeMoney);
// }
jedisTemplate.hset(USER_HIGH_PRIZE_NOTICE_KEY, field, JSON.toJSONString(value));
}
@Override
public void addIfNecessary(UserBets userBets) {
if (userBets.getPrizeMoney() <= 0) {
return;
}
if (userBets.getPrizeMoney() <= 100 && userBets.getMoney() <= 100) {
return;
}
// 奖金大于1万,倍数高于5倍
double times = userBets.getPrizeMoney() / userBets.getMoney();
if (userBets.getPrizeMoney() >= 10000 || times >= 5.0) {
userBetsQueue.offer(userBets);
}
}
public static void main(String[] args) {
String value = "用户%s在%s%s投注¥%s元中奖¥%s元,请在<大额中奖查询>中确认";
value = String.format(value, "aaa", "aaa", "aaa", "100", "200");
System.out.println(value);
}
}
@@ -0,0 +1,62 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.UserLotteryDetailsReportService;
import lottery.domains.content.dao.UserLotteryDetailsReportDao;
import lottery.domains.content.entity.UserLotteryDetailsReport;
import lottery.domains.content.global.Global;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserLotteryDetailsReportServiceImpl implements UserLotteryDetailsReportService {
@Autowired
private UserLotteryDetailsReportDao uLotteryDetailsReportDao;
@Override
public void addDetailsReports(List<UserLotteryDetailsReport> detailsReports) {
uLotteryDetailsReportDao.addDetailsReports(detailsReports);
}
@Override
public boolean update(int userId, int lotteryId, int ruleId, int type, double amount,
String time) {
UserLotteryDetailsReport entity = new UserLotteryDetailsReport();
switch (type) {
case Global.BILL_TYPE_SPEND:
entity.setSpend(amount);
break;
case Global.BILL_TYPE_PRIZE:
entity.setPrize(amount);
break;
case Global.BILL_TYPE_SPEND_RETURN:
entity.setSpendReturn(amount);
break;
case Global.BILL_TYPE_PROXY_RETURN:
entity.setProxyReturn(amount);
break;
case Global.BILL_TYPE_CANCEL_ORDER:
entity.setCancelOrder(amount);
break;
case Global.BILL_TYPE_BILLING_ORDER:
entity.setBillingOrder(amount);
break;
default:
return false;
}
UserLotteryDetailsReport bean = uLotteryDetailsReportDao.get(userId, lotteryId, ruleId, time);
if(bean != null) {
entity.setId(bean.getId());
return uLotteryDetailsReportDao.update(entity);
} else {
entity.setUserId(userId);
entity.setLotteryId(lotteryId);
entity.setRuleId(ruleId);
entity.setTime(time);
return uLotteryDetailsReportDao.add(entity);
}
}
}
@@ -0,0 +1,70 @@
package lottery.domains.content.biz.impl;
import lottery.domains.content.biz.UserLotteryReportService;
import lottery.domains.content.dao.UserLotteryReportDao;
import lottery.domains.content.entity.UserLotteryReport;
import lottery.domains.content.global.Global;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class UserLotteryReportServiceImpl implements UserLotteryReportService {
@Autowired
private UserLotteryReportDao uLotteryReportDao;
@Override
public boolean update(int userId, int type, double amount, String time) {
UserLotteryReport entity = new UserLotteryReport();
switch (type) {
case Global.BILL_TYPE_TRANS_IN:
entity.setTransIn(amount);
break;
case Global.BILL_TYPE_TRANS_OUT:
entity.setTransOut(amount);
break;
case Global.BILL_TYPE_SPEND:
entity.setSpend(amount);
break;
case Global.BILL_TYPE_PRIZE:
entity.setPrize(amount);
break;
case Global.BILL_TYPE_SPEND_RETURN:
entity.setSpendReturn(amount);
break;
case Global.BILL_TYPE_PROXY_RETURN:
entity.setProxyReturn(amount);
break;
case Global.BILL_TYPE_CANCEL_ORDER:
entity.setCancelOrder(amount);
break;
case Global.BILL_TYPE_DIVIDEND:
entity.setDividend(amount);
break;
case Global.BILL_TYPE_ACTIVITY:
case Global.BILL_TYPE_INTEGRAL:
entity.setActivity(amount);
break;
case Global.BILL_TYPE_RED_PACKET:
entity.setPacket(amount);
break;
case Global.BILL_TYPE_BILLING_ORDER:
entity.setBillingOrder(amount);
break;
default:
return false;
}
UserLotteryReport bean = uLotteryReportDao.get(userId, time);
if(bean != null) {
entity.setId(bean.getId());
return uLotteryReportDao.update(entity);
} else {
entity.setUserId(userId);
entity.setTime(time);
return uLotteryReportDao.add(entity);
}
}
}
@@ -0,0 +1,14 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.DbServerSync;
import lottery.domains.content.global.DbServerSyncEnum;
import java.util.List;
public interface DbServerSyncDao {
List<DbServerSync> listAll();
boolean update(DbServerSyncEnum type);
}
@@ -0,0 +1,12 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.Lottery;
import java.util.List;
public interface LotteryDao {
List<Lottery> listAll();
boolean updateStatus(int id, int status);
}
@@ -0,0 +1,36 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryOpenCode;
import java.util.List;
public interface LotteryOpenCodeDao {
/**
* 修改为已开奖
*/
boolean updateOpened(int id, String updateTime);
/**
* 修改为无效已撤单
*/
boolean updateCancelled(int id, String updateTime);
List<LotteryOpenCode> getLatest(String lottery, int count);
List<LotteryOpenCode> listAfter(String lottery, String expect);
/**
* 获取往期未开奖的期数
*/
List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count);
LotteryOpenCode getByExcept(String lottery, String except);
/**
* 根据彩票ID和期号以及用户获取开奖号码
*/
LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except);
boolean add(LotteryOpenCode openCode);
boolean update(LotteryOpenCode openCode);
}
@@ -0,0 +1,16 @@
package lottery.domains.content.dao;
import javautils.jdbc.PageList;
import lottery.domains.content.entity.LotteryOpenTime;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import java.util.List;
public interface LotteryOpenTimeDao {
List<LotteryOpenTime> listAll();
PageList find(List<Criterion> criterions, List<Order> orders, int start, int limit);
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryPlayRulesConfig;
import java.util.List;
public interface LotteryPlayRulesConfigDao {
List<LotteryPlayRulesConfig> listAll();
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryPlayRules;
import java.util.List;
public interface LotteryPlayRulesDao {
List<LotteryPlayRules> listAll();
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
import java.util.List;
public interface LotteryPlayRulesGroupConfigDao {
List<LotteryPlayRulesGroupConfig> listAll();
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryPlayRulesGroup;
import java.util.List;
public interface LotteryPlayRulesGroupDao {
List<LotteryPlayRulesGroup> listAll();
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.LotteryType;
import java.util.List;
public interface LotteryTypeDao {
List<LotteryType> listAll();
}
@@ -0,0 +1,11 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.SysConfig;
import java.util.List;
public interface SysConfigDao {
List<SysConfig> listAll();
}
@@ -0,0 +1,44 @@
package lottery.domains.content.dao;
import javautils.jdbc.PageList;
import lottery.domains.content.entity.UserBets;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import java.util.List;
public interface UserBetsDao {
boolean add(UserBets userBets);
UserBets getById(int id);
UserBets getById(int id, int userId);
List<UserBets> getByChaseBillno(String chaseBillno, int userId, String winExpect);
List<UserBets> getByFollowBillno(String followBillno);
boolean updateToPlan(int id, int type, String planBillno);
List<UserBets> list(List<Criterion> criterions, List<Order> orders);
PageList search(List<Criterion> criterions, List<Order> orders, int start, int limit);
boolean updateStatus(int id, int status, String openCode, double prizeMoney, String prizeTime);
boolean cancel(int id);
boolean cancelAndSetOpenCode(int id, String openCode);
List<?> sumUserProfitGroupByUserId(int lotteryId, String startTime, String endTime, List<Integer> userIds);
double[] sumProfit(int lotteryId, String startTime, String endTime);
List<UserBets> getLatest(int userId, int lotteryId, int count);
List<UserBets> getByExpect(int lotteryId, String expect);
List<UserBets> getByUserIdAndExpect(int userId, int lotteryId, String expect);
List<UserBets> getNoDemoUserBetsByExpect(String hsql ,Object[] values);
}
@@ -0,0 +1,25 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserBetsHitRanking;
import java.util.List;
public interface UserBetsHitRankingDao {
long getTotalSize(int platform);
UserBetsHitRanking getMinRanking(int platform, String startTime, String endTime);
boolean add(UserBetsHitRanking ranking);
List<Integer> getIds(int platform, String startTime, String endTime);
List<Integer> getTotalIds(int count, int platform, String startTime, String endTime);
List<Integer> getIdsByTimeDesc(int count, int platform);
int delNotInIds(List<Integer> ids, int platform);
boolean delNotInIds(List<Integer> ids, int platform, String startTime, String endTime);
boolean delByTime(int platform, String endTime);
}
@@ -0,0 +1,10 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserBetsOriginal;
/**
* Created by Nick on 2017/1/15.
*/
public interface UserBetsOriginalDao {
boolean add(UserBetsOriginal original);
}
@@ -0,0 +1,13 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserBetsRisk;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import java.util.List;
public interface UserBetsRiskDao {
List<UserBetsRisk> list(List<Criterion> criterions, List<Order> orders);
boolean updateStatus(int id, int fromStatus, int toStatus, String openCode, double prizeMoney, String prizeTime, int winNum);
}
@@ -0,0 +1,34 @@
package lottery.domains.content.dao;
import java.util.List;
import javautils.jdbc.PageList;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import lottery.domains.content.entity.UserBill;
public interface UserBillDao {
boolean add(UserBill entity);
/**
* 批量新增注单
*/
boolean addBills(List<UserBill> userBills);
UserBill getById(int id);
PageList search(List<Criterion> criterions, List<Order> orders, int start, int limit);
/**
* 清理负数之前之前金额
*/
int clearUserBillNegateBeforeMoney();
/**
* 清理负数之前之后金额
*/
int clearUserBillNegateAfterMoney();
}
@@ -0,0 +1,55 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.User;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import java.util.List;
public interface UserDao {
/**
* 列出用户
*/
List<User> list(List<Criterion> criterions, List<Order> orders);
/**
* 列出所有用户
*/
List<User> listAll();
/**
* 更新彩票账户资金
*/
boolean updateLotteryMoney(int id, double lotteryAmount, double freezeAmount);
/**
* 更新彩票账户资金
*/
boolean updateLotteryMoney(int id, double lotteryAmount);
/**
* 更新彩票账户资金
*/
boolean updateFreezeMoney(int id, double freezeAmount);
/**
* 通过id获取用户
*/
User getById(int id);
/**
* 清理用户负数金额
*/
int clearUserNegateFreezeMoney();
/**
* 获取用户下级代理
*/
List<User> getUserLower(int id);
/**
* 获取直属下级
*/
List<User> getUserDirectLower(int id);
}
@@ -0,0 +1,7 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserHighPrize;
public interface UserHighPrizeDao {
boolean add(UserHighPrize entity);
}
@@ -0,0 +1,16 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserLotteryDetailsReport;
import java.util.List;
public interface UserLotteryDetailsReportDao {
boolean add(UserLotteryDetailsReport entity);
UserLotteryDetailsReport get(int userId, int lotteryId, int ruleId, String time);
boolean update(UserLotteryDetailsReport entity);
void addDetailsReports(List<UserLotteryDetailsReport> detailsReports);
}
@@ -0,0 +1,18 @@
package lottery.domains.content.dao;
import lottery.domains.content.entity.UserLotteryReport;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import java.util.List;
public interface UserLotteryReportDao {
UserLotteryReport get(int userId, String time);
boolean update(UserLotteryReport entity);
boolean add(UserLotteryReport entity);
List<UserLotteryReport> find(List<Criterion> criterions, List<Order> orders);
}
@@ -0,0 +1,35 @@
package lottery.domains.content.dao.impl;
import javautils.date.Moment;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.DbServerSyncDao;
import lottery.domains.content.entity.DbServerSync;
import lottery.domains.content.global.DbServerSyncEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class DbServerSyncDaoImpl implements DbServerSyncDao {
private final String tab = DbServerSync.class.getSimpleName();
@Autowired
private HibernateSuperDao<DbServerSync> superDao;
@Override
public List<DbServerSync> listAll() {
String hql = "from " + tab;
return superDao.list(hql);
}
@Override
public boolean update(DbServerSyncEnum type) {
String key = type.name();
String time = new Moment().toSimpleTime();
String hql = "update " + tab + " set lastModTime = ?1 where key = ?0";
Object[] values = {key, time};
return superDao.update(hql, values);
}
}
@@ -0,0 +1,32 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryDao;
import lottery.domains.content.entity.Lottery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryDaoImpl implements LotteryDao {
private final String tab = Lottery.class.getSimpleName();
@Autowired
private HibernateSuperDao<Lottery> superDao;
@Override
public List<Lottery> listAll() {
String hql = "from " + tab + " order by sort, type";
return superDao.list(hql);
}
@Override
public boolean updateStatus(int id, int status) {
String hql = "update " + tab + " set status = ?1 where id = ?0";
Object[] values = {id, status};
return superDao.update(hql, values);
}
}
@@ -0,0 +1,87 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryOpenCodeDao;
import lottery.domains.content.entity.LotteryOpenCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryOpenCodeDaoImpl implements LotteryOpenCodeDao {
private final String tab = LotteryOpenCode.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryOpenCode> superDao;
@Override
public boolean updateOpened(int id, String updateTime) {
String hql = "update " + tab + " set openStatus = 1, openTime = ?0 where id=?1";
Object[] values = {updateTime, id};
return superDao.update(hql, values);
}
@Override
public boolean updateCancelled(int id, String updateTime) {
String hql = "update " + tab + " set openStatus = 3, openTime = ?0 where id=?1";
Object[] values = {updateTime, id};
return superDao.update(hql, values);
}
@Override
public List<LotteryOpenCode> getLatest(String lottery, int count) {
String hql = "from " + tab + " where lottery=?0 order by expect desc";
Object[] values = {lottery};
List<LotteryOpenCode> list = superDao.list(hql, values, 0, count);
return list;
}
@Override
public List<LotteryOpenCode> listAfter(String lottery, String expect) {
String hql = "from " + tab + " where lottery=?0 and expect>=?1";
Object[] values = {lottery, expect};
List<LotteryOpenCode> list = superDao.list(hql, values);
return list;
}
@Override
public List<LotteryOpenCode> getBeforeNotOpen(String lottery, int count) {
String hql = "from " + tab + " where openStatus = 0 and lottery=?0 order by expect desc";
Object[] values = {lottery};
List<LotteryOpenCode> list = superDao.list(hql, values, 0, count);
return list;
}
@Override
public LotteryOpenCode getByExcept(String lottery, String except) {
String hql = "from " + tab + " where lottery=?0 and expect = ?1 ";
Object[] values = {lottery,except};
List<LotteryOpenCode> list = superDao.list(hql, values, 0, 1);
if(list != null && list.size() > 0) {
return list.get(0);
}
return null;
}
@Override
public LotteryOpenCode getByExceptAndUserId(String lottery, int userId, String except) {
String hql = "from " + tab + " where lottery=?0 and expect = ?1 and userId = ?2";
Object[] values = {lottery,except, userId};
List<LotteryOpenCode> list = superDao.list(hql, values, 0, 1);
if(list != null && list.size() > 0) {
return list.get(0);
}
return null;
}
@Override
public boolean add(LotteryOpenCode openCode) {
return superDao.save(openCode);
}
@Override
public boolean update(LotteryOpenCode openCode) {
return superDao.update(openCode);
}
}
@@ -0,0 +1,32 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.PageList;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryOpenTimeDao;
import lottery.domains.content.entity.LotteryOpenTime;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryOpenTimeDaoImpl implements LotteryOpenTimeDao {
private final String tab = LotteryOpenTime.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryOpenTime> superDao;
@Override
public List<LotteryOpenTime> listAll() {
String hql = "from " + tab + " order by expect asc";
return superDao.list(hql);
}
@Override
public PageList find(List<Criterion> criterions, List<Order> orders, int start, int limit) {
return superDao.findPageList(LotteryOpenTime.class, criterions, orders, start, limit);
}
}
@@ -0,0 +1,24 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryPlayRulesConfigDao;
import lottery.domains.content.entity.LotteryPlayRulesConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryPlayRulesConfigDaoImpl implements LotteryPlayRulesConfigDao {
private final String tab = LotteryPlayRulesConfig.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryPlayRulesConfig> superDao;
@Override
public List<LotteryPlayRulesConfig> listAll() {
String hql = "from " + tab;
return superDao.list(hql);
}
}
@@ -0,0 +1,24 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryPlayRulesDao;
import lottery.domains.content.entity.LotteryPlayRules;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryPlayRulesDaoImpl implements LotteryPlayRulesDao {
private final String tab = LotteryPlayRules.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryPlayRules> superDao;
@Override
public List<LotteryPlayRules> listAll() {
String hql = "from " + tab + " order by typeId, groupId";
return superDao.list(hql);
}
}
@@ -0,0 +1,24 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryPlayRulesGroupConfigDao;
import lottery.domains.content.entity.LotteryPlayRulesGroupConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryPlayRulesGroupConfigDaoImpl implements LotteryPlayRulesGroupConfigDao {
private final String tab = LotteryPlayRulesGroupConfig.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryPlayRulesGroupConfig> superDao;
@Override
public List<LotteryPlayRulesGroupConfig> listAll() {
String hql = "from " + tab + " order by id";
return superDao.list(hql);
}
}
@@ -0,0 +1,24 @@
package lottery.domains.content.dao.impl;
import javautils.jdbc.hibernate.HibernateSuperDao;
import lottery.domains.content.dao.LotteryPlayRulesGroupDao;
import lottery.domains.content.entity.LotteryPlayRulesGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class LotteryPlayRulesGroupDaoImpl implements LotteryPlayRulesGroupDao {
private final String tab = LotteryPlayRulesGroup.class.getSimpleName();
@Autowired
private HibernateSuperDao<LotteryPlayRulesGroup> superDao;
@Override
public List<LotteryPlayRulesGroup> listAll() {
String hql = "from " + tab + " order by typeId,sort";
return superDao.list(hql);
}
}

Some files were not shown because too many files have changed in this diff Show More