feat(file): 优化文件上传功能并添加批量下载支持

- 修改文件上传接口,返回 FileUploadVO 对象包含文件信息
- 添加文件批量下载功能,支持压缩包下载
- 更新相关实体类和控制器以适应新的文件上传逻辑- 优化文件名处理,使用 UUID 生成唯一后缀
This commit is contained in:
曹鹏飞 2025-04-03 19:47:05 +08:00
parent 4fa4e8cdf5
commit 63a587f39e
13 changed files with 212 additions and 85 deletions

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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()));
}
/**

View File

@ -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:{}";

View File

@ -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;

View File

@ -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;

View File

@ -29,10 +29,10 @@ public class TicketAddRequest {
@Size(max = 500, message = "描述长度不能超过500")
private String description;
//图片
//图片列表
private List<String> images;
//附件
//附件列表
private List<String> attachments;
//设备地址

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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())

View File

@ -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;