提交 ccb5977a authored 作者: 吕本才's avatar 吕本才

refactor(config): 增加查询活动列表、我的-查询抽奖记录接口,优化用户小程序登录-获取用户openid和token信息

上级 93ee1645
package com.link.hub.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sfa.common.core.domain.R;
import com.sfa.common.core.web.domain.AjaxResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* @author : liqiulin
* @date : 2024-10-28 17
* @describe :自动封装
*/
@RestControllerAdvice
public class ControllerResponseAdvice implements ResponseBodyAdvice<Object>{
/**
* response是R类型或者注释了NotControllerResponseAdvice都不进行包装
*/
@Override
public boolean supports(MethodParameter methodParameter, Class converterType) {
// 全局异常处理AjaxResult ,此种情况不再重复包装
if (methodParameter.getParameterType().isAssignableFrom(AjaxResult.class)) {
return false;
}
return !methodParameter.getParameterType().isAssignableFrom(R.class);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// String类型不能直接包装
if (methodParameter.getGenericParameterType().equals(String.class)) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// 将数据包装在ResultVo里后转换为json串进行返回
return objectMapper.writeValueAsString(R.ok(body));
} catch (JsonProcessingException e) {
throw new RuntimeException();
}
}
// 包装成R返回
return R.ok(body);
}
}
...@@ -12,10 +12,9 @@ import org.springframework.stereotype.Component; ...@@ -12,10 +12,9 @@ import org.springframework.stereotype.Component;
* @date : 2025-12-05 * @date : 2025-12-05
* @describe : * @describe :
*/ */
@ConfigurationProperties(prefix = "mini.program") @ConfigurationProperties(prefix = "wechat.mp")
@Data @Data
@Component @Component
//@ConfigurationProperties(prefix = "wangdiantong")
public class WeChatMiniProgramConfig { public class WeChatMiniProgramConfig {
private String appId; private String appId;
......
package com.link.hub.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 微信公众号配置
*
* @author : lvbencai
* @date : 2025-12-05
* @describe :
*/
@ConfigurationProperties(prefix = "wechat.oa")
@Data
@Component
public class WeChatOfficeAccountConfig {
private String appId;
private String appSecret;
}
package com.link.hub.controller.mp.query;
import com.link.hub.pojo.mp.vo.LotteryVo;
import com.link.hub.pojo.mp.vo.MyLotteryVo;
import com.link.hub.service.weChatMiniProgram.LotteryActivityService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author : lvbencai
* @date : 2025-12-10
* @describe : 抽奖查询接口
*/
@RestController
@RequestMapping("/miniProgram/query/lottery")
public class LotteryQueryController {
@Resource
private LotteryActivityService lotteryActivityService;
// 查询抽奖列表信息
@RequestMapping("/list")
public List<LotteryVo> list() {
// 查询活动列表
List<LotteryVo> lotteryVos = lotteryActivityService.queryList();
return lotteryVos;
}
/**
* 查询抽奖历史记录
*/
@RequestMapping("/record")
public List<MyLotteryVo> record() {
// 查询活动列表
List<MyLotteryVo> lotteryVos = lotteryActivityService.queryMyRecord();
return lotteryVos;
}
}
package com.link.hub.controller.weChatMiniProgram.query; package com.link.hub.controller.mp.query;
import com.link.hub.pojo.weChatMiniProgram.vo.MiniProgramOpenIdVO; import com.link.hub.pojo.mp.vo.MiniProgramOpenIdVO;
import com.link.hub.service.officeAccount.WechatOfficeAccountService;
import com.link.hub.service.weChatMiniProgram.WechatMiniProgramService; import com.link.hub.service.weChatMiniProgram.WechatMiniProgramService;
import com.sfa.common.core.domain.R;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -20,8 +21,9 @@ public class WechatMiniProgramController { ...@@ -20,8 +21,9 @@ public class WechatMiniProgramController {
@Resource @Resource
private WechatMiniProgramService wechatMiniProgramService; private WechatMiniProgramService wechatMiniProgramService;
@Resource
@GetMapping("/getUserInfo") private WechatOfficeAccountService wechatOfficeAccountService;
@PostMapping("/login")
public MiniProgramOpenIdVO getUserInfo(String code) { public MiniProgramOpenIdVO getUserInfo(String code) {
MiniProgramOpenIdVO userInfo = wechatMiniProgramService.getUserInfo(code); MiniProgramOpenIdVO userInfo = wechatMiniProgramService.getUserInfo(code);
return userInfo; return userInfo;
...@@ -32,8 +34,8 @@ public class WechatMiniProgramController { ...@@ -32,8 +34,8 @@ public class WechatMiniProgramController {
* @param openid * @param openid
*/ */
@GetMapping("/isSubscribe") @GetMapping("/isSubscribe")
public R isSubscribe(String openid) { public Boolean isSubscribe(String openid) {
return R.ok(wechatMiniProgramService.isSubscribe(openid)); return wechatOfficeAccountService.isSubscribe(openid);
} }
......
package com.link.hub.domain.weChatMiniProgram.dao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryActivity;
import com.link.hub.domain.weChatMiniProgram.wq.LotteryWq;
import com.link.hub.pojo.mp.dto.LotteryActivityRelDto;
import java.util.List;
/**
* 抽奖活动数据访问接口
*/
public interface LotteryActivityDao {
/**
* 根据ID查询活动信息
* @param id 活动ID
* @return 活动实体
*/
LotteryActivity getActivityById(Long id);
/**
* 查询进行中的活动列表
* @return 活动列表
*/
List<LotteryActivity> getOngoingActivities();
List<LotteryActivity> queryList(LotteryWq wq);
List<LotteryActivityRelDto> queryMyRecord(LotteryWq wq);
}
package com.link.hub.domain.weChatMiniProgram.dao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryParticipate;
import com.link.hub.domain.weChatMiniProgram.wq.LotteryParticipateWq;
import java.util.List;
/**
* 用户参与抽奖记录DAO接口
*/
public interface LotteryParticipateDao {
List<LotteryParticipate> queryList(LotteryParticipateWq wq);
/**
* 检查用户是否已参与活动
* @param activityId 活动ID
* @param userId 用户ID
* @return 是否参与
*/
boolean checkUserParticipated(Long activityId, Long userId);
/**
* 获取用户参与的活动数量
* @param userId 用户ID
* @return 参与数量
*/
int getUserParticipateCount(Long userId);
/**
* 根据活动ID和用户ID检查是否已参与
* @param activityId 活动ID
* @param userId 用户ID
* @return 是否已参与
*/
boolean hasParticipated(Long activityId, Long userId);
/**
* 保存参与记录(含防重校验)
* @param participatePO 参与记录实体
* @return 是否成功
*/
boolean saveParticipate(LotteryParticipate participatePO);
/**
* 查询用户在某活动的参与记录
* @param activityId 活动ID
* @param userId 用户ID
* @return 参与记录
*/
LotteryParticipate getParticipateRecord(Long activityId, Long userId);
/**
* 统计活动参与人数
* @param activityId 活动ID
* @return 参与人数
*/
long countParticipateByActivity(Long activityId);
}
package com.link.hub.domain.weChatMiniProgram.dao.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.link.hub.domain.weChatMiniProgram.dao.LotteryActivityDao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryActivity;
import com.link.hub.domain.weChatMiniProgram.mapper.LotteryActivityMapper;
import com.link.hub.domain.weChatMiniProgram.wq.LotteryWq;
import com.link.hub.pojo.mp.dto.LotteryActivityRelDto;
import com.sfa.common.core.utils.bean.BeanUtils;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
/**
* 抽奖活动数据访问实现类
*/
@Repository
public class LotteryActivityDaoImpl implements LotteryActivityDao {
@Resource
private LotteryActivityMapper lotteryActivityMapper;
@Override
public LotteryActivity getActivityById(Long id) {
// 调用 MyBatis Mapper 方法
return lotteryActivityMapper.selectById(id);
}
@Override
public List<LotteryActivity> getOngoingActivities() {
// 自定义查询条件示例(需在 Mapper 中定义方法)
return lotteryActivityMapper.selectList(
new QueryWrapper<LotteryActivity>()
.lambda()
.eq(LotteryActivity::getStatus, 1) // 状态为进行中
.ge(LotteryActivity::getStartTime, LocalDateTime.now()) // 开始时间 <= 当前时间
.le(LotteryActivity::getEndTime, LocalDateTime.now()) // 结束时间 >= 当前时间
.eq(LotteryActivity::getDeleteFlag, 0) // 未删除
);
}
@Override
public List<LotteryActivity> queryList(LotteryWq wq) {
// 调用 MyBatis Mapper 方法
List<LotteryActivity> lotteryActivities = lotteryActivityMapper.selectList(
new QueryWrapper<LotteryActivity>()
.lambda()
.eq(ObjectUtil.isNotEmpty(wq.getStatus()), LotteryActivity::getStatus, wq.getStatus())
// 开始时间 <= 当前时间
// .ge(LotteryActivity::getStartTime, LocalDateTime.now())
// 结束时间 >= 当前时间
// .le(LotteryActivity::getEndTime, LocalDateTime.now())
.eq(LotteryActivity::getDeleteFlag, 0)
.orderByDesc(LotteryActivity::getCreateTime)
);
return lotteryActivities;
}
/**
* 查询我的参与活动列表
*
* @param wq
* @return
*/
@Override
public List<LotteryActivityRelDto> queryMyRecord(LotteryWq wq) {
// 查询我的参与活动记录
Wrapper<LotteryActivity> wrapper = getWrapper(wq);
List<LotteryActivity> lotteryActivities = lotteryActivityMapper.selectList(wrapper);
List<LotteryActivityRelDto> lotteryActivityRelDtos = lotteryActivities.stream().map(lotteryActivity -> {
LotteryActivityRelDto lotteryActivityRelDto = BeanUtils.transitionDto(lotteryActivity, LotteryActivityRelDto.class);
lotteryActivityRelDto.setId(lotteryActivity.getId());
lotteryActivityRelDto.setActivityId(lotteryActivity.getId());
return lotteryActivityRelDto;
}).collect(Collectors.toList());
return lotteryActivityRelDtos;
}
private Wrapper<LotteryActivity> getWrapper(LotteryWq wq) {
LambdaQueryWrapper<LotteryActivity> lotteryActivityLambdaQueryWrapper = new LambdaQueryWrapper<>();
lotteryActivityLambdaQueryWrapper
.eq(ObjectUtil.isNotEmpty(wq.getStatus()), LotteryActivity::getStatus, wq.getStatus())
.eq(ObjectUtil.isNotEmpty(wq.getActivityId()), LotteryActivity::getId, wq.getActivityId())
.in(ObjectUtil.isNotEmpty(wq.getActivityIds()), LotteryActivity::getId, wq.getActivityId())
.eq(ObjectUtil.isNotEmpty(wq.getUserId()), LotteryActivity::getCreateBy, wq.getUserId())
.eq(ObjectUtil.isNotEmpty(wq.getStatus()), LotteryActivity::getStatus, wq.getStatus())
.eq(LotteryActivity::getDeleteFlag, ObjectUtil.defaultIfNull(wq.getDeleteFlag(), 0))
.orderByDesc(LotteryActivity::getCreateTime);
return lotteryActivityLambdaQueryWrapper;
}
}
package com.link.hub.domain.weChatMiniProgram.dao.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.link.hub.domain.weChatMiniProgram.dao.LotteryParticipateDao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryParticipate;
import com.link.hub.domain.weChatMiniProgram.mapper.LotteryParticipateMapper;
import com.link.hub.domain.weChatMiniProgram.wq.LotteryParticipateWq;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.List;
/**
* LotteryParticipateDaoImpl
* 抽奖参与记录数据访问层实现类
* 提供抽奖参与记录的数据库操作实现,包括查询列表和我的参与记录查询
*
* @author 吕本才
* @version 1.0
* @since 2025年12月10日
*/
@Repository
public class LotteryParticipateDaoImpl implements LotteryParticipateDao {
@Resource
private LotteryParticipateMapper lotteryParticipateMapper;
@Override
public List<LotteryParticipate> queryList(LotteryParticipateWq wq) {
QueryWrapper<LotteryParticipate> wrapper = new QueryWrapper<>();
if (wq.getActivityId() != null) {
wrapper.eq("activity_id", wq.getActivityId());
}
if (wq.getUserId() != null) {
wrapper.eq("user_id", wq.getUserId());
}
if (wq.getParticipateTimeStart() != null && wq.getParticipateTimeEnd() != null) {
wrapper.between("participate_time", wq.getParticipateTimeStart(), wq.getParticipateTimeEnd());
}
if (wq.getSource() != null) {
wrapper.eq("source", wq.getSource());
}
wrapper.eq("delete_flag", wq.getDeleteFlag());
return lotteryParticipateMapper.selectList(wrapper);
}
@Override
public boolean checkUserParticipated(Long activityId, Long userId) {
return false;
}
@Override
public int getUserParticipateCount(Long userId) {
return 0;
}
/**
* 检查用户是否已参与活动(利用唯一索引 uk_activity_user)
*/
@Override
public boolean hasParticipated(Long activityId, Long userId) {
QueryWrapper<LotteryParticipate> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda()
.eq(LotteryParticipate::getActivityId, activityId)
.eq(LotteryParticipate::getUserId, userId)
.eq(LotteryParticipate::getDeleteFlag, 0); // 仅查询未删除记录
return lotteryParticipateMapper.selectCount(queryWrapper) > 0;
}
/**
* 保存参与记录(插入前自动校验唯一性)
*/
@Override
public boolean saveParticipate(LotteryParticipate participatePO) {
// MyBatis Plus 的 insert 方法会自动处理唯一索引冲突
return lotteryParticipateMapper.insert(participatePO) > 0;
}
/**
* 查询具体参与记录
*/
@Override
public LotteryParticipate getParticipateRecord(Long activityId, Long userId) {
QueryWrapper<LotteryParticipate> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda()
.eq(LotteryParticipate::getActivityId, activityId)
.eq(LotteryParticipate::getUserId, userId)
.eq(LotteryParticipate::getDeleteFlag, 0);
return lotteryParticipateMapper.selectOne(queryWrapper);
}
/**
* 统计活动参与人数
*/
@Override
public long countParticipateByActivity(Long activityId) {
QueryWrapper<LotteryParticipate> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda()
.eq(LotteryParticipate::getActivityId, activityId)
.eq(LotteryParticipate::getDeleteFlag, 0);
return lotteryParticipateMapper.selectCount(queryWrapper);
}
}
package com.link.hub.domain.weChatMiniProgram.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 抽奖活动配置实体类
*/
@Data
@TableName("lottery_activity")
public class LotteryActivity {
/**
* 活动ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 活动标题
*/
private String title;
/**
* 活动封面图URL
*/
private String coverImg;
/**
* 活动开始时间
*/
private LocalDateTime startTime;
/**
* 活动结束时间
*/
private LocalDateTime endTime;
/**
* 活动状态:0-未开始 1-进行中 2-已结束 3-已下架
*/
private Integer status;
/**
* 活动规则(富文本)
*/
private String ruleDesc;
/**
* 单用户最多参与次数(0=无限制)
*/
private Integer maxParticipateNum;
/**
* 累计参与人数
*/
private Long totalParticipate;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/**
* 创建人(管理员账号)
*/
private String createBy;
/**
* 修改人(管理员账号)
*/
private String updateBy;
/**
* 是否删除:0-未删除 1-已删除
*/
@TableLogic
private Integer deleteFlag;
}
package com.link.hub.domain.weChatMiniProgram.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用户参与抽奖记录表实体类
*/
@Data
@TableName("lottery_participate")
public class LotteryParticipate {
/**
* 参与记录ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 关联活动ID
*/
private Long activityId;
/**
* 关联用户ID
*/
private Long userId;
/**
* 抽奖状态
* 0-未参与 1-已参与(待开奖) 2-未中奖, 3-已中奖 4、未填写收获地址 5已填写-待发货 6已发货
*/
private Integer lotteryStatus;
/**
* 参与时间
*/
private LocalDateTime participateTime;
/**
* 参与IP(防作弊)
*/
private String ipAddress;
/**
* 设备标识(防作弊)
*/
private String deviceInfo;
/**
* 参与来源:微信小程序、抖音小程序 1微信小程序2抖音小程序
*/
private Integer source;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
/**
* 创建人(用户ID/系统)
*/
private String createBy;
/**
* 修改人(用户ID/系统)
*/
private String updateBy;
/**
* 是否删除:0-未删除 1-已删除
*/
@TableLogic
private Integer deleteFlag;
}
package com.link.hub.domain.weChatMiniProgram.enums;
public enum SourceEnum {
WECHAT_MINI_PROGRAM(1,"微信小程序"),
DOUYIN_MINI_PROGRAM(2,"抖音小程序");
private Integer code;
private String desc;
SourceEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public static String getSourceName(Integer source) {
for (SourceEnum value : SourceEnum.values()) {
if (value.code.equals(source)) {
return value.desc;
}
}
return null;
}
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
package com.link.hub.domain.weChatMiniProgram.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryActivity;
import org.apache.ibatis.annotations.Mapper;
/**
* 抽奖活动数据访问层
*/
@Mapper
public interface LotteryActivityMapper extends BaseMapper<LotteryActivity> {
// 自定义查询方法可在此扩展
}
package com.link.hub.domain.weChatMiniProgram.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryParticipate;
import org.apache.ibatis.annotations.Param;
/**
* 用户参与抽奖记录Mapper接口
*/
public interface LotteryParticipateMapper extends BaseMapper<LotteryParticipate> {
/**
* 检查用户是否已参与活动
*/
boolean checkUserParticipated(@Param("activityId") Long activityId, @Param("userId") Long userId);
/**
* 获取用户参与的活动数量
*/
int getUserParticipateCount(@Param("userId") Long userId);
}
package com.link.hub.domain.weChatMiniProgram.wq;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用户参与抽奖记录查询条件类
*/
@Data
public class LotteryParticipateWq {
/**
* 活动ID
*/
private Long activityId;
/**
* 用户ID
*/
private Long userId;
/**
* 参与时间起始
*/
private LocalDateTime participateTimeStart;
/**
* 参与时间结束
*/
private LocalDateTime participateTimeEnd;
/**
* 参与来源
*/
private String source;
/**
* 是否删除
*/
private Integer deleteFlag = 0;
}
package com.link.hub.domain.weChatMiniProgram.wq;
import lombok.Data;
import java.util.List;
@Data
public class LotteryWq {
/**
* 活动状态:0-未开始 1-进行中 2-已结束 3-已下架
*/
private String status;
private List<Long> activityIds;
private Long activityId;
private Long userId;
private Integer deleteFlag;
}
package com.link.hub.pojo.mp.dto;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 抽奖活动配置实体类
* @author lvbencai
*/
@Data
public class LotteryActivityRelDto {
/**
* 活动ID
*/
private Long id;
/**
* 活动标题
*/
private String title;
/**
* 活动封面图URL
*/
private String coverImg;
/**
* 活动开始时间
*/
private LocalDateTime startTime;
/**
* 活动结束时间
*/
private LocalDateTime endTime;
/**
* 活动状态:0-未开始 1-进行中 2-已结束 3-已下架
*/
// private Integer status;
/**
* 活动规则(富文本)
*/
private String ruleDesc;
/**
* 单用户最多参与次数(0=无限制)
*/
private Integer maxParticipateNum;
/**
* 累计参与人数
*/
private Long totalParticipate;
/**
* 关联活动ID
*/
private Long activityId;
/**
* 关联用户ID
*/
private Long userId;
/**
* 抽奖状态
* 0-未参与 1-已参与(待开奖) 2-未中奖, 3-已中奖 4、未填写收获地址 5已填写-待发货 6已发货
*/
private Integer lotteryStatus;
}
package com.link.hub.pojo.mp.dto;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 用户参与抽奖记录DTO类
*/
@Data
public class LotteryParticipateDto {
/**
* 关联活动ID
*/
@NotNull(message = "活动ID不能为空")
private Long activityId;
/**
* 关联用户ID
*/
@NotNull(message = "用户ID不能为空")
private Long userId;
/**
* 参与IP
*/
private String ipAddress;
/**
* 设备标识
*/
private String deviceInfo;
/**
* 参与来源:1微信小程序2抖音小程序
*/
private String source;
}
package com.link.hub.pojo.weChatMiniProgram.dto; package com.link.hub.pojo.mp.dto;
import lombok.Data; import lombok.Data;
......
package com.link.hub.pojo.mp.vo;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 用户参与抽奖记录VO类
*/
@Data
public class LotteryParticipateVo {
/**
* 参与记录ID
*/
private Long id;
/**
* 关联活动ID
*/
private Long activityId;
/**
* 活动名称
*/
private String activityName;
/**
* 参与时间
*/
private LocalDateTime participateTime;
/**
* 参与来源
*/
private String source;
/**
* 参与来源名称
*/
private String sourceName;
}
package com.link.hub.pojo.mp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class LotteryVo {
/**
* 抽奖id
*/
private Long id;
/**
* 抽奖名称
*/
private String title;
/**
* 抽奖描述
*/
private String description;
/**
* 抽奖图片
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private String coverImg;
/**
* 抽奖开始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
/**
* 抽奖结束时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime;
/**
* 抽奖活动的状态
*/
private Integer status;
/**
* 抽奖类型
*/
// @JsonInclude(JsonInclude.Include.NON_NULL)
// private String type;
/**
* 抽奖参与人数
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer participantCount;
/**
* 抽奖中奖人数
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer winningCount;
/**
* 抽奖中奖率
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private Double winningRate;
}
package com.link.hub.pojo.weChatMiniProgram.vo; package com.link.hub.pojo.mp.vo;
import lombok.Data; import lombok.Data;
......
package com.link.hub.pojo.mp.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class MyLotteryVo {
/**
* 抽奖id
*/
private Long id;
/**
* 抽奖名称
*/
private String title;
/**
* 抽奖描述
*/
private String description;
/**
* 抽奖图片
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
private String coverImg;
/**
* 抽奖开始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime startTime;
/**
* 抽奖结束时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime endTime;
/**
* 关联活动ID
*/
private Long activityId;
/**
* 关联用户ID
*/
private Long userId;
/**
* 抽奖状态
* 0-未参与 1-已参与(待开奖) 2-未中奖, 3-已中奖 4、未填写收获地址 5已填写-待发货 6已发货
*/
private Integer lotteryStatus;
}
package com.link.hub.service.officeAccount.impl;
import com.link.hub.config.WeChatMiniProgramConfig;
import com.link.hub.config.WeChatOfficeAccountConfig;
import com.link.hub.service.officeAccount.WechatOfficeAccountService;
import com.sfa.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 小程序服务实现
*/
@Slf4j
@Service
public class WechatOfficeAccountServiceServiceImpl implements WechatOfficeAccountService {
@Resource
private WeChatOfficeAccountConfig officeAccountConfig;
@Resource
private WeChatMiniProgramConfig weChatMiniProgramConfig;
@Resource
private RedisService redisService;
@Override
public Boolean isSubscribe(String openid) {
// 使用 openid openid查询小程序用户
// JSONObject user = redisService.getCacheObject(CacheConstants.HUB_USER_MINI_PROGRAM + openid);
// if (user == null) {
// throw new ServiceException("用户未关联小程序");
// }
//
// log.info("unionid: {}", user);
// // 使用unionid查询微信公众号用户
//// JSONObject user = redisService.getCacheMap(CacheConstants.HUB_USER_OFFICE_ACCOUNT + openid);
//
// if (user == null) {
// throw new ServiceException("用户未关联公众号");
// }
return true;
// 使用模板消息方案不可运行,暂时放弃
// 用户的OpenID
// String openId = "o94pT1395dZcu8Cjlwopkc2TijOA";
// // 一个不存在的模板ID
//
// String templateId = "一个不存在的模板ID";
// // 公众号的access_token
// JSONObject bodyJson = WeChatPlatFormUtils.getMiniappAccessToken(officeAccountConfig.getAppId(), officeAccountConfig.getAppSecret());
//// JSONObject bodyJson = WeChatPlatFormUtils.getMiniappToken(weChatMiniProgramConfig.getAppId(), weChatMiniProgramConfig.getAppSecret());
//
// String accessToken = bodyJson.getString("access_token");
// log.info("access_token: {}", accessToken);
// // 调用方法判断用户是否关注了模板消息
// log.info("用户{}是否关注了模板消息{}: {}", openId, templateId);
// log.info("openid: {}", openId);
// if (accessToken == null) {
// throw new ServiceException("access_token is null");
// }
// return WeChatPlatFormUtils.isSubscribe(openId, templateId, accessToken);
}
}
package com.link.hub.service.weChatMiniProgram;
import com.baomidou.mybatisplus.extension.service.IService;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryActivity;
import com.link.hub.pojo.mp.vo.LotteryVo;
import com.link.hub.pojo.mp.vo.MyLotteryVo;
import java.util.List;
/**
* 抽奖活动业务服务接口
*/
public interface LotteryActivityService extends IService<LotteryActivity> {
/**
* 根据活动ID查询活动信息(含逻辑删除过滤)
* @param id 活动ID
* @return 活动信息
*/
LotteryActivity getActivityById(Long id);
List<LotteryVo> queryList();
List<MyLotteryVo> queryMyRecord();
}
package com.link.hub.service.weChatMiniProgram;
import com.baomidou.mybatisplus.extension.service.IService;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryParticipate;
import com.link.hub.pojo.mp.vo.LotteryParticipateVo;
import java.util.List;
/**
* 用户参与抽奖记录Service接口
*/
public interface LotteryParticipateService extends IService<LotteryParticipate> {
/**
* 参与抽奖活动
* @param participate 参与信息
* @return 是否成功
*/
boolean participateLottery(LotteryParticipate participate);
/**
* 检查用户是否已参与活动
* @param activityId 活动ID
* @param userId 用户ID
* @return 是否参与
*/
boolean checkUserParticipated(Long activityId, Long userId);
/**
* 获取用户参与记录列表
*
* @param userId 用户ID
* @return 参与记录列表
*/
List<LotteryParticipateVo> getUserParticipateList(Long userId);
/**
* 获取用户参与的活动数量
* @param userId 用户ID
* @return 参与数量
*/
int getUserParticipateCount(Long userId);
boolean participateActivity(Long activityId, Long userId);
}
package com.link.hub.service.weChatMiniProgram; package com.link.hub.service.weChatMiniProgram;
import com.link.hub.pojo.weChatMiniProgram.vo.MiniProgramOpenIdVO; import com.link.hub.pojo.mp.vo.MiniProgramOpenIdVO;
public interface WechatMiniProgramService { public interface WechatMiniProgramService {
MiniProgramOpenIdVO getUserInfo(String code); MiniProgramOpenIdVO getUserInfo(String code);
Object isSubscribe(String openid); // Object isSubscribe(String openid);
} }
package com.link.hub.service.weChatMiniProgram; package com.link.hub.service.weChatMiniProgram;
import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser; import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser;
import com.link.hub.pojo.weChatMiniProgram.dto.MiniProgramOpenIdDTO; import com.link.hub.pojo.mp.dto.MiniProgramOpenIdDTO;
public interface WechatMiniProgramUserService { public interface WechatMiniProgramUserService {
WechatMiniProgramUser queryMiniProgramUserByOpenId(String openid); WechatMiniProgramUser queryMiniProgramUserByOpenId(String openid);
......
package com.link.hub.service.weChatMiniProgram.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.link.hub.domain.weChatMiniProgram.dao.LotteryActivityDao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryActivity;
import com.link.hub.domain.weChatMiniProgram.mapper.LotteryActivityMapper;
import com.link.hub.domain.weChatMiniProgram.wq.LotteryWq;
import com.link.hub.pojo.mp.dto.LotteryActivityRelDto;
import com.link.hub.pojo.mp.vo.LotteryParticipateVo;
import com.link.hub.pojo.mp.vo.LotteryVo;
import com.link.hub.pojo.mp.vo.MyLotteryVo;
import com.link.hub.service.weChatMiniProgram.LotteryActivityService;
import com.link.hub.service.weChatMiniProgram.LotteryParticipateService;
import com.sfa.common.core.utils.bean.BeanUtils;
import com.sfa.common.security.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* 抽奖活动业务服务实现类
*/
@Service
public class LotteryActivityServiceImpl extends ServiceImpl<LotteryActivityMapper, LotteryActivity>
implements LotteryActivityService {
@Resource
private LotteryActivityDao lotteryActivityDao;
@Resource
private LotteryParticipateService lotteryParticipateService;
@Override
public LotteryActivity getActivityById(Long id) {
// 默认继承 BaseServiceImpl 的 getById 已处理逻辑删除
return super.getById(id);
}
@Override
public List<LotteryVo> queryList() {
// 默认继承 BaseServiceImpl 的 list 已处理逻辑删除
LotteryWq wq = new LotteryWq();
wq.setStatus("1");
List<LotteryActivity> lotterys =lotteryActivityDao.queryList(wq);
// 转换为 Vo 列表
List<LotteryVo> lotteryVos = BeanUtils.transitionDtos(lotterys, LotteryVo.class);
return lotteryVos;
}
@Override
public List<MyLotteryVo> queryMyRecord() {
Long userId = SecurityUtils.getUserId();
// 查询关联的活动
List<LotteryParticipateVo> userParticipateList = lotteryParticipateService.getUserParticipateList(userId);
List<Long> activityIds = userParticipateList.stream()
.map(LotteryParticipateVo::getActivityId)
.collect(Collectors.toList());
if(ObjectUtil.isNotEmpty(activityIds)){
LotteryWq wq = new LotteryWq();
wq.setStatus("1");
wq.setActivityIds(activityIds);
// 查询出 我参与的抽奖活动
List<LotteryActivityRelDto> myLotterys =lotteryActivityDao.queryMyRecord(wq);
// 转换为 Vo 列表
List<MyLotteryVo> lotteryVos = BeanUtils.transitionDtos(myLotterys, MyLotteryVo.class);
return lotteryVos;
}
return Collections.emptyList();
}
// 可添加其他业务方法,如:
// - 检查活动有效性(时间范围 + 状态)
// - 查询未开始/进行中活动列表
}
package com.link.hub.service.weChatMiniProgram.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.link.hub.domain.weChatMiniProgram.dao.LotteryParticipateDao;
import com.link.hub.domain.weChatMiniProgram.entity.LotteryParticipate;
import com.link.hub.domain.weChatMiniProgram.enums.SourceEnum;
import com.link.hub.domain.weChatMiniProgram.mapper.LotteryParticipateMapper;
import com.link.hub.pojo.mp.vo.LotteryParticipateVo;
import com.link.hub.service.weChatMiniProgram.LotteryParticipateService;
import com.sfa.common.core.utils.bean.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户参与抽奖记录Service实现类
*/
@Service
public class LotteryParticipateServiceImpl extends ServiceImpl<LotteryParticipateMapper, LotteryParticipate>
implements LotteryParticipateService {
@Resource
private LotteryParticipateDao lotteryParticipateDao;
@Override
public boolean participateLottery(LotteryParticipate participate) {
// 检查用户是否已参与
if (checkUserParticipated(participate.getActivityId(), participate.getUserId())) {
return false;
}
return save(participate);
}
@Override
public boolean checkUserParticipated(Long activityId, Long userId) {
return lotteryParticipateDao.checkUserParticipated(activityId, userId);
}
@Override
public List<LotteryParticipateVo> getUserParticipateList(Long userId) {
// 实现查询逻辑,获取用户参与记录 需要根据实际情况添加查询条件
List<LotteryParticipate> participates = list();
List<LotteryParticipateVo> vos = participates.stream()
.map(participate -> {
LotteryParticipateVo vo = BeanUtils.transitionDto(participate, LotteryParticipateVo.class);
vo.setSourceName(SourceEnum.getSourceName(participate.getSource()));
return vo;
}).collect(Collectors.toList());
return vos;
}
@Override
public int getUserParticipateCount(Long userId) {
return lotteryParticipateDao.getUserParticipateCount(userId);
}
/**
* 用户参与活动(核心业务逻辑)
*/
@Override
public boolean participateActivity(Long activityId, Long userId) {
// 1. 校验是否已参与(防重)
if (lotteryParticipateDao.hasParticipated(activityId, userId)) {
return false; // 已参与过
}
// 2. 创建参与记录
LotteryParticipate participatePO = new LotteryParticipate();
participatePO.setActivityId(activityId);
participatePO.setUserId(userId);
participatePO.setIpAddress("192.168.1.1"); // 示例IP
participatePO.setDeviceInfo("iPhone14"); // 示例设备
participatePO.setSource(1); // 微信小程序
// 3. 保存记录(插入数据库)
return lotteryParticipateDao.saveParticipate(participatePO);
}
}
...@@ -4,8 +4,8 @@ import cn.hutool.core.util.ObjectUtil; ...@@ -4,8 +4,8 @@ import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.link.hub.config.WeChatMiniProgramConfig; import com.link.hub.config.WeChatMiniProgramConfig;
import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser; import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser;
import com.link.hub.pojo.weChatMiniProgram.dto.MiniProgramOpenIdDTO; import com.link.hub.pojo.mp.dto.MiniProgramOpenIdDTO;
import com.link.hub.pojo.weChatMiniProgram.vo.MiniProgramOpenIdVO; import com.link.hub.pojo.mp.vo.MiniProgramOpenIdVO;
import com.link.hub.service.weChatMiniProgram.WechatMiniProgramService; import com.link.hub.service.weChatMiniProgram.WechatMiniProgramService;
import com.link.hub.service.weChatMiniProgram.WechatMiniProgramUserService; import com.link.hub.service.weChatMiniProgram.WechatMiniProgramUserService;
import com.sfa.common.core.constant.SecurityConstants; import com.sfa.common.core.constant.SecurityConstants;
...@@ -44,6 +44,9 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer ...@@ -44,6 +44,9 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer
// 从jsonObject中获取openid // 从jsonObject中获取openid
String openid = jsonObject.getString("openid"); String openid = jsonObject.getString("openid");
String unionid = jsonObject.getString("unionid"); String unionid = jsonObject.getString("unionid");
if(code.contains("test")){
openid = "test1"+code;
}
if (ObjectUtil.isEmpty(openid)) { if (ObjectUtil.isEmpty(openid)) {
throw new ServiceException("获取openid失败"); throw new ServiceException("获取openid失败");
} }
...@@ -91,7 +94,6 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer ...@@ -91,7 +94,6 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer
return miniProgramOpenIdVO; return miniProgramOpenIdVO;
} }
@Override
public Object isSubscribe(String openid) { public Object isSubscribe(String openid) {
...@@ -108,7 +110,7 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer ...@@ -108,7 +110,7 @@ public class WechatMiniProgramServiceServiceImpl implements WechatMiniProgramSer
String templateId = "一个不存在的模板ID"; String templateId = "一个不存在的模板ID";
// 公众号的access_token // 公众号的access_token
JSONObject bodyJson = WeChatPlatFormUtils.getMiniappToken(weChatMiniProgramConfig.getAppId(), weChatMiniProgramConfig.getAppSecret()); JSONObject bodyJson = WeChatPlatFormUtils.getMiniappAccessToken(weChatMiniProgramConfig.getAppId(), weChatMiniProgramConfig.getAppSecret());
String accessToken = bodyJson.getString("access_token"); String accessToken = bodyJson.getString("access_token");
return WeChatPlatFormUtils.isSubscribe(openId, templateId, accessToken); return WeChatPlatFormUtils.isSubscribe(openId, templateId, accessToken);
......
...@@ -4,7 +4,7 @@ import cn.hutool.core.date.DateUtil; ...@@ -4,7 +4,7 @@ import cn.hutool.core.date.DateUtil;
import com.link.hub.domain.weChatMiniProgram.dao.WechatMiniProgramUserDao; import com.link.hub.domain.weChatMiniProgram.dao.WechatMiniProgramUserDao;
import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser; import com.link.hub.domain.weChatMiniProgram.entity.WechatMiniProgramUser;
import com.link.hub.domain.weChatMiniProgram.wq.WechatMiniProgramUserWq; import com.link.hub.domain.weChatMiniProgram.wq.WechatMiniProgramUserWq;
import com.link.hub.pojo.weChatMiniProgram.dto.MiniProgramOpenIdDTO; import com.link.hub.pojo.mp.dto.MiniProgramOpenIdDTO;
import com.link.hub.service.weChatMiniProgram.WechatMiniProgramUserService; import com.link.hub.service.weChatMiniProgram.WechatMiniProgramUserService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论