👨🎓作者:bug菌 ✏️博客:CSDN、掘金等 💌公众号:猿圈奇妙屋 🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。 🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。
接下来的这几期,bug菌想跟大家分享一下自己昨天刚接到一个临时的需求,热乎着呢,想分享一下自己是如何面对临时需求并制定整个开发周期,其中包括从梳理业务到创建业务表再到实现业务逻辑形成闭环再到与前端对接,其中会穿插一些业务拓展及功能性拓展,这一条龙流程在线与大家一起见证,分享给刚入门的小伙伴,希望对你们有所帮助。
环境说明:idea2019.3 + springboot2.3.1.REALSE + mybati-plus3.2.0 + mysql5.6 + jdk1.8
上一期我们讲述了如何从一个业务梳理成具体的某些接口,再到接口如何定义,需要注意那些事项,不知道大家是否有记起来,然而这一期,我们就顺着已经确定的接口上实现业务逻辑,可能你们还会问,不就是对于该接口进行一个代码实现么,是的没错,但是我此处讲的肯定是经过了自己改了又改,删了又写最终得出来的,我就要拿最优的代码思路给大家做参考,但是也并不是说我这就是最优的,肯定都是有值得优化的地方,这里就需要发挥大家的思维与创造力了。
好啦,咱们进入正题吧。手把手带着大家进行coding。
我们先是在Controller层定义了该问题反馈保存接口及访问接口路径等,具体定义如下:
/**
* 反馈问题保存
*
* @param images img图片数组
* @param inPage 问题反馈/建议所在页面
* @param questionContent 反问题反馈/建议描述
* @param
@PostMapping("/save")
@SysLog(logType = LogTypeEnum.LOG_TYPE_IMG_UPLOAD)
@ApiOperation(value = "反馈问题保存", notes = "反馈问题保存")
public ResultResponse<Boolean> saveQuestion(@ApiParam("图片数组") MultipartFile[] images,
@ApiParam("问题反馈类型") String questionType,
@ApiParam("问题反馈/建议描述") String questionContent,
@ApiParam("问题反馈/建议所在页面") throws IOException {
return
接着就是实现saveQuestion()方法了。这里对于肯定是直接先定义到userQuestionsService接口层,然后通过实现该接口层进行方法的具体实现。
定义接口方法如下:
ResultResponse<Boolean> saveQuestion(MultipartFile[] images, String questionType, String questionContent, String inPage) throws
这里我是直接反回了一个自定义类型,且自定义类型是个布尔值。
然后就是该接口的的重点了,怎么说呢?这也是该接口的核心业务了,如何保存反馈内容,如何保存问题反馈图片数组。切记这里是支持多图片上传。
接着就是通过UserQuestionsServiceImpl 通过implements关键字来实现 IUserQuestionsService 接口层的所有方法,其中也就包括实现saveQuestion()方法。
@Override
public ResultResponse<Boolean> saveQuestion(MultipartFile[] images, String questionType, String questionContent, String inPage) throws
对于这个业务实现,也是有点坑的。对于业务实现,我们一般要做的步骤就是,第一步干嘛,第二步干嘛...一定要先列举清楚,要不然写一点敲一点,最后肯定是有问题的。
第一步:遍历MultipartFile[] images 图片数组,分别调用图片上传方法。 第二步:实现图片上传方法。 第三部:实现基础字段内容保存并方法返回。
然后具体对于三步骤,我们也是要具体的业务思维,对于遍历图片保存,这里就需要有一点要注意,你应该要留意,我们一次问题反馈调用,就生成一条记录,但对于一次请求,对于多图片,我们怎么做到一对多呢?其实啊,这就在你定义表字段时,就应该考虑清楚,所以我这里就根据一个字段来处理,也就是在你进行保存图片之后,专属定义一个外循环变量来存放所有的图片保存地址,然后两图片地址之间,你可以用逗号隔开,也可以用别的字段间隔都可。
imgPaths = imgPaths + ","
就像如上所示,直接用逗号隔开,但是有一点是需要大家注意的,在你进行逗号隔开时,你要考虑如果MultipartFile[] images 图片数组为1,你就不应该有逗号间隔了啊。
讲到这里,我也诺列的差不多了,想必小伙伴们心里都清楚如何实现了吧?
if (images.length > 0) {
//分批处理图片保存
for (int i = 1; i <= images.length; i++) {
//当前图片
MultipartFile img = images[i - 1];
//获取文件后缀。
String imageSuffix = FilenameUtils.getExtension(img.getOriginalFilename()).toLowerCase();
//非以上文件后缀直接跳过。
if (!CONTENT_TYPES.contains(imageSuffix)) {
continue;
}
//获取当前时间进行命名。
String template = TimeUtils.getPrivateTime(ConstantUtils.TIME_STAMP_BEFORE2) + "_" + i;
//重写img文件名 eg:20220527100245.jpg
String saveImgPath = template + "." + imageSuffix;
//图片保存绝对地址
String savePath = this.buildImgPath(saveImgPath, accountId);
//图片上传
uploader.uploadImg(img, savePath);
//路径用逗号拼接。
if (StringUtils.isNotEmpty(imgPaths)) {
imgPaths = imgPaths + "," + saveImgPath;
} else
注意:这里会涉及到两个比较坑的点。第一个就是对于同一个遍历方法,获取到的时间戳会是一致的,所以如果你想自定义别名图片,你就不能只通过时间戳来进行别名,你应该还得加盐,由于我是想区分用户那天上传的那些图片,才特定通过获取时间戳来进行别名,我这里提供的做法就是在时间戳后再拼接一个遍历下边,这样就保证了同一用户在一次接口调用反馈时,图片是按template_index来命名的。第二点就是需要留意对于图片数组=1的,你就不应该也逗号间隔,加一个判断即可。
对于这一步,实现方式还是相对较多的,我这里为了给大家教学,就使用一种超级简单的实现方式,比如MultipartFile类自带的transferTo()方法。
public void uploadImg(MultipartFile image, String savePath) throws IOException {
File file = new File(savePath);
//检测是否存在该目录
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
//写入文件
这里需要注意的就是一点,要判断该路径存在与否,不存在还是得要进行路径的创建再进行文件写入。
这一步就相对比较简单了,我们由于将已上传成功返回的图片保存地址进行了路径拼接,我们即可直接定义一个实体,进行数据赋值即可。
UserQuestionsEntity entity = new UserQuestionsEntity(user, questionType, questionContent, inPage, imgPaths);
然后在对应的实体类将字段内容进行手动赋值即可。
public UserQuestionsEntity(SysUserEntity user, String questionType, String questionContent, String inPage, String imgPath) {
this.status = UsualStatusEnum.NORMAL.getKey();
this.creatorAccountId = user.getAccountId();
this.creatorName = user.getAccountName();
this.creatorDeptName = user.getDeptName();
this.questionType = questionType;
this.questionContent = questionContent;
this.inPage = inPage;
this.filePaths = imgPath;
}
这里就不需要再手动赋值那些创建时间、创建人等操作字段了,因为我们前边是已经添加了字段自动填充。
最后就是直接调用mp提供的save方法即可。
return new ResultResponse<>(this.save(entity));
最后,我们重启项目,通过postman进行接口调用测试。
很完美也是成功将图片保存到了指定位置下。