feat(ticket): 实现工单撤销功能的权限分离

- 将工单撤销方法分离为app端和admin端两个独立方法
- 添加工单状态检查,防止已完成工单被撤销
- 增加工单评价检查,已评价工单不允许撤销
- 更新派工相关错误提示信息,统一使用"派工"而非"派工单"
- 调整工单列表排序规则,按状态和ID降序排列
- 在应用启动时添加Sa-Token配置日志输出
- 更新消息类型常量中的派工相关描述
This commit is contained in:
曹鹏飞 2025-12-31 12:08:46 +08:00
parent 8a0f4620c8
commit 0c792869ba
11 changed files with 62 additions and 24 deletions

View File

@ -480,7 +480,7 @@ public class TicketController extends ControllerBase {
**/ **/
@GetMapping("revokedTicket") @GetMapping("revokedTicket")
public ApiResult<Void> revokedTicket(@Valid @RequestParam @NotNull Integer id) { public ApiResult<Void> revokedTicket(@Valid @RequestParam @NotNull Integer id) {
ticketService.revoked(id); ticketService.revokedFromAdmin(id);
return ApiResult.success(); return ApiResult.success();
} }

View File

@ -1,5 +1,7 @@
package com.nflg.mobilebroken.cfs; package com.nflg.mobilebroken.cfs;
import cn.dev33.satoken.SaManager;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -8,6 +10,7 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@SpringBootApplication @SpringBootApplication
@MapperScan("com.nflg.mobilebroken.repository.mapper") @MapperScan("com.nflg.mobilebroken.repository.mapper")
@ComponentScan(basePackages = {"com.nflg.mobilebroken.repository.service", "com.nflg.mobilebroken.cfs" @ComponentScan(basePackages = {"com.nflg.mobilebroken.repository.service", "com.nflg.mobilebroken.cfs"
@ -19,5 +22,6 @@ public class CfsApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(CfsApplication.class, args); SpringApplication.run(CfsApplication.class, args);
log.info("启动成功Sa-Token 配置如下:{}", SaManager.getConfig());
} }
} }

View File

@ -35,12 +35,12 @@ public class TicketUnionService {
public TicketDTO revoked(Long id) { public TicketDTO revoked(Long id) {
if (id < Integer.MAX_VALUE) { if (id < Integer.MAX_VALUE) {
Ticket ticket = ticketService.revoked(Math.toIntExact(id)); Ticket ticket = ticketService.revokedFromApp(Math.toIntExact(id));
TicketDTO dto = Convert.convert(TicketDTO.class, ticket); TicketDTO dto = Convert.convert(TicketDTO.class, ticket);
dto.setType(0); dto.setType(0);
return dto; return dto;
} else { } else {
GongfuTicket ticket = gongfuTicketService.revoked(id); GongfuTicket ticket = gongfuTicketService.revokedFromApp(id);
TicketDTO dto = Convert.convert(TicketDTO.class, ticket); TicketDTO dto = Convert.convert(TicketDTO.class, ticket);
dto.setType(1); dto.setType(1);
return dto; return dto;

View File

@ -32,13 +32,13 @@ public enum MessageSubType {
//工单解决方案审核 //工单解决方案审核
TicketSolutionAudit(11, "工单解决方案审核"), TicketSolutionAudit(11, "工单解决方案审核"),
//派工单延期审核 //派工单延期审核
DispatchApplyforAudit(12, "派工延期审核"), DispatchApplyforAudit(12, "派工延期审核"),
//派工单创建 //派工单创建
DispatchCreate(13, "派工创建"), DispatchCreate(13, "派工创建"),
//派工单完成 //派工单完成
DispatchComplate(14, "派工完成"), DispatchComplate(14, "派工完成"),
//派工单延期审核结果 //派工单延期审核结果
DispatchAuditResult(15, "派工延期审核结果"), DispatchAuditResult(15, "派工延期审核结果"),
//工单解决方案审核 //工单解决方案审核
TicketSolutionAuditResult(16, "工单解决方案审核结果"), TicketSolutionAuditResult(16, "工单解决方案审核结果"),
; ;

View File

@ -219,7 +219,7 @@ public class DispatchController extends ControllerBase {
@GetMapping("/getInfo") @GetMapping("/getInfo")
public ApiResult<DispatchVO> getInfo(@RequestParam Long id) { public ApiResult<DispatchVO> getInfo(@RequestParam Long id) {
DispatchVO vo = dispatchService.getInfo(id); DispatchVO vo = dispatchService.getInfo(id);
VUtils.trueThrowBusinessError(Objects.isNull(vo)).throwMessage("派工不存在"); VUtils.trueThrowBusinessError(Objects.isNull(vo)).throwMessage("派工不存在");
vo.setFiles(Convert.toList(GongfuFileVO.class, fileService.lambdaQuery() vo.setFiles(Convert.toList(GongfuFileVO.class, fileService.lambdaQuery()
.eq(GongfuFile::getSourceId, id) .eq(GongfuFile::getSourceId, id)
.list() .list()
@ -238,7 +238,7 @@ public class DispatchController extends ControllerBase {
public ApiResult<Void> applyforAdd(@Valid @RequestBody DispatchApplyForAddRequest request) { public ApiResult<Void> applyforAdd(@Valid @RequestBody DispatchApplyForAddRequest request) {
GongfuDispatch dispatch = dispatchService.getById(request.getTicketId()); GongfuDispatch dispatch = dispatchService.getById(request.getTicketId());
VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getHandlerUserId(), AdminUserUtil.getUserId().longValue())) VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getHandlerUserId(), AdminUserUtil.getUserId().longValue()))
.throwMessage("你不是派工处理人,无法申请延期"); .throwMessage("你不是派工处理人,无法申请延期");
VUtils.trueThrowBusinessError(Objects.equals(dispatch.getState(), 2)).throwMessage("已完成状态不能申请延期"); VUtils.trueThrowBusinessError(Objects.equals(dispatch.getState(), 2)).throwMessage("已完成状态不能申请延期");
VUtils.trueThrowBusinessError(dispatchApplyforService.lambdaQuery() VUtils.trueThrowBusinessError(dispatchApplyforService.lambdaQuery()
.eq(GongfuDispatchApplyfor::getTicketId, request.getTicketId()) .eq(GongfuDispatchApplyfor::getTicketId, request.getTicketId())
@ -285,7 +285,7 @@ public class DispatchController extends ControllerBase {
VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("延期申请不存在"); VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("延期申请不存在");
VUtils.trueThrowBusinessError(!Objects.equals(applyfor.getAuditState(), 0)).throwMessage("已经审核过了"); VUtils.trueThrowBusinessError(!Objects.equals(applyfor.getAuditState(), 0)).throwMessage("已经审核过了");
GongfuDispatch dispatch = dispatchService.getById(applyfor.getTicketId()); GongfuDispatch dispatch = dispatchService.getById(applyfor.getTicketId());
VUtils.trueThrowBusinessError(Objects.isNull(dispatch)).throwMessage("派工不存在"); VUtils.trueThrowBusinessError(Objects.isNull(dispatch)).throwMessage("派工不存在");
ApplyforAuditVO vo = new ApplyforAuditVO(); ApplyforAuditVO vo = new ApplyforAuditVO();
vo.setApplyUser(adminUserService.getInfo(applyfor.getCreateById())); vo.setApplyUser(adminUserService.getInfo(applyfor.getCreateById()));
DispatchApplyforAuditVO ao = Convert.convert(DispatchApplyforAuditVO.class, dispatch); DispatchApplyforAuditVO ao = Convert.convert(DispatchApplyforAuditVO.class, dispatch);
@ -306,10 +306,10 @@ public class DispatchController extends ControllerBase {
VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("延期申请不存在"); VUtils.trueThrowBusinessError(Objects.isNull(applyfor)).throwMessage("延期申请不存在");
VUtils.trueThrowBusinessError(!Objects.equals(applyfor.getAuditState(), 0)).throwMessage("已经审核过了"); VUtils.trueThrowBusinessError(!Objects.equals(applyfor.getAuditState(), 0)).throwMessage("已经审核过了");
GongfuDispatch dispatch = dispatchService.getById(applyfor.getTicketId()); GongfuDispatch dispatch = dispatchService.getById(applyfor.getTicketId());
VUtils.trueThrowBusinessError(Objects.isNull(dispatch)).throwMessage("派工不存在"); VUtils.trueThrowBusinessError(Objects.isNull(dispatch)).throwMessage("派工不存在");
VUtils.trueThrowBusinessError(dispatch.getState() == 2).throwMessage("派工已完成不能延期"); VUtils.trueThrowBusinessError(dispatch.getState() == 2).throwMessage("派工已完成不能延期");
VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getCreateById(), AdminUserUtil.getUserId())) VUtils.trueThrowBusinessError(!Objects.equals(dispatch.getCreateById(), AdminUserUtil.getUserId()))
.throwMessage("你不是派工创建人,无法审核延期申请"); .throwMessage("你不是派工创建人,无法审核延期申请");
applyfor.setAuditState(request.getPass() ? 1 : 2); applyfor.setAuditState(request.getPass() ? 1 : 2);
applyfor.setAuditUser(AdminUserUtil.getUserName()); applyfor.setAuditUser(AdminUserUtil.getUserName());
applyfor.setAuditTime(LocalDateTime.now()); applyfor.setAuditTime(LocalDateTime.now());

View File

@ -481,7 +481,7 @@ public class TicketController extends ControllerBase {
**/ **/
@GetMapping("revokedTicket") @GetMapping("revokedTicket")
public ApiResult<Void> revokedTicket(@Valid @RequestParam @NotNull Long id) { public ApiResult<Void> revokedTicket(@Valid @RequestParam @NotNull Long id) {
ticketService.revoked(id); ticketService.revokedFromAdmin(id);
return ApiResult.success(); return ApiResult.success();
} }
@ -562,7 +562,7 @@ public class TicketController extends ControllerBase {
variables.put("ticket", vo); variables.put("ticket", vo);
Map<String, Object> base = new HashMap<>(); Map<String, Object> base = new HashMap<>();
base.put("t1", Objects.isNull(ticket.getThroughput()) ? "设备运行时间" : "产量"); base.put("t1", Objects.isNull(ticket.getThroughput()) ? "设备运行时间" : "产量");
base.put("v1", Objects.isNull(ticket.getThroughput()) ? ticket.getUseTime() + "小时" : new DecimalFormat("0.#").format(ticket.getThroughput())); base.put("v1", Objects.isNull(ticket.getThroughput()) ? ticket.getUseTime() + "小时" : new DecimalFormat("0.#").format(ticket.getThroughput()) + "(吨或方)");
variables.put("base", base); variables.put("base", base);
// 渲染HTML // 渲染HTML
TemplateEngine templateEngine = new TemplateEngine(); TemplateEngine templateEngine = new TemplateEngine();

View File

@ -42,7 +42,9 @@ public interface IGongfuTicketService extends IService<GongfuTicket> {
List<GongfuTicket> getNonemergency(int days); List<GongfuTicket> getNonemergency(int days);
GongfuTicket revoked(Long id); GongfuTicket revokedFromApp(Long id);
GongfuTicket revokedFromAdmin(Long id);
GongfuTicket reopen(Long id); GongfuTicket reopen(Long id);

View File

@ -44,7 +44,9 @@ public interface ITicketService extends IService<Ticket> {
List<Ticket> getNonemergency(int days); List<Ticket> getNonemergency(int days);
Ticket revoked(Integer id); Ticket revokedFromApp(Integer id);
Ticket revokedFromAdmin(Integer id);
Ticket reopen(Integer id); Ticket reopen(Integer id);

View File

@ -289,11 +289,26 @@ public class GongfuTicketServiceImpl extends ServiceImpl<GongfuTicketMapper, Gon
} }
@Override @Override
public GongfuTicket revoked(Long id) { public GongfuTicket revokedFromApp(Long id) {
GongfuTicket ticket = lambdaQuery().eq(GongfuTicket::getId, id).one(); GongfuTicket ticket = lambdaQuery().eq(GongfuTicket::getId, id).one();
VUtils.trueThrowBusinessError(!(Objects.equals(ticket.getUserId(), AppUserUtil.getUserId()) && StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom()))) VUtils.trueThrowBusinessError(!(Objects.equals(ticket.getUserId(), AppUserUtil.getUserId()) && StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom())))
.throwMessage("无权操作该工单"); .throwMessage("无权操作该工单");
VUtils.trueThrowBusinessError(Byte.compare(ticket.getState(), TicketState.ProcessingCompleted.getState()) > 0) VUtils.trueThrowBusinessError(ticket.getState() > TicketState.ProcessingCompleted.getState())
.throwMessage("当前工单状态不允许撤销");
VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists())
.throwMessage("工单已评价,不允许撤销");
ticket.setState(TicketState.Revoked.getState());
ticket.setUpdateTime(LocalDateTime.now());
updateById(ticket);
return ticket;
}
@Override
public GongfuTicket revokedFromAdmin(Long id) {
GongfuTicket ticket = lambdaQuery().eq(GongfuTicket::getId, id).one();
VUtils.trueThrowBusinessError(!(StrUtil.equals(ticket.getUserPlatform(), Constant.FROM_ADMIN) && Objects.equals(ticket.getUserId(), AdminUserUtil.getUserId())))
.throwMessage("无权操作该工单");
VUtils.trueThrowBusinessError(ticket.getState() > TicketState.ProcessingCompleted.getState())
.throwMessage("当前工单状态不允许撤销"); .throwMessage("当前工单状态不允许撤销");
VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists()) VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists())
.throwMessage("工单已评价,不允许撤销"); .throwMessage("工单已评价,不允许撤销");

View File

@ -326,11 +326,26 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
} }
@Override @Override
public Ticket revoked(Integer id) { public Ticket revokedFromApp(Integer id) {
Ticket ticket = lambdaQuery().eq(Ticket::getId, id).one(); Ticket ticket = lambdaQuery().eq(Ticket::getId, id).one();
VUtils.trueThrowBusinessError(!(Objects.equals(ticket.getUserId(), AppUserUtil.getUserId()) && StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom()))) VUtils.trueThrowBusinessError(!(Objects.equals(ticket.getUserId(), AppUserUtil.getUserId()) && StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom())))
.throwMessage("无权操作该工单"); .throwMessage("无权操作该工单");
VUtils.trueThrowBusinessError(Byte.compare(ticket.getState(), TicketState.ProcessingCompleted.getState()) > 0) VUtils.trueThrowBusinessError(ticket.getState() > TicketState.ProcessingCompleted.getState())
.throwMessage("当前工单状态不允许撤销");
VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists())
.throwMessage("工单已评价,不允许撤销");
ticket.setState(TicketState.Revoked.getState());
ticket.setUpdateTime(LocalDateTime.now());
updateById(ticket);
return ticket;
}
@Override
public Ticket revokedFromAdmin(Integer id) {
Ticket ticket = lambdaQuery().eq(Ticket::getId, id).one();
VUtils.trueThrowBusinessError(!(StrUtil.equals(ticket.getUserPlatform(), Constant.FROM_ADMIN) && Objects.equals(ticket.getUserId(), AdminUserUtil.getUserId())))
.throwMessage("无权操作该工单");
VUtils.trueThrowBusinessError(ticket.getState() > TicketState.ProcessingCompleted.getState())
.throwMessage("当前工单状态不允许撤销"); .throwMessage("当前工单状态不允许撤销");
VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists()) VUtils.trueThrowBusinessError(ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, id).exists())
.throwMessage("工单已评价,不允许撤销"); .throwMessage("工单已评价,不允许撤销");

View File

@ -107,7 +107,7 @@
LEFT JOIN v_device_part_language l ON p.id=l.source_id AND l.language_code=#{language} LEFT JOIN v_device_part_language l ON p.id=l.source_id AND l.language_code=#{language}
WHERE t.user_id=#{userId} AND t.user_platform=#{from} AND t.state!=4 WHERE t.user_id=#{userId} AND t.user_platform=#{from} AND t.state!=4
<include refid="searchWhereCondition"/> <include refid="searchWhereCondition"/>
ORDER BY t.id DESC ORDER BY t.state,t.id DESC
</select> </select>
<select id="searchFollow" resultType="com.nflg.mobilebroken.common.pojo.vo.TicketVO"> <select id="searchFollow" resultType="com.nflg.mobilebroken.common.pojo.vo.TicketVO">
@ -124,7 +124,7 @@
LEFT JOIN v_device_part_language l ON p.id=l.source_id AND l.language_code=#{language} LEFT JOIN v_device_part_language l ON p.id=l.source_id AND l.language_code=#{language}
WHERE tf.user_id=#{userId} AND t.user_platform=#{from} AND t.state!=4 WHERE tf.user_id=#{userId} AND t.user_platform=#{from} AND t.state!=4
<include refid="searchWhereCondition"/> <include refid="searchWhereCondition"/>
ORDER BY t.id DESC ORDER BY t.state,t.id DESC
</select> </select>
<select id="searchArea" resultType="com.nflg.mobilebroken.common.pojo.vo.TicketVO"> <select id="searchArea" resultType="com.nflg.mobilebroken.common.pojo.vo.TicketVO">
@ -152,7 +152,7 @@
AND t.user_platform='admin' AND t.user_platform='admin'
</if> </if>
<include refid="searchWhereCondition"/> <include refid="searchWhereCondition"/>
ORDER BY t.id DESC ORDER BY t.state,t.id DESC
</select> </select>
<select id="searchFromAdmin" resultType="com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO"> <select id="searchFromAdmin" resultType="com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO">