Browse Source

Merge branch 'jihaipeng/feature-20250714184358-抽奖众筹' into milestone-20250723-wwl

# Conflicts:合并代码
#	lottery-system/pom.xml
feature/0725lihuilin
jihaipeng 1 month ago
parent
commit
4dddc0aef6
  1. 56
      lottery-system/lottery-common/src/main/java/com/lottery/utils/HttpUtils.java
  2. 68
      lottery-system/lottery-common/src/main/java/com/lottery/utils/ValidationUtils.java
  3. 21
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FundingRecordDto.java
  4. 24
      lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FundingUserDto.java
  5. 4
      lottery-system/lottery-pojo/src/main/java/com/lottery/entity/FundingData.java
  6. 4
      lottery-system/lottery-pojo/src/main/java/com/lottery/entity/FundingUser.java
  7. 25
      lottery-system/lottery-pojo/src/main/java/com/lottery/vo/FundingUserVo.java
  8. 48
      lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/FundingController.java
  9. 31
      lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/IFundingMapper.java
  10. 16
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/IFundingService.java
  11. 179
      lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/FundingServiceImpl.java
  12. 116
      lottery-system/lottery-service/src/main/resources/mapper/admin/fundingMapper.xml

56
lottery-system/lottery-common/src/main/java/com/lottery/utils/HttpUtils.java

@ -0,0 +1,56 @@
package com.lottery.utils;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Map;
public class HttpUtils{
private static final HttpClient client = HttpClient.newHttpClient();
/**
* 发送 POST 请求urlencoded 格式仅设置 Content-Type
* @param url 接口地址
* @param params 请求参数键值对自动编码
* @return 响应字符串
*/
public static String postUrlencoded(String url, Map<String, String> params) throws Exception {
// 1. 构建 urlencoded 请求体
StringBuilder requestBody = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (requestBody.length() > 0) {
requestBody.append("&");
}
requestBody.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append("=")
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
// 2. 创建 HTTP 请求仅设置 Content-Type
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded") // 仅设置 Content-Type
.POST(HttpRequest.BodyPublishers.ofString(requestBody.toString()))
.build();
// 3. 发送请求并返回响应
return sendRequest(request);
}
/**
* 发送请求并返回响应
*/
private static String sendRequest(HttpRequest request) throws Exception {
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException("HTTP 错误,状态码: " + response.statusCode() + ", 响应: " + response.body());
}
return response.body();
}
}

68
lottery-system/lottery-common/src/main/java/com/lottery/utils/ValidationUtils.java

@ -0,0 +1,68 @@
package com.lottery.utils;
/**
* @program: lottery-system
* @ClassName ValidationUtils
* @description:
* @author:jihaipeng
* @create: 202507-15 16:26
* @Version 1.0
**/
public class ValidationUtils {
/**
* 校验数值是否满足
* 1. 可以小于 0允许负数
* 2. 必须是整数不能是小数
*
* @param value 待校验的数值可以是 String Number 类型
* @return 是否校验通过
*/
public static boolean validateInteger(Object value) {
try {
// 如果是 String 类型先尝试转为 Number
if (value instanceof String) {
// 去掉可能的空格
String strValue = ((String) value).trim();
// 检查是否为空
if (strValue.isEmpty()) {
return false;
}
// 尝试解析为 Long支持更大的整数范围
try {
Long.parseLong(strValue);
} catch (NumberFormatException e) {
return false; // 解析失败说明不是整数
}
}
// 如果是 Number 类型IntegerLong
else if (value instanceof Number) {
Number num = (Number) value;
// 检查是否是整数避免浮点数
if (num instanceof Double || num instanceof Float) {
double doubleValue = num.doubleValue();
if (doubleValue != Math.floor(doubleValue)) {
return false; // 有小数部分不合法
}
}
// 如果是 Integer Long直接合法
return true;
}
// 其他类型如非数值类型
else {
return false;
}
// 所有检查通过
return true;
} catch (Exception e) {
return false; // 任何异常都视为不合法
}
}
}

21
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FundingRecordDto.java

@ -0,0 +1,21 @@
package com.lottery.dto;
import lombok.Data;
/**
* @program: lottery-system
* @ClassName FundingRecordDto
* @description:
* @author:jihaipeng
* @create: 202507-15 14:27
* @Version 1.0
**/
@Data
public class FundingRecordDto {
private String token;
private Integer activityId;
private String marketSign;
}

24
lottery-system/lottery-pojo/src/main/java/com/lottery/dto/FundingUserDto.java

@ -0,0 +1,24 @@
package com.lottery.dto;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @program: lottery-system
* @ClassName FundingUserDto
* @description:
* @author:jihaipeng
* @create: 202507-15 10:47
* @Version 1.0
**/
@Data
public class FundingUserDto {
public Integer activityId;
private String marketSign; // 市场标识(usa/hk)
private String username; // 用户名
private String jwcode; // 用户唯一码
private Integer page=1;
private Integer pagesize=10;
}

4
lottery-system/lottery-pojo/src/main/java/com/lottery/entity/FundingData.java

@ -24,11 +24,9 @@ import java.util.Date;
public class FundingData {
@TableId(type = IdType.AUTO) // 主键自增策略
private Integer id;
private Date time; // 统计时间(众筹初始时间)
private Integer time; // 统计时间(众筹初始时间)
private String stock; // 市场(美股/港股)
private Integer addTotal; // 虚拟参与人数
private Integer activityId; // 关联的活动ID
// 可选关联的活动对象
private Activity activity;
}

4
lottery-system/lottery-pojo/src/main/java/com/lottery/entity/FundingUser.java

@ -7,6 +7,8 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
/**
@ -27,6 +29,6 @@ public class FundingUser {
private String marketSign; // 市场标识(usa/hk)
private String username; // 用户名
private String jwcode; // 用户唯一码
private Date joinTime; // 参与时间
private LocalDateTime joinTime; // 参与时间
private Integer activityId; // 关联的活动ID
}

25
lottery-system/lottery-pojo/src/main/java/com/lottery/vo/FundingUserVo.java

@ -0,0 +1,25 @@
package com.lottery.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @program: lottery-system
* @ClassName FundingUserDto
* @description:
* @author:jihaipeng
* @create: 202507-15 10:09
* @Version 1.0
**/
@Data
public class FundingUserVo {
@TableId(type = IdType.AUTO) // 主键自增策略
private Integer id;
private String marketSign; // 市场标识(usa/hk)
private String username; // 用户名
private String jwcode; // 用户唯一码
private LocalDateTime joinTime; // 参与时间
}

48
lottery-system/lottery-service/src/main/java/com/lottery/admin/controller/FundingController.java

@ -3,13 +3,18 @@ package com.lottery.admin.controller;
import com.lottery.dto.FundingActivityDto;
import com.lottery.admin.service.IFundingService;
import com.lottery.dto.FundingRecordDto;
import com.lottery.dto.FundingUserDto;
import com.lottery.result.Result;
import com.lottery.vo.FundingActivityVo;
import com.lottery.vo.FundingUserVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* @program: lottery-system
@ -69,4 +74,47 @@ public class FundingController {
}
}
//根据活动id查询助力详情
@PostMapping("/getActivityDetail")
public Map<String, Object> getActivityDetail(@RequestBody FundingUserDto fundingUserDto) {
// 必填参数校验可选但推荐
if (fundingUserDto.getActivityId() == null) {
throw new IllegalArgumentException("activityId 不能为空");
}
return fundingService.getActivityDetail(fundingUserDto);
}
// //根据活动id查询数据统计
@PostMapping("/getActivityDate")
public Map<String, Object> getActivityDate(@RequestParam Integer activityId ) {
return fundingService.getActivityDate(activityId);
}
//添加用户参与记录
@PostMapping("/addRecord")
public Result<String> addRecord(@RequestBody FundingRecordDto fundingRecordDto) throws Exception {
return fundingService.addRecord(fundingRecordDto);
}
//设置活动初始活动
@PostMapping("/setActivityTime")
public Result<String> setActivityTime(@RequestParam Integer activityId, @RequestParam Integer time) {
return fundingService.setActivityTime(activityId, time);
}
//添加虚拟次数
@PostMapping("/addDateVirtual")
public Result<String> addVirtual(@RequestParam Integer activityId, @RequestParam String stock, @RequestParam Integer addTotal) {
return fundingService.addVirtual(activityId, stock, addTotal);
}
//返回数据详情
@PostMapping("/getDate")
public Result<Map<String, Object> > getDate(@RequestParam Integer activityId) {
return Result.success(fundingService.getDate(activityId));
}
}

31
lottery-system/lottery-service/src/main/java/com/lottery/admin/mapper/IFundingMapper.java

