diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java index 30c9947b..3dee957b 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java @@ -12,10 +12,7 @@ import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO; import com.nflg.mobilebroken.common.pojo.dto.SSEMessageDTO; -import com.nflg.mobilebroken.common.pojo.request.AddChatMessageRequest; -import com.nflg.mobilebroken.common.pojo.request.AdminTicketSearchRequest; -import com.nflg.mobilebroken.common.pojo.request.AssignmentTicketRequest; -import com.nflg.mobilebroken.common.pojo.request.FollowRequest; +import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO; import com.nflg.mobilebroken.common.pojo.vo.DeviceInfoVO; import com.nflg.mobilebroken.common.pojo.vo.TicketInfoVO; @@ -84,6 +81,9 @@ public class TicketController extends ControllerBase { @Resource private IAppAreaService appAreaService; + @Resource + private IDictionaryItemService dictionaryItemService; + /** * 获取问题类型 * @@ -114,8 +114,16 @@ public class TicketController extends ControllerBase { */ @PostMapping("searchTicket") @ApiMark(moduleName = "工单管理", apiName = "搜索工单") - public ApiResult> searchTicket(@RequestBody AdminTicketSearchRequest request) { - return ApiResult.success(PageUtil.convert(ticketService.searchPage(request), d -> d)); + public ApiResult> searchTicket(@Valid @RequestBody AdminTicketSearchRequest request) { + return ApiResult.success(PageUtil.convert(ticketService.searchPage(request), d -> { + if (StrUtil.isNotBlank(d.getHandle())) { + List adminUsers = adminUserService.listByIds(StrUtil.split(d.getHandle(), ",").stream().map(Integer::parseInt).collect(Collectors.toList())); + d.setHandleBy(adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.toList())); + } + AppUser primaryUser = appUserService.getPrimaryByCompanyId(d.getCompanyId()); + d.setPrimaryUserName(primaryUser.getName()); + return d; + })); } /** @@ -155,13 +163,13 @@ public class TicketController extends ControllerBase { /** * 关闭工单 - * @param ids 工单id列表 + * @param request 请求参数 */ @PostMapping("closeTicket") @MethodInfoMark(value = "关闭工单", menuName = "工单管理") @ApiMark(moduleName = "工单管理", apiName = "关闭工单") - public ApiResult closeTicket(@Valid @RequestBody @NotEmpty List ids) { - ticketService.closeTicket(ids); + public ApiResult closeTicket(@Valid @RequestBody TicketCloseRequest request) { + ticketService.closeTicket(request); return ApiResult.success(); } @@ -248,7 +256,6 @@ public class TicketController extends ControllerBase { /** * 获取工单详情 - * * @param id 工单编号 * @return 工单详情 **/ @@ -259,20 +266,35 @@ public class TicketController extends ControllerBase { AppArea appArea = appAreaService.getById(user.getAreaId()); TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId())); DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo()); + String warrantyStateDesc = ""; + if (Objects.nonNull(device.getWarrantyState())) { + DictionaryItem warrantyState = dictionaryItemService.getById(device.getWarrantyState()); + warrantyStateDesc = warrantyState.getName(); + } String handle = ticket.getHandle(); if (StrUtil.isNotBlank(handle)) { List adminUsers = adminUserService.listByIds(Arrays.stream(handle.split(",")).map(Integer::parseInt).collect(Collectors.toList())); handle = adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.joining(",")); } + AppUser primaryUser = appUserService.getPrimaryByCompanyId(user.getCompanyId()); TicketInfoVO vo = new TicketInfoVO() .setId(ticket.getId()) .setTitle(ticket.getTitle()) .setDeviceNo(ticket.getDeviceNo()) .setModelNo(device.getModelNo()) + .setDeviceType(device.getDeviceType()) .setComponent(ticket.getComponent()) .setUseTime(ticket.getUseTime()) .setDescription(ticket.getDescription()) .setState(ticket.getState()) + .setShipmentDate(device.getShipmentDate()) + .setStartWarrantyDate(device.getStartWarrantyDate()) + .setWarrantyMonth(device.getWarrantyMonth()) + .setQuestion(ticket.getQuestion()) + .setWarrantyStateDesc(warrantyStateDesc) + .setUrgency(ticket.getUrgency()) + .setDeviceTypeSub(device.getDeviceTypeSub()) + .setPrimaryUserName(primaryUser.getName()) .setImages(StrUtil.isNotBlank(ticket.getImages()) ? StrUtil.split(ticket.getImages(), ",") : Collections.emptyList()) .setAttachments(StrUtil.isNotBlank(ticket.getAttachments()) ? StrUtil.split(ticket.getAttachments(), ",") : Collections.emptyList()) .setCreateUserId(ticket.getUserId()) diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketCloseRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketCloseRequest.java new file mode 100644 index 00000000..a4023387 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/TicketCloseRequest.java @@ -0,0 +1,18 @@ +package com.nflg.mobilebroken.common.pojo.request; + +import lombok.Data; + +import java.util.List; + +@Data +public class TicketCloseRequest { + + //工单id + private Integer ticketId; + + //解决方案 + private String solution; + + //附件 + private List attachments; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java index 9e97a14d..9ba3a703 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AdminTicketVO.java @@ -1,6 +1,5 @@ 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.TicketState; import com.nflg.mobilebroken.common.constant.TicketUrgency; @@ -63,11 +62,15 @@ public class AdminTicketVO { //代理商名称 @ExcelColumn("代理商") - private String companyName; + private String primaryUserName; + + @JsonIgnore + @IgnoreExport + private String companyId; //客户 @ExcelColumn("客户") - private String createUserName; + private String companyName; //设备编号 @ExcelColumn("设备编号") @@ -144,10 +147,6 @@ public class AdminTicketVO { return TicketUrgency.findByValue(urgency).getDescription(); } - public List getHandleBy() { - return StrUtil.split(handle, ","); - } - public String getFollowedDesc() { return followed ? "已关注" : "未关注"; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppUserVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppUserVO.java index e45f0486..c5d387c6 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppUserVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/AppUserVO.java @@ -36,8 +36,8 @@ public class AppUserVO { //头像 private String avatar; - //是否启用 - private boolean enable; + //状态,0:待激活,1-启用,2:禁用 + private byte userState; //创建人 private String createBy; diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceInfoVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceInfoVO.java index 2be489fa..90f3b494 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceInfoVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/DeviceInfoVO.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.experimental.Accessors; +import java.time.LocalDate; import java.util.List; @Data @@ -17,6 +18,24 @@ public class DeviceInfoVO { //设备机型 private String modelNo; + //设备类型 + private String deviceType; + + //设备细分类 + private String deviceTypeSub; + + //质保状态(关联字典项) + private Integer warrantyState; + + //发货日期 + private LocalDate shipmentDate; + + //质保开始日期 + private LocalDate startWarrantyDate; + + //质保期(月) + private Integer warrantyMonth; + //机型部件 @JsonIgnore private String component; diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/TicketInfoVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/TicketInfoVO.java index e272aef6..a0a8404c 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/TicketInfoVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/TicketInfoVO.java @@ -3,6 +3,7 @@ package com.nflg.mobilebroken.common.pojo.vo; import lombok.Data; import lombok.experimental.Accessors; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; @@ -34,7 +35,10 @@ public class TicketInfoVO { //工单状态 private Byte state; - //所属公司 + //代理商 + private String primaryUserName; + + //客户名称 private String companyName; //所属区域 @@ -46,6 +50,24 @@ public class TicketInfoVO { //设备机型 private String modelNo; + //设备类型 + private String deviceType; + + //设备细分类 + private String deviceTypeSub; + + //质保状态 + private String warrantyStateDesc; + + //发货日期 + private LocalDate shipmentDate; + + //质保开始日期 + private LocalDate startWarrantyDate; + + //质保期(月) + private Integer warrantyMonth; + //问题部位 private String component; @@ -55,6 +77,12 @@ public class TicketInfoVO { //处理人 private String handle; + //问题类型 + private String question; + + //紧急程度,0:非紧急;1:普通;2:紧急 + private Byte urgency; + //图片 private List images; diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java index f7dc468f..33a9ccac 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/Ticket.java @@ -97,6 +97,11 @@ public class Ticket implements Serializable { */ private String solution; + /** + * 解决方案附件 + */ + private String solutionAttachments; + /** * 解决时间 */ diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/TicketMapper.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/TicketMapper.java index 063c55b4..d2fd7bf7 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/TicketMapper.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/mapper/TicketMapper.java @@ -26,12 +26,10 @@ public interface TicketMapper extends BaseMapper { IPage searchArea(IPage page, TicketSearchRequest request, List companyIds); - IPage searchFromAdmin(AdminTicketSearchRequest request, IPage page); + IPage searchFromAdmin(AdminTicketSearchRequest request, Integer userId, IPage page); void completeTicket(List ids, Integer userId); - void closeTicket(List ids); - List searchAllFromAdmin(AdminTicketSearchRequest request); IPage searchFromAdminAndFollow(AdminTicketSearchRequest request, Integer userId, IPage page); diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java index 909f2b6d..a6760574 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAppUserService.java @@ -52,4 +52,6 @@ public interface IAppUserService extends IService { void activateUser(UserActivateRequest request); void forgetPassword(String email, String password); + + AppUser getPrimaryByCompanyId(String companyId); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketService.java index 3f99453b..b8fd4307 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketService.java @@ -3,10 +3,7 @@ package com.nflg.mobilebroken.repository.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import com.nflg.mobilebroken.common.pojo.dto.UserDTO; -import com.nflg.mobilebroken.common.pojo.request.AdminTicketSearchRequest; -import com.nflg.mobilebroken.common.pojo.request.AssignmentTicketRequest; -import com.nflg.mobilebroken.common.pojo.request.TicketAddRequest; -import com.nflg.mobilebroken.common.pojo.request.TicketSearchRequest; +import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO; import com.nflg.mobilebroken.common.pojo.vo.TicketVO; import com.nflg.mobilebroken.repository.entity.Ticket; @@ -33,7 +30,7 @@ public interface ITicketService extends IService { void completeTicket(List ids); - void closeTicket(List ids); + void closeTicket(TicketCloseRequest request); List exportSearch(AdminTicketSearchRequest request); diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java index 02983ea7..40999c99 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AppUserServiceImpl.java @@ -3,7 +3,6 @@ package com.nflg.mobilebroken.repository.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -193,9 +192,7 @@ public class AppUserServiceImpl extends ServiceImpl impl @Override public void migrate(MigrateAppUserRequest request) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.apply("FIND_IN_SET({0}, company_id)", request.getCompanyId()); - AppUser appUser = appUserService.getBaseMapper().selectOne(queryWrapper); + AppUser appUser = getPrimaryByCompanyId(request.getCompanyId().toString()); VUtils.trueThrowBusinessError(Objects.isNull(appUser)).throwMessage("该公司还未设置主账号"); lambdaUpdate() .set(AppUser::getCompanyId, request.getCompanyId()) @@ -418,6 +415,14 @@ public class AppUserServiceImpl extends ServiceImpl impl updateById(user); } + @Override + public AppUser getPrimaryByCompanyId(String companyId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(AppUser::getIsPrimary, true); + queryWrapper.apply("FIND_IN_SET({0}, company_id)>0", companyId); + return appUserService.getBaseMapper().selectOne(queryWrapper); + } + private List getByCompanyId(Long companyId) { return lambdaQuery() .eq(AppUser::getCompanyId, companyId.toString()) diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java index c07637fe..e9402612 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketServiceImpl.java @@ -1,6 +1,5 @@ package com.nflg.mobilebroken.repository.service.impl; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -8,10 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.nflg.mobilebroken.common.constant.TicketState; import com.nflg.mobilebroken.common.constant.TicketUrgency; import com.nflg.mobilebroken.common.pojo.dto.UserDTO; -import com.nflg.mobilebroken.common.pojo.request.AdminTicketSearchRequest; -import com.nflg.mobilebroken.common.pojo.request.AssignmentTicketRequest; -import com.nflg.mobilebroken.common.pojo.request.TicketAddRequest; -import com.nflg.mobilebroken.common.pojo.request.TicketSearchRequest; +import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO; import com.nflg.mobilebroken.common.pojo.vo.TicketVO; import com.nflg.mobilebroken.common.util.AdminUserUtil; @@ -28,7 +24,6 @@ import java.time.LocalDateTime; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; /** *

@@ -85,7 +80,7 @@ public class TicketServiceImpl extends ServiceImpl impleme if (request.getType() == 2) { return baseMapper.searchFromAdminAndFollow(request, AdminUserUtil.getUserId(), new Page<>(request.getPage(), request.getPageSize())); } else if (request.getType() == 4) { - return baseMapper.searchFromAdmin(request, new Page<>(request.getPage(), request.getPageSize())); + return baseMapper.searchFromAdmin(request, AdminUserUtil.getUserId(), new Page<>(request.getPage(), request.getPageSize())); } return new Page<>(request.getPage(), request.getPageSize(), 0); } @@ -113,12 +108,17 @@ public class TicketServiceImpl extends ServiceImpl impleme } @Override - public void closeTicket(List ids) { - List tickets = listByIds(ids); - List tids = tickets.stream().map(Ticket::getId).filter(cqm -> Objects.equals(AdminUserUtil.getUserId(), cqm)).collect(Collectors.toList()); - if (CollectionUtil.isNotEmpty(tids)) { - baseMapper.closeTicket(ids); - } + public void closeTicket(TicketCloseRequest request) { + Ticket ticket = getById(request.getTicketId()); + VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("未找到工单"); + VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.ProcessingCompleted.getState())) + .throwMessage("工单状态不允许关闭"); + VUtils.trueThrowBusinessError(!Objects.equals(ticket.getCqm(), AdminUserUtil.getUserId())) + .throwMessage("当前工单未归属当前CQM负责人"); + ticket.setState(TicketState.Closed.getState()); + ticket.setSolutionAttachments(StrUtil.join(",", request.getAttachments())); + ticket.setSolveTime(LocalDateTime.now()); + updateById(ticket); } @Override diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/AppUserMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/AppUserMapper.xml index f9011f2f..c304ec35 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/AppUserMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/AppUserMapper.xml @@ -38,7 +38,7 @@ - SELECT d.device_no AS 'deviceNo',d.model_no AS 'modelNo',dc.component AS 'component' + SELECT d.device_no AS 'deviceNo',d.model_no AS 'modelNo',dc.component AS 'component',d.device_type AS 'deviceType' + ,d.device_type_sub AS 'deviceTypeSub',d.warranty_state AS 'warrantyState',d.shipment_date AS 'shipmentDate' + ,d.start_warranty_date AS 'startWarrantyDate',d.warranty_month AS 'warrantyMonth' FROM device d LEFT JOIN device_component dc ON d.model_no=dc.model_no AND dc.`enable`=1 WHERE d.device_no=#{deviceNo} diff --git a/nflg-mobilebroken-repository/src/main/resources/mapper/TicketMapper.xml b/nflg-mobilebroken-repository/src/main/resources/mapper/TicketMapper.xml index 21e6bc13..fccea6a8 100644 --- a/nflg-mobilebroken-repository/src/main/resources/mapper/TicketMapper.xml +++ b/nflg-mobilebroken-repository/src/main/resources/mapper/TicketMapper.xml @@ -98,14 +98,16 @@ @@ -118,18 +120,9 @@ - - SELECT t.id,t.`no`,t.title,t.state,t.urgency,t.component,t.question,t.solution,a.`name` AS 'areaName' - ,c.agency_company_name AS 'companyName',u.`name` AS 'createUserName',t.device_no AS 'deviceNo',t.use_time AS 'useTime' - ,t.create_time AS 'createTime',t.handle,t.solve_time AS 'solveTime',di.name AS 'warrantyStatusDesc',IF(tf.id IS NULL, false, true) AS 'followed' + ,c.agency_company_name AS 'companyName',u.company_id AS 'companyId',u.`name` AS 'createBy',t.device_no AS 'deviceNo',t.use_time AS 'useTime' + ,t.create_time AS 'createTime',t.handle,t.solve_time AS 'solveTime',di.name AS 'warrantyStatusDesc',d.device_type AS 'deviceType' + ,d.model_no AS 'equipmentModel',d.shipment_date AS 'shipmentDate',IF(tf.id IS NULL, false, true) AS 'followed' FROM ticket t LEFT JOIN app_user u ON t.user_id=u.id LEFT JOIN t_base_customer c ON u.company_id=c.id @@ -156,7 +150,7 @@