feat: 一些调整

This commit is contained in:
曹鹏飞 2025-02-11 11:21:20 +08:00
parent 6bdc334c91
commit cfc9b461da
25 changed files with 432 additions and 49 deletions

View File

@ -1,7 +1,10 @@
package com.nflg.mobilebroken.admin.controller; package com.nflg.mobilebroken.admin.controller;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.nflg.mobilebroken.admin.annotation.ApiMark; 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.constant.STATE;
import com.nflg.mobilebroken.common.exception.NflgException; import com.nflg.mobilebroken.common.exception.NflgException;
import com.nflg.mobilebroken.common.pojo.ApiResult; 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.AdminUserVO;
import com.nflg.mobilebroken.common.pojo.vo.DepartmentSimpleVO; import com.nflg.mobilebroken.common.pojo.vo.DepartmentSimpleVO;
import com.nflg.mobilebroken.common.pojo.vo.TitleSimpleVO; 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.IAdminUserService;
import com.nflg.mobilebroken.repository.service.ITBaseDepartmentService; import com.nflg.mobilebroken.repository.service.ITBaseDepartmentService;
import com.nflg.mobilebroken.repository.service.ITBasePositionService; import com.nflg.mobilebroken.repository.service.ITBasePositionService;
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark; import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
import com.nflg.mobilebroken.starter.service.EmailService; 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.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import java.time.Duration;
import java.util.List; import java.util.List;
/** /**
@ -46,6 +53,12 @@ public class AdminUserController extends ControllerBase {
@Resource @Resource
private EmailService emailService; private EmailService emailService;
@Resource
private WXQRCodeService wxQRCodeService;
@Resource
private RedisTemplate<String, String> redisTemplate;
/** /**
* 获取部门列表 * 获取部门列表
* @return 部门列表 * @return 部门列表
@ -145,4 +158,59 @@ public class AdminUserController extends ControllerBase {
} }
return ApiResult.success(); 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<Void> setAvatar(@Valid @RequestBody AvatarSetRequest request) {
adminUserService.setAvatar(AdminUserUtil.getUserId(), request.getAvatar());
return ApiResult.success();
}
/**
* 更新密码
*
* @param request 请求信息
* @return 更新结果
**/
@PostMapping("updatePassword")
public ApiResult<Void> 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<Void> 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();
}
} }

View File

