feat(chat): 添加消息附件验证和撤回功能

- 在 AddChatMessageRequest 中添加 @Valid 注解验证附件、图片和被艾特用户列表
- 为 FileUploadVO 添加文件id、名称和路径的非空验证
- 为 RemindUserRequest 添加用户id和名称的非空验证
- 实现消息撤回时自动删除相关附件记录功能
- 重构派工单搜索接口,添加用户ID参数和排序逻辑
- 更新工单重新开启权限判断逻辑,限制仅用户本人可操作
This commit is contained in:
曹鹏飞 2026-01-08 13:44:48 +08:00
parent 49cec25f53
commit 76e8235d75
10 changed files with 50 additions and 13 deletions

View File

@ -328,15 +328,16 @@ public class TicketController extends ControllerBase {
if (Objects.nonNull(part)) {
vo.setComponent(part.getPartName());
}
vo.setCanReopen(Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState())
&& !ticketSolutionAuditService.lambdaQuery().eq(TicketSolutionAudit::getTicketId, ticket.getId()).exists());
} else {
GongfuDevicePart part = part1Service.getByIdAndLanguage(ticket.getComponentId(), MultilingualUtil.getLanguage());
if (Objects.nonNull(part)) {
vo.setComponent(part.getPartName());
}
vo.setCanReopen(false);
}
vo.setCanReopen((StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom()) && Objects.equals(ticket.getUserId(), AppUserUtil.getUserId()))
&& Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState())
&& !ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, ticket.getId()).exists()
);
return ApiResult.success(vo);
}

View File

@ -3,6 +3,7 @@ package com.nflg.mobilebroken.common.pojo.request;
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@ -20,14 +21,17 @@ public class AddChatMessageRequest {
private String audioUrl;
//附件列表
@Valid
private List<FileUploadVO> attachments;
//图片列表
@Valid
private List<FileUploadVO> images;
// 引用的消息
private String quoteId;
//被艾特的用户列表
@Valid
private List<RemindUserRequest> remindUsers;
}

View File

@ -2,16 +2,21 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class RemindUserRequest {
/**
* 用户id
*/
@NotNull
private Integer id;
/**
* 用户名
*/
@NotBlank
private String name;
}

View File

