X723595506 1 săptămână în urmă
părinte
comite
f6b966d826

+ 41 - 0
src/main/java/com/example/course/controller/KafkaController.java

@@ -0,0 +1,41 @@
+package com.example.course.controller;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.example.course.dto.KafkaDto;
+import com.example.course.utils.DateUtils;
+import com.example.course.utils.RedisUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/kafka")
+@EnableScheduling
+public class KafkaController {
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private KafkaTemplate<String,String> kafkaTemplate;
+    @PostMapping("/send")
+    @Scheduled(cron = "0 * * * * *")
+    public void send(){
+        //redis格式化订单
+        String yyMMddHHmmss = DateUtils.getDateTimeNum();
+        String num = redisUtil.getStartNum(yyMMddHHmmss);
+        num = num += 1;
+        String orderNo = yyMMddHHmmss + num;
+        System.err.println(orderNo);
+        KafkaDto kafkaDto = new KafkaDto();
+        kafkaDto.setMsgId("123698745");
+        kafkaDto.setContent("消息内容");
+        kafkaDto.setMsgType("消息类型");
+        kafkaTemplate.send("zxcv",JSONUtil.toJsonStr(kafkaDto));
+    }
+}

+ 10 - 0
src/main/java/com/example/course/dto/KafkaDto.java

@@ -0,0 +1,10 @@
+package com.example.course.dto;
+
+import lombok.Data;
+
+@Data
+public class KafkaDto {
+    private String msgId;
+    private String msgType;
+    private String content;
+}

+ 16 - 0
src/main/java/com/example/course/kafka/KafkaConsumerService.java

@@ -0,0 +1,16 @@
+package com.example.course.kafka;
+
+import com.example.course.dto.KafkaDto;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.kafka.support.Acknowledgment;
+import org.springframework.stereotype.Service;
+
+@Service
+public class KafkaConsumerService {
+
+    @KafkaListener(topics = "zxcv")
+    public void listen(String message, Acknowledgment acknowledgment){
+        System.err.println("接收消息" + message);
+        acknowledgment.acknowledge();
+    }
+}

+ 70 - 0
src/main/java/com/example/course/test/VerifyTest.java

@@ -0,0 +1,70 @@
+package com.example.course.test;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import com.example.course.utils.EraHelper;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class VerifyTest {
+    public static void Verify(){
+        Long appId = 147896325L;
+        String appSecret = "123";
+        String reqId = IdUtil.getSnowflake().nextIdStr();
+        Long timeStamp = System.currentTimeMillis();
+        //ASCII码排序
+        TreeMap<String,String> treeMap = new TreeMap<>();
+        treeMap.put("appId",appId.toString());
+        treeMap.put("reqId",reqId);
+        treeMap.put("reqTime",timeStamp.toString());
+        //key=value&key=value最后加一个appSecret
+        StringBuffer buffer = new StringBuffer();
+        boolean flag = true;
+        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
+            if (flag){
+                buffer.append(entry.getKey()).append("=").append(entry.getValue());
+                flag = false;
+            }else{
+                buffer.append("&").append(entry.getKey()).append("=").append(entry.getValue());
+            }
+        }
+        buffer.append(appSecret);
+
+
+        try {
+            String sign = EraHelper.byte2HexStr(MessageDigest.getInstance("MD5").digest(buffer.toString().getBytes("UTF-8")));
+
+            HashMap<String,String> map = new HashMap<>();
+//            map.put("goodsId","1");
+            map.put("sign",sign);
+
+            HashMap<String,String> header = new HashMap<>();
+            header.put("Content-Type","application/json");
+            header.put("reqId",reqId);
+            header.put("appId",appId.toString());
+            header.put("reqTime",timeStamp.toString());
+
+            HttpRequest request = HttpUtil.createPost("http://localhost:8080/goods/verify");
+            request.addHeaders(header);
+            request.body(JSONUtil.toJsonStr(map));
+            String result = request.execute().body();
+            System.err.println(result);
+
+        } catch (NoSuchAlgorithmException e) {
+
+        } catch (UnsupportedEncodingException e) {
+
+        }
+    }
+
+    public static void main(String[] args) {
+        VerifyTest.Verify();
+    }
+}

+ 152 - 0
src/main/java/com/example/course/utils/CacheKey.java

