springboot基于小米运动的微信步数刷新

前段时间闲着无聊    给自己手上现有的springboot项目中添加了一个每天自动刷微信步数的模块      可以实现最新邮箱登录   每天自动刷新步数  自定义步数区间  自定义最终步数  已自测    主要功能实现代码在XiaoMiSportUtils里   大佬可以忽略CRUD方法   全部代码奉上 

controller表现层:

package com.ruoyi.wechatCampaign.controller;

import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.wechatCampaign.domain.WechatCampaign;
import com.ruoyi.wechatCampaign.service.IWechatCampaignService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 微信运动Controller
 * 
 * @author Qisheng
 * @date 2023-07-18
 */
@RestController
@RequestMapping("/wechatCampaign/campaign")
public class WechatCampaignController extends BaseController
{
    @Autowired
    private IWechatCampaignService wechatCampaignService;

    /**
     * 查询微信运动列表
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:list')")
    @GetMapping("/list")
    public TableDataInfo list(WechatCampaign wechatCampaign)
    {
        startPage();
        List<WechatCampaign> list = wechatCampaignService.selectWechatCampaignList(wechatCampaign);
        return getDataTable(list);
    }

    /**
     * 导出微信运动列表
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:export')")
    @Log(title = "微信运动", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, WechatCampaign wechatCampaign)
    {
        List<WechatCampaign> list = wechatCampaignService.selectWechatCampaignList(wechatCampaign);
        ExcelUtil<WechatCampaign> util = new ExcelUtil<WechatCampaign>(WechatCampaign.class);
        util.exportExcel(response, list, "微信运动数据");
    }

    /**
     * 获取微信运动详细信息
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(wechatCampaignService.selectWechatCampaignById(id));
    }

    /**
     * 新增微信运动
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:add')")
    @Log(title = "微信运动", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody WechatCampaign wechatCampaign)
    {
        return toAjax(wechatCampaignService.insertWechatCampaign(wechatCampaign));
    }

    /**
     * 修改微信运动
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:edit')")
    @Log(title = "微信运动", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody WechatCampaign wechatCampaign)
    {
        return toAjax(wechatCampaignService.updateWechatCampaign(wechatCampaign));
    }

    /**
     * 删除微信运动
     */
    @PreAuthorize("@ss.hasPermi('wechatCampaign:campaign:remove')")
    @Log(title = "微信运动", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(wechatCampaignService.deleteWechatCampaignByIds(ids));
    }
}

domain实体类:

package com.ruoyi.wechatCampaign.domain;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;

/**
 * 微信运动对象 wechat_campaign
 * 
 * @author Qisheng
 * @date 2023-07-18
 */
public class WechatCampaign extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** ID */
    private Long id;

    /** 邮箱号 */
    @Excel(name = "邮箱号")
    private String username;

    /** 密码 */
    @Excel(name = "密码")
    private String password;

    /** 最小随机数 */
    @Excel(name = "最小随机数")
    private String mixRandom;

    /** 最大随机数 */
    @Excel(name = "最大随机数")
    private String maxRandom;

    /** 步数 */
    @Excel(name = "步数")
    private String steps;

    /** 最终步数 */
    @Excel(name = "最终步数")
    private String endSteps;

    public void setId(Long id) 
    {
        this.id = id;
    }

    public Long getId() 
    {
        return id;
    }
    public void setUsername(String username) 
    {
        this.username = username;
    }

    public String getUsername() 
    {
        return username;
    }
    public void setPassword(String password) 
    {
        this.password = password;
    }

    public String getPassword() 
    {
        return password;
    }
    public void setMixRandom(String mixRandom)
    {
        this.mixRandom = mixRandom;
    }

    public String getMixRandom()
    {
        return mixRandom;
    }

    public void setMaxRandom(String maxRandom)
    {
        this.maxRandom = maxRandom;
    }

    public String getMaxRandom()
    {
        return maxRandom;
    }

    public void setSteps(String steps) 
    {
        this.steps = steps;
    }

    public String getSteps() 
    {
        return steps;
    }
    public void setEndSteps(String endSteps) 
    {
        this.endSteps = endSteps;
    }

    public String getEndSteps() 
    {
        return endSteps;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("id", getId())
            .append("username", getUsername())
            .append("password", getPassword())
            .append("mixRandom", getMixRandom())
            .append("maxRandom", getMaxRandom())
            .append("steps", getSteps())
            .append("endSteps", getEndSteps())
            .append("createBy", getCreateBy())
            .append("createTime", getCreateTime())
            .append("updateBy", getUpdateBy())
            .append("updateTime", getUpdateTime())
            .append("remark", getRemark())
            .toString();
    }
}

