admin管理员组文章数量:1565269
文章目录
- 前言
- 一、思考过程?
- 二、完善
- 接口设计思路
- 开发过程中出现的问题(未解决,求解)
- 1、文件上传接口(考虑到其中文件已经存过则不必重复存储,可以复用的图片)
- 2、service层
- 3、service实现层
- 4、FileSecret的文件摘要存储
- 接口
- 1、组件类型Controller层
- 2、组件Controller层
- 3、组件排序接口
- 4、请求对象(意在减少前端查询时需要请求的条件)
- 5、返回对象(意在减少前端获取的数据字段,使其简洁)
前言
为自己搭建一个可以自我思考的平台,其核心为“心想事成”。
一、思考过程?
后端框架搭建完成之后,如果不能允许以及访问不了接口也是不完美的。那么接着继续!
二、完善
接口设计思路
1、首先我要完成的是“心想事成”的第一步,其名为:实现可拖拽列表功能
2、该案例意为组件拖拽切换顺序
3、关于生成对应的Service、Mapper前置步骤就不介绍了(详情借鉴:可持续发展项目(二):后端框架搭建)
4、后端主要是提供对象、数据存储、数据获取、数据修改等逻辑
开发过程中出现的问题(未解决,求解)
在组件对象中有imgUrl用来存储组件图片,我想着没有OSS服务器。那么将图片如何在前端展示,网上搜索是放在assets下即可以使用el-image展示出来,我也尝试实现了下放在assets下后确实展示出来了。那么就是将图片通过流的方式从本地A文件夹复制到前端项目的assets下,实现时貌似不行,el-upload组件在上传后调用后端接口获取到路径后展示图片为已删除图片的标识。我尝试在下面展示下复制的图片是可行的,哎,望广大网友能实现这功能提供借鉴。虽该功能已被我司大佬否定在线上并不实际,但我只是想尝试实现这个案例。最后el-upload上传的地方为我司的oss地址,以下是我的原后端逻辑。
1、文件上传接口(考虑到其中文件已经存过则不必重复存储,可以复用的图片)
package com.etp.sustainable.controller;
import com.etp.sustainable.service.FileService;
import com.etp.sustainable.util.R;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author ETP
* @since 2023/10/23 16:06
*/
@Tag(name="组件管理")
@RestController
@AllArgsConstructor
@RequestMapping("/file")
public class FileController {
private final FileService fileService;
@SneakyThrows
@PostMapping("upload")
public R uploadFile(@RequestPart("file") MultipartFile file) {
String fileUrl = fileService.uploadFile(file);
return R.ok(fileUrl);
}
}
2、service层
package com.etp.sustainable.service;
import org.springframework.web.multipart.MultipartFile;
/**
* @author ETP
* @since 2023/10/23 16:07
*/
public interface FileService {
/**
* 文件上传
* @param file
*/
String uploadFile(MultipartFile file);
}
3、service实现层
package com.etp.sustainable.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.etp.sustainable.domain.FileSecret;
import com.etp.sustainable.service.FileSecretService;
import com.etp.sustainable.service.FileService;
import com.etp.sustainable.util.MultipartFileToFile;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.security.MessageDigest;
/**
* @author ETP
* @since 2023/10/23 16:08
*/
@AllArgsConstructor
@Service
public class FileServiceImpl implements FileService {
private final FileSecretService fileSecretService;
@SneakyThrows
@Override
public String uploadFile(MultipartFile file) {
String fileName = file.getOriginalFilename();
String fileUrl = "/sustainable/img/" + fileName;
// String integrityUrl = "/sustainable/img/" + fileName;
File source = null;
try {
//将MultipartFile转为File
source = MultipartFileToFile.multipartFileToFile(file);
} catch (Exception e) {
e.printStackTrace();
}
FileSecret fileSecret = new FileSecret();
if (source != null) {
MessageDigest md = MessageDigest.getInstance("SHA-256");
try (FileInputStream fis = new FileInputStream(source)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
md.update(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] hash = md.digest();
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
String sha256Hash = hexString.toString();
fileSecret.setSecret(sha256Hash);
LambdaQueryWrapper<FileSecret> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(FileSecret::getSecret, sha256Hash);
FileSecret getFile = fileSecretService.getOne(lambdaQueryWrapper);
if (getFile == null) {
fileSecret.setFileUrl(fileUrl);
fileSecretService.save(fileSecret);
String path = "D:\\XLZ\\MyProject\\sustainable_front\\src\\assets\\img\\" + fileName;
File toFile = new File(path);
copyFileUsingFileStreams(source, toFile);
}
}
return fileUrl;
}
public static void main(String[] args) {
File source = new File("C:\\Users\\admin\\Pictures\\Saved Pictures\\2@2x.png");
File toFile = new File("D:\\XLZ\\MyProject\\sustainable_front\\src\\assets\\img\\copyImg.png");
try {
copyFileUsingFileStreams(source, toFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void copyFileUsingFileStreams(File source, File toFile)
throws IOException {
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream(source);
output = new FileOutputStream(toFile);
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
} finally {
input.close();
output.close();
}
}
}
4、FileSecret的文件摘要存储
package com.etp.sustainable.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import lombok.Data;
/**
* 文件摘要
* @TableName file_secret
*/
@TableName(value ="file_secret")
@Data
public class FileSecret implements Serializable {
/**
* 文件路径
*/
@TableId
private String fileUrl;
/**
* 文件摘要
*/
private String secret;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 是否删除(0-否,1-是)
*/
private Integer isDeleted;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
接口
1、组件类型Controller层
package com.etp.sustainable.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etp.sustainable.domain.ComponentType;
import com.etp.sustainable.service.ComponentTypeService;
import com.etp.sustainable.service.KeywordRecordService;
import com.etp.sustainable.service.KeywordRelationService;
import com.etp.sustainable.util.R;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author ETP
* @since 2023/10/20 11:05
*/
@Tag(name="组件类型管理")
@RestController
@AllArgsConstructor
@RequestMapping("/componentType")
public class ComponentTypeController {
private final ComponentTypeService componentTypeService;
private final KeywordRecordService keywordRecordService;
private final KeywordRelationService keywordRelationService;
@GetMapping("page")
public R page(Page<ComponentType> page, ComponentType componentType) {
List<OrderItem> orderItems = new ArrayList<>();
OrderItem orderItem = new OrderItem();
orderItem.setColumn("create_time");
orderItem.setAsc(false);
orderItem.setColumn("sort");
orderItem.setAsc(true);
orderItems.add(orderItem);
page.setOrders(orderItems);
LambdaQueryWrapper<ComponentType> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(componentType.getName())) {
lambdaQueryWrapper.eq(ComponentType::getName, componentType.getName());
String name = componentType.getName();
String[] nameArray = name.split("");
keywordRecordService.saveKeywordRecord(nameArray, 3);
keywordRelationService.saveKeywordRelation(nameArray, name, 3);
List<String> nameWordList = new ArrayList<>();
StringBuilder nameWord = new StringBuilder();
int i = 1;
for (String s : nameArray) {
int nameIndex = i % 2;
if (nameIndex == 0) {
nameWord.append(s);
nameWordList.add(nameWord.toString());
nameWord = new StringBuilder();
} else {
nameWord.append(s);
}
i++;
}
List<String> stringList = nameWordList.stream().distinct().toList();
keywordRecordService.saveKeywordRecordList(stringList, 3);
keywordRelationService.saveKeywordRelationList(stringList, name, 3);
}
return R.ok(componentTypeService.page(page, lambdaQueryWrapper));
}
@GetMapping("/list")
public R list(ComponentType componentType) {
LambdaQueryWrapper<ComponentType> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.orderByDesc(ComponentType::getCreateTime);
return R.ok(componentTypeService.list(lambdaQueryWrapper));
}
@PostMapping("/save")
public R save(@RequestBody ComponentType componentType) {
return R.ok(componentTypeService.selfSave(componentType));
}
@PutMapping("/update")
public R update(@RequestBody ComponentType componentType) {
return R.ok(componentTypeService.updateById(componentType));
}
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(componentTypeService.getById(id));
}
@DeleteMapping("/delById/{id}")
public R delById(@PathVariable Long id) {
return R.ok(componentTypeService.removeById(id));
}
}
2、组件Controller层
package com.etp.sustainable.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etp.sustainable.domain.Component;
import com.etp.sustainable.service.ComponentService;
import com.etp.sustainable.service.KeywordRecordService;
import com.etp.sustainable.service.KeywordRelationService;
import com.etp.sustainable.util.R;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author ETP
* @since 2023/10/20 11:04
*/
@Tag(name="组件管理")
@RestController
@AllArgsConstructor
@RequestMapping("/component")
public class ComponentController {
private final ComponentService componentService;
private final KeywordRecordService keywordRecordService;
private final KeywordRelationService keywordRelationService;
@GetMapping("page")
public R page(Page<Component> page, Component component) {
List<OrderItem> orderItems = new ArrayList<>();
OrderItem orderItem = new OrderItem();
orderItem.setColumn("create_time");
orderItem.setAsc(false);
orderItem.setColumn("sort");
orderItem.setAsc(true);
orderItems.add(orderItem);
page.setOrders(orderItems);
LambdaQueryWrapper<Component> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(component.getName())) {
lambdaQueryWrapper.eq(Component::getName, component.getName());
String name = component.getName();
String[] nameArray = name.split("");
keywordRecordService.saveKeywordRecord(nameArray, 3);
keywordRelationService.saveKeywordRelation(nameArray, name, 3);
List<String> nameWordList = new ArrayList<>();
StringBuilder nameWord = new StringBuilder();
int i = 1;
for (String s : nameArray) {
int nameIndex = i % 2;
if (nameIndex == 0) {
nameWord.append(s);
nameWordList.add(nameWord.toString());
nameWord = new StringBuilder();
} else {
nameWord.append(s);
}
i++;
}
List<String> stringList = nameWordList.stream().distinct().toList();
keywordRecordService.saveKeywordRecordList(stringList, 3);
keywordRelationService.saveKeywordRelationList(stringList, name, 3);
}
return R.ok(componentService.page(page, lambdaQueryWrapper));
}
@PostMapping("/save")
public R save(@RequestBody Component component) {
return R.ok(componentService.selfSave(component));
}
@PutMapping("/update")
public R update(@RequestBody Component component) {
return R.ok(componentService.updateById(component));
}
@GetMapping("/{id}")
public R getById(@PathVariable Long id) {
return R.ok(componentService.getById(id));
}
@DeleteMapping("/delById/{id}")
public R delById(@PathVariable Long id) {
return R.ok(componentService.removeById(id));
}
}
3、组件排序接口
package com.etp.sustainable.controller;
import com.etp.sustainable.domain.req.SortReq;
import com.etp.sustainable.service.SortService;
import com.etp.sustainable.util.R;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author ETP
* @since 2023/10/25 15:46
*/
@RestController
@AllArgsConstructor
@RequestMapping("/sort")
public class SortController {
private final SortService sortService;
@GetMapping("/list")
public R list(SortReq req) {
return R.ok(sortService.componentWithTypeList(req));
}
}
4、请求对象(意在减少前端查询时需要请求的条件)
package com.etp.sustainable.domain.req;
import lombok.Data;
import java.util.List;
/**
* @author ETP
* @since 2023/10/25 15:49
*/
@Data
public class SortReq {
/**
* 名称
*/
private String name;
/**
* 组件类型ID集合
*/
private List<Long> componentTypeIdList;
}
5、返回对象(意在减少前端获取的数据字段,使其简洁)
package com.etp.sustainable.domain.resp;
import lombok.Data;
import java.util.List;
/**
* @author ETP
* @since 2023/10/25 15:49
*/
@Data
public class SortResp {
/**
* 主键ID
*/
private Long id;
/**
* 类型ID
*/
private Long typeId;
/**
* 名称
*/
private String name;
/**
* 排序
*/
private Integer sort;
/**
* 图片
*/
private String imgUrl;
/**
* 组件字集列表
*/
private List<SortResp> componentList;
}
版权声明:本文标题:可持续发展项目(八):拖拽功能后端对象提供 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726927316a1090692.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论