From cfc9b461daec60ff0ef4d7df028bd74e5e1bc76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Tue, 11 Feb 2025 11:21:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=80=E4=BA=9B=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/AdminUserController.java | 76 ++++++++++++++++++- .../admin/controller/FileController.java | 45 ++++++++--- .../controller/MultilingualController.java | 29 ++++++- .../admin/controller/TicketController.java | 4 +- .../admin/service/WXQRCodeService.java | 42 ++++++++++ .../src/test/java/ControllerTest.java | 3 +- .../auth/controller/AdminController.java | 1 + .../cfs/controller/SystemController.java | 16 ---- .../cfs/controller/UserController.java | 21 ++++- .../src/test/java/EmailTest.java | 58 ++++++++++++++ .../common/constant/Constant.java | 4 +- .../common/pojo/request/AvatarSetRequest.java | 13 ++++ .../pojo/request/FileSearchRequest.java | 26 +++++++ .../pojo/request/WebComponentAddRequest.java | 4 + .../request/WebComponentDeleteRequest.java | 11 +++ .../mobilebroken/common/pojo/vo/FileVO.java | 33 ++++++++ .../common/pojo/vo/LanguageVO.java | 2 + .../common/util/AdminUserUtil.java | 7 ++ .../repository/entity/FileUploadRecord.java | 18 +++-- .../repository/service/IAdminUserService.java | 4 + .../service/IFileUploadRecordService.java | 4 + .../service/impl/AdminUserServiceImpl.java | 16 ++++ .../impl/FileUploadRecordServiceImpl.java | 26 +++++++ .../service/impl/WebComponentServiceImpl.java | 8 +- nflg-mobilebroken-starter/pom.xml | 10 +-- 25 files changed, 432 insertions(+), 49 deletions(-) create mode 100644 nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/WXQRCodeService.java create mode 100644 nflg-mobilebroken-cfs-app/src/test/java/EmailTest.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/AvatarSetRequest.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/FileSearchRequest.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentDeleteRequest.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/FileVO.java diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/AdminUserController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/AdminUserController.java index 35c61894..fabae8a9 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/AdminUserController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/AdminUserController.java @@ -1,7 +1,10 @@ package com.nflg.mobilebroken.admin.controller; import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.StrUtil; import com.nflg.mobilebroken.admin.annotation.ApiMark; +import com.nflg.mobilebroken.admin.service.WXQRCodeService; +import com.nflg.mobilebroken.common.constant.Constant; import com.nflg.mobilebroken.common.constant.STATE; import com.nflg.mobilebroken.common.exception.NflgException; import com.nflg.mobilebroken.common.pojo.ApiResult; @@ -10,20 +13,24 @@ import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.AdminUserVO; import com.nflg.mobilebroken.common.pojo.vo.DepartmentSimpleVO; import com.nflg.mobilebroken.common.pojo.vo.TitleSimpleVO; +import com.nflg.mobilebroken.common.util.AdminUserUtil; +import com.nflg.mobilebroken.common.util.VUtils; +import com.nflg.mobilebroken.repository.entity.AdminUser; import com.nflg.mobilebroken.repository.service.IAdminUserService; import com.nflg.mobilebroken.repository.service.ITBaseDepartmentService; import com.nflg.mobilebroken.repository.service.ITBasePositionService; import com.nflg.mobilebroken.starter.annotation.MethodInfoMark; import com.nflg.mobilebroken.starter.service.EmailService; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; +import java.time.Duration; import java.util.List; /** @@ -46,6 +53,12 @@ public class AdminUserController extends ControllerBase { @Resource private EmailService emailService; + @Resource + private WXQRCodeService wxQRCodeService; + + @Resource + private RedisTemplate redisTemplate; + /** * 获取部门列表 * @return 部门列表 @@ -145,4 +158,59 @@ public class AdminUserController extends ControllerBase { } return ApiResult.success(); } + + /** + * 生成微信服务号关注二维码 + */ + @GetMapping("generateQRCode") + @ApiMark(moduleName = "账号管理", apiName = "生成微信服务号关注二维码") + public void generateQRCode(HttpServletResponse response) throws Exception { + response.setContentType(MediaType.IMAGE_PNG_VALUE); + response.getOutputStream().write(wxQRCodeService.generateQRCode(AdminUserUtil.getUserId())); + } + + /** + * 设置头像 + */ + @PostMapping("setAvatar") + @ApiMark(moduleName = "账号管理", apiName = "设置头像") + public ApiResult setAvatar(@Valid @RequestBody AvatarSetRequest request) { + adminUserService.setAvatar(AdminUserUtil.getUserId(), request.getAvatar()); + return ApiResult.success(); + } + + /** + * 更新密码 + * + * @param request 请求信息 + * @return 更新结果 + **/ + @PostMapping("updatePassword") + public ApiResult updatePassword(@Valid @RequestBody UpdatePasswordRequest request) { + String redisKey = StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA_ADMIN, request.getEmail()); + String captcha = redisTemplate.opsForValue().get(redisKey); + VUtils.trueThrowBusinessError(StrUtil.isBlank(captcha)).throwMessage("验证码已失效,请重新获取"); + VUtils.trueThrowBusinessError(StrUtil.equals(captcha, request.getCaptcha())).throwMessage("验证码不正确"); + AdminUser adminUser = adminUserService.lambdaQuery().eq(AdminUser::getEmail, request.getEmail()).one(); + redisTemplate.delete(redisKey); + adminUserService.updatePassword(adminUser.getId(), request.getNewPassword()); + return ApiResult.success(); + } + + /** + * 发送修改密码验证码邮件 + **/ + @PostMapping("sendUpdatePasswordCaptchaEmail") + public ApiResult sendUpdatePasswordCaptchaEmail() { + try { + String email = AdminUserUtil.getEmail(); + String kaptcha = RandomUtil.randomString(6); + // 将生成的验证码存入redis + redisTemplate.opsForValue().set(StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA_ADMIN, email), kaptcha, Duration.ofMinutes(10)); + emailService.sendEmail(email, "您正在申请修改密码", "验证码为: " + kaptcha); + } catch (Exception ex) { + throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage()); + } + return ApiResult.success(); + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java index 02213b78..95273b91 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/FileController.java @@ -6,12 +6,13 @@ import com.nflg.mobilebroken.admin.annotation.ApiMark; 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.PageData; +import com.nflg.mobilebroken.common.pojo.request.FileSearchRequest; +import com.nflg.mobilebroken.common.pojo.vo.FileVO; import com.nflg.mobilebroken.common.util.AdminUserUtil; +import com.nflg.mobilebroken.repository.service.IFileUploadRecordService; import com.nflg.mobilebroken.starter.service.FileUploadService; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; @@ -23,7 +24,7 @@ import java.util.ArrayList; import java.util.List; /** - * 文件上传相关接口 + * 文件管理相关接口 * * @author 曹鹏飞 **/ @@ -32,17 +33,20 @@ import java.util.List; public class FileController extends ControllerBase { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); + @Resource private FileUploadService fileUploadService; + @Resource + private IFileUploadRecordService fileUploadRecordService; + /** * 上传单个文件 - * * @param file 要上传的文件 * @return 可访问的文件url */ @PostMapping("uploadSingleFile") - @ApiMark(moduleName = "文件上传", apiName = "上传单个文件") + @ApiMark(moduleName = "文件管理", apiName = "上传单个文件") public ApiResult uploadSingleFile(@RequestParam("file") MultipartFile file) { try { return ApiResult.success(fileUploadService.upload(buildFilePath(file.getOriginalFilename()), file)); @@ -58,12 +62,11 @@ public class FileController extends ControllerBase { /** * 上传多个文件 - * * @param files 要上传的文件列表 * @return 可访问的文件url列表 */ @PostMapping("uploadMultipleFiles") - @ApiMark(moduleName = "文件上传", apiName = "上传多个文件") + @ApiMark(moduleName = "文件管理", apiName = "上传多个文件") public ApiResult> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List files) { try { List list = new ArrayList<>(); @@ -75,4 +78,28 @@ public class FileController extends ControllerBase { throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage()); } } + + /** + * 搜索文件 + * + * @param request 搜索条件 + * @return 搜索到的文件列表 + */ + @PostMapping("searchFiles") + @ApiMark(moduleName = "文件管理", apiName = "搜索文件") + public ApiResult> searchFiles(@Valid @RequestBody FileSearchRequest request) { + return ApiResult.success(fileUploadRecordService.search(request)); + } + + /** + * 删除文件 + * + * @param ids 文件id列表 + */ + @PostMapping("deleteFile") + @ApiMark(moduleName = "文件管理", apiName = "删除文件") + public ApiResult deleteFile(@Valid @RequestBody @NotEmpty List ids) { + fileUploadRecordService.removeBatchByIds(ids); + return ApiResult.success(); + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java index 3d24cac3..9d56b045 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java @@ -72,13 +72,28 @@ public class MultilingualController extends ControllerBase { * 获取语言列表 * @return 语言列表 */ - @GetMapping("/getLanguage") + @GetMapping("/getAllLanguage") @ApiMark(moduleName = "多语言管理", apiName = "获取语言列表") public ApiResult> getLanguage() { List languages = languageService.getAllLanguages(); return ApiResult.success(Convert.toList(LanguageVO.class, languages)); } + /** + * 获取启用的语言列表 + * + * @return 取语言列表 + */ + @GetMapping("getLanguages") + @ApiMark(moduleName = "多语言管理", apiName = "获取启用的语言列表") + public ApiResult> getLanguages() { + List languages = languageService.getLanguages(); + if (CollectionUtil.isEmpty(languages)) { + return ApiResult.success(Collections.emptyList()); + } + return ApiResult.success(Convert.toList(LanguageVO.class, languages)); + } + /** * 启用/禁言语言 * @param request 请求参数 @@ -122,6 +137,18 @@ public class MultilingualController extends ControllerBase { return ApiResult.success(webComponentService.search(request)); } + /** + * 删除网页组件 + * + * @param ids 组件id列表 + */ + @PostMapping("/deleteWebComponent") + @ApiMark(moduleName = "多语言管理", apiName = "删除网页组件") + public ApiResult deleteWebComponent(@Valid @RequestBody @NotEmpty List ids) { + webComponentService.removeByIds(ids); + return ApiResult.success(); + } + /** * 导出网页组件翻译列表 * @param request 请求参数 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 d38e934a..30c9947b 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 @@ -90,7 +90,7 @@ public class TicketController extends ControllerBase { * @return 问题类型列表 */ @GetMapping("getQuestions") - @ApiMark(moduleName = "获取问题类型", apiName = "搜索工单", isPublic = true) + @ApiMark(moduleName = "工单管理", apiName = "获取问题类型", isPublic = true) public ApiResult> getQuestions() { return ApiResult.success(Arrays.asList("技术设计问题", "装配工艺问题", "焊接质量问题", "机组装配质量问题", "电控问题", "工况方案问题", "操作不当", "原材料配件质量问题", "QC检验遗漏/误差", "部件/整机外观")); } @@ -101,7 +101,7 @@ public class TicketController extends ControllerBase { * @param request 请求信息 **/ @PostMapping("followTiket") - @ApiMark(moduleName = "关注或取消关注工单", apiName = "搜索工单") + @ApiMark(moduleName = "工单管理", apiName = "关注或取消关注") public ApiResult followTiket(@Valid @RequestBody FollowRequest request) { ticketFollowService.handleAdmin(request, AdminUserUtil.getUserId()); return ApiResult.success(); diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/WXQRCodeService.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/WXQRCodeService.java new file mode 100644 index 00000000..f84affd1 --- /dev/null +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/WXQRCodeService.java @@ -0,0 +1,42 @@ +package com.nflg.mobilebroken.admin.service; + +import cn.hutool.json.JSONUtil; +import com.nflg.mobilebroken.common.constant.Constant; +import com.nflg.mobilebroken.common.pojo.dto.WXTokenDTO; +import com.nflg.mobilebroken.common.pojo.request.WXQrcodeActionInfo; +import com.nflg.mobilebroken.common.pojo.request.WXQrcodeRequest; +import com.nflg.mobilebroken.common.pojo.request.WXQrcodeScene; +import com.nflg.mobilebroken.common.pojo.vo.WXQrcodeVO; +import com.nflg.mobilebroken.common.util.QRCodeUtil; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.util.Objects; + +@Component +public class WXQRCodeService { + + @Resource + private RedisTemplate redisTemplate; + + public byte[] generateQRCode(Integer userId) throws Exception { + Object obj = redisTemplate.opsForHash().get("wx:url:follow", userId); + if (Objects.isNull(obj)) { + RestTemplate restTemplate = new RestTemplate(); + ResponseEntity response1 = restTemplate.getForEntity(Constant.WX_TOKEN_URL, String.class); + String text = response1.getBody().substring(1, response1.getBody().length() - 1).replace("\\", ""); + WXTokenDTO token = JSONUtil.toBean(text, WXTokenDTO.class); + String accessToken = token.getAccess_token(); + String url = Constant.WX_QRCODE + "?access_token=" + accessToken; + String scene_str = "app_" + userId; + WXQrcodeRequest req = new WXQrcodeRequest().setAction_info(new WXQrcodeActionInfo().setScene(new WXQrcodeScene().setScene_str(scene_str))); + WXQrcodeVO qvo = restTemplate.postForObject(url, req, WXQrcodeVO.class); + obj = qvo.getUrl(); + redisTemplate.opsForHash().put("wx:url:follow", userId, obj); + } + return QRCodeUtil.generateQRCode(obj.toString(), 200, 200); + } +} diff --git a/nflg-mobilebroken-admin/src/test/java/ControllerTest.java b/nflg-mobilebroken-admin/src/test/java/ControllerTest.java index 1957c9c9..e78fd0c9 100644 --- a/nflg-mobilebroken-admin/src/test/java/ControllerTest.java +++ b/nflg-mobilebroken-admin/src/test/java/ControllerTest.java @@ -28,6 +28,7 @@ public class ControllerTest { @Test public void test2() { // List apis = new ArrayList<>(); + String pre = ""; // 获取所有的请求映射 Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); for (Map.Entry entry : handlerMethods.entrySet()) { @@ -53,7 +54,7 @@ public class ControllerTest { // .setUrl(StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns())); // apis.add(api); // 打印请求路径 - String url = StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns()); + String url = pre + StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns()); System.out.println("Request Paths: " + url); AdminApi api = adminApiService.lambdaQuery() .eq(AdminApi::getModuleName, mark.moduleName()) diff --git a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/AdminController.java b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/AdminController.java index 0c4688c6..f64f3bb2 100644 --- a/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/AdminController.java +++ b/nflg-mobilebroken-auth/src/main/java/com/nflg/mobilebroken/auth/controller/AdminController.java @@ -54,6 +54,7 @@ public class AdminController extends ControllerBase { .setExtra("from", "admin") .setExtra("name", user.getUserName()) .setExtra("code", user.getUserCode()) + .setExtra("email", user.getEmail()) .setExtra("roles", roleCodes)); return ApiResult.success(SaTokenAdminUtil.getTokenInfo()); } diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/SystemController.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/SystemController.java index 1ccd6a8c..89ead5f3 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/SystemController.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/SystemController.java @@ -1,19 +1,15 @@ package com.nflg.mobilebroken.cfs.controller; import cn.hutool.core.collection.CollectionUtil; -import com.nflg.mobilebroken.cfs.service.WXQRCodeService; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.vo.LanguageVO; -import com.nflg.mobilebroken.common.util.AppUserUtil; import com.nflg.mobilebroken.repository.entity.Language; import com.nflg.mobilebroken.repository.service.ILanguageService; -import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -30,9 +26,6 @@ public class SystemController extends ControllerBase { @Resource private ILanguageService languageService; - @Resource - private WXQRCodeService wxQRCodeService; - /** * 获取语言列表 * @return 取语言列表 @@ -54,13 +47,4 @@ public class SystemController extends ControllerBase { .collect(Collectors.toList()); return ApiResult.success(vos); } - - /** - * 生成微信服务号关注二维码 - */ - @GetMapping("generateQRCode") - public void generateQRCode(HttpServletResponse response) throws Exception { - response.setContentType(MediaType.IMAGE_PNG_VALUE); - response.getOutputStream().write(wxQRCodeService.generateQRCode(AppUserUtil.getUserId())); - } } \ No newline at end of file diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/UserController.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/UserController.java index efe908e1..e066a743 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/UserController.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/UserController.java @@ -3,6 +3,7 @@ package com.nflg.mobilebroken.cfs.controller; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.nflg.mobilebroken.cfs.service.WXQRCodeService; import com.nflg.mobilebroken.common.constant.Constant; import com.nflg.mobilebroken.common.constant.STATE; import com.nflg.mobilebroken.common.exception.NflgException; @@ -20,10 +21,12 @@ import com.nflg.mobilebroken.repository.service.ITBaseCustomerService; import com.nflg.mobilebroken.repository.service.ITBasePositionService; import com.nflg.mobilebroken.starter.service.EmailService; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import java.time.Duration; @@ -58,6 +61,9 @@ public class UserController extends ControllerBase { @Resource ITBasePositionService positionService; + @Resource + private WXQRCodeService wxQRCodeService; + /** * 获取用户信息 * @return 用户信息 @@ -74,7 +80,7 @@ public class UserController extends ControllerBase { **/ @PostMapping("updatePassword") public ApiResult updatePassword(@Valid @RequestBody UpdatePasswordRequest request){ - String redisKey = StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA, request.getEmail()); + String redisKey = StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA_APP, request.getEmail()); String captcha = redisTemplate.opsForValue().get(redisKey); VUtils.trueThrowBusinessError(StrUtil.isBlank(captcha)).throwMessage("验证码已失效,请重新获取"); VUtils.trueThrowBusinessError(StrUtil.equals(captcha, request.getCaptcha())).throwMessage("验证码不正确"); @@ -195,14 +201,23 @@ public class UserController extends ControllerBase { @PostMapping("sendUpdatePasswordCaptchaEmail") public ApiResult sendUpdatePasswordCaptchaEmail() { try { - String email = AppUserUtil.getEmail(); + String email = "rakor2010@gmail.com"; //AppUserUtil.getEmail(); String kaptcha = RandomUtil.randomString(6); // 将生成的验证码存入redis - redisTemplate.opsForValue().set(StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA, email), kaptcha, Duration.ofMinutes(10)); + redisTemplate.opsForValue().set(StrUtil.format(Constant.REDIS_KEY_USER_UPDATE_KAPTCHA_APP, email), kaptcha, Duration.ofMinutes(10)); emailService.sendEmail(email, "您正在申请修改密码", "验证码为: " + kaptcha); } catch (Exception ex) { throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage()); } return ApiResult.success(); } + + /** + * 生成微信服务号关注二维码 + */ + @GetMapping("generateQRCode") + public void generateQRCode(HttpServletResponse response) throws Exception { + response.setContentType(MediaType.IMAGE_PNG_VALUE); + response.getOutputStream().write(wxQRCodeService.generateQRCode(AppUserUtil.getUserId())); + } } diff --git a/nflg-mobilebroken-cfs-app/src/test/java/EmailTest.java b/nflg-mobilebroken-cfs-app/src/test/java/EmailTest.java new file mode 100644 index 00000000..aa576512 --- /dev/null +++ b/nflg-mobilebroken-cfs-app/src/test/java/EmailTest.java @@ -0,0 +1,58 @@ +import com.nflg.mobilebroken.cfs.CfsApplication; +import com.nflg.mobilebroken.common.pojo.dto.EmailConfig; +import com.nflg.mobilebroken.starter.service.EmailService; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import javax.annotation.Resource; +import javax.mail.*; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.Properties; + + +@SpringBootTest +@ContextConfiguration(classes = CfsApplication.class) +public class EmailTest { + + @Resource + EmailService emailService; + + @Test + public void test0() throws MessagingException { + emailService.sendEmail("rakor2010@gmail.com", "您正在申请修改密码", "这是邮件内容"); + } + + @Test + public void test1() throws MessagingException { + EmailConfig emailConfig = new EmailConfig() + .setHost("smtp.exmail.qq.com") + .setPort(465) + .setUsername("cfsnflg@nflg.com") + .setPassword("Cf250117"); + Properties properties = new Properties(); + properties.put("mail.smtp.host", emailConfig.getHost()); + properties.put("mail.smtp.port", emailConfig.getPort().toString()); + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.ssl.enable", "true"); + //properties.setProperty("mail.smtp.starttls.enable", "true"); + // 设置超时时间(单位:毫秒) + properties.put("mail.smtp.connectiontimeout", "5000"); // 连接超时 + properties.put("mail.smtp.timeout", "5000"); // 读取超时 + properties.put("mail.smtp.writetimeout", "5000"); // 写入超时 + Session session = Session.getInstance(properties, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(emailConfig.getUsername(), emailConfig.getPassword()); + } + }); + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(emailConfig.getUsername())); + message.addRecipient(Message.RecipientType.TO, new InternetAddress("rakor2010@gmail.com")); + message.setSubject("您正在申请修改密码"); +// message.setText("这是邮件内容"); + message.setContent("这是邮件内容", "text/html; charset=UTF-8"); + Transport.send(message); + } +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java index 4826857e..fa750ed8 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java @@ -12,7 +12,9 @@ public class Constant { public static final String DICTIONARY_TYPE_TITLE_CQM = "CQM"; - public static final String REDIS_KEY_USER_UPDATE_KAPTCHA = "kaptcha:userupdate:{}"; + public static final String REDIS_KEY_USER_UPDATE_KAPTCHA_APP = "kaptcha:userupdate:app:{}"; + + public static final String REDIS_KEY_USER_UPDATE_KAPTCHA_ADMIN = "kaptcha:userupdate:admin:{}"; public static final String REDIS_KEY_MESSAGECONFIG_WX = "wxNotifyEnabled"; diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/AvatarSetRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/AvatarSetRequest.java new file mode 100644 index 00000000..56777525 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/AvatarSetRequest.java @@ -0,0 +1,13 @@ +package com.nflg.mobilebroken.common.pojo.request; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AvatarSetRequest { + + // 头像 + @NotBlank + private String avatar; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/FileSearchRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/FileSearchRequest.java new file mode 100644 index 00000000..732233cd --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/FileSearchRequest.java @@ -0,0 +1,26 @@ +package com.nflg.mobilebroken.common.pojo.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDate; + +@EqualsAndHashCode(callSuper = false) +@Data +public class FileSearchRequest extends PageRequest { + + //关键字 + private String key; + + //文件来源,0:工单 + private Integer source; + + //文件类型 + private String fileType; + + //开始时间 + private LocalDate startTime; + + //结束时间 + private LocalDate endTime; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentAddRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentAddRequest.java index 69899496..76abd54d 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentAddRequest.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentAddRequest.java @@ -2,7 +2,9 @@ package com.nflg.mobilebroken.common.pojo.request; import lombok.Data; +import javax.validation.Valid; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; import java.util.List; @Data @@ -33,5 +35,7 @@ public class WebComponentAddRequest { private String componetCode; //多语言翻译 + @Valid + @NotEmpty private List traslates; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentDeleteRequest.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentDeleteRequest.java new file mode 100644 index 00000000..0ecf0f63 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/request/WebComponentDeleteRequest.java @@ -0,0 +1,11 @@ +package com.nflg.mobilebroken.common.pojo.request; + +import lombok.Data; + +import java.util.List; + +@Data +public class WebComponentDeleteRequest { + + private List ids; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/FileVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/FileVO.java new file mode 100644 index 00000000..641af3bd --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/FileVO.java @@ -0,0 +1,33 @@ +package com.nflg.mobilebroken.common.pojo.vo; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class FileVO { + + //关联 + public byte source; + public String sourceDesc; + //关联ID + public String sourceId; + //文件路径 + public String url; + //上传时间 + public LocalDateTime createTime; + //上传人 + public String createBy; + private Integer id; + // 文件名 + private String fileName; + // 文件类型 + private String fileType; + + public String getSourceDesc() { + if (source == 0) { + return "工单"; + } + return "未知"; + } +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/LanguageVO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/LanguageVO.java index 7311af38..f4aeec98 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/LanguageVO.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/vo/LanguageVO.java @@ -7,6 +7,8 @@ import lombok.experimental.Accessors; @Accessors(chain = true) public class LanguageVO { + private Integer id; + //语言代码 private String code; diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/AdminUserUtil.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/AdminUserUtil.java index a65c3419..da383af7 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/AdminUserUtil.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/AdminUserUtil.java @@ -51,4 +51,11 @@ public class AdminUserUtil { public static void clearPermissions() { PERMISSION_MAP.remove(getUserId()); } + + public static String getEmail() { + if (SaTokenAdminUtil.isLogin()) { + return (String) SaTokenAdminUtil.getExtra("email"); + } + return "aa@gmail.com"; + } } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java index 9ac53ea1..22a5db95 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/entity/FileUploadRecord.java @@ -1,14 +1,16 @@ package com.nflg.mobilebroken.repository.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import java.io.Serializable; -import java.time.LocalDateTime; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; +import java.io.Serializable; +import java.time.LocalDateTime; + /** *

* @@ -39,20 +41,26 @@ public class FileUploadRecord implements Serializable { private String fileType; /** - * 来源,0:工单 + * 关联类型,0:工单 */ private Byte source; /** - * 来源id + * 关联id */ - private Integer sourceId; + private String sourceId; /** * 访问地址 */ private String url; + /** + * 来源 + */ + @TableField("`from`") + private String from; + /** * 上传人 */ diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java index 4650f123..adb396aa 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IAdminUserService.java @@ -33,4 +33,8 @@ public interface IAdminUserService extends IService { void authorizeRole(AuthorizeRoleRequest request); String resetPassword(Integer id, String password); + + void setAvatar(Integer userId, String avatar); + + void updatePassword(Integer id, String newPassword); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IFileUploadRecordService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IFileUploadRecordService.java index 880d0a94..d53fcee3 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IFileUploadRecordService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/IFileUploadRecordService.java @@ -1,6 +1,9 @@ package com.nflg.mobilebroken.repository.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.nflg.mobilebroken.common.pojo.PageData; +import com.nflg.mobilebroken.common.pojo.request.FileSearchRequest; +import com.nflg.mobilebroken.common.pojo.vo.FileVO; import com.nflg.mobilebroken.repository.entity.FileUploadRecord; /** @@ -13,4 +16,5 @@ import com.nflg.mobilebroken.repository.entity.FileUploadRecord; */ public interface IFileUploadRecordService extends IService { + PageData search(FileSearchRequest request); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java index 2fffdec0..dcf2e75f 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/AdminUserServiceImpl.java @@ -177,6 +177,22 @@ public class AdminUserServiceImpl extends ServiceImpl * 服务实现类 @@ -17,4 +27,20 @@ import org.springframework.stereotype.Service; @Service public class FileUploadRecordServiceImpl extends ServiceImpl implements IFileUploadRecordService { + @Override + public PageData search(FileSearchRequest request) { + LocalDate endTime = request.getEndTime(); + if (Objects.nonNull(endTime)) { + endTime = endTime.plusDays(1); + } + Page datas = lambdaQuery() + .eq(Objects.nonNull(request.getSource()), FileUploadRecord::getSource, request.getSource()) + .eq(Objects.nonNull(request.getFileType()), FileUploadRecord::getFileType, request.getFileType()) + .like(StrUtil.isNotBlank(request.getKey()), FileUploadRecord::getFileName, request.getKey()) + .like(StrUtil.isNotBlank(request.getKey()), FileUploadRecord::getSourceId, request.getKey()) + .ge(Objects.nonNull(request.getStartTime()), FileUploadRecord::getCreateTime, request.getStartTime()) + .lt(Objects.nonNull(endTime), FileUploadRecord::getCreateTime, endTime) + .page(new Page<>(request.getPage(), request.getPageSize())); + return PageUtil.convert(datas, d -> Convert.convert(FileVO.class, d)); + } } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/WebComponentServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/WebComponentServiceImpl.java index a1a19ae6..d221f13c 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/WebComponentServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/WebComponentServiceImpl.java @@ -129,7 +129,11 @@ public class WebComponentServiceImpl extends ServiceImpl translates = webComponentTranslateService.lambdaQuery().eq(WebComponentTranslate::getComponentId, id).list(); - List languages = languageService.listByIds(translates.stream().map(WebComponentTranslate::getLanguageId).collect(Collectors.toList())); + List languages = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(translates)) { + languages = languageService.listByIds(translates.stream().map(WebComponentTranslate::getLanguageId).collect(Collectors.toList())); + } + List finalLanguages = languages; return new WebComponentInfoVO() .setId(webComponent.getId()) .setModuleName(webComponent.getModuleName()) @@ -140,7 +144,7 @@ public class WebComponentServiceImpl extends ServiceImpl new WebComponentTraslateVO() .setLanguageId(t.getLanguageId()) - .setLanguageName(languages.stream().filter(l -> l.getId().equals(t.getLanguageId())).findFirst().get().getName()) + .setLanguageName(finalLanguages.stream().filter(l -> l.getId().equals(t.getLanguageId())).findFirst().get().getName()) .setValue(t.getValue())).collect(Collectors.toList())); } diff --git a/nflg-mobilebroken-starter/pom.xml b/nflg-mobilebroken-starter/pom.xml index 984a81a9..17b48db4 100644 --- a/nflg-mobilebroken-starter/pom.xml +++ b/nflg-mobilebroken-starter/pom.xml @@ -85,11 +85,11 @@ com.nflg nflg-mobilebroken-repository - - com.sun.mail - jakarta.mail - 2.0.1 - + + + + + org.springframework.boot spring-boot-starter-test