赞
踩
目录
实现微信步数的同步(也就是获取当前的微信步数更新至数据库)
实现获取我当日的微信步数的查询
实现按照日排行,周排行,月排行榜的功能
主要思路:通过前端传递的encryptedData加密数据包,解密后得到微信步数,此文中的方式,为前端获取微信步数并将加密数据包发送后端解析。
注意的点:数据库表设计为,一个用户,一天一条步数信息,在当天,第一次获取微信步数后为新增,之后同步均为更新,在根据不同条件获取排名时,将同一个用户,处于这个时间段内的步数相加后排序得出排名。
请求参数实体
- @Data
- public class StepDTO implements Serializable {
-
- @ApiModelProperty(value = "小程序用户id",required=true)
- @NotBlank(message = "小程序用户id不能为空")
- private String appUserId;
-
- @ApiModelProperty(value = "微信昵称",required=true)
- @NotBlank(message = "微信昵称不能为空")
- private String nickName;
-
- //前端传递的步数数据包 用于解密获取步数
- @ApiModelProperty(value = "数据包",required=true)
- @NotBlank(message = "前端数据包不能为空")
- private String encryptedData;
-
- @ApiModelProperty(value = "iv" ,required=true)
- @NotBlank(message = "iv不能为空")
- private String iv;
-
- @ApiModelProperty(value = "session_key" ,required=false)
- private String sessionKey;
-
- @ApiModelProperty(value = "步数")
- private String step;
-
- }
返回结果实体
- @Data
- public class BizStep extends BaseEntity{
-
- private static final long serialVersionUID = 1L;
-
- @ApiModelProperty(value = "小程序用户id")
- private String appUserId;
-
- @ApiModelProperty(value = "微信昵称")
- private String wechatName;
-
- @ApiModelProperty(value = "姓名")
- private String name;
-
- @ApiModelProperty(value = "步数")
- private Integer step;
-
- @ApiModelProperty(value = "头像")
- private String avatar ;
-
- @ApiModelProperty(value = "session_key")
- private String sessionKey;
-
- @ApiModelProperty(value = "手机号码")
- private String mobile;
-
- }
微信步数VO
- @Data
- public class WxRunDataBO {
-
- @ApiModelProperty("stepInfoList")
- private List<StepInfoListBO> stepInfoList;
-
- @ApiModelProperty("stepInfoList")
- private WatermarkBO watermark;
- }
-
- @Data
- public class StepInfoListBO {
-
- @ApiModelProperty("timestamp")
- private Long timestamp;
-
- @ApiModelProperty("step")
- private Integer step;
- }
控制层
- @Resource
- private BizStepService bizStepService;
-
- @PostMapping("/synchronize")
- public ResponseEntity<BizStep> uploadStep(@RequestBody @Valid StepDTO stepDTO) {
- return ResultUtil.success("同步步数功",this.bizStepService.uploadStep(stepDTO));
- }
service
业务层
- @Resource
- @Lazy
- private AccountClient accountClient;
- @Resource
- private BizStepMapper bizStepMapper;
-
- @Transactional(rollbackFor = Exception.class)
- public BizStep uploadStep(StepDTO stepDTO) {
- Assert.isTrue(LocalTime.now().isBefore(LocalTime.parse("22:00:00")), "每日同步步数截止时间为22:00");
- //获取微信用户数据 此处的目的为获取用户的sessionKey
- WxUser wxUser = accountClient.getById(stepDTO.getAppUserId());
- stepDTO.setSessionKey(wxUser.getSessionKey());
- //获取用户步数
- String step = this.decryptWeChatStep(stepDTO);
- BizStep bizStep = new BizStep();
- //step入库
- if (StrUtil.isNotBlank(step)) {
- LocalDateTime localDateTime = LocalDateTime.now();
- String today = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(localDateTime);
- bizStep =
- this.getOne(Wrappers.lambdaQuery(BizStep.class).eq(BizStep::getAppUserId,
- stepDTO.getAppUserId())
- .apply("to_char(created_date,'yyyy-MM-dd') = {0}", today));
- if (null != bizStep) {
- //如果今天舒徐不为空则更新
- bizStep.setStep(Integer.valueOf(step));
- this.updateById(bizStep);
- //入果用户头像更改,需要更新历史数据的头像 保持一致性
- if (!wxUser.getAvatar().equals(bizStep.getAvatar())) {
- this.update(Wrappers.lambdaUpdate(BizStep.class).eq(BizStep::getAppUserId, stepDTO.getAppUserId())
- .set(BizStep::getAvatar, wxUser.getAvatar()));
- }
- //保持昵称的一致性 如果昵称改变保持历史数据的一致
- if (!wxUser.getNickName().equals(bizStep.getName())) {
- this.update(Wrappers.lambdaUpdate(BizStep.class).eq(BizStep::getAppUserId, stepDTO.getAppUserId())
- .set(BizStep::getName, wxUser.getNickName()));
- }
- } else {
- BizStep newBizStep = new BizStep();
- //如果今天数据为空则新增
- newBizStep.setAppUserId(stepDTO.getAppUserId());
- newBizStep.setWechatName(wxUser.getNickName());
- newBizStep.setName(wxUser.getNickName());
- newBizStep.setAvatar(wxUser.getAvatar());
- newBizStep.setSessionKey(wxUser.getSessionKey());
- newBizStep.setStep(Integer.valueOf(step));
- newBizStep.setMobile(wxUser.getMobile());
- this.save(newBizStep);
- return newBizStep;
- }
- }
- return bizStep;
- }
-
- /**
- * 微信步数同步
- *
- * @param stepDTO
- * @return
- */
- public String decryptWeChatStep(StepDTO stepDTO) {
- String step = "0";
- byte[] encrypData = Base64.decodeBase64(stepDTO.getEncryptedData());
- byte[] ivData = Base64.decodeBase64(stepDTO.getIv());
- byte[] sessionKeyB = Base64.decodeBase64(stepDTO.getSessionKey());
-
- try {
- AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
- Cipher cipher = Cipher.getInstance(TRANSFORMATION);
- SecretKeySpec keySpec = new SecretKeySpec(sessionKeyB, AES);
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- byte[] doFinal = cipher.doFinal(encrypData);
- String result = new String(doFinal);
- WxRunDataBO wxRunDataBO = JSON.parseObject(result, WxRunDataBO.class);
- List<StepInfoListBO> stepInfoList = wxRunDataBO.getStepInfoList();
- Assert.isTrue(stepInfoList.size() > 0, "微信没有您今日的步数");
- StepInfoListBO stepInfoListBO = stepInfoList.get(stepInfoList.size() - 1);
- log.info("stepInfoListBO={}", stepInfoListBO);
- Long timestamp = stepInfoListBO.getTimestamp();
- step = String.valueOf(stepInfoListBO.getStep());
- log.info("step={}", step);
- } catch (Exception e) {
- log.error("解析步数报错", e);
- throw new IllegalArgumentException("微信步数解析异常");
- }
- return step;
- }
入参实体(结果实体同上BizStep)
- @Data
- public class MineStepDTO {
-
- @ApiModelProperty(value = "小程序用户id",required=true)
- @NotBlank(message = "小程序用户id不能为空")
- private String appUserId;
- }
- @PostMapping("/getStep")
- @ApiOperation(value = "获取我当天的步数" , notes = "")
- @PreAuthorize("hasRole('MINI_APP')")
- public ResponseEntity<BizStep> getMineStep(@RequestBody @Valid MineStepDTO mineStepDTO) {
- return ResultUtil.success(this.bizStepService.getMineStep(mineStepDTO));
- }
service
对我方步数表的查询
- public BizStep getMineStep(MineStepDTO mineStepDTO) {
- LocalDateTime localDateTime = LocalDateTime.now();
- String today = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(localDateTime);
- BizStep bizStep = this.getOne(Wrappers.lambdaQuery(BizStep.class).eq(BizStep::getAppUserId, mineStepDTO.getAppUserId())
- .apply("to_char(created_date,'yyyy-MM-dd') = {0}", today));
- if (null == bizStep) {
- //如果今日无数据 返回0步
- BizStep newBizStep = new BizStep();
- //如果今天数据为空则新增
- newBizStep.setAppUserId(mineStepDTO.getAppUserId());
- newBizStep.setStep(0);
- return newBizStep;
-
- }
- return bizStep;
- }
请求实体
- @Data
- public class RankDTO implements Serializable {
-
- @ApiModelProperty(value = "排序方式 月month 周week 日day", required = true)
- @NotBlank(message = "请选择排序方式")
- private String type;
-
- @ApiModelProperty(value = "小程序用户id", required = true)
- @NotBlank(message = "小程序用户id不能为空")
- private String appUserId;
-
- //当前页,默认第一页
- @ApiModelProperty(value = "当前页")
- private Integer currPage = 1;
-
- //每页记录数,默认为10
- @ApiModelProperty(value = "显示条数")
- private Integer size = 100000;
-
- }
controller
- @PostMapping("/rank")
- public ResponseEntity<List<StepRankVO>> getRank(@RequestBody @Valid RankDTO rankDTO) {
- return ResultUtil.success(this.bizStepService.getRank(rankDTO));
- }
service
- public StepRankVO getRank(RankDTO rankDTO) {
- StepRankVO stepRankVO = new StepRankVO();
- //时间条件
- String startDate = "";
- String endDate = "";
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- Calendar calendar = Calendar.getInstance();
- calendar.setTimeInMillis(System.currentTimeMillis());
-
- if (MONTH.equals(rankDTO.getType())) {
- calendar.add(Calendar.MONTH, 0);
- calendar.set(Calendar.DAY_OF_MONTH, 1);
- startDate = dateFormat.format(calendar.getTime()) + " 00:00:00";
- calendar.add(Calendar.MONTH, 1);
- calendar.set(Calendar.DAY_OF_MONTH, 0);
- endDate = dateFormat.format(calendar.getTime()) + " 23:59:59";
- }
- if (WEEK.equals(rankDTO.getType())) {
- calendar.setFirstDayOfWeek(Calendar.MONDAY);
- calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
- startDate = dateFormat.format(calendar.getTime()) + " 00:00:00";
- calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
- endDate = dateFormat.format(calendar.getTime()) + " 23:59:59";
- }
- if (DAY.equals(rankDTO.getType())) {
- calendar.add(Calendar.DATE, 0);
- String today = dateFormat.format(calendar.getTime());
- startDate = today + " 00:00:00";
- endDate = today + " 23:59:59";
- }
- Page<RankResultVO> ranks = this.bizStepMapper.getRank(new Page<>(rankDTO.getCurrPage(), rankDTO.getSize()), startDate, endDate);
- if (CollectionUtil.isNotEmpty(ranks.getRecords())) {
- stepRankVO.setRankList(ranks.getRecords());
- RankResultVO myRankVO = new RankResultVO();
- List<RankResultVO> myRank = ranks.getRecords().stream().filter(e -> rankDTO.getAppUserId().equals(e.getAppUserId())).collect(Collectors.toList());
- if (CollectionUtil.isNotEmpty(myRank)) {
- BeanUtils.copyProperties(myRank.get(0), myRankVO);
- }
- stepRankVO.setMine(myRankVO);
-
- }
-
- return stepRankVO;
- }
mapper
- @Mapper
- public interface BizStepMapper extends BaseMapper<BizStep> {
-
- Page<RankResultVO> getRank(Page<RankResultVO> page, @Param("startDate") String startDate, @Param("endDate") String endDate);
-
- }
xml
- <select id="getRank" resultType="com.vo.mp.RankResultVO">
- SELECT
- rank ( ) over ( ORDER BY t.step DESC ) AS rank,
- t.step,
- t.app_user_id,
- t.NAME,
- t.avatar
- FROM
- (
- SELECT
- sum( a.step ) AS step,
- a.app_user_id,
- a.NAME,
- a.avatar
- FROM
- ssyy_biz_step a
- where
- to_char(created_date,'yyyy-MM-dd HH24:MI:ss') <![CDATA[>=]]> #{startDate}
- and
- to_char(created_date,'yyyy-MM-dd HH24:MI:ss')<![CDATA[<=]]> #{endDate}
- GROUP BY
- a.app_user_id,
- a.NAME,
- a.avatar
- ) t
- </select>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。