@ -2,9 +2,12 @@ package com.lottery.admin.mapper;
import com.lottery.entity.Activity;
import com.lottery.vo.FundingActivityVo;
import com.lottery.vo.FundingUserVo;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* @program: lottery-system
@ -22,4 +25,32 @@ public interface IFundingMapper {
void updateActivityStatus(Integer id, Integer status);
void addActivity(Activity activity);
List<FundingUserVo> selectByCondition(Integer activityId, String username, String jwcode, String marketSign, Integer pagesize, int offset);
int searchcount(Integer activityId, String username, String jwcode, String marketSign);
Integer searchPeopleTotal(Integer activityId);
Map<String, Object> getMarket(Integer activityId);
Integer searchMarketPeople(Integer activityId, String marketSign);
Integer searchMarketTotal(Integer activityId, String marketSign);
void addRecord(Integer activityId, String username, String jwcode, String marketSign, LocalDateTime joinTime);
void setActivityDate(Integer activityId, Integer time);
void addDate(Integer time, String stock, Integer addTotal, Integer activityId);
void setVirtual(Integer activityId, String stock, Integer addTotal);
Integer searchVirtual(Integer activityId, String stock);
Integer getTime(Integer activityId, String stock);
}

16
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/IFundingService.java

@ -1,10 +1,14 @@
package com.lottery.admin.service;
import com.lottery.dto.FundingActivityDto;
import com.lottery.dto.FundingRecordDto;
import com.lottery.dto.FundingUserDto;
import com.lottery.result.Result;
import com.lottery.vo.FundingActivityVo;
import com.lottery.vo.FundingUserVo;
import java.util.List;
import java.util.Map;
/**
* @program: lottery-system
@ -23,4 +27,16 @@ public interface IFundingService {
void updateActivityStatus(Integer id, Integer status);
Result<String> addActivity(FundingActivityDto fundingActivityDto);
Map<String, Object> getActivityDetail(FundingUserDto fundingUserDto);
Map<String, Object> getActivityDate(Integer activityId);
Result<String> addRecord(FundingRecordDto fundingRecordDto) throws Exception;
Result<String> setActivityTime(Integer activityId, Integer time);
Result<String> addVirtual(Integer activityId, String stock, Integer addTotal);
Map<String, Object> getDate(Integer activityId);
}

179
lottery-system/lottery-service/src/main/java/com/lottery/admin/service/Impl/FundingServiceImpl.java

@ -1,19 +1,29 @@
package com.lottery.admin.service.Impl;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lottery.dto.FundingActivityDto;
import com.lottery.dto.FundingRecordDto;
import com.lottery.dto.FundingUserDto;
import com.lottery.entity.Activity;
import com.lottery.admin.mapper.IFundingMapper;
import com.lottery.admin.service.IFundingService;
import com.lottery.result.Result;
import com.lottery.utils.ConvertBeanUtil;
import com.lottery.utils.HttpUtils;
import com.lottery.utils.ValidationUtils;
import com.lottery.vo.FundingActivityVo;
import com.lottery.vo.FundingUserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.chrono.ChronoLocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.lottery.result.Result.success;
@ -29,8 +39,10 @@ import static com.lottery.result.Result.success;
public class FundingServiceImpl implements IFundingService {
@Autowired
private IFundingMapper fundingMapper;
@Autowired
ObjectMapper objectMapper = new ObjectMapper();
// 获取所有众筹活动
// 获取所有众筹活动
@Override
public List<FundingActivityVo> getFundingActivity() {
List<FundingActivityVo> list = fundingMapper.getFundingActivity();
@ -63,7 +75,7 @@ public class FundingServiceImpl implements IFundingService {
return Result.failure("结束时间不能为空");
}
LocalDate now = LocalDate.now();
System.out.println( now);
System.out.println(now);
if (fundingActivityDto.getEndTime().isBefore(fundingActivityDto.getStartTime())) {
return Result.failure("结束时间不能早于开始时间");
}
@ -76,7 +88,170 @@ public class FundingServiceImpl implements IFundingService {
activity.setCreatedTime(creatTime);
activity.setUpdatedTime(creatTime);
fundingMapper.addActivity(activity);
String one = fundingActivityDto.getMarketOne();
String two = fundingActivityDto.getMarketTwo();
Integer activityId = activity.getId();
Integer time = 0;
Integer addTotal = 0;
fundingMapper.addDate(time,one, addTotal, activityId);
fundingMapper.addDate(time,two, addTotal, activityId);
return Result.success("添加活动成功");
}
@Override
public Map<String, Object> getActivityDetail(FundingUserDto fundingUserDto) {
// 计算分页偏移量
int offset = (fundingUserDto.getPage() - 1) * fundingUserDto.getPagesize();
// 查询数据列表
List<FundingUserVo> list = fundingMapper.selectByCondition(
fundingUserDto.getActivityId(),
fundingUserDto.getUsername(),
fundingUserDto.getJwcode(),
fundingUserDto.getMarketSign(),
fundingUserDto.getPagesize(),
offset
);
int total = fundingMapper.searchcount(
fundingUserDto.getActivityId(),
fundingUserDto.getUsername(),
fundingUserDto.getJwcode(),
fundingUserDto.getMarketSign()
);
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("list", list);
result.put("total", total);
result.put("page", fundingUserDto.getPage());
result.put("pageSize", fundingUserDto.getPagesize());
return result;
}
@Override
public Map<String, Object> getActivityDate(Integer activityId) {
//参与总人数
Integer people_total = fundingMapper.searchPeopleTotal(activityId);
//根据活动id查询俩个市场,俩个市场是一条数据
Map<String, Object> market = fundingMapper.getMarket(activityId);
//获取map
String marketOne = (String) market.get("market_one");
String marketTwo = (String) market.get("market_two");
//参与市场一的人数
Integer markerOnePeople = fundingMapper.searchMarketPeople(activityId, marketOne);
//市场一的总的助力次数
Integer markerOneTotal = fundingMapper.searchMarketTotal(activityId, marketOne);
//参与市场二的人数
Integer markerTwoPeople = fundingMapper.searchMarketPeople(activityId, marketTwo);
//市场二的总的助力次数
Integer markerTwoTotal = fundingMapper.searchMarketTotal(activityId, marketTwo);
//存入
market.put("people_total", people_total);
market.put("marketOnePeople", markerOnePeople);
market.put("marketOneTotal", markerOneTotal);
market.put("marketTwoPeople", markerTwoPeople);
market.put("marketTwoTotal", markerTwoTotal);
return market;
}
@Override
public Result<String> addRecord(FundingRecordDto fundingRecordDto) throws Exception {
String token = fundingRecordDto.getToken();
try {
// 1. 定义请求 URL
String url = "https://api.homilychart.com/hljw/api/v2/member/info";
// 准备请求参数
Map<String, String> params = new HashMap<>();
params.put("token", token); // 如果接口需要 token 作为参数
// 调用接口
String response = HttpUtils.postUrlencoded(url, params);
JsonNode rootNode = objectMapper.readTree(response);
// 提取 username
String username = rootNode.path("data").path("username").asText();
String jwcode = rootNode.path("data").path("jwcode").asText();
LocalDateTime joinTime = LocalDateTime.now();
String marketSign = fundingRecordDto.getMarketSign();
Integer activityId = fundingRecordDto.getActivityId();
//添加到数据库
fundingMapper.addRecord(activityId, username, jwcode, marketSign, joinTime);
} catch (Exception e) {
System.err.println("请求失败: " + e.getMessage());
}
return Result.success("助力成功");
}
@Override
public Result<String> setActivityTime(Integer activityId, Integer time) {
if(time == null){
return Result.failure("初始时间不能为空");
}
if(!ValidationUtils.validateInteger(time)){
return Result.failure("时间格式错误");
}
fundingMapper.setActivityDate(activityId, time);
return Result.success("设置初始时间成功");
}
@Override
public Result<String> addVirtual(Integer activityId, String stock, Integer addTotal) {
if(addTotal == null){
return Result.failure("添加次数不能为空");
}
if(!ValidationUtils.validateInteger(addTotal)){
return Result.failure("添加次数格式错误");
}
fundingMapper.setVirtual(activityId, stock, addTotal);
return Result.success("设置虚拟次数成功");
}
@Override
public Map<String, Object> getDate(Integer activityId) {
//根据活动id查询俩个市场,俩个市场是一条数据
Map<String, Object> market = fundingMapper.getMarket(activityId);
//获取map
String marketOne = (String) market.get("market_one");
//市场一的总的助力次数
Integer markerOneTotal = fundingMapper.searchMarketTotal(activityId, marketOne);
//市场一的虚拟次数
Integer markerOneVirtual = fundingMapper.searchVirtual(activityId, marketOne);
String marketTwo = (String) market.get("market_two");
//市场二的总的助力次数
Integer markerTwoTotal = fundingMapper.searchMarketTotal(activityId, marketTwo);
//市场二的虚拟次数
Integer markerTwoVirtual = fundingMapper.searchVirtual(activityId, marketTwo);
Integer showOne = markerOneTotal + markerOneVirtual;
Integer showTwo = markerTwoTotal + markerTwoVirtual;
Integer time = fundingMapper.getTime(activityId,marketOne);
Map<String, Object> result = new HashMap<>();
result.put("time", time) ;
result.put("showOne", showOne);
result.put("showTwo", showTwo);
result.put("markerOneTotal", markerTwoVirtual);
result.put("markerTwoTotal", markerTwoVirtual);
result.put("marketOneVirtual", markerOneVirtual);
result.put("marketTwoVirtual", markerTwoVirtual);
return result;
}
}

116
lottery-system/lottery-service/src/main/resources/mapper/admin/fundingMapper.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lottery.admin.mapper.IFundingMapper">
<insert id="addActivity" parameterType="com.lottery.entity.Activity">
<insert id="addActivity" parameterType="com.lottery.entity.Activity" useGeneratedKeys="true" keyProperty="id">
INSERT INTO activity (activity_name,
market_one,
market_two,
@ -19,12 +19,45 @@
#{createdTime},
#{updatedTime})
</insert>
<insert id="addRecord">
INSERT INTO z_user (activity_id,
username,
jwcode,
market_sign,
join_time)
VALUES (#{activityId},
#{username},
#{jwcode},
#{marketSign},
#{joinTime})
</insert>
<insert id="addDate">
INSERT INTO data (time,
stock,
add_total,
activity_id)
VALUES (#{time},
#{stock},
#{addTotal},
#{activityId})
</insert>
<update id="updateActivityStatus">
UPDATE activity
SET status = #{status}
WHERE id = #{id}
</update>
<update id="setActivityDate">
UPDATE data
SET time = #{time}
where activity_id = #{activityId}
</update>
<update id="setVirtual">
UPDATE data
SET add_total = add_total + #{addTotal}
where activity_id = #{activityId}
and stock = #{stock}
</update>
<select id="getFundingActivity" resultType="com.lottery.vo.FundingActivityVo">
SELECT id,
@ -41,5 +74,86 @@
FROM activity
ORDER BY created_time DESC
</select>
<select id="searchcount" resultType="java.lang.Integer">
SELECT
COUNT(*)
FROM z_user
WHERE
activity_id = #{activityId}
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="jwcode != null and jwcode != ''">
AND jwcode = #{jwcode}
</if>
<if test="marketSign != null and marketSign != ''">
AND market_sign = #{marketSign}
</if>
</select>
<select id="selectByCondition" resultType="com.lottery.vo.FundingUserVo">
SELECT
id, activity_id, username, jwcode, market_sign, join_time
FROM
z_user
WHERE
activity_id = #{activityId}
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="jwcode != null and jwcode != ''">
AND jwcode = #{jwcode}
</if>
<if test="marketSign != null and marketSign != ''">
AND market_sign = #{marketSign}
</if>
ORDER BY join_time DESC
LIMIT #{pagesize} OFFSET #{offset}
</select>
<select id="searchPeopleTotal" resultType="java.lang.Integer" parameterType="java.lang.Integer">
SELECT
COUNT(DISTINCT jwcode)
FROM z_user
WHERE
activity_id = #{activityId}
</select>
<select id="getMarket" resultType="java.util.Map" parameterType="java.lang.Integer">
SELECT
market_one,market_two
FROM
activity
WHERE
id = #{activityId}
</select>
<select id="searchMarketPeople" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT jwcode)
FROM z_user
WHERE market_sign = #{marketSign}
AND activity_id = #{activityId}
</select>
<select id="searchMarketTotal" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM z_user
WHERE market_sign = #{marketSign}
AND activity_id = #{activityId}
</select>
<select id="searchVirtual" resultType="java.lang.Integer">
SELECT
add_total
FROM
data
WHERE
activity_id = #{activityId}
and stock = #{stock}
</select>
<select id="getTime" resultType="java.lang.Integer">
SELECT
time
FROM
data
WHERE
activity_id = #{activityId}
and stock = #{stock}
</select>
</mapper>
Loading…
Cancel
Save