前言大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂
现在是2022年5月4日19:25:55!今天写了个这样的功能:
某用户在一天内有多个训练项目,比如:晨跑,有氧训练,跳绳这三个项目。这三个训练项目都在数据库中有记录,每个项目都有开始时间,结束时间以及状态。状态包含:未开始,进行中和已结束。
下图展示的就是训练项目
用户早上醒来之后,点击第一个晨跑的小卡片,那么就开始记录当前时间就是晨跑的开始时间。训练完之后,用户接着点击有氧训练的小卡片,那么此时,晨跑项目的结束时间就是当前时间,有氧训练的开始时间也是当前时间,此时的晨跑状态是已结束,有氧训练的状态是进行中
没明白的话多看几遍就明白了,哈哈哈,这儿有点绕。
因为这是两个系统,训练项目所属一个项目,调用的是另一个项目,下面说一下我的实现方式。
实现思路- 在训练项目的系统上,只实现更新 *** 作,传参:项目id,开始时间,结束时间,状态
- 在调用的系统上,编写业务代码块,一共有三个接口。
- 接口一:记录第一个训练项目的开始时间,将当前训练项目的id放在redis中。
- 接口二:从
redis
中获取上一个动作的id
,传递动作的id
,时间戳,然后修改上一个动作的结束时间是当前的时间戳,第一个动作的状态是【已结束】,当前动作的开始时间是当前的时间戳,状态是【训练中】,删除上一个动作的id
,将当前动作的id
放在redis
里面 - 接口三:最后一个动作的结束:传递当前方案的
id
,动作的id
,用户id
,时间戳,然后修改当前动作的结束时间是时间戳,状态是【已结束】,删掉redis里面的用户id
说明:大家可以看到,我将第一个训练项目的id
放在了redis
中,这么放的目的就是下一个训练项目传过来之后,更好的知道上一个训练项目是哪个,因为我们需要更改它的状态和结束时间。之后还需要更改当前训练项目的开始时间和状态。以此类推,一直到最后一个。
接口三主要实现的功能就是更新最后一个训练项目的结束时间,这样我们就可以依次更改每个训练项目的开始时间、结束时间以及训练状态。
上面还是有点绕,大家可以仔细的看看~
实现代码下面我来介绍一下代码是怎么实现的。
首先是训练项目中的更新 *** 作,这个方法就一个修改的 *** 作,没啥特别复杂的,下面是代码:
/**
* 根据项目project的id,修改动作状态和开始时间,结束时间
* 参数:动作id,状态,开始时间,结束时间
*/
@PostMapping(value = "/updateProjectById")
public String updateProjectById(@RequestHeader("Authorization")
String token,
Long pid,
int status,
Long beginTime,
Long endTime) {
JSONObject jsonObject = new JSONObject();
//1.验证token
boolean isOk = TokenUtil.verify(token);
if (!isOk) {
jsonObject.put("code", 401);
jsonObject.put("msg", "令牌失效");
return jsonObject.toString();
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
//查询
Project project = projectService.getById(pid);
//训练项目状态,0未开始,1进行中,2已完成
project.setProjectStatus(status + "");
//将时间戳转换成时间
if (beginTime != null) {
String kstime = DateParseUtils.getTimeChuo(beginTime);
project.setBeginTime(format.parse(kstime));
}
//结束时间
if (endTime != null) {
String jstime = DateParseUtils.getTimeChuo(endTime);
project.setEndTime(format.parse(jstime));
}
projectService.updateById(project);
jsonObject.put("code",200);
jsonObject.put("msg"," *** 作成功");
jsonObject.put("status",true);
} catch (ParseException e) {
jsonObject.put("code",500);
jsonObject.put("msg"," *** 作失败");
jsonObject.put("status",false);
e.printStackTrace();
}
return jsonObject.toJSONString();
}
可以发现,开始时间和结束时间都不能是必填,因为在更新第一个训练项目的时候,我们只能知道当前的时间是开始时间,并不知道何时结束。同理,在更新第二个训练项目时,我们只需拿着当前时间更新上一个训练项目的结束时间就行。
下面是调用方的实现:
- 将参数封装成实体:
package org.springblade.modules.system.vo;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author: muxiongxiong
* @date: 2022年04月30日 20:34
* 公众号:雄雄的小课堂
* 博客:https://blog.csdn.net/qq_34137397
* 个人站:http://www.穆雄雄.com
* 个人站:http://www.muxiongxiong.cn
* @Description: 类的描述
*/
@Data
@ApiModel(value = "TrainingVO对象", description = "TrainingVO对象")
public class TrainingVO {
/**
* 动作id
*/
private Long projectId;
/**
* 方案id
*/
private Long programmeId;
/**
* 用户id
*/
private Long userId;
/**
* 动作状态
*/
private Integer status;
/**
* 时间戳 接收前台传过来的时间戳
*/
private Long time;
/**
* 业务上处理的动作,开始时间
*/
private Long beginTime;
/**
* 业务上处理的动作,结束时间
*/
private Long endTime;
}
- 公共接口,也就是更新的接口:
/**
* 公共的接口
* 调用训练方案的
* 更新动作的状态和时间
*
* @param trainingVO
* @return
*/
@Override
public R updateTrainingProgrammeAndProjectStatusAndTime(TrainingVO trainingVO) {
//判断是否为空
R rt = getToken();
String token = "";
if (rt != null) {
JSONObject jsonObject = (JSONObject) rt.getData();
if (jsonObject != null) {
token = jsonObject.getStr("access_token");
}
} else {
return R.fail(500, "获取token失败");
}
if (StringUtil.isEmpty(token)) {
return R.fail(500, "获取token失败");
}
//请求接口地址
String url = TrainingSchemeConstant.updateProjectById;
Map paramMap = new HashMap();
//动作id
if (trainingVO.getProjectId() != null) {
paramMap.put("pid", trainingVO.getProjectId());
}
//开始时间
if (trainingVO.getBeginTime() != null) {
paramMap.put("beginTime", trainingVO.getBeginTime());
}
//状态
if (trainingVO.getStatus() != null) {
paramMap.put("status", trainingVO.getStatus());
}
//结束时间
if (trainingVO.getEndTime() != null) {
paramMap.put("endTime", trainingVO.getEndTime());
}
try {
String body = HttpUtil.createPost(url).header("Authorization", token).form(paramMap).execute().body();
if (StringUtils.isBlank(body)) {
return R.status(false);
}
JSONObject obj = JSONUtil.parseObj(body);
if (obj == null) {
return R.status(false);
}
boolean flag = Boolean.parseBoolean(obj.get("status").toString());
return R.status(flag);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
return R.status(false);
}
}
- 接口一,更新第一个训练项目的开始时间状态:
/**
* 接口一:第一个动作的开始:
* 1.当前动作的id,时间戳,然后将当前动作的开始时间修改,当前动作的状态该成 【训练中】
* 2.将当前动做的id放在redis里面。
* 参数:用户id,方案id,主要是放在redis的时候需要用
*
* @param trainingVO
* @return
*/
@PostMapping("/updateProjectBeginTime")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "threePlant-第一个动作的更新", notes = "传入userId,programmeId,projectId,time")
public R updateProjectBeginTime(@ApiParam(value = "训练方案业务对象", required = true) @RequestBody TrainingVO trainingVO) {
//第一个动作的开始时间
trainingVO.setBeginTime(trainingVO.getTime());
//第一个动作:训练中
trainingVO.setStatus(1);
//将第一个动作放在redis的缓存中
bladeRedis.set("training:updateTrainingStatusAndTime:" +
trainingVO.getUserId() + ":" +
trainingVO.getProgrammeId(), trainingVO.getProjectId());
//调用更新的借口
return trainingSchemeUrlService.updateTrainingProgrammeAndProjectStatusAndTime(trainingVO);
}
- 接口二,更新当前动作的开始时间,状态和上一个动作的结束时间、状态。
/**
* 接口二:中间的动作 *** 作:
* 1.从redis中获取上一个动作的id。
* 2.传递动作的id,时间戳,然后修改上一个动作的结束时间是当前的时间戳,第一个动作的状态是【已结束】,当前动作的开始时间是当前的时间戳,状态是【训练中】
* 3.删除上一个动作的id,将当前动作的id放在redis里面
*
* @param trainingVO
* @return
*/
@PostMapping("/updateProjectBeginTimeAndEndTime")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "threePlant-中间动作的更新", notes = "传入userId,programmeId,projectId,time")
public R updateProjectBeginTimeAndEndTime(@ApiParam(value = "训练方案业务对象", required = true) @RequestBody TrainingVO trainingVO) {
TrainingVO trainingVONew = new TrainingVO();
//先从redis中获取上一个动作的id
Long beforePid = bladeRedis.get("training:updateTrainingStatusAndTime:" + trainingVO.getUserId() + ":" + trainingVO.getProgrammeId());
//用完之后删掉redis里面的数据
bladeRedis.del("training:updateTrainingStatusAndTime:" + trainingVO.getUserId() + ":" + trainingVO.getProgrammeId());
//修改上个动作的结束时间是当前的时间戳
trainingVONew.setEndTime(trainingVO.getTime());
//上个动作的状态是已结束
trainingVONew.setStatus(2);
trainingVONew.setProjectId(beforePid);
//调用更新的借口
R resultR = trainingSchemeUrlService.updateTrainingProgrammeAndProjectStatusAndTime(trainingVONew);
if (resultR.getCode() == 200) {
//更新没啥问题
//开始修改当前状态
//状态是训练中
trainingVO.setStatus(1);
//开始时间是时间戳
trainingVO.setBeginTime(trainingVO.getTime());
//将当前的动作在放在redis里面
bladeRedis.set("training:updateTrainingStatusAndTime:" +
trainingVO.getUserId() + ":" +
trainingVO.getProgrammeId(), trainingVO.getProjectId());
//调用更新的方法
return trainingSchemeUrlService.updateTrainingProgrammeAndProjectStatusAndTime(trainingVO);
} else {
return R.status(false);
}
}
- 接口三,更新最后一个训练项目的结束时间和训练状态:
/**
* 接口三:最后一个动作的结束:
* 1.传递当前方案的id,动作的id,用户id,时间戳,然后修改当前动作的结束时间是时间戳,状态是【已结束】
* 2.删掉redis里面的用户id
*
* @param trainingVO
* @return
*/
@PostMapping("/updateProjectEndTime")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "threePlant-最后一个动作的更新", notes = "传入userId,programmeId,projectId,time")
public R updateProjectEndTime(@ApiParam(value = "训练方案业务对象", required = true) @RequestBody TrainingVO trainingVO) {
//最后一个动作的结束时间是时间戳
trainingVO.setEndTime(trainingVO.getTime());
//最后一个动作是已结束
trainingVO.setStatus(2);
//删掉redis中的动作id
bladeRedis.del("training:updateTrainingStatusAndTime:" +
trainingVO.getUserId() + ":" +
trainingVO.getProgrammeId());
return trainingSchemeUrlService.updateTrainingProgrammeAndProjectStatusAndTime(trainingVO);
}
trainingVO.setStatus(2);
//删掉redis中的动作id
bladeRedis.del("training:updateTrainingStatusAndTime:" +
trainingVO.getUserId() + ":" +
trainingVO.getProgrammeId());
return trainingSchemeUrlService.updateTrainingProgrammeAndProjectStatusAndTime(trainingVO);
}
以上就是整个流程的实现,其实写代码难的不是代码,而是业务,当你明白了业务是什么,随之而来的就是实现方式,所以,业务是重中之重的~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)