feat(file): 优化文件上传功能并添加批量下载支持
- 修改文件上传接口,返回 FileUploadVO 对象包含文件信息 - 添加文件批量下载功能,支持压缩包下载 - 更新相关实体类和控制器以适应新的文件上传逻辑- 优化文件名处理,使用 UUID 生成唯一后缀
This commit is contained in:
parent
4fa4e8cdf5
commit
63a587f39e
|
|
@ -1,5 +1,7 @@
|
|||
package com.nflg.mobilebroken.admin.controller;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.nflg.mobilebroken.admin.annotation.ApiMark;
|
||||
|
|
@ -8,11 +10,22 @@ import com.nflg.mobilebroken.common.exception.NflgException;
|
|||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||
import com.nflg.mobilebroken.common.pojo.request.FileSearchRequest;
|
||||
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
|
||||
import com.nflg.mobilebroken.common.pojo.vo.FileVO;
|
||||
import com.nflg.mobilebroken.common.util.AdminUserUtil;
|
||||
import com.nflg.mobilebroken.common.util.DateTimeUtil;
|
||||
import com.nflg.mobilebroken.common.util.VUtils;
|
||||
import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
|
||||
import com.nflg.mobilebroken.repository.service.IFileUploadRecordService;
|
||||
import com.nflg.mobilebroken.starter.service.FileUploadService;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
|
|
@ -20,10 +33,18 @@ import javax.annotation.Resource;
|
|||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 文件管理相关接口
|
||||
|
|
@ -34,6 +55,8 @@ import java.util.List;
|
|||
@RequestMapping("/file")
|
||||
public class FileController extends ControllerBase {
|
||||
|
||||
private final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
|
||||
|
||||
@Resource
|
||||
|
|
@ -51,23 +74,24 @@ public class FileController extends ControllerBase {
|
|||
*/
|
||||
@PostMapping("uploadSingleFile")
|
||||
@ApiMark(moduleName = "文件管理", apiName = "上传单个文件")
|
||||
public ApiResult<String> uploadSingleFile(@Valid @NotNull @RequestParam("file") MultipartFile file
|
||||
public ApiResult<FileUploadVO> uploadSingleFile(@Valid @NotNull @RequestParam("file") MultipartFile file
|
||||
,@Valid @NotNull @RequestParam("source") Byte source
|
||||
,@Valid @NotNull @RequestParam("sourceId") Integer sourceId) {
|
||||
try {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
fileUploadRecordService.save(buildFileUploadRecord(source,sourceId,fileName,fileType,url));
|
||||
return ApiResult.success(url);
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
FileUploadRecord record=buildFileUploadRecord(source,sourceId,fileName,fileType,url);
|
||||
fileUploadRecordService.save(record);
|
||||
return ApiResult.success(new FileUploadVO(record.getId(),fileName,url));
|
||||
} catch (Exception ex) {
|
||||
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildFilePath(String fileName, String fileType) {
|
||||
private String buildFilePath(String fileType) {
|
||||
return StrUtil.format("admin/{}/{}/{}/{}{}", LocalDateTime.now().format(FORMATTER), AdminUserUtil.getUserId()
|
||||
, RandomUtil.randomString(4), fileName, fileType);
|
||||
, RandomUtil.randomString(4), IdUtil.fastUUID(), fileType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,22 +101,22 @@ public class FileController extends ControllerBase {
|
|||
* @param sourceId 文件来源id 对应来源的数据id,比如工单id,代理商id,管理端账户id
|
||||
* @return 可访问的文件url列表
|
||||
*/
|
||||
@Transactional
|
||||
@PostMapping("uploadMultipleFiles")
|
||||
@ApiMark(moduleName = "文件管理", apiName = "上传多个文件")
|
||||
public ApiResult<List<String>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files
|
||||
public ApiResult<List<FileUploadVO>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files
|
||||
,@Valid @NotNull @RequestParam("source") Byte source
|
||||
,@Valid @NotNull @RequestParam("sourceId") Integer sourceId) {
|
||||
try {
|
||||
List<String> list = new ArrayList<>();
|
||||
List<FileUploadRecord> records = new ArrayList<>();
|
||||
List<FileUploadVO> list = new ArrayList<>();
|
||||
for (MultipartFile file : files) {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
list.add(url);
|
||||
records.add(buildFileUploadRecord(source,sourceId,fileName,fileType,url));
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
FileUploadRecord record=buildFileUploadRecord(source,sourceId,fileName,fileType,url);
|
||||
fileUploadRecordService.save(record);
|
||||
list.add(new FileUploadVO(record.getId(),fileName,url));
|
||||
}
|
||||
fileUploadRecordService.saveBatch(records);
|
||||
return ApiResult.success(list);
|
||||
} catch (Exception ex) {
|
||||
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
|
||||
|
|
@ -105,21 +129,24 @@ public class FileController extends ControllerBase {
|
|||
* @return 可访问的文件url
|
||||
*/
|
||||
@PostMapping("uploadSingleFile1")
|
||||
public ApiResult<String> uploadSingleFile1(@Valid @NotNull @RequestParam("file") MultipartFile file) {
|
||||
public ApiResult<FileUploadVO> uploadSingleFile1(@Valid @NotNull @RequestParam("file") MultipartFile file) {
|
||||
try {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
return ApiResult.success(url);
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
return ApiResult.success(new FileUploadVO(0,fileName,url));
|
||||
}catch (Exception ex){
|
||||
throw new NflgException(STATE.BusinessError,"上传文件失败:"+ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getFileType(String fileName){
|
||||
return "."+FilenameUtils.getExtension(fileName);
|
||||
}
|
||||
|
||||
private FileUploadRecord buildFileUploadRecord(Byte source,Integer sourceId,String fileName,String fileType, String url){
|
||||
return new FileUploadRecord()
|
||||
.setFileName(fileName)
|
||||
.setFileName(FilenameUtils.getBaseName(fileName))
|
||||
.setFileType(fileType)
|
||||
.setFrom("admin")
|
||||
.setCreateTime(LocalDateTime.now())
|
||||
|
|
@ -160,4 +187,45 @@ public class FileController extends ControllerBase {
|
|||
public ApiResult<List<String>> getFileTypes(){
|
||||
return ApiResult.success(fileUploadRecordService.getFileTypes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件压缩下载
|
||||
*
|
||||
* @param fileIds 文件id列表
|
||||
*/
|
||||
@PostMapping("zipDownload")
|
||||
public ResponseEntity<byte[]> zipDownload(@Valid @RequestParam @NotNull List<Integer> fileIds) throws IOException {
|
||||
List<String> urls = fileUploadRecordService.listByIds(fileIds).stream().map(FileUploadRecord::getUrl).collect(Collectors.toList());
|
||||
VUtils.trueThrowBusinessError(CollectionUtil.isEmpty(urls)).throwMessage("没有需要下载的文件");
|
||||
Path tempZipFile = Files.createTempFile("files", ".zip");
|
||||
try (FileOutputStream fos = new FileOutputStream(tempZipFile.toFile());
|
||||
ZipOutputStream zos = new ZipOutputStream(fos)) {
|
||||
for (String fileUrl : urls) {
|
||||
Request request = new Request.Builder().url(fileUrl).build();
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
|
||||
ZipEntry zipEntry = new ZipEntry(fileName);
|
||||
zos.putNextEntry(zipEntry);
|
||||
// 使用流式处理将文件内容写入 ZIP 输出流
|
||||
InputStream inputStream = response.body().byteStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = inputStream.read(buffer)) >= 0) {
|
||||
zos.write(buffer, 0, length);
|
||||
}
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] zipContent = Files.readAllBytes(tempZipFile);
|
||||
Files.deleteIfExists(tempZipFile);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ DateTimeUtil.format(LocalDateTime.now(),"yyyyMMddHHmmss")+".zip");
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.body(zipContent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
package com.nflg.mobilebroken.cfs.controller;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.nflg.mobilebroken.common.constant.STATE;
|
||||
import com.nflg.mobilebroken.common.exception.NflgException;
|
||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
|
||||
import com.nflg.mobilebroken.common.util.AppUserUtil;
|
||||
import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
|
||||
import com.nflg.mobilebroken.repository.service.IFileUploadRecordService;
|
||||
import com.nflg.mobilebroken.starter.service.FileUploadService;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
|
@ -49,23 +52,24 @@ public class FileController extends ControllerBase {
|
|||
* @return 可访问的文件url
|
||||
*/
|
||||
@PostMapping("uploadSingleFile")
|
||||
public ApiResult<String> uploadSingleFile(@Valid @NotNull @RequestParam("file") MultipartFile file
|
||||
public ApiResult<FileUploadVO> uploadSingleFile(@Valid @NotNull @RequestParam("file") MultipartFile file
|
||||
,@Valid @NotNull @RequestParam("source") Byte source
|
||||
,@Valid @NotNull @RequestParam("sourceId") Integer sourceId) {
|
||||
try {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
fileUploadRecordService.save(buildFileUploadRecord(source,sourceId,fileName,fileType,url));
|
||||
return ApiResult.success(url);
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
FileUploadRecord record=buildFileUploadRecord(source,sourceId,fileName,fileType,url);
|
||||
fileUploadRecordService.save(record);
|
||||
return ApiResult.success(new FileUploadVO(record.getId(),fileName,url));
|
||||
}catch (Exception ex){
|
||||
throw new NflgException(STATE.BusinessError,"上传文件失败:"+ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String buildFilePath(String fileName,String fileType) {
|
||||
private String buildFilePath(String fileType) {
|
||||
return StrUtil.format("cfs/{}/{}/{}/{}{}", LocalDateTime.now().format(FORMATTER), AppUserUtil.getUserId()
|
||||
, RandomUtil.randomString(4), fileName,fileType);
|
||||
, RandomUtil.randomString(4), IdUtil.fastUUID(),fileType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -76,20 +80,19 @@ public class FileController extends ControllerBase {
|
|||
* @return 可访问的文件url列表
|
||||
*/
|
||||
@PostMapping("uploadMultipleFiles")
|
||||
public ApiResult<List<String>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files
|
||||
public ApiResult<List<FileUploadVO>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files
|
||||
,@Valid @NotNull @RequestParam("source") Byte source
|
||||
,@Valid @NotNull @RequestParam("sourceId") Integer sourceId) {
|
||||
try {
|
||||
List<String> list = new ArrayList<>();
|
||||
List<FileUploadRecord> records = new ArrayList<>();
|
||||
List<FileUploadVO> list = new ArrayList<>();
|
||||
for (MultipartFile file : files) {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
list.add(url);
|
||||
records.add(buildFileUploadRecord(source,sourceId,fileName,fileType,url));
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
FileUploadRecord record=buildFileUploadRecord(source,sourceId,fileName,fileType,url);
|
||||
fileUploadRecordService.save(record);
|
||||
list.add(new FileUploadVO(record.getId(),fileName,url));
|
||||
}
|
||||
fileUploadRecordService.saveBatch(records);
|
||||
return ApiResult.success(list);
|
||||
} catch (Exception ex) {
|
||||
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
|
||||
|
|
@ -102,17 +105,21 @@ public class FileController extends ControllerBase {
|
|||
* @return 可访问的文件url
|
||||
*/
|
||||
@PostMapping("uploadSingleFile1")
|
||||
public ApiResult<String> uploadSingleFile1(@Valid @NotNull @RequestParam("file") MultipartFile file) {
|
||||
public ApiResult<FileUploadVO> uploadSingleFile1(@Valid @NotNull @RequestParam("file") MultipartFile file) {
|
||||
try {
|
||||
String fileName=file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."));
|
||||
String fileType=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
|
||||
String url=fileUploadService.upload(buildFilePath(fileName,fileType), file);
|
||||
return ApiResult.success(url);
|
||||
String fileName=file.getOriginalFilename();
|
||||
String fileType=getFileType(fileName);
|
||||
String url=fileUploadService.upload(buildFilePath(fileType), file);
|
||||
return ApiResult.success(new FileUploadVO(0,fileName,url));
|
||||
}catch (Exception ex){
|
||||
throw new NflgException(STATE.BusinessError,"上传文件失败:"+ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String getFileType(String fileName){
|
||||
return "."+FilenameUtils.getExtension(fileName);
|
||||
}
|
||||
|
||||
private FileUploadRecord buildFileUploadRecord(Byte source,Integer sourceId,String fileName,String fileType,String url){
|
||||
return new FileUploadRecord()
|
||||
.setFileName(fileName)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import cn.hutool.core.util.StrUtil;
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher;
|
||||
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||
import com.nflg.mobilebroken.common.constant.Constant;
|
||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||
|
|
@ -84,6 +83,9 @@ public class TiketController extends ControllerBase {
|
|||
@Resource
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
@Resource
|
||||
private ITBasePartService partService;
|
||||
|
||||
/**
|
||||
* 搜索设备
|
||||
* @param request 搜索条件
|
||||
|
|
@ -110,12 +112,7 @@ public class TiketController extends ControllerBase {
|
|||
**/
|
||||
@GetMapping("getAllDeviceComponents")
|
||||
public ApiResult<List<String>> getAllDeviceComponents() {
|
||||
return ApiResult.success(
|
||||
dictionaryItemTranslateService.getAllByDictionaryCode(Constant.DICTIONARY_ITEM_DEVICECOMPONENT, MultilingualUtil.getLanguage())
|
||||
.stream()
|
||||
.map(DictionaryItemTranslateVO::getValue)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
return ApiResult.success(partService.lambdaQuery().select(TBasePart::getPartName).eq(TBasePart::getEnable, true).list().stream().map(TBasePart::getPartName).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ public class Constant {
|
|||
|
||||
public static final String DICTIONARY_TYPE_TITLE_CQM = "YDP-007";
|
||||
|
||||
public static final String DICTIONARY_ITEM_DEVICECOMPONENT = "modelComponents";
|
||||
|
||||
public static final String REDIS_KEY_USER_UPDATE_KAPTCHA_APP = "app:kaptcha:user:update:{}";
|
||||
|
||||
public static final String REDIS_KEY_USER_UPDATE_KAPTCHA_ADMIN = "admin:kaptcha:user:update:{}";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.nflg.mobilebroken.common.pojo.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
|
|
@ -29,10 +30,10 @@ public class ChatMessageDTO {
|
|||
private String content;
|
||||
|
||||
// 附件列表
|
||||
private List<String> attachments;
|
||||
private List<FileUploadVO> attachments;
|
||||
|
||||
//图片列表
|
||||
private List<String> images;
|
||||
private List<FileUploadVO> images;
|
||||
|
||||
// 创建时间
|
||||
private Instant createTime;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.nflg.mobilebroken.common.pojo.request;
|
||||
|
||||
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
|
@ -16,10 +17,10 @@ public class AddChatMessageRequest {
|
|||
private String content;
|
||||
|
||||
//附件列表
|
||||
private List<String> attachments;
|
||||
private List<FileUploadVO> attachments;
|
||||
|
||||
//图片列表
|
||||
private List<String> images;
|
||||
private List<FileUploadVO> images;
|
||||
|
||||
// 引用的消息
|
||||
private String quoteId;
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ public class TicketAddRequest {
|
|||
@Size(max = 500, message = "描述长度不能超过500")
|
||||
private String description;
|
||||
|
||||
//图片
|
||||
//图片列表
|
||||
private List<String> images;
|
||||
|
||||
//附件
|
||||
//附件列表
|
||||
private List<String> attachments;
|
||||
|
||||
//设备地址
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ public class AdminTicketVO {
|
|||
return ChronoUnit.DAYS.between(createTime.toLocalDate(), LocalDateTime.now().toLocalDate()) + 1;
|
||||
}
|
||||
if (TicketState.Closed.getState().compareTo(state) >= 0) {
|
||||
return ChronoUnit.DAYS.between(completeTime, LocalDateTime.now()) + 1;
|
||||
return ChronoUnit.DAYS.between(createTime.toLocalDate(), completeTime.toLocalDate()) + 1;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ public class ChatMessageVO {
|
|||
private String content;
|
||||
|
||||
// 附件列表
|
||||
private List<String> attachments;
|
||||
private List<FileUploadVO> attachments;
|
||||
|
||||
//图片列表
|
||||
private List<String> images;
|
||||
private List<FileUploadVO> images;
|
||||
|
||||
// 创建时间
|
||||
private String createTime;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.nflg.mobilebroken.common.pojo.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@AllArgsConstructor
|
||||
public class FileUploadVO {
|
||||
|
||||
/**
|
||||
* 文件id
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 显示名称
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* url路径
|
||||
*/
|
||||
private String url;
|
||||
}
|
||||
|
|
@ -20,6 +20,13 @@ public class DateTimeUtil {
|
|||
return dateTime.format(FORMATTER);
|
||||
}
|
||||
|
||||
public static String format(LocalDateTime dateTime,String pattern){
|
||||
if (Objects.isNull(dateTime)){
|
||||
return "";
|
||||
}
|
||||
return dateTime.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
public static LocalDate asSystemDate(LocalDate date){
|
||||
if (Objects.isNull(date)){
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -336,6 +336,7 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
|
|||
String areaName=StrUtil.join(",",customers.stream().map(TBaseCustomer::getAreaName).flatMap(name->StrUtil.split(name, ",").stream()).collect(Collectors.toSet()));
|
||||
primary=new AppUserForAdminVO()
|
||||
.setPrimary(true)
|
||||
.setLoginName(appUser.getLoginName())
|
||||
.setUserName(appUser.getName())
|
||||
.setAvatar(appUser.getAvatar())
|
||||
.setUserState(appUser.getState())
|
||||
|
|
|
|||
|
|
@ -20,10 +20,14 @@ import com.nflg.mobilebroken.repository.entity.*;
|
|||
import com.nflg.mobilebroken.repository.mapper.TicketMapper;
|
||||
import com.nflg.mobilebroken.repository.service.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +59,7 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||
@Resource
|
||||
private ITicketSolutionService ticketSolutionService;
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Ticket add(TicketAddRequest request, Integer userId) {
|
||||
Ticket lastTicket=lambdaQuery()
|
||||
|
|
@ -77,26 +82,40 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||
.setUserId(userId)
|
||||
.setCreateTime(LocalDateTime.now());
|
||||
save(ticket);
|
||||
Collection<String> files=CollectionUtil.addAll(request.getImages(),request.getAttachments());
|
||||
if (CollectionUtil.isNotEmpty(files)){
|
||||
List<FileUploadRecord> fileUploadRecords=new ArrayList<>();
|
||||
for (String url : files) {
|
||||
String fileName=url.substring(url.lastIndexOf("/")+1);
|
||||
String pre=fileName.substring(0,fileName.lastIndexOf("."));
|
||||
String end=fileName.substring(fileName.lastIndexOf("."));
|
||||
FileUploadRecord fileUploadRecord = new FileUploadRecord()
|
||||
.setFrom("app")
|
||||
.setUrl(url)
|
||||
.setFileName(pre)
|
||||
.setFileType(end)
|
||||
.setSource((byte) 0)
|
||||
.setSourceId(ticket.getId())
|
||||
.setCreateBy(AppUserUtil.getUserName())
|
||||
.setCreateTime(LocalDateTime.now());
|
||||
fileUploadRecords.add(fileUploadRecord);
|
||||
// Collection<String> files=CollectionUtil.addAll(request.getImages(),request.getAttachments());
|
||||
List<FileUploadRecord> imagesRecords = new ArrayList<>();
|
||||
if (CollectionUtil.isNotEmpty(request.getImages())) {
|
||||
for (String url : request.getImages()) {
|
||||
FileUploadRecord record = fileUploadRecordService.lambdaQuery()
|
||||
.eq(FileUploadRecord::getSource, (byte) 0)
|
||||
.eq(FileUploadRecord::getSourceId, 0)
|
||||
.eq(FileUploadRecord::getUrl, url)
|
||||
.one();
|
||||
VUtils.trueThrowBusinessError(Objects.isNull(record)).throwMessage("未找到图片上传记录:" + url);
|
||||
record.setSourceId(ticket.getId());
|
||||
imagesRecords.add(record);
|
||||
}
|
||||
fileUploadRecordService.saveBatch(fileUploadRecords);
|
||||
fileUploadRecordService.updateBatchById(imagesRecords);
|
||||
}
|
||||
List<FileUploadRecord> attachmentsRecords = new ArrayList<>();
|
||||
if (CollectionUtil.isNotEmpty(request.getAttachments())) {
|
||||
for (String url : request.getAttachments()) {
|
||||
FileUploadRecord record = fileUploadRecordService.lambdaQuery()
|
||||
.eq(FileUploadRecord::getSource, (byte) 0)
|
||||
.eq(FileUploadRecord::getSourceId, 0)
|
||||
.eq(FileUploadRecord::getUrl, url)
|
||||
.one();
|
||||
VUtils.trueThrowBusinessError(Objects.isNull(record)).throwMessage("未找到附件上传记录:" + url);
|
||||
record.setSourceId(ticket.getId());
|
||||
attachmentsRecords.add(record);
|
||||
}
|
||||
fileUploadRecordService.updateBatchById(attachmentsRecords);
|
||||
}
|
||||
lambdaUpdate()
|
||||
.set(CollectionUtil.isNotEmpty(imagesRecords),Ticket::getImages, imagesRecords.stream().map(FileUploadRecord::getId).collect(Collectors.toList()))
|
||||
.set(CollectionUtil.isNotEmpty(attachmentsRecords),Ticket::getAttachments, attachmentsRecords.stream().map(FileUploadRecord::getId).collect(Collectors.toList()))
|
||||
.eq(Ticket::getId, ticket.getId())
|
||||
.update();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +314,7 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||
VUtils.trueThrowBusinessError(Byte.compare(ticket.getState(), TicketState.ProcessingCompleted.getState())>0)
|
||||
.throwMessage("当前工单状态不允许重新打开");
|
||||
ticket.setState(TicketState.Processing.getState());
|
||||
ticket.setSolveTime(null);
|
||||
ticket.setUpdateTime(LocalDateTime.now());
|
||||
updateById(ticket);
|
||||
return ticket;
|
||||
|
|
@ -350,6 +370,7 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
|||
VUtils.trueThrowBusinessError(tickerMangagers.stream().noneMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId())))
|
||||
.throwMessage("你无权驳回工单");
|
||||
ticket.setState(TicketState.Processing.getState());
|
||||
ticket.setSolveTime(null);
|
||||
ticket.setUpdateTime(LocalDateTime.now());
|
||||
updateById(ticket);
|
||||
return ticket;
|
||||
|
|
|
|||
Loading…
Reference in New Issue