feat(ticket): 添加事故等级功能并优化解决方案措施

- 在 Ticket 和 AdminTicketVO 中添加事故等级字段
- 新增 TicketAccidentLevel 枚举类
- 修改 SolutionMeasures 相关的 VO 和 Request 类
- 优化 TicketController 中的解决方案措施获取和审核逻辑
- 更新 TicketServiceImpl 中的工单创建和完成逻辑
-改进 TicketSolutionAuditServiceImpl 中的审核功能
- 重构 TicketSolutionServiceImpl 中的解决方案措施获取和保存逻辑
This commit is contained in:
曹鹏飞 2025-03-28 20:14:00 +08:00
parent 2e47076abb
commit c7de80b9cf
19 changed files with 298 additions and 135 deletions

View File

@ -6,6 +6,8 @@ import com.itextpdf.text.pdf.BaseFont;
import com.nflg.mobilebroken.admin.annotation.ApiMark;
import com.nflg.mobilebroken.admin.publisher.TicketEventPublisher;
import com.nflg.mobilebroken.admin.service.SsePushService;
import com.nflg.mobilebroken.common.constant.MessageSubType;
import com.nflg.mobilebroken.common.constant.MessageType;
import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.constant.TicketState;
import com.nflg.mobilebroken.common.exception.NflgException;
@ -40,6 +42,7 @@ import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@ -105,6 +108,12 @@ public class TicketController extends ControllerBase {
@Resource
private ITicketSolutionAuditService ticketSolutionAuditService;
@Resource
private IAdminMessageService adminMessageService;
@Resource
private ITBaseDeviceTypeService deviceTypeService;
/**
* 获取问题类型
* @return 问题类型列表
@ -476,24 +485,6 @@ public class TicketController extends ControllerBase {
images.add(new FileInfo(item.substring(item.lastIndexOf("/")+1),item));
});
}
//加上聊天中的图片和文件
List<ChatMessageVO> messageVOS=ticketChatService.getMessages(ticket.getId());
messageVOS.forEach(messageVO -> {
if (CollectionUtil.isNotEmpty(messageVO.getImages())){
messageVO.getImages().forEach(image -> {
images.add(new FileInfo(image.substring(image.lastIndexOf("/")+1),image));
});
}
if (CollectionUtil.isNotEmpty(messageVO.getAttachments())){
messageVO.getAttachments().forEach(attachment -> {
if (attachment.endsWith(".jpg") || attachment.endsWith(".png") || attachment.endsWith(".jpeg")) {
images.add(new FileInfo(attachment.substring(attachment.lastIndexOf("/")+1),urlEncode(attachment)));
} else {
files.add(new FileInfo(attachment.substring(attachment.lastIndexOf("/")+1),urlEncode(attachment)));
}
});
}
});
TicketPdfVO vo = new TicketPdfVO()
.setNo(ticket.getNo())
.setTitle(ticket.getTitle())
@ -513,7 +504,7 @@ public class TicketController extends ControllerBase {
.setDeviceAddress(ticket.getDeviceAddress())
.setImages(images)
.setFiles(files)
.setMeasures(ticketSolutionService.getSolutionMeasures(ticket.getId()));
.setMeasures(ticketSolutionService.getSolutionMeasures(ticket.getId()).getMeasures());
Map<String, Object> variables = new HashMap<>();
variables.put("ticket", vo);
// 渲染HTML
@ -610,6 +601,7 @@ public class TicketController extends ControllerBase {
.setCompanyName(device.getCustomerName())
.setHandle(handle)
.setSolution(ticket.getReason())
.setAccidentLevel(ticket.getAccidentLevel())
.setEvaluate(getTicketEvaluate(ticket.getId()));
return ApiResult.success(vo);
}
@ -740,7 +732,7 @@ public class TicketController extends ControllerBase {
**/
@GetMapping("getSolutionMeasures")
@ApiMark(moduleName = "工单管理", apiName = "获取工单解决方案措施")
public ApiResult<List<SolutionMeasuresVO>> getSolutionMeasures(@Valid @RequestParam @NotNull Integer ticketId){
public ApiResult<SolutionMeasuresVO> getSolutionMeasures(@Valid @RequestParam @NotNull Integer ticketId){
return ApiResult.success(ticketSolutionService.getSolutionMeasures(ticketId));
}
@ -783,8 +775,28 @@ public class TicketController extends ControllerBase {
**/
@GetMapping("rejectSolution")
@ApiMark(moduleName = "工单管理", apiName = "驳回工单解决方案")
public ApiResult<Void> rejectSolution(@Valid @RequestBody SolutionRejectRequest request){
ticketSolutionAuditService.reject(request);
public ApiResult<Void> rejectSolution(@Valid @RequestBody SolutionRejectRequest request) {
Ticket ticket = ticketSolutionAuditService.reject(request);
if (Objects.nonNull(ticket)) {
TicketSolutionAudit audit = ticketSolutionAuditService.lambdaQuery()
.eq(TicketSolutionAudit::getTicketId, ticket.getId())
.eq(TicketSolutionAudit::getUserId, AdminUserUtil.getUserId())
.one();
List<Integer> cqms = deviceTypeService.getCqmsByDeviceType(ticket.getDeviceNo());
cqms.forEach(cqm -> {
adminMessageService.add(
new AdminMessage()
.setNo(ticket.getNo())
.setTitle(ticket.getTitle() + "工单解决方案报告," + audit.getDeptName() + "部门主管不同意,请更正解决方案")
.setUserId(cqm)
.setSourceId(ticket.getId())
.setSource(0)
.setType(MessageType.WorkOrderAssignment.getState())
.setSubType(MessageSubType.TicketSolutionAudit.getState())
.setIsRead(false)
.setCreateTime(LocalDateTime.now()));
});
}
return ApiResult.success();
}

View File

@ -0,0 +1,25 @@
package com.nflg.mobilebroken.common.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TicketAccidentLevel {
General((byte) 0, "一般"),
MoreSerious((byte) 1, "较严重"),
Serious((byte) 2, "严重");
private final Byte state;
private final String description;
public static TicketAccidentLevel findByValue(Byte value) {
for (TicketAccidentLevel valueEnum : TicketAccidentLevel.values()) {
if (valueEnum.getState().equals(value)) {
return valueEnum;
}
}
return null;
}
}

View File

@ -2,8 +2,7 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.*;
import java.util.List;
@Data
@ -13,13 +12,15 @@ public class AssignmentTicketRequest {
@NotNull
private Integer ticketId;
// //紧急程度0非紧急1普通2紧急
// @NotNull
// private Byte urgency;
//
// //问题类型
// @NotBlank
// private String question;
//紧急程度0非紧急1普通2紧急
@NotNull
@Min(value = 0)
@Max(value = 2)
private Byte urgency;
//问题类型
@NotBlank
private String question;
//备注
private String remark;

View File

@ -1,6 +1,6 @@
package com.nflg.mobilebroken.common.pojo.request;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresVO;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresItemVO;
import lombok.Data;
import javax.validation.Valid;
@ -18,13 +18,11 @@ public class SolutionMeasuresSaveRequest {
@NotNull
private Integer ticketId;
//紧急程度0非紧急1普通2紧急
/**
* 事故等级0一般1较严重2严重
*/
@NotNull
private Byte urgency;
//问题类型
@NotBlank
private String question;
private Byte accidentLevel;
/**
* 根本原因
@ -37,5 +35,5 @@ public class SolutionMeasuresSaveRequest {
*/
@Valid
@NotEmpty
private List<SolutionMeasuresVO> solutionMeasures;
private List<SolutionMeasuresItemVO> solutionMeasures;
}

View File

@ -2,6 +2,7 @@ package com.nflg.mobilebroken.common.pojo.vo;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.nflg.mobilebroken.common.constant.TicketAccidentLevel;
import com.nflg.mobilebroken.common.constant.TicketState;
import com.nflg.mobilebroken.common.constant.TicketUrgency;
import lombok.Data;
@ -153,6 +154,21 @@ public class AdminTicketVO {
@ExcelColumn("关闭时间")
private LocalDateTime closeTime;
//事故等级0一般1较严重2严重
@IgnoreExport
private Byte accidentLevel;
//事故等级
@ExcelColumn("事故等级")
private String accidentLevelDesc;
public String getAccidentLevelDesc() {
if (Objects.isNull(accidentLevel)) {
return "";
}
return TicketAccidentLevel.findByValue(accidentLevel).getDescription();
}
//是否已关注
@IgnoreExport
private boolean followed;

View File

@ -0,0 +1,50 @@
package com.nflg.mobilebroken.common.pojo.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
@Data
@Accessors(chain = true)
public class SolutionMeasuresDataItemVO {
/**
* 措施id
*/
private Integer id;
/**
* 措施
*/
@NotBlank
private String name;
/**
* 负责人
*/
@NotBlank
private String superintendent;
/**
* 计划日期
*/
@NotBlank
private String scheduleDate;
/**
* 确认日期
*/
@NotBlank
private String confirmedDate;
/**
* 备注
*/
private String remark;
/**
* 创建人id
*/
private Integer createUserId;
}

View File

@ -3,45 +3,30 @@ package com.nflg.mobilebroken.common.pojo.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@Accessors(chain = true)
public class SolutionMeasuresItemVO {
/**
* 措施分类id
*/
@NotNull
private Integer id;
/**
* 措施
* 措施分类名称
*/
@NotBlank
private String name;
/**
* 负责人
* 具体的措施
*/
@NotBlank
private String superintendent;
/**
* 计划日期
*/
@NotBlank
private String scheduleDate;
/**
* 确认日期
*/
@NotBlank
private String confirmedDate;
/**
* 备注
*/
private String remark;
/**
* 创建人id
*/
private Integer createUserId;
@Valid
private List<SolutionMeasuresDataItemVO> items;
}

View File

@ -3,21 +3,21 @@ package com.nflg.mobilebroken.common.pojo.vo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
@Accessors(chain = true)
public class SolutionMeasuresVO {
@NotNull
private Integer id;
// 解决方案措施
private List<SolutionMeasuresItemVO> measures;
@NotBlank
private String name;
// //是否已结案
// private boolean locked;
@Valid
private List<SolutionMeasuresItemVO> items;
//是否是审核人
private boolean inAudit=false;
// 是否已审核
private boolean audited=false;
}

View File

@ -21,6 +21,18 @@ public class SolutionReviewDepartmentVO {
//用户名称
private String userName;
//用户部门名称
private String userDeptName;
//用户职位名称
private String userTitle;
//用户编号
private String userCode;
//审核状态0不通过1通过, null未审核
private Integer state;
//审核不通过原因
private String reason;
}

View File

@ -107,4 +107,9 @@ public class TicketInfoVO {
* 设备地址
*/
private String deviceAddress;
/**
* 事故等级0一般1较严重2严重
*/
private Byte accidentLevel;
}

View File

@ -77,5 +77,5 @@ public class TicketPdfVO {
//设备地址
private String deviceAddress;
private List<SolutionMeasuresVO> measures;
private List<SolutionMeasuresItemVO> measures;
}

View File

@ -112,6 +112,11 @@ public class Ticket implements Serializable {
*/
private String question;
/**
* 事故等级
*/
private Byte accidentLevel;
/**
* 备注
*/

View File

@ -72,7 +72,7 @@ public class TicketSolution implements Serializable {
/**
* 创建人id
*/
private Integer createUserid;
private Integer createUserId;
/**
* 创建时间

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.mobilebroken.common.pojo.request.SolutionRejectRequest;
import com.nflg.mobilebroken.common.pojo.request.SolutionReviewDepartmentSaveRequest;
import com.nflg.mobilebroken.common.pojo.vo.SolutionReviewDepartmentVO;
import com.nflg.mobilebroken.repository.entity.Ticket;
import com.nflg.mobilebroken.repository.entity.TicketSolutionAudit;
import java.util.List;
@ -22,7 +23,9 @@ public interface ITicketSolutionAuditService extends IService<TicketSolutionAudi
void saveSolutionReviewDepartment(SolutionReviewDepartmentSaveRequest request);
void reject(SolutionRejectRequest request);
Ticket reject(SolutionRejectRequest request);
boolean pass(Integer ticketId);
TicketSolutionAudit getByTicketAndUser(Integer ticketId, Integer userId);
}

View File

@ -5,8 +5,6 @@ import com.nflg.mobilebroken.common.pojo.request.SolutionMeasuresSaveRequest;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresVO;
import com.nflg.mobilebroken.repository.entity.TicketSolution;
import java.util.List;
/**
* <p>
* 服务类
@ -17,7 +15,7 @@ import java.util.List;
*/
public interface ITicketSolutionService extends IService<TicketSolution> {
List<SolutionMeasuresVO> getSolutionMeasures(Integer ticketId);
SolutionMeasuresVO getSolutionMeasures(Integer ticketId);
void saveSolutionMeasures(SolutionMeasuresSaveRequest request);
}

View File

@ -52,6 +52,9 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
@Resource
private ITicketSolutionAuditService ticketSolutionAuditService;
@Resource
private ITicketSolutionService ticketSolutionService;
@Override
public Ticket add(TicketAddRequest request, Integer userId) {
Ticket lastTicket=lambdaQuery()
@ -144,8 +147,8 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
List<Integer> tickerMangagers = adminUserService.getTickerMangagers();
VUtils.trueThrowBusinessError(tickerMangagers.stream().noneMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId())))
.throwMessage("你无权分派工单");
// ticket.setUrgency(TicketUrgency.findByValue(request.getUrgency()).getState());
// ticket.setQuestion(request.getQuestion());
ticket.setUrgency(request.getUrgency());
ticket.setQuestion(request.getQuestion());
ticket.setState(TicketState.Processing.getState());
ticket.setRemark(request.getRemark());
ticket.setHandle(StrUtil.join(",", request.getUserIds()));
@ -198,6 +201,8 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
tickerMangagers.addAll(Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).collect(Collectors.toList()));
VUtils.trueThrowBusinessError(tickerMangagers.stream().noneMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId())))
.throwMessage("你无权完成工单");
VUtils.trueThrowBusinessError(!ticketSolutionService.lambdaQuery().eq(TicketSolution::getTicketId, id).exists())
.throwMessage("工单“" + ticket.getTitle() + "”还未填写解决方案");
ticket.setState(TicketState.ProcessingCompleted.getState());
ticket.setCurrentHandle(AdminUserUtil.getUserId());
ticket.setUpdateTime(LocalDateTime.now());

View File

@ -68,6 +68,8 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
@Transactional
@Override
public void saveSolutionReviewDepartment(SolutionReviewDepartmentSaveRequest request) {
List<Integer> users=request.getDepartments().stream().map(SolutionReviewDepartmentVO::getUserId).collect(Collectors.toList());
VUtils.trueThrowBusinessError(!Objects.equals((long)users.size(),users.stream().distinct().count())).throwMessage("不同部门不能设置为同一个人");
remove(new LambdaQueryWrapper<TicketSolutionAudit>()
.eq(TicketSolutionAudit::getTicketId,request.getTicketId())
.notIn(TicketSolutionAudit::getDeptName,request.getDepartments().stream().map(SolutionReviewDepartmentVO::getDeptName).collect(Collectors.toList())));
@ -115,7 +117,7 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
}
@Override
public void reject(SolutionRejectRequest request) {
public Ticket reject(SolutionRejectRequest request) {
Ticket ticket=ticketService.getById(request.getTicketId());
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState()))
@ -132,13 +134,17 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
.eq(TicketSolutionAudit::getState, 1)
.exists())
.throwMessage("已通过后不能再次审核");
lambdaUpdate()
if(lambdaUpdate()
.set(TicketSolutionAudit::getState,0)
.set(TicketSolutionAudit::getReason,request.getReason())
.set(TicketSolutionAudit::getCreateTime,LocalDateTime.now())
.eq(TicketSolutionAudit::getTicketId,request.getTicketId())
.eq(TicketSolutionAudit::getUserId,userId)
.update();
.update()){
return ticket;
}else {
return null;
}
}
@Transactional
@ -169,4 +175,13 @@ public class TicketSolutionAuditServiceImpl extends ServiceImpl<TicketSolutionAu
.update();
return ticketService.close(ticket);
}
@Override
public TicketSolutionAudit getByTicketAndUser(Integer ticketId, Integer userId) {
return lambdaQuery()
.eq(TicketSolutionAudit::getTicketId,ticketId)
.eq(TicketSolutionAudit::getUserId,userId)
.last("limit 1")
.one();
}
}

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.constant.TicketState;
import com.nflg.mobilebroken.common.pojo.request.SolutionMeasuresSaveRequest;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresDataItemVO;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresItemVO;
import com.nflg.mobilebroken.common.pojo.vo.SolutionMeasuresVO;
import com.nflg.mobilebroken.common.util.AdminUserUtil;
@ -13,11 +14,9 @@ import com.nflg.mobilebroken.common.util.VUtils;
import com.nflg.mobilebroken.repository.entity.DictionaryItem;
import com.nflg.mobilebroken.repository.entity.Ticket;
import com.nflg.mobilebroken.repository.entity.TicketSolution;
import com.nflg.mobilebroken.repository.entity.TicketSolutionAudit;
import com.nflg.mobilebroken.repository.mapper.TicketSolutionMapper;
import com.nflg.mobilebroken.repository.service.IAdminUserService;
import com.nflg.mobilebroken.repository.service.IDictionaryItemService;
import com.nflg.mobilebroken.repository.service.ITicketService;
import com.nflg.mobilebroken.repository.service.ITicketSolutionService;
import com.nflg.mobilebroken.repository.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -46,55 +45,68 @@ public class TicketSolutionServiceImpl extends ServiceImpl<TicketSolutionMapper,
@Resource
private IAdminUserService adminUserService;
@Resource
private ITicketSolutionAuditService ticketSolutionAuditService;
@Override
public List<SolutionMeasuresVO> getSolutionMeasures(Integer ticketId) {
public SolutionMeasuresVO getSolutionMeasures(Integer ticketId) {
Ticket ticket = ticketService.getById(ticketId);
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
List<String> initialNames= new ArrayList<>();
if (Objects.equals(ticket.getState(), TicketState.Processing.getState())) {
List<DictionaryItem> items = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_SOLUTION_MEASURES);
initialNames=items.stream().map(DictionaryItem::getValue).collect(Collectors.toList());
List<DictionaryItem> initial= new ArrayList<>();
if (Objects.equals(ticket.getState(), TicketState.Processing.getState()) || Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState())) {
initial = dictionaryItemService.getListByDictionaryCode(Constant.DICTIONARY_SOLUTION_MEASURES);
}
List<TicketSolution> solutions = lambdaQuery().eq(TicketSolution::getTicketId, ticketId).orderByAsc(TicketSolution::getId).list();
Map<String, List<TicketSolution>> groupedSolutions = solutions.stream().collect(Collectors.groupingBy(TicketSolution::getDictionaryItemName, LinkedHashMap::new, Collectors.toList()));
SolutionMeasuresVO vo=new SolutionMeasuresVO();
TicketSolutionAudit audit =ticketSolutionAuditService.getByTicketAndUser(ticketId,AdminUserUtil.getUserId());
if (Objects.nonNull(audit)){
vo.setInAudit(true);
vo.setAudited(Objects.equals(audit.getState(),1));
}
List<SolutionMeasuresItemVO> items = new ArrayList<>();
if (CollectionUtil.isEmpty(groupedSolutions)) {
return initialNames.stream().map(ticketSolutions -> new SolutionMeasuresVO()
.setName(ticketSolutions)
items= initial.stream().map(it -> new SolutionMeasuresItemVO()
.setId(it.getId())
.setName(it.getName())
.setItems(Collections.emptyList()))
.collect(Collectors.toList());
} else if (CollectionUtil.isEmpty(initialNames)) {
return groupedSolutions.entrySet().stream().map(ks -> new SolutionMeasuresVO()
} else if (CollectionUtil.isEmpty(initial)) {
items= groupedSolutions.entrySet().stream().map(ks -> new SolutionMeasuresItemVO()
.setName(ks.getKey())
.setItems(ks.getValue().stream().map(v -> new SolutionMeasuresItemVO()
.setItems(ks.getValue().stream().map(v -> new SolutionMeasuresDataItemVO()
.setId(v.getId())
.setName(v.getDescription())
.setSuperintendent(v.getSuperintendent())
.setScheduleDate(v.getScheduleDate())
.setConfirmedDate(v.getConfirmedDate())
.setRemark(v.getRemark())
.setCreateUserId(v.getCreateUserid())).collect(Collectors.toList())
.setCreateUserId(v.getCreateUserId())).collect(Collectors.toList())
)).collect(Collectors.toList());
} else {
List<SolutionMeasuresVO> vos = new ArrayList<>();
initialNames.forEach(name -> {
List<TicketSolution> values = groupedSolutions.get(name);
for (DictionaryItem it : initial){
List<TicketSolution> values = groupedSolutions.get(it.getName());
if (CollectionUtil.isEmpty(values)) {
vos.add(new SolutionMeasuresVO().setName(name).setItems(Collections.emptyList()));
items.add(new SolutionMeasuresItemVO().setId(it.getId()).setName(it.getName()).setItems(Collections.emptyList()));
} else {
vos.add(new SolutionMeasuresVO()
.setName(name)
.setItems(values.stream().map(v -> new SolutionMeasuresItemVO()
items.add(new SolutionMeasuresItemVO()
.setId(it.getId())
.setName(it.getName())
.setItems(values.stream().map(v -> new SolutionMeasuresDataItemVO()
.setId(v.getId())
.setName(v.getDescription())
.setSuperintendent(v.getSuperintendent())
.setScheduleDate(v.getScheduleDate())
.setConfirmedDate(v.getConfirmedDate())
.setRemark(v.getRemark())
.setCreateUserId(v.getCreateUserid())).collect(Collectors.toList())
.setCreateUserId(v.getCreateUserId())).collect(Collectors.toList())
)
);
}
});
return vos;
}
}
vo.setMeasures(items);
return vo;
}
@Transactional
@ -105,42 +117,54 @@ public class TicketSolutionServiceImpl extends ServiceImpl<TicketSolutionMapper,
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())
&& !Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState()))
.throwMessage("当前工单状态不允许修改解决方案");
Integer userId=AdminUserUtil.getUserId();
List<Integer> cqmIds=adminUserService.getCQMIds();
cqmIds.addAll(Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).collect(Collectors.toList()));
VUtils.trueThrowBusinessError(cqmIds.stream().noneMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId())))
List<Integer> handleIds=Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).collect(Collectors.toList());
VUtils.trueThrowBusinessError(cqmIds.stream().noneMatch(uid -> Objects.equals(uid, userId))
&& handleIds.stream().noneMatch(uid -> Objects.equals(uid, userId)))
.throwMessage("无权修改解决方案");
ticketService.lambdaUpdate()
.set(Ticket::getReason, request.getReason())
.set(Ticket::getUrgency, request.getUrgency())
.set(Ticket::getQuestion, request.getQuestion())
.eq(Ticket::getId, request.getTicketId())
.update();
baseMapper.delete(new LambdaQueryWrapper<TicketSolution>()
.eq(TicketSolution::getTicketId,request.getTicketId())
.notIn(TicketSolution::getId, request.getSolutionMeasures().stream().flatMap(s -> s.getItems().stream()).map(SolutionMeasuresItemVO::getId).collect(Collectors.toList()))
);
List<TicketSolution> forAdd=new ArrayList<>();
List<TicketSolution> forUpdate=new ArrayList<>();
for (SolutionMeasuresVO solutionMeasuresVO : request.getSolutionMeasures()) {
for (SolutionMeasuresItemVO solutionMeasuresItemVO : solutionMeasuresVO.getItems()){
for (SolutionMeasuresItemVO solutionMeasuresItemVO : request.getSolutionMeasures()) {
for (SolutionMeasuresDataItemVO solutionMeasuresDataItemVO : solutionMeasuresItemVO.getItems()){
TicketSolution solution=new TicketSolution()
.setTicketId(request.getTicketId())
.setDictionaryItemId(solutionMeasuresVO.getId())
.setDictionaryItemName(solutionMeasuresVO.getName())
.setDescription(solutionMeasuresItemVO.getName())
.setSuperintendent(solutionMeasuresItemVO.getSuperintendent())
.setScheduleDate(solutionMeasuresItemVO.getScheduleDate())
.setConfirmedDate(solutionMeasuresItemVO.getConfirmedDate());
if (Objects.isNull(solutionMeasuresItemVO.getId())){
solution.setCreateUserid(AdminUserUtil.getUserId())
.setDictionaryItemId(solutionMeasuresItemVO.getId())
.setDictionaryItemName(solutionMeasuresItemVO.getName())
.setDescription(solutionMeasuresDataItemVO.getName())
.setSuperintendent(solutionMeasuresDataItemVO.getSuperintendent())
.setScheduleDate(solutionMeasuresDataItemVO.getScheduleDate())
.setConfirmedDate(solutionMeasuresDataItemVO.getConfirmedDate());
if (Objects.isNull(solutionMeasuresDataItemVO.getId())){
solution.setCreateUserId(userId)
.setCreateTime(LocalDateTime.now());
forAdd.add(solution);
}else {
solution.setId(solutionMeasuresItemVO.getId());
solution.setId(solutionMeasuresDataItemVO.getId());
forUpdate.add(solution);
}
}
}
List<Integer> idForReserve=forUpdate.stream().map(TicketSolution::getId).collect(Collectors.toList());
List<TicketSolution> solutions=lambdaQuery().eq(TicketSolution::getTicketId, request.getTicketId()).orderByAsc(TicketSolution::getId).list();
if (!cqmIds.contains(userId)){
List<TicketSolution> solutions1=solutions.stream().filter(s->idForReserve.contains(s.getId())).collect(Collectors.toList());
solutions.removeAll(solutions1);
VUtils.trueThrowBusinessError(solutions.stream().anyMatch(s->!Objects.equals(s.getCreateUserId(), userId)))
.throwMessage("不能删除他人创建的措施");
solutions1.removeIf(s->Objects.equals(s.getCreateUserId(), userId));
List<TicketSolution> ts=forUpdate.stream().filter(s->!Objects.equals(s.getCreateUserId(), userId)).collect(Collectors.toList());
VUtils.trueThrowBusinessError(!ts.equals(solutions1)).throwMessage("不能修改他人创建的措施");
}
ticketService.lambdaUpdate()
.set(Ticket::getReason, request.getReason())
.set(Ticket::getAccidentLevel, request.getAccidentLevel())
.eq(Ticket::getId, request.getTicketId())
.update();
baseMapper.delete(new LambdaQueryWrapper<TicketSolution>()
.eq(TicketSolution::getTicketId,request.getTicketId())
.notIn(TicketSolution::getId, idForReserve)
);
if (CollectionUtil.isNotEmpty(forAdd)){
saveBatch(forAdd);
}

View File

@ -1,11 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nflg.mobilebroken.repository.mapper.TicketSolutionAuditMapper">
<select id="getByTicket" resultType="com.nflg.mobilebroken.common.pojo.vo.SolutionReviewDepartmentVO">
SELECT tsa.id, tsa.dept_name, tsa.user_id, au.user_name, tsa.state
SELECT tsa.id,
tsa.dept_name,
tsa.user_id,
au.user_name,
tsa.state,
d.dept_name AS user_dept_name,
p.position_name AS user_title,
au.user_code,
tsa.reason
FROM ticket_solution_audit tsa
LEFT JOIN admin_user au ON tsa.user_id = au.id
LEFT JOIN t_base_department d ON d.id = au.department_id
LEFT JOIN t_base_position p ON p.id = au.title_id
WHERE tsa.ticket_id = #{ticketId}
</select>
</mapper>