@ -6,12 +6,13 @@ import com.nflg.mobilebroken.admin.annotation.ApiMark;
import com.nflg.mobilebroken.common.constant.STATE; import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.exception.NflgException; 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.request.FileSearchRequest;
import com.nflg.mobilebroken.common.pojo.vo.FileVO;
import com.nflg.mobilebroken.common.util.AdminUserUtil; import com.nflg.mobilebroken.common.util.AdminUserUtil;
import com.nflg.mobilebroken.repository.service.IFileUploadRecordService;
import com.nflg.mobilebroken.starter.service.FileUploadService; import com.nflg.mobilebroken.starter.service.FileUploadService;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
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.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -23,7 +24,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* 文件上传相关接口 * 文件管理相关接口
* *
* @author 曹鹏飞 * @author 曹鹏飞
**/ **/
@ -32,17 +33,20 @@ import java.util.List;
public class FileController extends ControllerBase { public class FileController extends ControllerBase {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
@Resource @Resource
private FileUploadService fileUploadService; private FileUploadService fileUploadService;
@Resource
private IFileUploadRecordService fileUploadRecordService;
/** /**
* 上传单个文件 * 上传单个文件
*
* @param file 要上传的文件 * @param file 要上传的文件
* @return 可访问的文件url * @return 可访问的文件url
*/ */
@PostMapping("uploadSingleFile") @PostMapping("uploadSingleFile")
@ApiMark(moduleName = "文件上传", apiName = "上传单个文件") @ApiMark(moduleName = "文件管理", apiName = "上传单个文件")
public ApiResult<String> uploadSingleFile(@RequestParam("file") MultipartFile file) { public ApiResult<String> uploadSingleFile(@RequestParam("file") MultipartFile file) {
try { try {
return ApiResult.success(fileUploadService.upload(buildFilePath(file.getOriginalFilename()), file)); return ApiResult.success(fileUploadService.upload(buildFilePath(file.getOriginalFilename()), file));
@ -58,12 +62,11 @@ public class FileController extends ControllerBase {
/** /**
* 上传多个文件 * 上传多个文件
*
* @param files 要上传的文件列表 * @param files 要上传的文件列表
* @return 可访问的文件url列表 * @return 可访问的文件url列表
*/ */
@PostMapping("uploadMultipleFiles") @PostMapping("uploadMultipleFiles")
@ApiMark(moduleName = "文件上传", apiName = "上传多个文件") @ApiMark(moduleName = "文件管理", apiName = "上传多个文件")
public ApiResult<List<String>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files) { public ApiResult<List<String>> uploadMultipleFiles(@Valid @RequestParam("files") @NotEmpty List<MultipartFile> files) {
try { try {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
@ -75,4 +78,28 @@ public class FileController extends ControllerBase {
throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage()); throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage());
} }
} }
/**
* 搜索文件
*
* @param request 搜索条件
* @return 搜索到的文件列表
*/
@PostMapping("searchFiles")
@ApiMark(moduleName = "文件管理", apiName = "搜索文件")
public ApiResult<PageData<FileVO>> searchFiles(@Valid @RequestBody FileSearchRequest request) {
return ApiResult.success(fileUploadRecordService.search(request));
}
/**
* 删除文件
*
* @param ids 文件id列表
*/
@PostMapping("deleteFile")
@ApiMark(moduleName = "文件管理", apiName = "删除文件")
public ApiResult<Void> deleteFile(@Valid @RequestBody @NotEmpty List<Integer> ids) {
fileUploadRecordService.removeBatchByIds(ids);
return ApiResult.success();
}
} }

View File

@ -72,13 +72,28 @@ public class MultilingualController extends ControllerBase {
* 获取语言列表 * 获取语言列表
* @return 语言列表 * @return 语言列表
*/ */
@GetMapping("/getLanguage") @GetMapping("/getAllLanguage")
@ApiMark(moduleName = "多语言管理", apiName = "获取语言列表") @ApiMark(moduleName = "多语言管理", apiName = "获取语言列表")
public ApiResult<List<LanguageVO>> getLanguage() { public ApiResult<List<LanguageVO>> getLanguage() {
List<Language> languages = languageService.getAllLanguages(); List<Language> languages = languageService.getAllLanguages();
return ApiResult.success(Convert.toList(LanguageVO.class, languages)); return ApiResult.success(Convert.toList(LanguageVO.class, languages));
} }
/**
* 获取启用的语言列表
*
* @return 取语言列表
*/
@GetMapping("getLanguages")
@ApiMark(moduleName = "多语言管理", apiName = "获取启用的语言列表")
public ApiResult<List<LanguageVO>> getLanguages() {
List<Language> languages = languageService.getLanguages();
if (CollectionUtil.isEmpty(languages)) {
return ApiResult.success(Collections.emptyList());
}
return ApiResult.success(Convert.toList(LanguageVO.class, languages));
}
/** /**
* 启用/禁言语言 * 启用/禁言语言
* @param request 请求参数 * @param request 请求参数
@ -122,6 +137,18 @@ public class MultilingualController extends ControllerBase {
return ApiResult.success(webComponentService.search(request)); return ApiResult.success(webComponentService.search(request));
} }
/**
* 删除网页组件
*
* @param ids 组件id列表
*/
@PostMapping("/deleteWebComponent")
@ApiMark(moduleName = "多语言管理", apiName = "删除网页组件")
public ApiResult<Void> deleteWebComponent(@Valid @RequestBody @NotEmpty List<Integer> ids) {
webComponentService.removeByIds(ids);
return ApiResult.success();
}
/** /**
* 导出网页组件翻译列表 * 导出网页组件翻译列表
* @param request 请求参数 * @param request 请求参数

View File

@ -90,7 +90,7 @@ public class TicketController extends ControllerBase {
* @return 问题类型列表 * @return 问题类型列表
*/ */
@GetMapping("getQuestions") @GetMapping("getQuestions")
@ApiMark(moduleName = "获取问题类型", apiName = "搜索工单", isPublic = true) @ApiMark(moduleName = "工单管理", apiName = "获取问题类型", isPublic = true)
public ApiResult<List<String>> getQuestions() { public ApiResult<List<String>> getQuestions() {
return ApiResult.success(Arrays.asList("技术设计问题", "装配工艺问题", "焊接质量问题", "机组装配质量问题", "电控问题", "工况方案问题", "操作不当", "原材料配件质量问题", "QC检验遗漏/误差", "部件/整机外观")); return ApiResult.success(Arrays.asList("技术设计问题", "装配工艺问题", "焊接质量问题", "机组装配质量问题", "电控问题", "工况方案问题", "操作不当", "原材料配件质量问题", "QC检验遗漏/误差", "部件/整机外观"));
} }
@ -101,7 +101,7 @@ public class TicketController extends ControllerBase {
* @param request 请求信息 * @param request 请求信息
**/ **/
@PostMapping("followTiket") @PostMapping("followTiket")
@ApiMark(moduleName = "关注或取消关注工单", apiName = "搜索工单") @ApiMark(moduleName = "工单管理", apiName = "关注或取消关注")
public ApiResult<Void> followTiket(@Valid @RequestBody FollowRequest request) { public ApiResult<Void> followTiket(@Valid @RequestBody FollowRequest request) {
ticketFollowService.handleAdmin(request, AdminUserUtil.getUserId()); ticketFollowService.handleAdmin(request, AdminUserUtil.getUserId());
return ApiResult.success(); return ApiResult.success();

View File

@ -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<String, String> 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<String> 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);
}
}

View File

@ -28,6 +28,7 @@ public class ControllerTest {
@Test @Test
public void test2() { public void test2() {
// List<AdminApi> apis = new ArrayList<>(); // List<AdminApi> apis = new ArrayList<>();
String pre = "";
// 获取所有的请求映射 // 获取所有的请求映射
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) { for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
@ -53,7 +54,7 @@ public class ControllerTest {
// .setUrl(StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns())); // .setUrl(StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns()));
// apis.add(api); // apis.add(api);
// 打印请求路径 // 打印请求路径
String url = StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns()); String url = pre + StrUtil.join(",", mappingInfo.getPatternsCondition().getPatterns());
System.out.println("Request Paths: " + url); System.out.println("Request Paths: " + url);
AdminApi api = adminApiService.lambdaQuery() AdminApi api = adminApiService.lambdaQuery()
.eq(AdminApi::getModuleName, mark.moduleName()) .eq(AdminApi::getModuleName, mark.moduleName())

View File

@ -54,6 +54,7 @@ public class AdminController extends ControllerBase {
.setExtra("from", "admin") .setExtra("from", "admin")
.setExtra("name", user.getUserName()) .setExtra("name", user.getUserName())
.setExtra("code", user.getUserCode()) .setExtra("code", user.getUserCode())
.setExtra("email", user.getEmail())
.setExtra("roles", roleCodes)); .setExtra("roles", roleCodes));
return ApiResult.success(SaTokenAdminUtil.getTokenInfo()); return ApiResult.success(SaTokenAdminUtil.getTokenInfo());
} }

View File

@ -1,19 +1,15 @@
package com.nflg.mobilebroken.cfs.controller; package com.nflg.mobilebroken.cfs.controller;
import cn.hutool.core.collection.CollectionUtil; 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.ApiResult;
import com.nflg.mobilebroken.common.pojo.vo.LanguageVO; 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.entity.Language;
import com.nflg.mobilebroken.repository.service.ILanguageService; 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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,9 +26,6 @@ public class SystemController extends ControllerBase {
@Resource @Resource
private ILanguageService languageService; private ILanguageService languageService;
@Resource
private WXQRCodeService wxQRCodeService;
/** /**
* 获取语言列表 * 获取语言列表
* @return 取语言列表 * @return 取语言列表
@ -54,13 +47,4 @@ public class SystemController extends ControllerBase {
.collect(Collectors.toList()); .collect(Collectors.toList());
return ApiResult.success(vos); 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()));
}
} }

View File

@ -3,6 +3,7 @@ package com.nflg.mobilebroken.cfs.controller;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; 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.Constant;
import com.nflg.mobilebroken.common.constant.STATE; import com.nflg.mobilebroken.common.constant.STATE;
import com.nflg.mobilebroken.common.exception.NflgException; 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.repository.service.ITBasePositionService;
import com.nflg.mobilebroken.starter.service.EmailService; import com.nflg.mobilebroken.starter.service.EmailService;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotEmpty;
import java.time.Duration; import java.time.Duration;
@ -58,6 +61,9 @@ public class UserController extends ControllerBase {
@Resource @Resource
ITBasePositionService positionService; ITBasePositionService positionService;
@Resource
private WXQRCodeService wxQRCodeService;
/** /**
* 获取用户信息 * 获取用户信息
* @return 用户信息 * @return 用户信息
@ -74,7 +80,7 @@ public class UserController extends ControllerBase {
**/ **/
@PostMapping("updatePassword") @PostMapping("updatePassword")
public ApiResult<Void> updatePassword(@Valid @RequestBody UpdatePasswordRequest request){ public ApiResult<Void> 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); String captcha = redisTemplate.opsForValue().get(redisKey);
VUtils.trueThrowBusinessError(StrUtil.isBlank(captcha)).throwMessage("验证码已失效,请重新获取"); VUtils.trueThrowBusinessError(StrUtil.isBlank(captcha)).throwMessage("验证码已失效,请重新获取");
VUtils.trueThrowBusinessError(StrUtil.equals(captcha, request.getCaptcha())).throwMessage("验证码不正确"); VUtils.trueThrowBusinessError(StrUtil.equals(captcha, request.getCaptcha())).throwMessage("验证码不正确");
@ -195,14 +201,23 @@ public class UserController extends ControllerBase {
@PostMapping("sendUpdatePasswordCaptchaEmail") @PostMapping("sendUpdatePasswordCaptchaEmail")
public ApiResult<Void> sendUpdatePasswordCaptchaEmail() { public ApiResult<Void> sendUpdatePasswordCaptchaEmail() {
try { try {
String email = AppUserUtil.getEmail(); String email = "rakor2010@gmail.com"; //AppUserUtil.getEmail();
String kaptcha = RandomUtil.randomString(6); String kaptcha = RandomUtil.randomString(6);
// 将生成的验证码存入redis // 将生成的验证码存入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); emailService.sendEmail(email, "您正在申请修改密码", "验证码为: " + kaptcha);
} catch (Exception ex) { } catch (Exception ex) {
throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage()); throw new NflgException(STATE.BusinessError, "发送邮件失败:" + ex.getMessage());
} }
return ApiResult.success(); 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()));
}
} }

View File

@ -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);
}
}

View File

@ -12,7 +12,9 @@ public class Constant {
public static final String DICTIONARY_TYPE_TITLE_CQM = "CQM"; 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"; public static final String REDIS_KEY_MESSAGECONFIG_WX = "wxNotifyEnabled";

View File

@ -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;
}

View File

@ -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;
}

View File

@ -2,7 +2,9 @@ package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data; import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List; import java.util.List;
@Data @Data
@ -33,5 +35,7 @@ public class WebComponentAddRequest {
private String componetCode; private String componetCode;
//多语言翻译 //多语言翻译
@Valid
@NotEmpty
private List<WebComponentTraslateRequest> traslates; private List<WebComponentTraslateRequest> traslates;
} }

View File

@ -0,0 +1,11 @@
package com.nflg.mobilebroken.common.pojo.request;
import lombok.Data;
import java.util.List;
@Data
public class WebComponentDeleteRequest {
private List<Integer> ids;
}

View File

@ -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 "未知";
}
}

View File

@ -7,6 +7,8 @@ import lombok.experimental.Accessors;
@Accessors(chain = true) @Accessors(chain = true)
public class LanguageVO { public class LanguageVO {
private Integer id;
//语言代码 //语言代码
private String code; private String code;

View File

@ -51,4 +51,11 @@ public class AdminUserUtil {
public static void clearPermissions() { public static void clearPermissions() {
PERMISSION_MAP.remove(getUserId()); PERMISSION_MAP.remove(getUserId());
} }
public static String getEmail() {
if (SaTokenAdminUtil.isLogin()) {
return (String) SaTokenAdminUtil.getExtra("email");
}
return "aa@gmail.com";
}
} }

View File

@ -1,14 +1,16 @@
package com.nflg.mobilebroken.repository.entity; package com.nflg.mobilebroken.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
/** /**
* <p> * <p>
* *
@ -39,20 +41,26 @@ public class FileUploadRecord implements Serializable {
private String fileType; private String fileType;
/** /**
* 来源0工单 * 关联类型0工单
*/ */
private Byte source; private Byte source;
/** /**
* 来源id * 关联id
*/ */
private Integer sourceId; private String sourceId;
/** /**
* 访问地址 * 访问地址
*/ */
private String url; private String url;
/**
* 来源
*/
@TableField("`from`")
private String from;
/** /**
* 上传人 * 上传人
*/ */

View File

@ -33,4 +33,8 @@ public interface IAdminUserService extends IService<AdminUser> {
void authorizeRole(AuthorizeRoleRequest request); void authorizeRole(AuthorizeRoleRequest request);
String resetPassword(Integer id, String password); String resetPassword(Integer id, String password);
void setAvatar(Integer userId, String avatar);
void updatePassword(Integer id, String newPassword);
} }

View File

@ -1,6 +1,9 @@
package com.nflg.mobilebroken.repository.service; package com.nflg.mobilebroken.repository.service;
import com.baomidou.mybatisplus.extension.service.IService; 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; import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
/** /**
@ -13,4 +16,5 @@ import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
*/ */
public interface IFileUploadRecordService extends IService<FileUploadRecord> { public interface IFileUploadRecordService extends IService<FileUploadRecord> {
PageData<FileVO> search(FileSearchRequest request);
} }

View File

@ -177,6 +177,22 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser
return user.getEmail(); return user.getEmail();
} }
@Override
public void setAvatar(Integer userId, String avatar) {
lambdaUpdate().set(AdminUser::getAvatar, avatar)
.eq(AdminUser::getId, userId)
.update();
}
@Override
public void updatePassword(Integer id, String newPassword) {
AdminUser user = new AdminUser()
.setId(id)
.setPassword(PASSWORDENCODER.encode(newPassword))
.setUpdateTime(LocalDateTime.now());
updateById(user);
}
private String getDepartmentName(Integer departmentId) { private String getDepartmentName(Integer departmentId) {
TBaseDepartment department = departmentService.lambdaQuery() TBaseDepartment department = departmentService.lambdaQuery()
.eq(TBaseDepartment::getId, departmentId) .eq(TBaseDepartment::getId, departmentId)

View File

@ -1,11 +1,21 @@
package com.nflg.mobilebroken.repository.service.impl; package com.nflg.mobilebroken.repository.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.PageUtil;
import com.nflg.mobilebroken.repository.entity.FileUploadRecord; import com.nflg.mobilebroken.repository.entity.FileUploadRecord;
import com.nflg.mobilebroken.repository.mapper.FileUploadRecordMapper; import com.nflg.mobilebroken.repository.mapper.FileUploadRecordMapper;
import com.nflg.mobilebroken.repository.service.IFileUploadRecordService; import com.nflg.mobilebroken.repository.service.IFileUploadRecordService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.Objects;
/** /**
* <p> * <p>
* 服务实现类 * 服务实现类
@ -17,4 +27,20 @@ import org.springframework.stereotype.Service;
@Service @Service
public class FileUploadRecordServiceImpl extends ServiceImpl<FileUploadRecordMapper, FileUploadRecord> implements IFileUploadRecordService { public class FileUploadRecordServiceImpl extends ServiceImpl<FileUploadRecordMapper, FileUploadRecord> implements IFileUploadRecordService {
@Override
public PageData<FileVO> search(FileSearchRequest request) {
LocalDate endTime = request.getEndTime();
if (Objects.nonNull(endTime)) {
endTime = endTime.plusDays(1);
}
Page<FileUploadRecord> 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));
}
} }

View File

@ -129,7 +129,11 @@ public class WebComponentServiceImpl extends ServiceImpl<WebComponentMapper, Web
WebComponent webComponent = getById(id); WebComponent webComponent = getById(id);
VUtils.trueThrowBusinessError(Objects.isNull(webComponent)).throwMessage("未找到组件"); VUtils.trueThrowBusinessError(Objects.isNull(webComponent)).throwMessage("未找到组件");
List<WebComponentTranslate> translates = webComponentTranslateService.lambdaQuery().eq(WebComponentTranslate::getComponentId, id).list(); List<WebComponentTranslate> translates = webComponentTranslateService.lambdaQuery().eq(WebComponentTranslate::getComponentId, id).list();
List<Language> languages = languageService.listByIds(translates.stream().map(WebComponentTranslate::getLanguageId).collect(Collectors.toList())); List<Language> languages = new ArrayList<>();
if (CollectionUtil.isNotEmpty(translates)) {
languages = languageService.listByIds(translates.stream().map(WebComponentTranslate::getLanguageId).collect(Collectors.toList()));
}
List<Language> finalLanguages = languages;
return new WebComponentInfoVO() return new WebComponentInfoVO()
.setId(webComponent.getId()) .setId(webComponent.getId())
.setModuleName(webComponent.getModuleName()) .setModuleName(webComponent.getModuleName())
@ -140,7 +144,7 @@ public class WebComponentServiceImpl extends ServiceImpl<WebComponentMapper, Web
.setComponetCode(webComponent.getComponentCode()) .setComponetCode(webComponent.getComponentCode())
.setTraslates(translates.stream().map(t -> new WebComponentTraslateVO() .setTraslates(translates.stream().map(t -> new WebComponentTraslateVO()
.setLanguageId(t.getLanguageId()) .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())); .setValue(t.getValue())).collect(Collectors.toList()));
} }

View File

@ -85,11 +85,11 @@
<groupId>com.nflg</groupId> <groupId>com.nflg</groupId>
<artifactId>nflg-mobilebroken-repository</artifactId> <artifactId>nflg-mobilebroken-repository</artifactId>
</dependency> </dependency>
<dependency> <!-- <dependency>-->
<groupId>com.sun.mail</groupId> <!-- <groupId>com.sun.mail</groupId>-->
<artifactId>jakarta.mail</artifactId> <!-- <artifactId>jakarta.mail</artifactId>-->
<version>2.0.1</version> <!-- <version>2.0.1</version>-->
</dependency> <!-- </dependency>-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>