mapper数据层:

package com.ruoyi.wechatCampaign.mapper;

import java.util.List;
import com.ruoyi.wechatCampaign.domain.WechatCampaign;

/**
 * 微信运动Mapper接口
 * 
 * @author Qisheng
 * @date 2023-07-18
 */
public interface WechatCampaignMapper 
{
    /**
     * 查询微信运动
     * 
     * @param id 微信运动主键
     * @return 微信运动
     */
    public WechatCampaign selectWechatCampaignById(Long id);

    /**
     * 查询微信运动列表
     * 
     * @param wechatCampaign 微信运动
     * @return 微信运动集合
     */
    public List<WechatCampaign> selectWechatCampaignList(WechatCampaign wechatCampaign);

    /**
     * 新增微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    public int insertWechatCampaign(WechatCampaign wechatCampaign);

    /**
     * 修改微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    public int updateWechatCampaign(WechatCampaign wechatCampaign);

    /**
     * 删除微信运动
     * 
     * @param id 微信运动主键
     * @return 结果
     */
    public int deleteWechatCampaignById(Long id);

    /**
     * 批量删除微信运动
     * 
     * @param ids 需要删除的数据主键集合
     * @return 结果
     */
    public int deleteWechatCampaignByIds(Long[] ids);
}

service接口:

package com.ruoyi.wechatCampaign.service;

import java.util.List;
import com.ruoyi.wechatCampaign.domain.WechatCampaign;

/**
 * 微信运动Service接口
 * 
 * @author Qisheng
 * @date 2023-07-18
 */
public interface IWechatCampaignService 
{
    /**
     * 查询微信运动
     * 
     * @param id 微信运动主键
     * @return 微信运动
     */
    public WechatCampaign selectWechatCampaignById(Long id);

    /**
     * 查询微信运动列表
     * 
     * @param wechatCampaign 微信运动
     * @return 微信运动集合
     */
    public List<WechatCampaign> selectWechatCampaignList(WechatCampaign wechatCampaign);

    /**
     * 新增微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    public int insertWechatCampaign(WechatCampaign wechatCampaign);

    /**
     * 修改微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    public int updateWechatCampaign(WechatCampaign wechatCampaign);

    /**
     * 批量删除微信运动
     * 
     * @param ids 需要删除的微信运动主键集合
     * @return 结果
     */
    public int deleteWechatCampaignByIds(Long[] ids);

    /**
     * 删除微信运动信息
     * 
     * @param id 微信运动主键
     * @return 结果
     */
    public int deleteWechatCampaignById(Long id);
}

service逻辑层:

(1)WechatCampaignServiceImpl

package com.ruoyi.wechatCampaign.service.impl;

import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.wechatCampaign.mapper.WechatCampaignMapper;
import com.ruoyi.wechatCampaign.domain.WechatCampaign;
import com.ruoyi.wechatCampaign.service.IWechatCampaignService;

/**
 * 微信运动Service业务层处理
 * 
 * @author Qisheng
 * @date 2023-07-18
 */
@Service
public class WechatCampaignServiceImpl implements IWechatCampaignService 
{
    @Autowired
    private WechatCampaignMapper wechatCampaignMapper;

    /**
     * 查询微信运动
     * 
     * @param id 微信运动主键
     * @return 微信运动
     */
    @Override
    public WechatCampaign selectWechatCampaignById(Long id)
    {
        return wechatCampaignMapper.selectWechatCampaignById(id);
    }

    /**
     * 查询微信运动列表
     * 
     * @param wechatCampaign 微信运动
     * @return 微信运动
     */
    @Override
    public List<WechatCampaign> selectWechatCampaignList(WechatCampaign wechatCampaign)
    {
        return wechatCampaignMapper.selectWechatCampaignList(wechatCampaign);
    }

    /**
     * 新增微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    @Override
    public int insertWechatCampaign(WechatCampaign wechatCampaign)
    {
        wechatCampaign.setCreateTime(DateUtils.getNowDate());
        return wechatCampaignMapper.insertWechatCampaign(wechatCampaign);
    }

    /**
     * 修改微信运动
     * 
     * @param wechatCampaign 微信运动
     * @return 结果
     */
    @Override
    public int updateWechatCampaign(WechatCampaign wechatCampaign)
    {
        wechatCampaign.setUpdateTime(DateUtils.getNowDate());
        return wechatCampaignMapper.updateWechatCampaign(wechatCampaign);
    }

    /**
     * 批量删除微信运动
     * 
     * @param ids 需要删除的微信运动主键
     * @return 结果
     */
    @Override
    public int deleteWechatCampaignByIds(Long[] ids)
    {
        return wechatCampaignMapper.deleteWechatCampaignByIds(ids);
    }

    /**
     * 删除微信运动信息
     * 
     * @param id 微信运动主键
     * @return 结果
     */
    @Override
    public int deleteWechatCampaignById(Long id)
    {
        return wechatCampaignMapper.deleteWechatCampaignById(id);
    }
}

(2) XiaoMiSportUtils

package com.ruoyi.wechatCampaign.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.ruoyi.wechatCampaign.domain.WechatCampaign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @Name: Qisheng
 * @projectName: yltx
 * @version: 1.0.0
 * @createTime: 2023年07月06日 14:59:00
 * @Description:
 */
@Component("XiaoMiSportUtils")
public class XiaoMiSportUtils {

    @Autowired
    private WechatCampaignServiceImpl wechatCampaignService;
    private static final Log log = LogFactory.get();
    private static final HashMap<String, String> headers;

    static {
        headers = new HashMap<>();
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        headers.put("User-Agent", "MiFit/4.6.0 (iPhone; iOS 14.0.1; Scale/2.00)");
    }

    /**
     * 登录小米运动,并获取到login_token和user_id
     */
    public static String[] login(String username, String password) {
        String[] login = new String[3];
        HttpResponse response = HttpRequest.post("https://api-user.huami.com/registrations/" + username + "/tokens")
                .headerMap(headers, true)
                .form("client_id", "HuaMi")
                .form("password", password)
                .form("redirect_uri", "https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html")
                .form("token", "access").execute();

        log.info("请求状态码:{}", response.getStatus());
        String location = response.header("Location");
        List<String> list = HttpUtil.decodeParams(location, "UTF-8").get("access");
        if (list == null){
            return null;
        }else {
            login[0] = list.get(0);
        }

        String body = HttpRequest.post("https://account.huami.com/v2/client/login")
                .headerMap(headers, true)
                .form("app_name", "com.xiaomi.hm.health")
                .form("app_version", "4.6.0")
                .form("code", login[0])
                .form("country_code", "CN")
                .form("device_id", "2C8B4939-0CCD-4E94-8CBA-CB8EA6E613A1")
                .form("device_model", "phone")
                .form("grant_type", "access_token")
                .form("third_name", "email")
                .execute().body();

        String login_token = JSONUtil.parseObj(JSONUtil.parseObj(body).getStr("token_info")).getStr("login_token");
        login[1] = login_token;
        String user_id = JSONUtil.parseObj(JSONUtil.parseObj(body).getStr("token_info")).getStr("user_id");
        login[2] = user_id;
        return login;
    }

    /**
     * 获取服务器时间戳
     */
    public static String getTime() {
        String body = HttpRequest.get("http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp").execute().body();
        return JSONUtil.parseObj(JSONUtil.parseObj(body).getStr("data")).getStr("t");
    }

    /**
     * 获取当前appToken
     * @param loginToken 用户token
     */
    public static String getAppToken(String loginToken) {
        String body = HttpRequest.get("https://account-cn.huami.com/v1/client/app_tokens?app_name=com.xiaomi.hm.health&dn=api-user.huami.com%2Capi-mifit.huami.com%2Capp-analytics.huami.com&login_token=" + loginToken)
                .headerMap(headers, true)
                .execute().body();
        String app_token = JSONUtil.parseObj(JSONUtil.parseObj(body).getStr("token_info")).getStr("app_token");
        log.info("app_token获取成功...");
        return app_token;
    }