@@ -0,0 +1,152 @@
+package com.example.course.utils;
+
+/**
+ * 缓存key 定义
+ */
+public final class CacheKey {
+
+	/**
+	 * 1秒
+	 */
+	public static final int	SEC1		= 1;
+
+	/**
+	 * 3秒
+	 */
+	public static final int	SEC3		= SEC1 * 3;
+
+	/**
+	 * 5秒
+	 */
+	public static final int	SEC5		= SEC1 * 5;
+
+	/**
+	 * 15秒
+	 */
+	public static final int	SEC15		= SEC1 * 15;
+
+	/**
+	 * 30秒
+	 */
+	public static final int	SEC30		= SEC1 * 30;
+
+	/**
+	 * 1分钟
+	 */
+	public static final int	MINUTES1	= 60 * SEC1;
+
+	/**
+	 * 3分钟
+	 */
+	public static final int	MINUTES3	= 60 * SEC3;
+
+	/**
+	 * 5分钟
+	 */
+	public static final int	MINUTES5	= 5 * MINUTES1;
+	/**
+	 * 10分钟
+	 */
+	public static final int	MINUTES10	= 10 * MINUTES1;
+	/**
+	 * 30分钟
+	 */
+	public static final int	MINUTES30	= 30 * MINUTES1;
+	/**
+	 * 1小时
+	 */
+	public static final int	HOUR1		= 60 * MINUTES1;
+	/**
+	 * 半天
+	 */
+	public static final int	HOUR12		= 12 * HOUR1;
+	/**
+	 * 1天
+	 */
+	public static final int	DAY1		= 24 * HOUR1;
+
+	/**
+	 * 3天
+	 */
+	public static final int	DAY3		= 3 * DAY1;
+	/**
+	 * 7天
+	 */
+	public static final int	DAY7		= 7 * DAY1;
+
+	/**
+	 * 15天
+	 */
+	public static final int	DAY15		= 15 * DAY1;
+
+	/**
+	 * 30天
+	 */
+	public static final int	DAY30		= 30 * DAY1;
+
+	/**
+	 * 最大值
+	 */
+	public static final int	MAX			= Integer.MAX_VALUE;
+
+	/**
+	 * 超时时间
+	 */
+	private Integer			expire;
+
+	/**
+	 * 缓存 key,通常是一个前缀或后缀
+	 */
+	private String			key;
+
+	private CacheKey() {
+	}
+
+	public CacheKey(String key, Integer expire) {
+		this.expire = expire;
+		this.key = key;
+	}
+
+	public CacheKey(String key) {
+		this.key = key;
+	}
+
+	@Override
+	public String toString() {
+		return key;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public Integer getExpire() {
+		return expire;
+	}
+
+	/**
+	 * key+appendKey
+	 *
+	 * @param appendKey
+	 * @return
+	 */
+	public String getKeyPrefix(Object appendKey) {
+		if (appendKey == null) {
+			throw new IllegalArgumentException("appendKey 不能为空......");
+		}
+		return key + appendKey;
+	}
+
+	/**
+	 * appendKey+key
+	 *
+	 * @param appendKey
+	 * @return
+	 */
+	public String getKeySuffix(Object appendKey) {
+		if (appendKey == null) {
+			throw new IllegalArgumentException("appendKey 不能为空......");
+		}
+		return appendKey + key;
+	}
+}

+ 374 - 0
src/main/java/com/example/course/utils/DateUtils.java

@@ -0,0 +1,374 @@
+/**
+ * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.example.course.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
+ * @author jeeplus
+ * @version 2014-4-15
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+
+	private static String[] parsePatterns = {
+		"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+		"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+		"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+	/**
+	 * 得到当前日期字符串 格式(yyyy-MM-dd)
+	 */
+	public static String getDate() {
+		return getDate("yyyy-MM-dd");
+	}
+
+	/**
+	 * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
+	 */
+	public static String getDate(String pattern) {
+		return DateFormatUtils.format(new Date(), pattern);
+	}
+
+	/**
+	 * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E"
+	 */
+	public static String formatDate(Date date, Object... pattern) {
+		String formatDate = null;
+		if (pattern != null && pattern.length > 0) {
+			formatDate = DateFormatUtils.format(date, pattern[0].toString());
+		} else {
+			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
+		}
+		return formatDate;
+	}
+
+	/**
+	 * 获取年月
+	 */
+	public static String getYearMonth(Date date) {
+
+		return formatDate(date,"yyyy")+formatDate(date,"MM");
+	}
+
+	/**
+	 * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss)
+	 */
+	public static String formatDateTime(Date date) {
+		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
+	}
+
+	/**
+	 * 得到当前时间字符串 格式(HH:mm:ss)
+	 */
+	public static String getTime() {
+		return formatDate(new Date(), "HH:mm:ss");
+	}
+
+	/**
+	 * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss)
+	 */
+	public static String getDateTime() {
+		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
+	}
+
+	public static String getDateTimeNum(){
+		String date=formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
+		date= StringUtils.replace(date,"-","");
+		date= StringUtils.replace(date,":","");
+		date= StringUtils.replace(date," ","");
+
+		return date;
+	}
+	public static String getYearMonthDayNum(){
+		String date=formatDate(new Date(), "yyyy-MM-dd");
+		date= StringUtils.replace(date,"-","");
+
+		return date;
+	}
+
+	/**
+	 * 得到当前年份字符串 格式(yyyy)
+	 */
+	public static String getYear() {
+		return formatDate(new Date(), "yyyy");
+	}
+
+	public static String getYear(Date date) {
+		return formatDate(date, "yyyy");
+	}
+
+	/**
+	 * 得到当前月份字符串 格式(MM)
+	 */
+	public static String getMonth() {
+		return formatDate(new Date(), "MM");
+	}
+
+	/**
+	 * 得到当天字符串 格式(dd)
+	 */
+	public static String getDay() {
+		return formatDate(new Date(), "dd");
+	}
+
+	/**
+	 * 得到当前星期字符串 格式(E)星期几
+	 */
+	public static String getWeek() {
+		return formatDate(new Date(), "E");
+	}
+
+	/**
+	 * 日期型字符串转化为日期 格式
+	 * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
+	 *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm",
+	 *   "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm" }
+	 */
+	public static Date parseDate(Object str) {
+		if (str == null){
+			return null;
+		}
+		try {
+			return parseDate(str.toString(), parsePatterns);
+		} catch (ParseException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * 获取过去的天数
+	 * @param date
+	 * @return
+	 */
+	public static long pastDays(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(24*60*60*1000L);
+	}
+
+
+	/**
+	 * 之后多少天的时间
+	 * @param days
+	 * @return
+	 */
+	public static long getAfterDays(int days){
+		long t=new Date().getTime()+days*24*60*60*1000L;
+		return t;
+	}
+	public static Date getDateAfterDays(Date d,int days){
+		long t=d.getTime()+days*24*60*60*1000L;
+		Date afterTime=new Date(t);
+		return afterTime;
+	}
+	/**
+	 * 指定时间之后多少天的时间
+	 * @param days
+	 * @return
+	 */
+	public static long getAfterDays(Date d,int days){
+		long t=d.getTime()+days*24*60*60*1000L;
+		return t;
+	}
+
+	public static long diffDate(Date nowTime,Date extTime){
+	long time=	nowTime.getTime()-extTime.getTime();
+	return time;
+	}
+
+	/**
+	 * 之前多少天的时间
+	 * @param days
+	 * @return
+	 */
+	public static long getBeforeDays(int days){
+		long t=new Date().getTime()-days*24*60*60*1000L;
+		return t;
+	}
+
+	/**
+	 * 指定时间之前多少天的时间
+	 * @param days
+	 * @return
+	 */
+	public static long getBeforeDays(Date d,int days){
+		long t=d.getTime()-days*24*60*60*1000L;
+		return t;
+	}
+	public static Date getBeforeDaysDate(Date d,int days){
+		long t=d.getTime()-days*24*60*60*1000L;
+		Date beforeDays=new Date(t);
+		return beforeDays;
+	}
+	/**
+	 *
+	 * @param d
+	 * @param days
+	 * @return
+	 */
+	public static long getSpecificAfterDays(Date d,int days){
+		long t=d.getTime()+days*24*60*60*1000L;
+		return t;
+	}
+	/**
+	 * 获取过去的小时
+	 * @param date
+	 * @return
+	 */
+	public static long pastHour(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(60*60*1000L);
+	}
+
+	/**
+	 * 获取过去的分钟
+	 * @param date
+	 * @return
+	 */
+	public static long pastMinutes(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(60*1000L);
+	}
+
+	/**
+	 * 获取过去的分钟
+	 * @param date
+	 * @return
+	 */
+	public static long pastSecond(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(1*1000L);
+	}
+
+	/**
+	 * 转换为时间(天,时:分:秒.毫秒)
+	 * @param timeMillis
+	 * @return
+	 */
+    public static String formatDateTime(long timeMillis){
+		long day = timeMillis/(24*60*60*1000L);
+		long hour = (timeMillis/(60*60*1000L)-day*24);
+		long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
+		long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
+		return (day>0?day+",":"")+hour+":"+min+":"+s+"."+sss;
+    }
+
+	/**
+	 * 时长
+	 * @param timeMillis
+	 * @return
+	 */
+	public static String formatDateTimeToString(long timeMillis){
+
+		long day = timeMillis/(24*60*60*1000L);
+		long hour = (timeMillis/(60*60*1000L)-day*24);
+		long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
+		long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
+		return (day>0?day+"天":"")+(hour>0?hour+"时":"")+(min>0?min+"分":"")+(s>0?s+"秒":"");
+	}
+
+	/**
+	 * 过去多少时间转换为时间(天,时:分:秒.毫秒)
+	 * @param timeMillis
+	 * @return
+	 */
+	public static String pastTime(long timeMillis){
+		long tempTimeMillis=timeMillis;
+		timeMillis=new Date().getTime()-timeMillis;
+		long day = timeMillis/(24*60*60*1000L);
+		long hour = (timeMillis/(60*60*1000L)-day*24);
+		long min = ((timeMillis/(60*1000L))-day*24*60-hour*60);
+		long s = (timeMillis/1000L-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000L);
+		if(day>31){
+			return DateUtils.formateDate("yyyy-MM-dd",tempTimeMillis);
+		}
+		if(day>0){
+			return day+"天前";
+		}
+		if(hour>0){
+			return hour+"小时前";
+		}
+		if(min>0){
+			return min+"分钟前";
+		}
+		return "刚刚";
+	}
+	/**
+	 * 过去的时间
+
+	 * @return
+	 */
+	public static String pastTimeForDate(Date date){
+
+		long timeMillis=new Date().getTime()-date.getTime();
+		long day = timeMillis/(24*60*60*1000L);
+		long hour = (timeMillis/(60*60*1000)-day*24);
+		long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
+		long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
+		if(day>31){
+			return DateUtils.formatDate(date,"yyyy-MM-dd");
+		}
+		if(day>0){
+			return day+"天前";
+		}
+		if(hour>0){
+			return hour+"小时前";
+		}
+		if(min>0){
+			return min+"分钟前";
+		}
+		return "刚刚";
+	}
+
+	/**
+	 * 时长
+	 * @param timeMillis
+	 * @return
+	 */
+	public static String formatDateToHHMM(long timeMillis){
+		long day = timeMillis/(24*60*60*1000L);
+		long hour = (timeMillis/(60*60*1000));
+		long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
+		long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
+		return (hour>0?hour+"时":"0时")+(min>0?min+"分":"0分");
+	}
+    public static String formateDate(String dateFormat,long timeMillis){
+		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
+		      Date date = new Date(timeMillis);
+		     return sdf.format(date);
+	}
+
+	/**
+	 * 获取两个日期之间的天数
+	 *
+	 * @param before
+	 * @param after
+	 * @return
+	 */
+	public static double getDistanceOfTwoDate(Date before, Date after) {
+		long beforeTime = before.getTime();
+		long afterTime = after.getTime();
+		return (afterTime - beforeTime) / (1000 * 60 * 60 * 24L);
+	}
+
+	/**
+	 * @param args
+	 * @throws ParseException
+	 */
+	public static void main(String[] args) throws ParseException {
+		long timelong=0;
+	System.out.println(	DateUtils.formatDateTime(timelong));
+	System.out.println(DateUtils.formatDateToHHMM(timelong));
+	}
+}

+ 244 - 0
src/main/java/com/example/course/utils/EraHelper.java

@@ -0,0 +1,244 @@
+package com.example.course.utils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.security.MessageDigest;
+import java.util.UUID;
+
+
+/**
+ * 项目相关帮助函数。
+ *
+ *
+ */
+public class EraHelper {
+
+
+
+	/**
+	 * 生产新的UUID。
+	 *
+	 * @return uuid
+	 */
+	public static final String newUUID() {
+		return UUID.randomUUID().toString().replaceAll("-", "");
+	}
+
+	/**
+	 * 判断银行卡号是否合法。
+	 *
+	 * @param cardNumber
+	 *            银行卡号
+	 * @return boolean 表示合法
+	 */
+	public static final boolean isBankCard(String cardNumber) {
+		if (cardNumber == null || cardNumber.isEmpty() || cardNumber.length() <= 2) {
+			return false;
+		}
+		char[] chs = cardNumber.trim().toCharArray();
+		int luhmSum = 0;
+		for (int i = chs.length - 2, j = 0; i >= 0; i--, j++) {
+			if (!Character.isDigit(chs[i])) {
+				return false;
+			}
+			int k = chs[i] - '0';
+			if (j % 2 == 0) {
+				k *= 2;
+				k = k / 10 + k % 10;
+			}
+			luhmSum += k;
+		}
+		return ((luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0')) == chs[chs.length - 1];
+	}
+
+	/**
+	 * 获取远程请求IP
+	 *
+	 * @param request
+	 *            HTTP请求
+	 * @return String ip
+	 */
+	public static String getRemoteIP(HttpServletRequest request) {
+		String xff = request.getHeader("X-Forwarded-For");
+		if (xff != null && !xff.isEmpty()) {
+			return xff.split(", ?")[0];
+		} else {
+			return request.getRemoteAddr();
+		}
+	}
+
+	/**
+	 * 判断手机号是否合法。
+	 *
+	 * @param mobile
+	 *            手机号码
+	 * @return boolean 表示合法
+	 */
+	public static boolean isMobile(String mobile) {
+		if (mobile == null || mobile.length() != 11) {
+			return false;
+		}
+		int index = 0;
+		for (char ch : mobile.toCharArray()) {
+			if (index == 0 && ch != '1') {
+				return false;
+			}
+			if (!Character.isDigit(ch)) {
+				return false;
+			}
+			index++;
+		}
+		return true;
+	}
+
+	/**
+	 * 手机号打码
+	 *
+	 * @param mobile
+	 *            手机号码
+	 * @return String 打码后的手机号码
+	 */
+	public static String maskMobile(String mobile) {
+		StringBuilder builder = new StringBuilder();
+		builder.append(mobile, 0, 3);
+		builder.append("****").append(mobile.substring(7));
+		return builder.toString();
+	}
+
+	/**
+	 * 银行卡号打码
+	 *
+	 * @param cardNumber
+	 *            银行卡号
+	 * @return String 打码后的银行卡号
+	 */
+	public static String maskBankCard(String cardNumber) {
+		StringBuilder builder = new StringBuilder();
+		if (cardNumber.length() > 8) {
+			builder.append(cardNumber, 0, 4);
+			builder.append(" **** ").append(" **** ").append(cardNumber.substring(cardNumber.length() - 4));
+		}
+		return builder.toString();
+	}
+
+	/**
+	 * 判断短信验证码是否合法。
+	 *
+	 * @param verifyCode
+	 *            短信验证码
+	 * @return boolean 表示合法
+	 */
+	public static boolean isSMSCode(String verifyCode) {
+		if (verifyCode == null || verifyCode.length() != 4) {
+			return false;
+		}
+		for (char ch : verifyCode.toCharArray()) {
+			if (!Character.isDigit(ch)) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * 转换为十六进制字符串
+	 *
+	 * @param b
+	 *            字节数组
+	 * @return String 十六进制字符串
+	 */
+	public static String byte2HexStr(byte[] b) {
+		StringBuilder sb = new StringBuilder("");
+		for (int n = 0; n < b.length; n++) {
+			String stmp = Integer.toHexString(b[n] & 0xFF);
+			sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+		}
+		return sb.toString().toUpperCase().trim();
+	}
+
+
+
+	/**
+	 * 密码等资料混淆摘要
+	 *
+	 * @param content
+	 *            待混淆内容
+	 * @return String
+	 */
+	public static String confuse(String content) {
+		if (content == null || content.isEmpty()) {
+			return null;
+		}
+		try {
+			MessageDigest md5 = MessageDigest.getInstance("MD5");
+			md5.update(content.getBytes("UTF-8"));
+			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
+			return byte2HexStr(sha256.digest(md5.digest()));
+		} catch (Throwable e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+
+
+
+	private static double EARTH_RADIUS = 6378.137;// 地球半径
+
+	private static double rad(double d) {
+		return d * Math.PI / 180.0;
+	}
+
+	/**
+	 * 计算两个经纬度坐标距离.
+	 *
+	 * @param lat1
+	 * @param lng1
+	 * @param lat2
+	 * @param lng2
+	 * @return double
+	 */
+	public static BigDecimal getDistance(double lat1, double lng1, double lat2, double lng2) {
+		double radLat1 = rad(lat1);
+		double radLat2 = rad(lat2);
+		double a = radLat1 - radLat2;
+		double b = rad(lng1) - rad(lng2);
+		double s = 2 * Math.asin(Math.sqrt(
+				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+		s = s * EARTH_RADIUS;
+		return BigDecimal.valueOf(s).setScale(2, BigDecimal.ROUND_HALF_UP);
+	}
+
+	/**
+	 * 判断是否为微信。
+	 *
+	 * @param userAgent
+	 *            终端类型字符串
+	 * @return boolean true表示终端类型为微信
+	 */
+	public static boolean isWeiXin(String userAgent) {
+		return userAgent == null || userAgent.isEmpty() ? false : userAgent.indexOf("MicroMessenger") != -1;
+	}
+
+	/**
+	 * 判断是否为安卓。
+	 *
+	 * @param userAgent
+	 *            终端类型字符串
+	 * @return boolean true表示终端类型为安卓
+	 */
+	public static boolean isAndroid(String userAgent) {
+		return userAgent == null || userAgent.isEmpty() ? false : userAgent.indexOf("Android") != -1;
+	}
+
+	/**
+	 * 判断是否为iPhone。
+	 *
+	 * @param userAgent
+	 *            终端类型字符串
+	 * @return boolean true表示终端类型为iPhone
+	 */
+	public static boolean isIPhone(String userAgent) {
+		return userAgent == null || userAgent.isEmpty() ? false : userAgent.indexOf("iPhone") != -1;
+	}
+}

+ 61 - 0
src/main/java/com/example/course/utils/KafkaConfig.java

@@ -0,0 +1,61 @@
+package com.example.course.utils;
+
+import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.StringDeserializer;
+import org.apache.kafka.common.serialization.StringSerializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.annotation.EnableKafka;
+import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
+import org.springframework.kafka.config.KafkaListenerContainerFactory;
+import org.springframework.kafka.core.*;
+import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
+import org.springframework.kafka.listener.ContainerProperties;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@EnableKafka
+public class KafkaConfig {
+
+    @Bean
+    public ProducerFactory<String, String> producerFactory() {
+        Map<String, Object> configProps = new HashMap<>();
+        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "47.240.226.34:9092");
+        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        configProps.put(ProducerConfig.ACKS_CONFIG, "all");
+        configProps.put(ProducerConfig.RETRIES_CONFIG, 3);
+        return new DefaultKafkaProducerFactory<>(configProps);
+    }
+
+    @Bean
+    public KafkaTemplate<String, String> kafkaTemplate() {
+        return new KafkaTemplate<>(producerFactory());
+    }
+
+    @Bean
+    public ConsumerFactory<String, String> consumerFactory() {
+        Map<String, Object> configProps = new HashMap<>();
+        configProps.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "47.240.226.34:9092");
+        configProps.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group");
+        configProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
+        configProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
+        configProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
+        configProps.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
+        return new DefaultKafkaConsumerFactory<>(configProps);
+    }
+
+    @Bean
+    public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
+        ConcurrentKafkaListenerContainerFactory<String, String> factory =
+                new ConcurrentKafkaListenerContainerFactory<>();
+        factory.setConsumerFactory(consumerFactory());
+        factory.setConcurrency(3);
+        factory.getContainerProperties().setPollTimeout(3000);
+        factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
+        return factory;
+    }
+}

+ 1076 - 0
src/main/java/com/example/course/utils/RedisUtil.java

@@ -0,0 +1,1076 @@
+package com.example.course.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.BoundListOperations;
+import org.springframework.data.redis.core.HashOperations;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
+import org.springframework.data.redis.support.atomic.RedisAtomicLong;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * redisTemplate封装
+ */
+@Component
+public class RedisUtil {
+
+    @Autowired
+    private final RedisTemplate redisTemplate;
+
+    //锁名称前缀
+    public static final String LOCK_PREFIX = "redis_lock";
+    //加锁失效时间,毫秒
+    public static final int LOCK_EXPIRE = 10; // ms
+
+    public static Integer workId=0;
+    public static Integer dataId=0;
+
+
+    public RedisUtil(RedisTemplate<String, String> redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+
+
+
+    /**
+     * redis发布消息
+     *
+     * @param channel
+     * @param message
+     */
+    public void sendMessage(String channel, String message) {
+        redisTemplate.convertAndSend(channel, message);
+    }
+
+    /**
+     * 指定缓存失效时间
+     *
+     * @param key  键
+     * @param time 时间(秒)
+     * @return
+     */
+    public boolean expire(String key, long time, TimeUnit timeUnit) {
+        try {
+            if (time > 0) {
+                redisTemplate.expire(key, time, timeUnit);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据key 获取过期时间
+     *
+     * @param key 键 不能为null
+     * @return 时间(秒) 返回0代表为永久有效
+     */
+    public long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 判断key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public boolean hasKey(String key) {
+        try {
+            return redisTemplate.hasKey(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param key 可以传一个值 或多个
+     */
+    @SuppressWarnings("unchecked")
+    public void del(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                redisTemplate.delete(key[0]);
+            } else {
+                redisTemplate.delete(CollectionUtils.arrayToList(key));
+            }
+        }
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param keys 集合
+     */
+    public void del(Collection<String> keys) {
+        redisTemplate.delete(keys);
+    }
+
+    //============================String=============================
+
+    /**
+     * 普通缓存获取
+     *
+     * @param key 键
+     * @return 值
+     */
+    public Object get(String key) {
+        return key == null ? null : redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 普通缓存放入
+     *
+     * @param key   键
+     * @param value 值
+     * @return true成功 false失败
+     */
+    public boolean set(String key, Object value) {
+        try {
+            redisTemplate.opsForValue().set(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
+     * @return true成功 false 失败
+     */
+    public boolean set(String key, Object value, long time, TimeUnit timeUnit) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, timeUnit);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 递增
+     *
+     * @param key   键
+     * @param delta 要增加几(大于0)
+     * @return
+     */
+    public long incr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递增因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+
+    /**
+     * 递减
+     *
+     * @param key   键
+     * @param delta 要减少几(小于0)
+     * @return
+     */
+    public long decr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递减因子必须大于0");
+        }
+        return redisTemplate.opsForValue().decrement(key, delta);
+    }
+
+    //================================Map=================================
+
+    /**
+     * HashGet
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return 值
+     */
+    public Object hget(String key, String item) {
+        return redisTemplate.opsForHash().get(key, item);
+    }
+
+    /**
+     * 获取hashKey对应的所有键值
+     *
+     * @param key 键
+     * @return 对应的多个键值
+     */
+    public Map<Object, Object> hmget(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * HashSet
+     *
+     * @param key 键
+     * @param map 对应多个键值
+     * @return true 成功 false 失败
+     */
+    public boolean hmset(String key, Map<String, Object> map) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * HashSet 并设置时间
+     *
+     * @param key  键
+     * @param map  对应多个键值
+     * @param time 时间(秒)
+     * @return true成功 false失败
+     */
+    public boolean hmset(String key, Map<String, Object> map, long time, TimeUnit timeUnit) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            if (time > 0) {
+                expire(key, time, timeUnit);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value, long time, TimeUnit timeUnit) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            if (time > 0) {
+                expire(key, time, timeUnit);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除hash表中的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 可以使多个 不能为null
+     */
+    public void hdel(String key, Object... item) {
+        redisTemplate.opsForHash().delete(key, item);
+    }
+
+    /**
+     * 判断hash表中是否有该项的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return true 存在 false不存在
+     */
+    public boolean hHasKey(String key, String item) {
+        return redisTemplate.opsForHash().hasKey(key, item);
+    }
+
+    /**
+     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要增加几(大于0)
+     * @return
+     */
+    public double hincr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, by);
+    }
+
+    /**
+     * hash递减
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要减少记(小于0)
+     * @return
+     */
+    public double hdecr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, -by);
+    }
+
+    //============================set=============================
+
+    /**
+     * 根据key获取Set中的所有值
+     *
+     * @param key 键
+     * @return
+     */
+    public Set<Object> sGet(String key) {
+        try {
+            return redisTemplate.opsForSet().members(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据value从一个set中查询,是否存在
+     *
+     * @param key   键
+     * @param value 值
+     * @return true 存在 false不存在
+     */
+    public boolean sHasKey(String key, Object value) {
+        try {
+            return redisTemplate.opsForSet().isMember(key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将数据放入set缓存
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSet(String key, Object... values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 获得锁
+     *
+     * @param lock
+     * @return
+     */
+    public boolean lock(String lock) {
+        return (boolean) redisTemplate.execute((RedisCallback) connection -> {
+            //获取时间毫秒值
+            long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
+            //获取锁
+            Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
+            if (acquire) {
+                return true;
+            } else {
+                byte[] bytes = connection.get(lock.getBytes());
+                //非空判断
+                if (Objects.nonNull(bytes) && bytes.length > 0) {
+                    long expireTime = Long.parseLong(new String(bytes));
+                    // 如果锁已经过期
+                    if (expireTime < System.currentTimeMillis()) {
+                        // 重新加锁,防止死锁
+                        byte[] set = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
+                        return Long.parseLong(new String(set)) < System.currentTimeMillis();
+                    }
+                }
+            }
+            return false;
+        });
+    }
+
+    /**
+     * 获得锁
+     *
+     * @param lock
+     * @return
+     */
+    public boolean lock(String lock,Long timeOut) {
+        return (boolean) redisTemplate.execute((RedisCallback) connection -> {
+            //获取时间毫秒值
+            long expireAt = System.currentTimeMillis() + timeOut + 1;
+            //获取锁
+            Boolean acquire = connection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
+            if (acquire) {
+                return true;
+            } else {
+                byte[] bytes = connection.get(lock.getBytes());
+                //非空判断
+                if (Objects.nonNull(bytes) && bytes.length > 0) {
+                    long expireTime = Long.parseLong(new String(bytes));
+                    // 如果锁已经过期
+                    if (expireTime < System.currentTimeMillis()) {
+                        // 重新加锁,防止死锁
+                        byte[] set = connection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
+                        return Long.parseLong(new String(set)) < System.currentTimeMillis();
+                    }
+                }
+            }
+            return false;
+        });
+    }
+
+
+    /**
+     * 删除锁
+     *
+     * @param key
+     */
+    public void deleteLock(String key) {
+
+            redisTemplate.delete(key);
+
+    }
+
+
+    /**
+     * 加锁,⽆阻塞
+     * <p>
+     * 锁
+     *
+     * @param key        请求标识
+     * @param userId  超期时间
+     * @param expireTime 上锁时间,单位TimeUnit.SECONDS
+     * @param timeout 等待时间,单位TimeUnit.SECONDS
+     * @return
+     */
+    public Boolean lock(String key, long expireTime, Long userId, long timeout) {
+        Long start = System.currentTimeMillis();
+        //在⼀定时间内获取锁,超时则返回错误
+//
+        for (; ; ) {
+//,则证明获取锁成功
+//Set
+            //     OK
+            Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, userId, expireTime, TimeUnit.SECONDS);
+            if (ret != null && ret) {
+                return true;
+            }
+            //  否则循环等待,在
+            // 时间内仍未获取到锁,则获取失败
+            long end = System.currentTimeMillis() - start;
+            if (end >= timeout * 1000) {
+                return false;
+            }
+        }
+    }
+    public Boolean lock(String key, long expireTime, Long userId) {
+        Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, userId, expireTime, TimeUnit.SECONDS);
+        return ret != null && ret;
+    }
+
+    public Boolean unlock(String key, Long userId) {
+        Object o = redisTemplate.opsForValue().get(key);
+        if(userId.equals(o)){
+            return redisTemplate.delete(key);
+        }else{
+            return false;
+        }
+    }
+    /**
+     * 将set数据放入缓存
+     *
+     * @param key    键
+     * @param time   时间(秒)
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSetAndTime(String key, long time, TimeUnit timeUnit, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().add(key, values);
+            if (time > 0) {
+                expire(key, time, timeUnit);
+            }
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 获取set缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long sGetSetSize(String key) {
+        try {
+            return redisTemplate.opsForSet().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 移除值为value的
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 移除的个数
+     */
+    public long setRemove(String key, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    //===============================list=================================
+
+    /**
+     * 获取list缓存的内容
+     *
+     * @param key   键
+     * @param start 开始
+     * @param end   结束  0 到 -1代表所有值
+     * @return
+     */
+    public List<Object> listGet(String key, long start, long end) {
+        try {
+            return redisTemplate.opsForList().range(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    /**
+     * 弹出对象
+     * @param key
+     * @return
+     */
+    public Object popLeftList(String key){
+        return redisTemplate.opsForList().leftPop(key);
+    }
+
+    /**
+     * 获取list缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long listSize(String key) {
+        try {
+            return redisTemplate.opsForList().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 通过索引 获取list中的值
+     *
+     * @param key   键
+     * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+     * @return
+     */
+    public Object listGetIndex(String key, long index) {
+        try {
+            return redisTemplate.opsForList().index(key, index);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean listSet(String key, Object value) {
+        try {
+
+            redisTemplate.opsForList().rightPush(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public void listTrim(String key, long start,long end) {
+        try {
+
+            redisTemplate.opsForList().trim(key,start,end);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean listSet(String key, Object value, long time, TimeUnit timeUnit) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            if (time > 0) {
+                expire(key, time, timeUnit);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean listSet(String key, List<Object> value) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * list大小
+     * @param key
+     * @return
+     */
+    public Long getListSize(String key){
+        return redisTemplate.opsForList().size(key);
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean listSet(String key, List<Object> value, long time, TimeUnit timeUnit) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            if (time > 0) {
+                expire(key, time, timeUnit);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据索引修改list中的某条数据
+     *
+     * @param key   键
+     * @param index 索引
+     * @param value 值
+     * @return
+     */
+    public boolean listUpdateIndex(String key, long index, Object value) {
+        try {
+            redisTemplate.opsForList().set(key, index, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除N个值为value
+     *
+     * @param key   键
+     * @param count 移除多少个
+     * @param value 值
+     * @return 移除的个数
+     */
+    public long listRemove(String key, long count, Object value) {
+        try {
+            Long remove = redisTemplate.opsForList().remove(key, count, value);
+            return remove;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 模糊查询获取key值
+     *
+     * @param pattern
+     * @return
+     */
+    public Set keys(String pattern) {
+        return redisTemplate.keys(pattern);
+    }
+
+    /**
+     * 使用Redis的消息队列
+     *
+     * @param channel
+     * @param message 消息内容
+     */
+    public void convertAndSend(String channel, Object message) {
+        redisTemplate.convertAndSend(channel, message);
+    }
+
+
+    //=========BoundListOperations 用法 start============
+
+    /**
+     * 将数据添加到Redis的list中(从右边添加)
+     *
+     * @param listKey
+     * @param time    过期时间
+     * @param values  待添加的数据
+     */
+    public void addToListRight(String listKey, long time, Object... values) {
+        //绑定操作
+        BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
+        //插入数据
+        boundValueOperations.rightPushAll(values);
+        //设置过期时间
+        boundValueOperations.expire(time, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 根据起始结束序号遍历Redis中的list
+     *
+     * @param listKey
+     * @param start   起始序号
+     * @param end     结束序号
+     * @return
+     */
+    public List<Object> rangeList(String listKey, long start, long end) {
+        //绑定操作
+        BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
+        //查询数据
+        return boundValueOperations.range(start, end);
+    }
+
+    /**
+     * 弹出右边的值 --- 并且移除这个值
+     *
+     * @param listKey
+     */
+    public Object rifhtPop(String listKey) {
+        //绑定操作
+        BoundListOperations<String, Object> boundValueOperations = redisTemplate.boundListOps(listKey);
+        return boundValueOperations.rightPop();
+    }
+
+    /**
+     * @param key
+     * @return
+     */
+    public Long getIncr(String key) {
+        RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
+        Long increment = entityIdCounter.getAndIncrement();
+        return increment;
+    }
+
+    /**
+     * @return
+     */
+    public synchronized Integer getSequenceId() {
+        String key = "sms_sequence_id";
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        int sequenceId = idCount.getAndIncrement();
+        if (sequenceId <= 1000 || sequenceId >= 1000000000) {
+            idCount.set(1000);
+            sequenceId = idCount.getAndIncrement();
+            return sequenceId;
+        }
+        return sequenceId;
+    }
+
+    public void setCount(String key ,int initValue){
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        idCount.set(initValue);
+    }
+    /**
+     * @return
+     */
+    public  Integer getCount(String key) {
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        int count = idCount.getAndIncrement();
+        if (count ==Integer.MAX_VALUE-1) {
+            idCount.set(0);
+            count = idCount.getAndIncrement();
+            return count;
+        }
+        return count;
+    }
+    public  Integer getStartCount(String key) {
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+
+        int count = idCount.getAndIncrement();
+        if(count<=1){
+            this.expire(key, CacheKey.DAY1,TimeUnit.DAYS);
+        }
+        if (count ==Integer.MAX_VALUE-1) {
+
+            idCount.set(0);
+            count = idCount.getAndIncrement();
+            return count;
+        }
+
+        return count;
+    }
+    public String getStartNum(Integer num){
+
+        String str=num.toString();
+        int len=str.length();
+        if(str.length()<5){
+            StringBuilder sb = new StringBuilder();
+            for(int i=0;i<5-len;i++){
+
+                sb.append("0");
+
+            }
+            sb.append(str);
+            return sb.toString();
+        }
+        return str;
+    }
+    public String getStartNum(String key){
+        Integer num=getStartCount(key);
+        String str=num.toString();
+        int len=str.length();
+        if(str.length()<5){
+            StringBuilder sb = new StringBuilder();
+            for(int i=0;i<5-len;i++){
+
+                    sb.append("0");
+
+            }
+            sb.append(str);
+            return sb.toString();
+        }
+        return str;
+    }
+
+
+    public synchronized Integer getSequenceNumber3(String key) {
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        int sequenceId = idCount.getAndIncrement();
+        if (sequenceId < 0 || sequenceId >= Integer.MAX_VALUE) {
+            idCount.set(0);
+            sequenceId = idCount.getAndIncrement();
+            return sequenceId;
+        }
+        return sequenceId;
+    }
+    public synchronized  Integer getWorkId(String key) {
+        RedisAtomicInteger idCount = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        int sequenceId = idCount.getAndIncrement();
+        if (sequenceId < 0 || sequenceId >= 31) {
+            idCount.set(0);
+            sequenceId = idCount.getAndIncrement();
+            return sequenceId;
+        }
+        return sequenceId;
+    }
+
+    /**
+     * 14      * @Description: 初始化自增长值
+     * 15      * @param key key
+     * 16      * @param value 当前值
+     * 17
+     */
+    public void setIncr(String key, int value) {
+        RedisAtomicLong counter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
+        counter.set(value);
+    }
+
+    /**
+     * 14      * @Description: 初始化自增长值
+     * 15      * @param key key
+     * 16      * @param value 当前值
+     * 17
+     */
+    public void setInteger(String key, int value) {
+        RedisAtomicInteger counter = new RedisAtomicInteger(key, redisTemplate.getConnectionFactory());
+        counter.set(value);
+    }
+
+
+    /**
+     * 保存到hash
+     * @param key
+     * @param hashKey
+     * @param value
+     */
+    public void setHashMap(String key,Object hashKey,Object value){
+        redisTemplate.opsForHash().put(key,hashKey,value);
+    }
+
+    /**
+     * 获取hashvalue
+     * @param key
+     * @param hashKey
+     * @return
+     */
+    public Object getHashValue(String key,Object hashKey){
+       return  redisTemplate.opsForHash().get(key,hashKey);
+    }
+
+    /**
+     * 删除hash中单个对象
+     * @param key
+     * @param hashKey
+     */
+    public void remove(String key,Object hashKey){
+        redisTemplate.opsForHash().delete(key,hashKey);
+    }
+
+    /**
+     * 获取redisTemplate
+     * @return
+     */
+    public RedisTemplate getRedisTemplate(){
+        return redisTemplate;
+    }
+
+    /**
+     * 存储数据或修改数据
+     *
+     * @param modelMap
+     * @param mapName
+     */
+    public void setMap(String mapName, Map<String, Object> modelMap) {
+        HashOperations<String, Object, Object> hps = redisTemplate.opsForHash();
+        hps.putAll(mapName, modelMap);
+    }
+
+    /**
+     * 获取数据Map
+     *
+     * @param mapName
+     * @return
+     */
+    public Map<Object, Object> getMapValue(String mapName) {
+        HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
+        return hps.entries(mapName);
+
+    }
+
+    /**
+     * 获取数据Map size
+     *
+     * @param mapName
+     * @return
+     */
+    public int getMapSize(String mapName) {
+        HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
+        return hps.entries(mapName).size();
+
+    }
+
+    /**
+     * 获取数据value
+     *
+     * @param mapName
+     * @param hashKey
+     * @return
+     */
+    public Object getValue(String mapName, String hashKey) {
+        HashOperations<String, Object, Object> hps = this.redisTemplate.opsForHash();
+        return hps.get(mapName, hashKey);
+
+    }
+
+    /**
+     * 批量删除缓存数据
+     *
+     * @param keys
+     */
+    public long deleteData(String key,Object ...keys) {
+        // 执行批量删除操作时先序列化template
+       long b= redisTemplate.opsForHash().delete(key,keys);
+       return b;
+    }
+
+    private void batchCacheMarketInfo(List<Object > dataList, long expire) {
+        //使用pipeline方式
+        redisTemplate.executePipelined(new RedisCallback<List<Object>>() {
+            @Override
+            public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
+                for (Object marketInfo : dataList) {
+                    String key = "";
+                    byte[] rawKey = redisTemplate.getKeySerializer().serialize(key);
+                    connection.setEx(rawKey, expire, redisTemplate.getValueSerializer().serialize(marketInfo));
+                }
+                return null;
+            }
+        });
+
+    }
+
+
+
+    //=========BoundListOperations 用法 End============
+
+}