@ -5,6 +5,9 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
@Accessors(chain = true)
@AllArgsConstructor
@ -14,16 +17,19 @@ public class FileUploadVO {
/**
* 文件id
*/
@NotNull(message = "文件id不能为空")
private Integer id;
/**
* 显示名称
*/
@NotBlank(message = "文件名称不能为空")
private String fileName;
/**
* url路径
*/
@NotBlank(message = "文件路径不能为空")
private String url;
/**

View File

@ -210,7 +210,7 @@ public class DispatchController extends ControllerBase {
*/
@PostMapping("/search")
public ApiResult<PageData<DispatchVO>> search(@Valid @RequestBody DispatchSearchRequest request) {
return ApiResult.success(dispatchService.search(request));
return ApiResult.success(dispatchService.search(request, AdminUserUtil.getUserId()));
}
/**

View File

@ -19,7 +19,7 @@ import java.util.List;
*/
public interface GongfuDispatchMapper extends BaseMapper<GongfuDispatch> {
IPage<DispatchVO> search(DispatchSearchRequest request, Page<?> objectPage);
IPage<DispatchVO> search(DispatchSearchRequest request, Integer userId, Page<?> objectPage);
DispatchVO getInfo(Long id);

View File

@ -18,7 +18,7 @@ import java.util.List;
*/
public interface IGongfuDispatchService extends IService<GongfuDispatch> {
IPage<DispatchVO> search(DispatchSearchRequest request);
IPage<DispatchVO> search(DispatchSearchRequest request, Integer userId);
DispatchVO getInfo(Long id);

View File

@ -8,8 +8,10 @@ import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
import com.nflg.mobilebroken.common.pojo.dto.TicketChatDTO;
import com.nflg.mobilebroken.common.pojo.dto.TicketSet;
import com.nflg.mobilebroken.common.pojo.vo.ChatMessageVO;
import com.nflg.mobilebroken.common.pojo.vo.FileUploadVO;
import com.nflg.mobilebroken.common.util.MultilingualUtil;
import com.nflg.mobilebroken.common.util.VUtils;
import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
import com.nflg.mobilebroken.repository.entity.ParamConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
@ -23,6 +25,7 @@ import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@ -38,6 +41,9 @@ public class TicketChatService {
@Resource
private IParamConfigService paramConfigService;
@Resource
private IFileUploadRecordService fileUploadRecordService;
public void add(TicketChatDTO ticketChatDTO) {
mongoTemplate.save(ticketChatDTO);
}
@ -147,6 +153,19 @@ public class TicketChatService {
log.info("消息撤回 找到消息");
message.setContent("消息已撤回");
flag=true;
//删除消息附件
List<Integer> fileIds = new ArrayList<>();
if (CollectionUtil.isNotEmpty(message.getAttachments())) {
fileIds.addAll(message.getAttachments().stream().map(FileUploadVO::getId).collect(Collectors.toList()));
}
if (CollectionUtil.isNotEmpty(message.getImages())) {
fileIds.addAll(message.getImages().stream().map(FileUploadVO::getId).collect(Collectors.toList()));
}
if (CollectionUtil.isNotEmpty(fileIds)) {
fileUploadRecordService.lambdaUpdate()
.in(FileUploadRecord::getId, fileIds)
.remove();
}
}
}
if (flag && Objects.nonNull(message.getQuote()) && message.getQuote().getId().equals(messageId)){

View File

@ -18,6 +18,7 @@ import java.util.Objects;
* <p>
* 派工单 服务实现类
* </p>
*
* @author 代码生成器生成
* @since 2025
*/
@ -25,8 +26,8 @@ import java.util.Objects;
public class GongfuDispatchServiceImpl extends ServiceImpl<GongfuDispatchMapper, GongfuDispatch> implements IGongfuDispatchService {
@Override
public IPage<DispatchVO> search(DispatchSearchRequest request) {
return baseMapper.search(request, new Page<>(request.getPage(), request.getPageSize()));
public IPage<DispatchVO> search(DispatchSearchRequest request, Integer userId) {
return baseMapper.search(request, userId, new Page<>(request.getPage(), request.getPageSize()));
}
@Override

View File

@ -3,7 +3,8 @@
<mapper namespace="com.nflg.mobilebroken.repository.mapper.GongfuDispatchMapper">
<select id="search" resultType="com.nflg.mobilebroken.common.pojo.vo.DispatchVO">
SELECT da.*,dv.customer_name,bc.agency_company_name as agent_name,af.reason as "delayReason",af2.id as "applyforId"
SELECT da.*,dv.customer_name,bc.agency_company_name as agent_name,af.reason as "delayReason",af2.id as
"applyforId",if(da.create_by_id =#{userId} or da.handler_user_id = #{userId},1,0) AS usort
FROM gongfu_dispatch da
LEFT JOIN v_gongfu_device dv ON da.device_no=dv.device_no
LEFT JOIN t_base_customer bc ON dv.agent_code=bc.agency_company_code
@ -36,13 +37,13 @@
</if>
<if test="request.key!=null and request.key!=''">
AND (da.device_no like concat('%',#{request.key},'%')
or da.handler_user_name like concat('%',#{request.key},'%')
or da.title like concat('%',#{request.key},'%')
or dv.customer_name like concat('%',#{request.key},'%')
or da.handler_user_name like concat('%',#{request.key},'%')
or da.title like concat('%',#{request.key},'%')
or dv.customer_name like concat('%',#{request.key},'%')
)
</if>
</where>
ORDER BY da.state,da.id DESC
ORDER BY usort DESC,da.state,da.plan_start_date DESC,da.id DESC
</select>
<select id="getInfo" resultType="com.nflg.mobilebroken.common.pojo.vo.DispatchVO">