    /**
     * 替换请求参数中的数据
     *
     * @param time  当前时间
     * @param steps 运动步数
     * @return
     */
    public static String dataJson(String time, String steps) {
        String dataJson = "%5B%7B%22data_hr%22%3A%22%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FVv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0v%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0n%5C%2Fa%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1FK%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9PTFFpaf9L%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FR%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0j%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9K%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzf%5C%2F%5C%2F%5C%2F86%5C%2Fzr%5C%2FOv88%5C%2Fzf%5C%2FPf%5C%2F%5C%2F%5C%2F0v%5C%2FS%5C%2F8%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FSf%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fz3%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0r%5C%2FOv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F9L%5C%2Fzb%5C%2FSf9K%5C%2F0v%5C%2FRf9H%5C%2Fzj%5C%2FSf9K%5C%2F0%5C%2F%5C%2FN%5C%2F%5C%2F%5C%2F%5C%2F0D%5C%2FSf83%5C%2Fzr%5C%2FPf9M%5C%2F0v%5C%2FOv9e%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FS%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fzv%5C%2F%5C%2Fz7%5C%2FO%5C%2F83%5C%2Fzv%5C%2FN%5C%2F83%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fz%5C%2F%5C%2FNv83%5C%2Fzn%5C%2FXv84%5C%2Fzr%5C%2FPP84%5C%2Fzj%5C%2FN%5C%2F9e%5C%2Fzr%5C%2FN%5C%2F89%5C%2F03%5C%2FP%5C%2F89%5C%2Fz3%5C%2FQ%5C%2F9N%5C%2F0v%5C%2FTv9C%5C%2F0H%5C%2FOf9D%5C%2Fzz%5C%2FOf88%5C%2Fz%5C%2F%5C%2FPP9A%5C%2Fzr%5C%2FN%5C%2F86%5C%2Fzz%5C%2FNv87%5C%2F0D%5C%2FOv84%5C%2F0v%5C%2FO%5C%2F84%5C%2Fzf%5C%2FMP83%5C%2FzH%5C%2FNv83%5C%2Fzf%5C%2FN%5C%2F84%5C%2Fzf%5C%2FOf82%5C%2Fzf%5C%2FOP83%5C%2Fzb%5C%2FMv81%5C%2FzX%5C%2FR%5C%2F9L%5C%2F0v%5C%2FO%5C%2F9I%5C%2F0T%5C%2FS%5C%2F9A%5C%2Fzn%5C%2FPf89%5C%2Fzn%5C%2FNf9K%5C%2F07%5C%2FN%5C%2F83%5C%2Fzn%5C%2FNv83%5C%2Fzv%5C%2FO%5C%2F9A%5C%2F0H%5C%2FOf8%5C%2F%5C%2Fzj%5C%2FPP83%5C%2Fzj%5C%2FS%5C%2F87%5C%2Fzj%5C%2FNv84%5C%2Fzf%5C%2FOf83%5C%2Fzf%5C%2FOf83%5C%2Fzb%5C%2FNv9L%5C%2Fzj%5C%2FNv82%5C%2Fzb%5C%2FN%5C%2F85%5C%2Fzf%5C%2FN%5C%2F9J%5C%2Fzf%5C%2FNv83%5C%2Fzj%5C%2FNv84%5C%2F0r%5C%2FSv83%5C%2Fzf%5C%2FMP%5C%2F%5C%2F%5C%2Fzb%5C%2FMv82%5C%2Fzb%5C%2FOf85%5C%2Fz7%5C%2FNv8%5C%2F%5C%2F0r%5C%2FS%5C%2F85%5C%2F0H%5C%2FQP9B%5C%2F0D%5C%2FNf89%5C%2Fzj%5C%2FOv83%5C%2Fzv%5C%2FNv8%5C%2F%5C%2F0f%5C%2FSv9O%5C%2F0ZeXv%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F1X%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9B%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2FTP%5C%2F%5C%2F%5C%2F1b%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F0%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F9N%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2F%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%5C%2Fv7%2B%22%2C%22date%22%3A%22" + time + "%22%2C%22data%22%3A%5B%7B%22start%22%3A0%2C%22stop%22%3A1439%2C%22value%22%3A%22UA8AUBQAUAwAUBoAUAEAYCcAUBkAUB4AUBgAUCAAUAEAUBkAUAwAYAsAYB8AYB0AYBgAYCoAYBgAYB4AUCcAUBsAUB8AUBwAUBIAYBkAYB8AUBoAUBMAUCEAUCIAYBYAUBwAUCAAUBgAUCAAUBcAYBsAYCUAATIPYD0KECQAYDMAYB0AYAsAYCAAYDwAYCIAYB0AYBcAYCQAYB0AYBAAYCMAYAoAYCIAYCEAYCYAYBsAYBUAYAYAYCIAYCMAUB0AUCAAUBYAUCoAUBEAUC8AUB0AUBYAUDMAUDoAUBkAUC0AUBQAUBwAUA0AUBsAUAoAUCEAUBYAUAwAUB4AUAwAUCcAUCYAUCwKYDUAAUUlEC8IYEMAYEgAYDoAYBAAUAMAUBkAWgAAWgAAWgAAWgAAWgAAUAgAWgAAUBAAUAQAUA4AUA8AUAkAUAIAUAYAUAcAUAIAWgAAUAQAUAkAUAEAUBkAUCUAWgAAUAYAUBEAWgAAUBYAWgAAUAYAWgAAWgAAWgAAWgAAUBcAUAcAWgAAUBUAUAoAUAIAWgAAUAQAUAYAUCgAWgAAUAgAWgAAWgAAUAwAWwAAXCMAUBQAWwAAUAIAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWgAAWREAWQIAUAMAWSEAUDoAUDIAUB8AUCEAUC4AXB4AUA4AWgAAUBIAUA8AUBAAUCUAUCIAUAMAUAEAUAsAUAMAUCwAUBYAWgAAWgAAWgAAWgAAWgAAWgAAUAYAWgAAWgAAWgAAUAYAWwAAWgAAUAYAXAQAUAMAUBsAUBcAUCAAWwAAWgAAWgAAWgAAWgAAUBgAUB4AWgAAUAcAUAwAWQIAWQkAUAEAUAIAWgAAUAoAWgAAUAYAUB0AWgAAWgAAUAkAWgAAWSwAUBIAWgAAUC4AWSYAWgAAUAYAUAoAUAkAUAIAUAcAWgAAUAEAUBEAUBgAUBcAWRYAUA0AWSgAUB4AUDQAUBoAXA4AUA8AUBwAUA8AUA4AUA4AWgAAUAIAUCMAWgAAUCwAUBgAUAYAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAUAAAWwAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAeSEAeQ8AcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBcAcAAAcAAAcCYOcBUAUAAAUAAAUAAAUAAAUAUAUAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCgAeQAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcBgAeQAAcAAAcAAAegAAegAAcAAAcAcAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCkAeQAAcAcAcAAAcAAAcAwAcAAAcAAAcAIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcCIAeQAAcAAAcAAAcAAAcAAAcAAAeRwAeQAAWgAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcBoAeScAeQAAegAAcBkAeQAAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAAAegAAegAAcAAAcAAAcBgAeQAAcAAAcAAAcAAAcAAAcAAAcAkAegAAegAAcAcAcAAAcAcAcAAAcAAAcAAAcAAAcA8AeQAAcAAAcAAAeRQAcAwAUAAAUAAAUAAAUAAAUAAAUAAAcAAAcBEAcA0AcAAAWQsAUAAAUAAAUAAAUAAAUAAAcAAAcAoAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAYAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBYAegAAcAAAcAAAegAAcAcAcAAAcAAAcAAAcAAAcAAAeRkAegAAegAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAEAcAAAcAAAcAAAcAUAcAQAcAAAcBIAeQAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBsAcAAAcAAAcBcAeQAAUAAAUAAAUAAAUAAAUAAAUBQAcBYAUAAAUAAAUAoAWRYAWTQAWQAAUAAAUAAAUAAAcAAAcAAAcAAAcAAAcAAAcAMAcAAAcAQAcAAAcAAAcAAAcDMAeSIAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcAAAcBQAeQwAcAAAcAAAcAAAcAMAcAAAeSoAcA8AcDMAcAYAeQoAcAwAcFQAcEMAeVIAaTYAbBcNYAsAYBIAYAIAYAIAYBUAYCwAYBMAYDYAYCkAYDcAUCoAUCcAUAUAUBAAWgAAYBoAYBcAYCgAUAMAUAYAUBYAUA4AUBgAUAgAUAgAUAsAUAsAUA4AUAMAUAYAUAQAUBIAASsSUDAAUDAAUBAAYAYAUBAAUAUAUCAAUBoAUCAAUBAAUAoAYAIAUAQAUAgAUCcAUAsAUCIAUCUAUAoAUA4AUB8AUBkAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAAfgAA%22%2C%22tz%22%3A32%2C%22did%22%3A%22DA932FFFFE8816E7%22%2C%22src%22%3A24%7D%5D%2C%22summary%22%3A%22%7B%5C%22v%5C%22%3A6%2C%5C%22slp%5C%22%3A%7B%5C%22st%5C%22%3A1628296479%2C%5C%22ed%5C%22%3A1628296479%2C%5C%22dp%5C%22%3A0%2C%5C%22lt%5C%22%3A0%2C%5C%22wk%5C%22%3A0%2C%5C%22usrSt%5C%22%3A-1440%2C%5C%22usrEd%5C%22%3A-1440%2C%5C%22wc%5C%22%3A0%2C%5C%22is%5C%22%3A0%2C%5C%22lb%5C%22%3A0%2C%5C%22to%5C%22%3A0%2C%5C%22dt%5C%22%3A0%2C%5C%22rhr%5C%22%3A0%2C%5C%22ss%5C%22%3A0%7D%2C%5C%22stp%5C%22%3A%7B%5C%22ttl%5C%22%3A" + steps + "%2C%5C%22dis%5C%22%3A10627%2C%5C%22cal%5C%22%3A510%2C%5C%22wk%5C%22%3A41%2C%5C%22rn%5C%22%3A50%2C%5C%22runDist%5C%22%3A7654%2C%5C%22runCal%5C%22%3A397%2C%5C%22stage%5C%22%3A%5B%7B%5C%22start%5C%22%3A327%2C%5C%22stop%5C%22%3A341%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A481%2C%5C%22cal%5C%22%3A13%2C%5C%22step%5C%22%3A680%7D%2C%7B%5C%22start%5C%22%3A342%2C%5C%22stop%5C%22%3A367%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A368%2C%5C%22stop%5C%22%3A377%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A378%2C%5C%22stop%5C%22%3A386%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A387%2C%5C%22stop%5C%22%3A393%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A394%2C%5C%22stop%5C%22%3A398%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A399%2C%5C%22stop%5C%22%3A414%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A415%2C%5C%22stop%5C%22%3A427%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A428%2C%5C%22stop%5C%22%3A433%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%2C%7B%5C%22start%5C%22%3A434%2C%5C%22stop%5C%22%3A444%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A2295%2C%5C%22cal%5C%22%3A95%2C%5C%22step%5C%22%3A2874%7D%2C%7B%5C%22start%5C%22%3A445%2C%5C%22stop%5C%22%3A455%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1592%2C%5C%22cal%5C%22%3A88%2C%5C%22step%5C%22%3A1664%7D%2C%7B%5C%22start%5C%22%3A456%2C%5C%22stop%5C%22%3A466%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1072%2C%5C%22cal%5C%22%3A51%2C%5C%22step%5C%22%3A1245%7D%2C%7B%5C%22start%5C%22%3A467%2C%5C%22stop%5C%22%3A477%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A1036%2C%5C%22cal%5C%22%3A57%2C%5C%22step%5C%22%3A1124%7D%2C%7B%5C%22start%5C%22%3A478%2C%5C%22stop%5C%22%3A488%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A488%2C%5C%22cal%5C%22%3A19%2C%5C%22step%5C%22%3A607%7D%2C%7B%5C%22start%5C%22%3A489%2C%5C%22stop%5C%22%3A499%2C%5C%22mode%5C%22%3A4%2C%5C%22dis%5C%22%3A2220%2C%5C%22cal%5C%22%3A120%2C%5C%22step%5C%22%3A2371%7D%2C%7B%5C%22start%5C%22%3A500%2C%5C%22stop%5C%22%3A511%2C%5C%22mode%5C%22%3A3%2C%5C%22dis%5C%22%3A1268%2C%5C%22cal%5C%22%3A59%2C%5C%22step%5C%22%3A1489%7D%2C%7B%5C%22start%5C%22%3A512%2C%5C%22stop%5C%22%3A522%2C%5C%22mode%5C%22%3A1%2C%5C%22dis%5C%22%3A152%2C%5C%22cal%5C%22%3A4%2C%5C%22step%5C%22%3A238%7D%5D%7D%2C%5C%22goal%5C%22%3A8000%2C%5C%22tz%5C%22%3A%5C%2228800%5C%22%7D%22%2C%22source%22%3A24%2C%22type%22%3A0%7D%5D";
        return dataJson;
    }

    /**
     * 发送刷步数请求
     * @param username 用户名手机号
     * @param password 密码
     * @param steps    步数
     * @return
     */
    public static String sport(String username, String password, String steps) {
        String[] login = login(username, password);
        if (login == null){
            return null;
        }
        String t = getTime();
        String dataJson = dataJson(DateUtil.today(), steps);
        String appToken = getAppToken(login[1]);
        String bodys = StrFormatter.format("userid={}&last_sync_data_time=1597306380&device_type=0&last_deviceid=DA932FFFFE8816E7&data_json={}", login[2], dataJson);

        return HttpRequest.post("https://api-mifit-cn.huami.com/v1/data/band_data.json?&t=" + t)
                .header("apptoken", appToken)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .body(bodys)
                .execute().body();
    }

    private Map<String, Integer> newStepsMap = new HashMap<>();

    /**
     * 定时执行随机次数
     */
    public void motion() {
        WechatCampaign wechatCampaign = new WechatCampaign();
        List<WechatCampaign> sportList = wechatCampaignService.selectWechatCampaignList(wechatCampaign);

        LocalTime currentTime = LocalTime.now();
        Random random = new Random();

        for (WechatCampaign list : sportList) {
            String username = list.getUsername();
            String password = list.getPassword();
            String mixRandom = list.getMixRandom();
            String maxRandom = list.getMaxRandom();

            int newSteps = newStepsMap.getOrDefault(username, 0); // 从Map中获取上次的newSteps值,默认为0

            if (currentTime.getHour() == 9 && currentTime.getMinute() == 0) {
                newSteps = 0;
            }

            if (list.getEndSteps() != null && !list.getEndSteps().isEmpty()) {
                int endSteps = Integer.parseInt(list.getEndSteps());
                int max = Integer.parseInt(maxRandom);
                int a = endSteps - max;

                if (newSteps < a && currentTime.getHour() != 22) {
                    int randomValue = random.nextInt(max - Integer.parseInt(mixRandom) + 1) + Integer.parseInt(mixRandom);
                    System.out.println("添加随机步数:" + randomValue);
                    newSteps += randomValue;

                    // 调用 sport 方法,传递数据发送刷步请求
                    System.out.println("++++++++++++++++++++" + username + "," + newSteps + "++++++++++++++++++++");
                    sport(username, password, String.valueOf(newSteps));
                    System.out.println("发送步数:" + newSteps);
                } else {
                    System.out.println("步数即将达标");
                }
                // 在22点的时候发送最大步数
                if (currentTime.getHour() == 22) {
                    sport(username, password, String.valueOf(endSteps));
                    System.out.println("发送最大步数:" + endSteps);
                }
            } else {
                int randomValue = random.nextInt(Integer.parseInt(maxRandom) - Integer.parseInt(mixRandom) + 1) + Integer.parseInt(mixRandom);
                System.out.println("添加随机步数:" + randomValue);
                newSteps += randomValue;

                // 调用 sport 方法,传递数据发送刷步请求
                System.out.println("**********************" + username + "," + newSteps + "**********************");
                sport(username, password, String.valueOf(newSteps));
                System.out.println("发送步数:" + newSteps);
            }

            newStepsMap.put(username, newSteps); // 将更新后的newSteps值存回Map中
        }
    }

