feat: 一些调整
This commit is contained in:
parent
c48a5c34be
commit
37ed0275e4
|
|
@ -61,6 +61,31 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.xhtmlrenderer</groupId>-->
|
||||||
|
<!-- <artifactId>flying-saucer-pdf</artifactId>-->
|
||||||
|
<!-- <version>9.1.20</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ognl</groupId>
|
||||||
|
<artifactId>ognl</artifactId>
|
||||||
|
<version>3.1.26</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>com.itextpdf</groupId>-->
|
||||||
|
<!-- <artifactId>itext7-core</artifactId>-->
|
||||||
|
<!-- <version>7.2.3</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
<!-- html转pdf,包含类似于jsoup依赖的操作html文档的依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>html2pdf</artifactId>
|
||||||
|
<version>4.0.3</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取部门列表
|
* 获取部门列表
|
||||||
*
|
|
||||||
* @return 部门列表
|
* @return 部门列表
|
||||||
*/
|
*/
|
||||||
@PostMapping("getSimpleDepartments")
|
@PostMapping("getSimpleDepartments")
|
||||||
|
|
@ -53,7 +52,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取职位列表
|
* 获取职位列表
|
||||||
*
|
|
||||||
* @return 职位列表
|
* @return 职位列表
|
||||||
*/
|
*/
|
||||||
@PostMapping("getSimpleTitles")
|
@PostMapping("getSimpleTitles")
|
||||||
|
|
@ -64,7 +62,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增账号
|
* 新增账号
|
||||||
*
|
|
||||||
* @param request 请求参数
|
* @param request 请求参数
|
||||||
*/
|
*/
|
||||||
@PostMapping("addAccount")
|
@PostMapping("addAccount")
|
||||||
|
|
@ -76,7 +73,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新账号
|
* 更新账号
|
||||||
*
|
|
||||||
* @param request 请求参数
|
* @param request 请求参数
|
||||||
*/
|
*/
|
||||||
@PostMapping("updateAccount")
|
@PostMapping("updateAccount")
|
||||||
|
|
@ -88,7 +84,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 启用/禁用账号
|
* 启用/禁用账号
|
||||||
*
|
|
||||||
* @param request 请求参数
|
* @param request 请求参数
|
||||||
*/
|
*/
|
||||||
@PostMapping("enableAccount")
|
@PostMapping("enableAccount")
|
||||||
|
|
@ -100,7 +95,6 @@ public class AdminUserController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索账号
|
* 搜索账号
|
||||||
*
|
|
||||||
* @param request 请求参数
|
* @param request 请求参数
|
||||||
*/
|
*/
|
||||||
@PostMapping("searchAccount")
|
@PostMapping("searchAccount")
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ public class RoleController extends ControllerBase {
|
||||||
/**
|
/**
|
||||||
* 获取已授权人员
|
* 获取已授权人员
|
||||||
*/
|
*/
|
||||||
@PostMapping("getAuthorizeUser")
|
@GetMapping("getAuthorizeUser")
|
||||||
@MethodInfoMark(value = "获取已授权人员", menuName = "角色管理")
|
@MethodInfoMark(value = "获取已授权人员", menuName = "角色管理")
|
||||||
public ApiResult<List<AdminUserVO>> getAuthorizeUser(@RequestParam Integer roleId) {
|
public ApiResult<List<AdminUserVO>> getAuthorizeUser(@RequestParam Integer roleId) {
|
||||||
return ApiResult.success(adminUserRoleMapService.getAuthorizeUser(roleId));
|
return ApiResult.success(adminUserRoleMapService.getAuthorizeUser(roleId));
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,44 @@
|
||||||
package com.nflg.mobilebroken.admin.controller;
|
package com.nflg.mobilebroken.admin.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.itextpdf.html2pdf.ConverterProperties;
|
||||||
|
import com.itextpdf.html2pdf.HtmlConverter;
|
||||||
|
import com.itextpdf.layout.font.FontProvider;
|
||||||
|
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.ApiResult;
|
||||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||||
import com.nflg.mobilebroken.common.pojo.request.AdminTicketSearchRequest;
|
import com.nflg.mobilebroken.common.pojo.request.AdminTicketSearchRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.request.AssignmentTicketRequest;
|
import com.nflg.mobilebroken.common.pojo.request.AssignmentTicketRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO;
|
import com.nflg.mobilebroken.common.pojo.vo.AdminTicketVO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.vo.DeviceInfoVO;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.vo.TicketPdfVO;
|
||||||
import com.nflg.mobilebroken.common.util.EecExcelUtil;
|
import com.nflg.mobilebroken.common.util.EecExcelUtil;
|
||||||
import com.nflg.mobilebroken.common.util.PageUtil;
|
import com.nflg.mobilebroken.common.util.PageUtil;
|
||||||
import com.nflg.mobilebroken.repository.service.ITicketService;
|
import com.nflg.mobilebroken.repository.entity.AdminUser;
|
||||||
|
import com.nflg.mobilebroken.repository.entity.AppUser;
|
||||||
|
import com.nflg.mobilebroken.repository.entity.TBaseCustomer;
|
||||||
|
import com.nflg.mobilebroken.repository.entity.Ticket;
|
||||||
|
import com.nflg.mobilebroken.repository.service.*;
|
||||||
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
|
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.thymeleaf.TemplateEngine;
|
||||||
|
import org.thymeleaf.context.Context;
|
||||||
|
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工单相关
|
* 工单相关
|
||||||
|
|
@ -33,6 +51,18 @@ public class TicketController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private ITicketService ticketService;
|
private ITicketService ticketService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IAppUserService appUserService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITBaseCustomerService customerService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IAdminUserService adminUserService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索工单
|
* 搜索工单
|
||||||
*
|
*
|
||||||
|
|
@ -92,4 +122,84 @@ public class TicketController extends ControllerBase {
|
||||||
ticketService.closeTicket(ids);
|
ticketService.closeTicket(ids);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出工单为pdf
|
||||||
|
*
|
||||||
|
* @param id 工单id
|
||||||
|
*/
|
||||||
|
@GetMapping("exportPdf")
|
||||||
|
public void exportPdf(HttpServletResponse response, @Valid @RequestParam @NotBlank(message = "工单编号不能为空") String id) {
|
||||||
|
Ticket ticket = ticketService.getById(id);
|
||||||
|
AppUser user = appUserService.getById(ticket.getUserId());
|
||||||
|
TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId()));
|
||||||
|
DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo());
|
||||||
|
String handle = ticket.getHandle();
|
||||||
|
if (StrUtil.isNotBlank(handle)) {
|
||||||
|
List<AdminUser> adminUsers = adminUserService.listByIds(Arrays.stream(handle.split(",")).map(Integer::parseInt).collect(Collectors.toList()));
|
||||||
|
handle = adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.joining(","));
|
||||||
|
}
|
||||||
|
List<String> images = new ArrayList<>();
|
||||||
|
List<String> files = new ArrayList<>();
|
||||||
|
if (StrUtil.isNotBlank(ticket.getAttachments())) {
|
||||||
|
StrUtil.split(ticket.getAttachments(), ",").forEach(item -> {
|
||||||
|
if (item.endsWith(".jpg") || item.endsWith(".png") || item.endsWith(".jpeg")) {
|
||||||
|
images.add(item);
|
||||||
|
} else {
|
||||||
|
files.add(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
TicketPdfVO vo = new TicketPdfVO()
|
||||||
|
.setNo(ticket.getNo())
|
||||||
|
.setTitle(ticket.getTitle())
|
||||||
|
.setDeviceNo(ticket.getDeviceNo())
|
||||||
|
.setModelNo(device.getModelNo())
|
||||||
|
.setComponent(ticket.getComponent())
|
||||||
|
.setUseTime(ticket.getUseTime())
|
||||||
|
.setDescription(ticket.getDescription())
|
||||||
|
.setState(ticket.getState())
|
||||||
|
.setCreateUserName(user.getName())
|
||||||
|
.setCreateTime(ticket.getCreateTime())
|
||||||
|
.setCompanyName(company.getAgencyCompanyName())
|
||||||
|
.setUrgency(ticket.getUrgency())
|
||||||
|
.setUpdateTime(ticket.getUpdateTime())
|
||||||
|
.setHandleUserName(handle)
|
||||||
|
.setSolution(ticket.getSolution())
|
||||||
|
.setImages(images)
|
||||||
|
.setFiles(files);
|
||||||
|
Map<String, Object> variables = new HashMap<>();
|
||||||
|
variables.put("ticket", vo);
|
||||||
|
// 渲染HTML
|
||||||
|
TemplateEngine templateEngine = new TemplateEngine();
|
||||||
|
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
|
||||||
|
resolver.setPrefix("/templates/");
|
||||||
|
resolver.setSuffix(".html");
|
||||||
|
templateEngine.setTemplateResolver(resolver);
|
||||||
|
|
||||||
|
Context context = new Context();
|
||||||
|
context.setVariables(variables);
|
||||||
|
String html = templateEngine.process("ticketpdf", context);
|
||||||
|
|
||||||
|
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(ticket.getTitle() + ".pdf", StandardCharsets.UTF_8));
|
||||||
|
// 生成PDF
|
||||||
|
try {
|
||||||
|
ConverterProperties converterProperties = new ConverterProperties();
|
||||||
|
converterProperties.setCharset("UTF-8");
|
||||||
|
FontProvider fontProvider = new FontProvider();
|
||||||
|
fontProvider.addSystemFonts();
|
||||||
|
converterProperties.setFontProvider(fontProvider);
|
||||||
|
HtmlConverter.convertToPdf(html, response.getOutputStream(), converterProperties);
|
||||||
|
// ITextRenderer renderer = new ITextRenderer();
|
||||||
|
// ITextFontResolver fontResolver = renderer.getFontResolver();
|
||||||
|
// fontResolver.addFont("fonts/simsun.ttc", true);
|
||||||
|
// renderer.setDocumentFromString(html);
|
||||||
|
// renderer.layout();
|
||||||
|
// renderer.createPDF(response.getOutputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("生成pdf出错", e);
|
||||||
|
throw new NflgException(STATE.BusinessError, "生成pdf出错");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,4 +24,5 @@ spring.cloud.nacos.config.extension-configs[0].refresh=true
|
||||||
spring.cloud.nacos.discovery.server-addr=${nacos.server-addr}
|
spring.cloud.nacos.discovery.server-addr=${nacos.server-addr}
|
||||||
spring.cloud.nacos.discovery.namespace=mobilebroken
|
spring.cloud.nacos.discovery.namespace=mobilebroken
|
||||||
spring.cloud.nacos.discovery.group=${spring.profiles.active}
|
spring.cloud.nacos.discovery.group=${spring.profiles.active}
|
||||||
spring.cloud.nacos.discovery.metadata.env=${spring.profiles.active}
|
spring.cloud.nacos.discovery.metadata.env=${spring.profiles.active}
|
||||||
|
spring.thymeleaf.encoding=UTF-8
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<title th:text="${ticket.title}"></title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 12px;
|
||||||
|
font-family: simsun, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.style1 {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: black 1px solid;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2 class="style1"><img alt="" src="https://cabinet-tool.oss-cn-hangzhou.aliyuncs.com/admin/20250207/1/mmwf/logo.png"/>移动破售后问题反馈表
|
||||||
|
</h2>
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td class="style1">标题</td>
|
||||||
|
<td colspan="3" th:text="${ticket.title}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>问题详细描述</td>
|
||||||
|
<td colspan="3" th:text="${ticket.description}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>工单编号</td>
|
||||||
|
<td th:text="${ticket.no}"></td>
|
||||||
|
<td>设备编号</td>
|
||||||
|
<td th:text="${ticket.deviceNo}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>机型</td>
|
||||||
|
<td th:text="${ticket.modelNo}"></td>
|
||||||
|
<td>使用时长</td>
|
||||||
|
<td th:text="${ticket.useTime}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>问题部位</td>
|
||||||
|
<td colspan="3" th:text="${ticket.component}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>紧急程度</td>
|
||||||
|
<td th:text="${ticket.urgencyDesc}"></td>
|
||||||
|
<td>解决状态</td>
|
||||||
|
<td th:text="${ticket.stateDesc}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>处理人</td>
|
||||||
|
<td th:text="${ticket.handleUserName}"></td>
|
||||||
|
<td>解决时间</td>
|
||||||
|
<td th:text="${ticket.updateTime}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>解决方案</td>
|
||||||
|
<td colspan="3" th:text="${ticket.solution}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>提交人</td>
|
||||||
|
<td th:text="${ticket.createUserName}"></td>
|
||||||
|
<td>提交时间</td>
|
||||||
|
<td th:text="${ticket.createTime}"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">文件</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"><a th:each="url:${ticket.files}" th:href="${url}"></a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">图片</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4"><img alt="" th:each="url:${ticket.images}" th:src="${url}"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.nflg.mobilebroken.admin.AdminApplication;
|
||||||
|
import com.nflg.mobilebroken.repository.entity.AdminApi;
|
||||||
|
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.web.method.HandlerMethod;
|
||||||
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
@ContextConfiguration(classes = AdminApplication.class)
|
||||||
|
public class ControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestMappingHandlerMapping requestMappingHandlerMapping;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
List<AdminApi> apis = new ArrayList<>();
|
||||||
|
// 获取所有的请求映射
|
||||||
|
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
|
||||||
|
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
|
||||||
|
RequestMappingInfo mappingInfo = entry.getKey();
|
||||||
|
HandlerMethod handlerMethod = entry.getValue();
|
||||||
|
|
||||||
|
// 获取Controller的RequestMapping注解
|
||||||
|
// RequestMapping controllerRequestMapping = handlerMethod.getBeanType().getAnnotation(RequestMapping.class);
|
||||||
|
// if (controllerRequestMapping != null) {
|
||||||
|
// System.out.println("Controller: " + handlerMethod.getBeanType().getName());
|
||||||
|
// System.out.println("Controller RequestMapping: " + String.join(",", controllerRequestMapping.value()));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 获取方法的PostMapping注解
|
||||||
|
MethodInfoMark postMapping = handlerMethod.getMethod().getAnnotation(MethodInfoMark.class);
|
||||||
|
if (postMapping != null) {
|
||||||
|
System.out.println("Method: " + handlerMethod.getMethod().getName());
|
||||||
|
System.out.println("menuName: " + postMapping.menuName() + " - " + postMapping.value());
|
||||||
|
apis.add(new AdminApi()
|
||||||
|
.setName(postMapping.value())
|
||||||
|
.setModuleName(postMapping.menuName())
|
||||||
|
.setUrl(StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns())));
|
||||||
|
}
|
||||||
|
// 打印请求路径
|
||||||
|
System.out.println("Request Paths: " + mappingInfo.getPatternsCondition().getPatterns());
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
}
|
||||||
|
System.out.println(JSONUtil.toJsonStr(apis));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,5 +20,4 @@ public class AuthApplication {
|
||||||
SpringApplication.run(AuthApplication.class, args);
|
SpringApplication.run(AuthApplication.class, args);
|
||||||
log.info("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
log.info("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.nflg.mobilebroken.auth.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class JacksonConfig {
|
||||||
|
|
||||||
|
// 定义全局日期时间格式
|
||||||
|
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ObjectMapper objectMapper() {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// 创建并注册 JavaTimeModule,设置日期格式化
|
||||||
|
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||||
|
javaTimeModule.addSerializer(
|
||||||
|
java.time.LocalDateTime.class,
|
||||||
|
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT))
|
||||||
|
);
|
||||||
|
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATETIME_FORMAT)));
|
||||||
|
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
// 注册模块到 ObjectMapper
|
||||||
|
objectMapper.registerModule(javaTimeModule);
|
||||||
|
|
||||||
|
// 禁用时间戳(默认是 true,会序列化为数组)
|
||||||
|
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||||
|
|
||||||
|
return objectMapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.nflg.mobilebroken.cfs.controller;
|
package com.nflg.mobilebroken.cfs.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
|
@ -170,6 +171,11 @@ public class TiketController extends ControllerBase {
|
||||||
AppArea appArea = appAreaService.getById(user.getAreaId());
|
AppArea appArea = appAreaService.getById(user.getAreaId());
|
||||||
TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId()));
|
TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId()));
|
||||||
DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo());
|
DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo());
|
||||||
|
String handle = ticket.getHandle();
|
||||||
|
if (StrUtil.isNotBlank(handle)) {
|
||||||
|
List<AdminUser> adminUsers = adminUserService.listByIds(Arrays.stream(handle.split(",")).map(Integer::parseInt).collect(Collectors.toList()));
|
||||||
|
handle = adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.joining(","));
|
||||||
|
}
|
||||||
TicketInfoVO vo = new TicketInfoVO()
|
TicketInfoVO vo = new TicketInfoVO()
|
||||||
.setId(ticket.getId())
|
.setId(ticket.getId())
|
||||||
.setTitle(ticket.getTitle())
|
.setTitle(ticket.getTitle())
|
||||||
|
|
@ -212,13 +218,16 @@ public class TiketController extends ControllerBase {
|
||||||
.throwMessage("当前工单状态不允许发送消息");
|
.throwMessage("当前工单状态不允许发送消息");
|
||||||
AppUser user = appUserService.getById(AppUserUtil.getUserId());
|
AppUser user = appUserService.getById(AppUserUtil.getUserId());
|
||||||
ChatMessageDTO message = new ChatMessageDTO()
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
|
.setId(IdUtil.getSnowflakeNextId())
|
||||||
.setFrom("app")
|
.setFrom("app")
|
||||||
.setSenderId(user.getId())
|
.setSenderId(user.getId())
|
||||||
.setSenderName(user.getName())
|
.setSenderName(user.getName())
|
||||||
.setSenderAvatar(user.getAvatar())
|
.setSenderAvatar(user.getAvatar())
|
||||||
.setContent(request.getContent())
|
.setContent(request.getContent())
|
||||||
.setCreateTime(Instant.now())
|
.setCreateTime(Instant.now())
|
||||||
.setAttachments(request.getAttachments());
|
.setAttachments(request.getAttachments())
|
||||||
|
.setImages(request.getImages())
|
||||||
|
.setQuote(request.getQuote());
|
||||||
// ticketChatService.pushMessage(request.getTicketId(),message);
|
// ticketChatService.pushMessage(request.getTicketId(),message);
|
||||||
// TicketChat chat=ticketChatService.findByTicketId(request.getTicketId());
|
// TicketChat chat=ticketChatService.findByTicketId(request.getTicketId());
|
||||||
// chat.getMessages().add(message);
|
// chat.getMessages().add(message);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
|
@ -15,6 +17,8 @@ public class UserTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IAppUserService userService;
|
private IAppUserService userService;
|
||||||
|
|
||||||
|
private static final PasswordEncoder PASSWORDENCODER = new BCryptPasswordEncoder();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("获取用户数量")
|
@DisplayName("获取用户数量")
|
||||||
public void getUserCount(){
|
public void getUserCount(){
|
||||||
|
|
@ -26,4 +30,9 @@ public class UserTest {
|
||||||
LocalDateTime date = LocalDateTime.of(LocalDateTime.now().getYear(), 1, 1, 0, 0, 0).plusYears(1).minusDays(1);
|
LocalDateTime date = LocalDateTime.of(LocalDateTime.now().getYear(), 1, 1, 0, 0, 0).plusYears(1).minusDays(1);
|
||||||
System.out.println(date);
|
System.out.println(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() {
|
||||||
|
System.out.println(PASSWORDENCODER.encode("123456"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ import lombok.Getter;
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum TicketUrgency {
|
public enum TicketUrgency {
|
||||||
NONEMERGENCY(0, "非紧急"),
|
NONEMERGENCY((byte) 0, "非紧急"),
|
||||||
GENERAL(1, "普通"),
|
GENERAL((byte) 1, "普通"),
|
||||||
URGENCY(2, "紧急");
|
URGENCY((byte) 2, "紧急");
|
||||||
|
|
||||||
private final Integer state;
|
private final Byte state;
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
public static TicketUrgency findByValue(Integer value) {
|
public static TicketUrgency findByValue(Byte value) {
|
||||||
for (TicketUrgency valueEnum : TicketUrgency.values()) {
|
for (TicketUrgency valueEnum : TicketUrgency.values()) {
|
||||||
if (valueEnum.getState().equals(value)) {
|
if (valueEnum.getState().equals(value)) {
|
||||||
return valueEnum;
|
return valueEnum;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.nflg.mobilebroken.common.pojo.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.springframework.data.annotation.Id;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -11,8 +10,7 @@ import java.util.List;
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class ChatMessageDTO {
|
public class ChatMessageDTO {
|
||||||
|
|
||||||
@Id
|
private Long id;
|
||||||
private String id;
|
|
||||||
|
|
||||||
//来源
|
//来源
|
||||||
private String from;
|
private String from;
|
||||||
|
|
@ -29,9 +27,12 @@ public class ChatMessageDTO {
|
||||||
// 消息内容
|
// 消息内容
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
// 附件
|
// 附件列表
|
||||||
private List<String> attachments;
|
private List<String> attachments;
|
||||||
|
|
||||||
|
//图片列表
|
||||||
|
private List<String> images;
|
||||||
|
|
||||||
// 创建时间
|
// 创建时间
|
||||||
private Instant createTime;
|
private Instant createTime;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,12 @@ public class AddChatMessageRequest {
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
//附件
|
//附件列表
|
||||||
private List<String> attachments;
|
private List<String> attachments;
|
||||||
|
|
||||||
|
//图片列表
|
||||||
|
private List<String> images;
|
||||||
|
|
||||||
// 引用的消息
|
// 引用的消息
|
||||||
private ChatMessageDTO quote;
|
private ChatMessageDTO quote;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public class AssignmentTicketRequest {
|
||||||
|
|
||||||
//紧急程度,0:非紧急;1:普通;2:紧急
|
//紧急程度,0:非紧急;1:普通;2:紧急
|
||||||
@NotNull
|
@NotNull
|
||||||
private Integer urgency;
|
private Byte urgency;
|
||||||
|
|
||||||
//问题类型
|
//问题类型
|
||||||
@NotBlank
|
@NotBlank
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ public class AdminTicketVO {
|
||||||
//紧急程度
|
//紧急程度
|
||||||
@IgnoreExport
|
@IgnoreExport
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private Integer urgency;
|
private Byte urgency;
|
||||||
|
|
||||||
//紧急程度
|
//紧急程度
|
||||||
@ExcelColumn("紧急程度")
|
@ExcelColumn("紧急程度")
|
||||||
|
|
|
||||||
|
|
@ -54,4 +54,7 @@ public class AdminUserVO {
|
||||||
|
|
||||||
//最后更新时间
|
//最后更新时间
|
||||||
private LocalDateTime updateTime;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
|
//部门id
|
||||||
|
private Integer departmentId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ public class MenuVO {
|
||||||
// 是否显示
|
// 是否显示
|
||||||
private boolean show;
|
private boolean show;
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
private int sort;
|
||||||
|
|
||||||
// 创建人
|
// 创建人
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.nflg.mobilebroken.common.pojo.vo;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class TicketPdfVO {
|
||||||
|
|
||||||
|
//工单编号
|
||||||
|
private String no;
|
||||||
|
|
||||||
|
//工单标题
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
//工单描述
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
//创建人
|
||||||
|
private String createUserName;
|
||||||
|
|
||||||
|
//提交时间
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
//工单状态
|
||||||
|
private Byte state;
|
||||||
|
|
||||||
|
//所属公司
|
||||||
|
private String companyName;
|
||||||
|
|
||||||
|
//设备编号
|
||||||
|
private String deviceNo;
|
||||||
|
|
||||||
|
//设备机型
|
||||||
|
private String modelNo;
|
||||||
|
|
||||||
|
//问题部位
|
||||||
|
private String component;
|
||||||
|
|
||||||
|
//使用时长,单位: 小时
|
||||||
|
private Integer useTime;
|
||||||
|
|
||||||
|
private Byte urgency;
|
||||||
|
|
||||||
|
//紧急程度
|
||||||
|
private String urgencyDesc;
|
||||||
|
//解决状态描述
|
||||||
|
private String stateDesc;
|
||||||
|
//更新时间
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
//处理人
|
||||||
|
private String handleUserName;
|
||||||
|
//解决方案
|
||||||
|
private String solution;
|
||||||
|
//图片
|
||||||
|
private List<String> images;
|
||||||
|
//文件
|
||||||
|
private List<String> files;
|
||||||
|
|
||||||
|
public String getUrgencyDesc() {
|
||||||
|
if (Objects.isNull(urgency)) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return TicketState.findByValue(urgency).getDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStateDesc() {
|
||||||
|
return TicketState.findByValue(state).getDescription();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -126,7 +126,7 @@ public class AdminMenuServiceImpl extends ServiceImpl<AdminMenuMapper, AdminMenu
|
||||||
if (StrUtil.isNotBlank(request.getName())) {
|
if (StrUtil.isNotBlank(request.getName())) {
|
||||||
queryWrapper.like(AdminMenu::getName, request.getName());
|
queryWrapper.like(AdminMenu::getName, request.getName());
|
||||||
}
|
}
|
||||||
queryWrapper.orderByDesc(AdminMenu::getId);
|
queryWrapper.orderByDesc(AdminMenu::getSort);
|
||||||
List<AdminMenu> list = baseMapper.selectList(queryWrapper);
|
List<AdminMenu> list = baseMapper.selectList(queryWrapper);
|
||||||
//找出非根节点
|
//找出非根节点
|
||||||
List<AdminMenu> roots = list.stream().filter(l -> Objects.equals(l.getParentId(), 0)).collect(Collectors.toList());
|
List<AdminMenu> roots = list.stream().filter(l -> Objects.equals(l.getParentId(), 0)).collect(Collectors.toList());
|
||||||
|
|
@ -215,7 +215,7 @@ public class AdminMenuServiceImpl extends ServiceImpl<AdminMenuMapper, AdminMenu
|
||||||
|
|
||||||
private List<MenuVO> getChildren(Integer parentId) {
|
private List<MenuVO> getChildren(Integer parentId) {
|
||||||
List<MenuVO> datas = convert(lambdaQuery().eq(AdminMenu::getParentId, parentId)
|
List<MenuVO> datas = convert(lambdaQuery().eq(AdminMenu::getParentId, parentId)
|
||||||
.orderByAsc(AdminMenu::getId)
|
.orderByDesc(AdminMenu::getSort)
|
||||||
.list());
|
.list());
|
||||||
datas.forEach(d -> d.setChildren(getChildren(d.getId())));
|
datas.forEach(d -> d.setChildren(getChildren(d.getId())));
|
||||||
return datas;
|
return datas;
|
||||||
|
|
@ -263,7 +263,7 @@ public class AdminMenuServiceImpl extends ServiceImpl<AdminMenuMapper, AdminMenu
|
||||||
private void getChildren(MenuVO menu) {
|
private void getChildren(MenuVO menu) {
|
||||||
List<AdminMenu> menus = lambdaQuery()
|
List<AdminMenu> menus = lambdaQuery()
|
||||||
.eq(AdminMenu::getParentId, menu.getId())
|
.eq(AdminMenu::getParentId, menu.getId())
|
||||||
.orderByAsc(AdminMenu::getSort)
|
.orderByDesc(AdminMenu::getSort)
|
||||||
.list();
|
.list();
|
||||||
List<MenuVO> menuVos = Convert.toList(MenuVO.class, menus);
|
List<MenuVO> menuVos = Convert.toList(MenuVO.class, menus);
|
||||||
menu.setChildren(menuVos);
|
menu.setChildren(menuVos);
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,13 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AdminUser getUser(String userName, String password) {
|
public AdminUser getUser(String userName, String password) {
|
||||||
String encodePassword= PASSWORDENCODER.encode(password);
|
AdminUser user = lambdaQuery()
|
||||||
return lambdaQuery()
|
|
||||||
.eq(AdminUser::getLoginName, userName)
|
.eq(AdminUser::getLoginName, userName)
|
||||||
.eq(AdminUser::getPassword, encodePassword)
|
|
||||||
.one();
|
.one();
|
||||||
|
if (Objects.nonNull(user) && PASSWORDENCODER.matches(password, user.getPassword())) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -121,8 +123,10 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
|
||||||
.setUserCode(u.getUserCode())
|
.setUserCode(u.getUserCode())
|
||||||
.setLoginName(u.getLoginName())
|
.setLoginName(u.getLoginName())
|
||||||
.setUserName(u.getUserName())
|
.setUserName(u.getUserName())
|
||||||
|
.setEnabled(u.getEnable())
|
||||||
.setPhone(u.getPhone())
|
.setPhone(u.getPhone())
|
||||||
.setEmail(u.getEmail())
|
.setEmail(u.getEmail())
|
||||||
|
.setDepartmentId(u.getDepartmentId())
|
||||||
.setTitleName(getTitleName(u.getTitleId()))
|
.setTitleName(getTitleName(u.getTitleId()))
|
||||||
.setDepartmentName(getDepartmentName(u.getDepartmentId()))
|
.setDepartmentName(getDepartmentName(u.getDepartmentId()))
|
||||||
.setRoles(getRoles(u.getId()))).collect(Collectors.toList()));
|
.setRoles(getRoles(u.getId()))).collect(Collectors.toList()));
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,13 @@ public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> impl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppUser getUser(String userName, String password) {
|
public AppUser getUser(String userName, String password) {
|
||||||
String encodePassword=PASSWORDENCODER.encode(password);
|
AppUser user = lambdaQuery()
|
||||||
return lambdaQuery()
|
|
||||||
.eq(AppUser::getLoginName, userName)
|
.eq(AppUser::getLoginName, userName)
|
||||||
.eq(AppUser::getPassword, encodePassword)
|
|
||||||
.one();
|
.one();
|
||||||
|
if (Objects.nonNull(user) && PASSWORDENCODER.matches(password, user.getPassword())) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ public class TicketServiceImpl extends ServiceImpl<TicketMapper, Ticket> impleme
|
||||||
VUtils.trueThrowBusinessError(ticket.getState() != TicketState.PendingProcessing.getState().byteValue()).throwMessage("工单状态异常");
|
VUtils.trueThrowBusinessError(ticket.getState() != TicketState.PendingProcessing.getState().byteValue()).throwMessage("工单状态异常");
|
||||||
VUtils.trueThrowBusinessError(Objects.nonNull(ticket.getCqm()) && !Objects.equals(ticket.getCqm(), AdminUserUtil.getUserId()))
|
VUtils.trueThrowBusinessError(Objects.nonNull(ticket.getCqm()) && !Objects.equals(ticket.getCqm(), AdminUserUtil.getUserId()))
|
||||||
.throwMessage("当前工单已归属别的CQM负责人");
|
.throwMessage("当前工单已归属别的CQM负责人");
|
||||||
ticket.setUrgency(TicketUrgency.findByValue(request.getUrgency()).getState().byteValue());
|
ticket.setUrgency(TicketUrgency.findByValue(request.getUrgency()).getState());
|
||||||
ticket.setQuestion(request.getQuestion());
|
ticket.setQuestion(request.getQuestion());
|
||||||
ticket.setRemark(request.getRemark());
|
ticket.setRemark(request.getRemark());
|
||||||
ticket.setHandle(StrUtil.join(",", request.getUserIds()));
|
ticket.setHandle(StrUtil.join(",", request.getUserIds()));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue