fengjiajia 1 тиждень тому
коміт
9d480afda5

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 104 - 0
pom.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.zhentao</groupId>
+    <artifactId>fengjiajia2salt</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <name>fengjiajia2salt</name>
+    <description>fengjiajia2salt</description>
+    <properties>
+        <java.version>1.8</java.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <spring-boot.version>2.6.13</spring-boot.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.11</version> <!-- 确保版本号是正确的 -->
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>3.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <configuration>
+                    <mainClass>com.zhentao.Fengjiajia2saltApplication</mainClass>
+                    <skip>true</skip>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 13 - 0
src/main/java/com/zhentao/Fengjiajia2saltApplication.java

@@ -0,0 +1,13 @@
+package com.zhentao;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Fengjiajia2saltApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Fengjiajia2saltApplication.class, args);
+    }
+
+}

+ 42 - 0
src/main/java/com/zhentao/controller/GoodsController.java

@@ -0,0 +1,42 @@
+package com.zhentao.controller;
+
+import com.zhentao.dto.OrderAddDto;
+import com.zhentao.dto.VerifyDto;
+import com.zhentao.tool.VerifyUtil;
+import com.zhentao.vo.Result;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+public class GoodsController {
+
+    //写一个接口参数传(dto类中写参数)post方式,添加一个商品到数据库中
+    //创建Post接口传dto类参数goodsId,sign,(header参数reqId,reqTime时间戳long类型appId),ascii排序key=value&key=value......+key,md5加密,
+    // 验签返回一个商品名字(返回类型为ResultVo含code,msg,data属性),
+    // 如果失败返回1002失败,成功为200返回成功,内容返回可以写一个死对象。appSecretkey为123(不参与参数传输)
+    @PostMapping("addOrder")
+    public Result addOrder(@RequestBody OrderAddDto orderAddDto, @RequestHeader("reqId") String reqId,@RequestHeader("appId") String appId) throws NoSuchAlgorithmException {
+        VerifyDto verifyDto=new VerifyDto();
+        verifyDto.setReqTime(orderAddDto.getReqTime());
+        verifyDto.setGoodsId(orderAddDto.getGoodsId());
+        verifyDto.setSign(orderAddDto.getSign());
+        verifyDto.setAppId(appId);
+        verifyDto.setReqId(reqId);
+        verifyDto.setAppSecret("123");
+        Boolean verify = VerifyUtil.verify(verifyDto);
+        if(!verify){
+            return Result.Err(null,"签名验证失败");
+        }
+        List list=new ArrayList();
+        list.add("棒棒糖");
+        return Result.OK(list,"签名成功");
+    }
+
+
+}

+ 11 - 0
src/main/java/com/zhentao/dto/KafkaDto.java

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

+ 5 - 0
src/main/java/com/zhentao/dto/Message.java

@@ -0,0 +1,5 @@
+package com.zhentao.dto;
+
+public class Message {
+
+}

+ 15 - 0
src/main/java/com/zhentao/dto/OrderAddDto.java

@@ -0,0 +1,15 @@
+package com.zhentao.dto;
+
+import lombok.Data;
+
+@Data
+public class OrderAddDto {
+    private String GoodsId;
+    private String pageNo;
+    private String pageSize;
+    private String appId;
+    private String reqId;
+    private String appSecret;
+    private String sign;
+    private String reqTime;
+}

+ 13 - 0
src/main/java/com/zhentao/dto/VerifyDto.java

@@ -0,0 +1,13 @@
+package com.zhentao.dto;
+
+import lombok.Data;
+
+@Data
+public class VerifyDto {
+    private String goodsId;
+    private String reqId;
+    private String reqTime;
+    private String sign;
+    private String appId;
+    private String AppSecret;
+}

+ 46 - 0
src/main/java/com/zhentao/task/KafkaTask.java

@@ -0,0 +1,46 @@
+package com.zhentao.task;
+
+import cn.hutool.core.util.IdUtil;
+import com.zhentao.dto.KafkaDto;
+import com.zhentao.tool.VerifyUtil;
+import com.zhentao.util.OrderNumberGenerator;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.kafka.annotation.KafkaListeners;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+@EnableScheduling
+@Slf4j
+public class KafkaTask {
+
+    @Autowired
+    private KafkaTemplate<String,String> kafkaTemplate;
+
+    @Scheduled(cron = "0 * * * * *")
+    public void test1(){
+        KafkaDto kafkaDto=new KafkaDto();
+        long l = IdUtil.getSnowflake(1, 1).nextId();
+        kafkaDto.setMsgId(l+"");
+        kafkaDto.setMsgType("String");
+        kafkaDto.setContent("确认已消费");
+        kafkaTemplate.send("topic",kafkaDto.toString());
+    }
+
+    @KafkaListener(topics = "topic",groupId = "sms_group")
+    public void test2(String name){
+        System.err.println("消费者的信息:"+name);
+    }
+
+    @Test
+    public void test3(){
+        String s = OrderNumberGenerator.generateOrderNumber();
+        System.err.println("订单号:"+s);
+    }
+
+}

+ 244 - 0
src/main/java/com/zhentao/tool/EraHelper.java

@@ -0,0 +1,244 @@
+package com.zhentao.tool;
+
+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;
+	}
+}

+ 43 - 0
src/main/java/com/zhentao/tool/VerifyUtil.java

@@ -0,0 +1,43 @@
+package com.zhentao.tool;
+
+import com.zhentao.dto.VerifyDto;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class VerifyUtil {
+    public static Boolean verify(VerifyDto dto) throws NoSuchAlgorithmException {
+//        ASSII 码排序
+        Map<String,String> map = new TreeMap<>();
+        map.put("appId",dto.getAppId());
+        map.put("appSecret",dto.getAppSecret());
+        map.put("reqId",dto.getReqId());
+        map.put("reqTime",dto.getReqTime());
+        map.put("goodsId", dto.getGoodsId());
+        StringBuilder sb = new StringBuilder();
+        Boolean first = true;
+        for (Map.Entry<String,String> entry :  map.entrySet()){
+            if (first){
+                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+                first=false;
+            }else {
+                sb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
+            }
+
+        }
+//        key = value&key=values最后在添加一个appSecret
+        sb.append(dto.getAppSecret());
+        System.err.println(sb);
+//        MD5 加密
+        try {
+            String sign = EraHelper.byte2HexStr(MessageDigest.getInstance("MD5").digest(sb.toString().getBytes("UTF-8")));
+            return sign.equals(dto.getSign());
+        }catch (NoSuchAlgorithmException | UnsupportedEncodingException e){
+            return false;
+        }
+
+    }
+}

+ 36 - 0
src/main/java/com/zhentao/util/OrderNumberGenerator.java

@@ -0,0 +1,36 @@
+package com.zhentao.util;
+
+import redis.clients.jedis.Jedis;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class OrderNumberGenerator {
+
+    private static final String REDIS_KEY = "order_number";
+    private static final String REDIS_HOST = "localhost";
+    private static final int REDIS_PORT = 6379;
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+
+    /**
+     * 生成格式化订单号
+     * @return 格式化订单号
+     */
+    public static synchronized String generateOrderNumber() {
+        // 连接Redis
+        try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
+            // 使用Redis的原子操作生成订单号
+            Long nextOrderNumber = jedis.incr(REDIS_KEY);
+            // 格式化订单号,例如:ORDER2023051512340001
+            String orderNumber = String.format("ORDER%s%07d",
+                    DATE_TIME_FORMATTER.format(LocalDateTime.now()),
+                    nextOrderNumber);
+            return orderNumber;
+        }
+    }
+
+    public static void main(String[] args) {
+        // 生成并打印订单号
+        String orderNumber = generateOrderNumber();
+        System.out.println("Generated Order Number: " + orderNumber);
+    }
+}

+ 25 - 0
src/main/java/com/zhentao/vo/Result.java

@@ -0,0 +1,25 @@
+package com.zhentao.vo;
+
+import lombok.Data;
+
+@Data
+public class Result {
+    private Integer code;
+    private Object data;
+    private String msg;
+
+    public static Result OK(Object data,String msg){
+        Result result=new Result();
+        result.setCode(200);
+        result.setMsg(msg);
+        result.setData(data);
+        return result;
+    }
+    public static Result Err(Object data,String msg){
+        Result result=new Result();
+        result.setCode(400);
+        result.setMsg(msg);
+        result.setData(data);
+        return result;
+    }
+}

+ 19 - 0
src/main/resources/application.yml

@@ -0,0 +1,19 @@
+server:
+  port: 6900
+#kafka:
+#  producer:
+#    key-serializer: org.apache.kafka.common.serialization.StringSerializer
+#    value-serializer: org.apache.kafka.common.serialization.StringSerializer
+#    batch-size: 16384
+#    buffer-memory: 33554432
+#    retries: 3
+#    linger: 1
+#  bootstrap-servers: 192.168.0.45:9092
+#  consumer:
+#    group-id: sms_group
+#    auto-offset-reset: latest #latest
+#    enable-auto-commit: true
+#    auto-commit-interval: 100
+#    max-poll-records: 500
+#    key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+#    value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

+ 13 - 0
src/test/java/com/zhentao/Fengjiajia2saltApplicationTests.java

@@ -0,0 +1,13 @@
+package com.zhentao;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class Fengjiajia2saltApplicationTests {
+
+    @Test
+    void contextLoads() {
+    }
+
+}