    /**
     * 通过定时任务传参执行一次
     * @param username 邮箱账号
     * @param password 密码
     * @param steps 步数
     */
    public void maxMotion(String username, String password, String steps) {
        sport(username, password, steps);
    }
}

xml文件:

<?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.ruoyi.wechatCampaign.mapper.WechatCampaignMapper">
    
    <resultMap type="WechatCampaign" id="WechatCampaignResult">
        <result property="id"    column="id"    />
        <result property="username"    column="username"    />
        <result property="password"    column="password"    />
        <result property="mixRandom"    column="mix_random"    />
        <result property="maxRandom"    column="max_random"    />
        <result property="steps"    column="steps"    />
        <result property="endSteps"    column="end_steps"    />
        <result property="createBy"    column="create_by"    />
        <result property="createTime"    column="create_time"    />
        <result property="updateBy"    column="update_by"    />
        <result property="updateTime"    column="update_time"    />
        <result property="remark"    column="remark"    />
    </resultMap>

    <sql id="selectWechatCampaignVo">
        select id, username, password, mix_random, max_random, steps, end_steps, create_by, create_time, update_by, update_time, remark from wechat_campaign
    </sql>

    <select id="selectWechatCampaignList" parameterType="WechatCampaign" resultMap="WechatCampaignResult">
        <include refid="selectWechatCampaignVo"/>
        <where>  
            <if test="username != null  and username != ''"> and username like concat('%', #{username}, '%')</if>
            <if test="password != null  and password != ''"> and password = #{password}</if>
            <if test="mixRandom != null  and mixRandom != ''"> and mix_random = #{mixRandom}</if>
            <if test="maxRandom != null  and maxRandom != ''"> and max_random = #{maxRandom}</if>
            <if test="steps != null  and steps != ''"> and steps = #{steps}</if>
            <if test="endSteps != null  and endSteps != ''"> and end_steps = #{endSteps}</if>
        </where>
    </select>
    
    <select id="selectWechatCampaignById" parameterType="Long" resultMap="WechatCampaignResult">
        <include refid="selectWechatCampaignVo"/>
        where id = #{id}
    </select>
        
    <insert id="insertWechatCampaign" parameterType="WechatCampaign" useGeneratedKeys="true" keyProperty="id">
        insert into wechat_campaign
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username != null">username,</if>
            <if test="password != null">password,</if>
            <if test="random != null">random,</if>
            <if test="steps != null">steps,</if>
            <if test="endSteps != null">end_steps,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="updateBy != null">update_by,</if>
            <if test="updateTime != null">update_time,</if>
            <if test="remark != null">remark,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="username != null">#{username},</if>
            <if test="password != null">#{password},</if>
            <if test="random != null">#{random},</if>
            <if test="steps != null">#{steps},</if>
            <if test="endSteps != null">#{endSteps},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="updateBy != null">#{updateBy},</if>
            <if test="updateTime != null">#{updateTime},</if>
            <if test="remark != null">#{remark},</if>
         </trim>
    </insert>

    <update id="updateWechatCampaign" parameterType="WechatCampaign">
        update wechat_campaign
        <trim prefix="SET" suffixOverrides=",">
            <if test="username != null">username = #{username},</if>
            <if test="password != null">password = #{password},</if>
            <if test="random != null">random = #{random},</if>
            <if test="steps != null">steps = #{steps},</if>
            <if test="endSteps != null">end_steps = #{endSteps},</if>
            <if test="createBy != null">create_by = #{createBy},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="remark != null">remark = #{remark},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteWechatCampaignById" parameterType="Long">
        delete from wechat_campaign where id = #{id}
    </delete>

    <delete id="deleteWechatCampaignByIds" parameterType="String">
        delete from wechat_campaign where id in 
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>

mysql建表语句:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for wechat_campaign
-- ----------------------------
DROP TABLE IF EXISTS `wechat_campaign`;
CREATE TABLE `wechat_campaign`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱号',
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '密码',
  `mix_random` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最小随机数',
  `max_random` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最大随机数',
  `steps` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '步数',
  `end_steps` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最终步数',
  `create_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建者',
  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更新者',
  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '微信运动' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

可以直接在数据库放数据   前端代码涉及太多  暂时没有写  有大佬有优化版可以评论区留言   参考博客链接:Java实现微信运动步数(已自测)_java 微信刷步_辰兮ing的博客-CSDN博客

Spring Boot中获取微信运动步数通常涉及到微信公众号的OAuth授权以及微信开放平台提供的运动数据API。以下是简单的步骤: 1. **注册并配置微信开发者账户**: - 注册微信公众平台账号,并启用“微信运动”相关的权限。 - 获取AppID、AppSecret等必要的OAuth认证信息。 2. **添加微信SDK依赖**: - 将微信JS-SDK引入到项目中,例如通过maven或gradle添加微信官方提供的库。 3. **设置OAuth授权**: - 使用`wx.login`方法引导用户授权获取access_token和openid,这是访问用户运动数据的前提。 4. **请求运动数据**: - 调用微信运动的API `GET /api/mpsns/getmove`, 需要带上access_token和用户openid。这个API会返回用户的运动数据,包括步数等信息。 5. **处理响应**: - 确保所有的敏感数据传输都加密,并遵守微信的隐私政策。 下面是一个简化的示例代码片段(假设使用了Spring Security OAuth2和HttpURLConnection): ```java // 获取access_token String accessToken = getAccessTokenFromWechat(); // 获取用户运动数据 String url = "https://api.weixin.qq.com/mpsns/getmove?access_token=" + accessToken + "&open_id=USER_OPEN_ID"; URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("GET"); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String line; StringBuilder response = new StringBuilder(); while ((line = in.readLine()) != null) { response.append(line); } in.close(); Map<String, Object> jsonMap = JSON.parseObject(response.toString(), Map.class); // 解析JSON // 提取步数 Integer stepCount = (Integer) jsonMap.get("step"); // 存储或显示步数 // ... ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值