From 6d80269b2c13a446c058412385f46a64079b4d75 Mon Sep 17 00:00:00 2001 From: ovo Date: Wed, 7 May 2025 18:47:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20[=E4=B8=B4=E6=97=B6=E6=8F=90=E4=BA=A4]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArcFacePro64.dat | 2 +- docs/初步.md | 2 + .../backend/constant/CacheConstants.java | 2 +- .../backend/constant/SecurityConstants.java | 6 +- .../backend/controller/BSUserController.java | 7 +- .../backend/controller/CommonController.java | 8 ++ .../backend/controller/DockerCppRunner.java | 18 ++-- .../backend/controller/FaceController.java | 101 ++++++++++++------ .../backend/controller/MinioController.java | 26 +++++ .../backend/controller/SetController.java | 16 +++ .../backend/controller/UserController.java | 3 +- .../guwan/backend/face/util/Base64Util.java | 4 +- .../model/exam/controller/ExamController.java | 39 +++++-- .../model/exam/dto/ExamResponseDTO.java | 3 - .../backend/pojo/dto/user/BSRegisterDTO.java | 5 +- .../backend/pojo/dto/user/RegisterDTO.java | 4 +- .../guwan/backend/service/UserService.java | 7 +- .../backend/service/impl/UserServiceImpl.java | 24 ++--- .../com/guwan/backend/util/MinioUtil.java | 2 - src/main/resources/application.yml | 8 +- 20 files changed, 195 insertions(+), 92 deletions(-) create mode 100644 src/main/java/com/guwan/backend/controller/MinioController.java create mode 100644 src/main/java/com/guwan/backend/controller/SetController.java diff --git a/ArcFacePro64.dat b/ArcFacePro64.dat index 33dd326..6092476 100644 --- a/ArcFacePro64.dat +++ b/ArcFacePro64.dat @@ -1 +1 @@ -EWEPEPEOGMGTELIZJUGECKIUJDBCJTCNISGPBNHLJTJUBHEWGNAKGEGAIOHJDQAJGNCFDRFZJEDMJTGFGBEAAWGLBZAUCNHCCPBZCIIKBJATGYARHRAZHXFRBIEBCHIXAFDLFQBZFVJQGTCEHDIMIVGQEJAJIYHXHTISIVETBACMCCGFDPEKDQHYGGAPFXIOCJAAGOHYIFHNHZHWIGCZIGHHDMDXHQGTFLJOHGAYIVBGIHIQHHHJDJFWHMCRHJAMHZESGWGGAUJRGDHAGHIQITIJIUAXAEIZGBGZCCHJAHASGNCVIIJAIYFOEQGFELEIEDECJTCXBCAPIKHTFTHBAGJTERHQGSAFEUDIHLDDITDPIMACAOGTIIHFEMHLHIHYJTFDFDGWAKHJEIEIJFGABQJCIHIADYCXAHIMJTHOASFLGFFIBJJEHDHLHOCMDIGGDOJDHNBQCJENFUBAGOAZITIRJSFBBUCUHABLHRFVIUBWCADJCMDXDPATBPJSJRJLBRABGVFTDNFOAQDOARDEBRHJAQGYHIGMBDCJCSJKFBBLGECAEFEYCVCHAEAZJRIOFEHLCJILEHJVGYIVCWGHCMGJGLBTFMHFCAEAAUJQJLAEARDHDFHDBJJGALEHFNGSAIHOJUBOEAJDDFFYFTINITHTBNIJFDHLEAFGBFHFFQGHGFGREVFHFDCZGYEVBWAZDSCAGLDMIAAEFOAXIXFECSFQDWHFFHCFASFSGAHVJSDBBZJQAZBXARILBAJFJEHCANAIABBMECBJJFIOGYGHBXCUCVBDJOCYBZDZAJEXAXEPFRFOGVHQAOJLCYBOHFEKJFIJBDHDDCEAAUJVDRIGGGGCJOFVECAHAQFSBSGYJVGKCQDDHPGUCIARFAIEJGGDITAUDIIVBBJUEFCIDTGJGYJODRDEJPBMFNCXAKCPAIGOJQGHBZHQJUCOBKCKDPJSGGCVCAIWFVHIIEAJJMEFGRHZDEDACFBQJODGDVJBAUBXGKGCFZERAHIOALGKGAILDNHQGGAZDEIGATBTCWHMDKGSIWFMHAIZHREBJBEFENDFBRBLGLCMERJAEOBXCNDBHVCSJBDMEHCLJLCFFOGVGWATBOJBFJEQETHGESEXFDIIFDAGJPDNHEDSFNBRIVFMFPGOEEIHEFCOCKJGJAIZJIFTIGAWITGWDXGBEFDTJHFXBF \ No newline at end of file +EWEPEPEOGMGTELIZJUGECKIUJDBCJTCNISGPBNHLJTJUBHEWGNAKGEGAIOHJDQAJGNCFDRFZJEDMJTGKGSHREQHMATEHBXBBELGFHLHTHOEGBAEOIHCLEOHMBGAAGYCLCYAXCDJTCCEAIOJNEBAXFCBLJQCMJPFBHWAADIFPHXAFDQDXEHCODEIXBWDBCOEZIAFNBYGJFLJEFIHFIDETGZDMJAAYBVBWDKGOFEJDDXITHJCOJTHIHOIAETIBFLAWIZCBDNJSCBGXGQFLCOAEGXIHEKGXFPCAACCFGOGJIZISFMACEFJJAYDTIWCYHQFTDDGVANDNBICDBRJIBBIHHWFZHRHWJCBACHHSFPCKINHXHPEVDMAHAJBHHNBTFLEQEPDQIWCXBEGVEPCYECIFEHAMBQJIGUELIAAWHABFDTGYIPGDGOHVCJDFDDGUBTBECFFLIGJJBJJOGNJDHKIUBVHFIRAVHQGKJLBQIUAVFTICHLHFEAAGGAJODVIRINBWHXEDAWCMGOIHDZCNAFIEEEGXJMHXBAFXCJGNDSCOFPGLFNBQDRATGQEMAMDHHCEDJRDAITICJNJSJADSBAAVHNERBZJIAOIUAVIHFODFJDBQJBIPEXJOCXDSEAJUBXECHVCQGJGGFRIPIVGVHPBRAUIADJEWBPHAHXBICDBKELCIGEIBFLHHGFHNDDDMIRBYIIDODBDYBAIPBQAWHFAVFMJRGHHCDYJGDQJACYHGAXGSIPAGIWFJDRBRGXHJESHZHPAGDKGWFUIKJOEPITFCEXELAVITCPBFGXHNEDANGLDLCMDRHBEAEHEYIKAJDSDFCMGQIJAWHAGOJNFYIHDWACBTGBIHENHJFNITEWCIBPCEIYDVFCJQGZHDILIUGYFJBAGTICJVDYJLGIBMJAAUFIJNIEERJOIMDCFAANCEEXHBBBGNESJKCMDYDBGOBCBVEDAFCBIQAKHVHUIUEOHVBPCJIRDGIFCQBWAFACELFSGYEMENEUITANIAIMBLBAAQGCHOGFDSENIFEWFVEYHZIVEUGXAXGCHSCXEOALHQGPCYDIBRHYHCEFAFHNAMCVHBBUFPJMHPDXIHBXGXJPFRCHBPGPFWABCKIEHOIZFLJECTERFOHAHZGXGLIJAAFBCRDCGOFPBCIGJPBXJMEYGQDVAXHMJGBIIOCLDYJQHNJMECBK \ No newline at end of file diff --git a/docs/初步.md b/docs/初步.md index 8eecdb7..6a2f9e3 100644 --- a/docs/初步.md +++ b/docs/初步.md @@ -10,5 +10,7 @@ RBAC——基于角色权限的模型 要做全控制 表单 按钮 视图 +merge和rebase + diff --git a/src/main/java/com/guwan/backend/constant/CacheConstants.java b/src/main/java/com/guwan/backend/constant/CacheConstants.java index 005f787..f9716e7 100644 --- a/src/main/java/com/guwan/backend/constant/CacheConstants.java +++ b/src/main/java/com/guwan/backend/constant/CacheConstants.java @@ -13,7 +13,7 @@ public class CacheConstants { */ public static final List CACHE_LIST = List.of( "userCache", - "paperCache" + "paperCache" ); diff --git a/src/main/java/com/guwan/backend/constant/SecurityConstants.java b/src/main/java/com/guwan/backend/constant/SecurityConstants.java index a996a40..292f4a7 100644 --- a/src/main/java/com/guwan/backend/constant/SecurityConstants.java +++ b/src/main/java/com/guwan/backend/constant/SecurityConstants.java @@ -12,9 +12,11 @@ public class SecurityConstants { * 这些路径可以直接访问,不需要认证 */ public static final List WHITE_LIST = List.of( - + "/faceTest","/compareFaces", + "/minio/**", "/exam/api/paper/**", - "/bs/**", + "/bs/user/login", + "/bs/user/register", "/api/common/**", //公共接口 "/demo/**", // 测试接口 "/api/products", diff --git a/src/main/java/com/guwan/backend/controller/BSUserController.java b/src/main/java/com/guwan/backend/controller/BSUserController.java index 00bec97..ef9981c 100644 --- a/src/main/java/com/guwan/backend/controller/BSUserController.java +++ b/src/main/java/com/guwan/backend/controller/BSUserController.java @@ -32,14 +32,13 @@ public class BSUserController { public Result register(@RequestBody @Valid BSRegisterDTO request) { try { log.info("用户注册: {}", request); - // return Result.success("注册成功", userService.register(request)); + return Result.success("注册成功", userService.register(request)); } catch (IllegalArgumentException e) { - // return Result.validateFailed(e.getMessage()); + return Result.validateFailed(e.getMessage()); } catch (Exception e) { log.error("注册失败", e); - // return Result.error("系统错误"); + return Result.error("系统错误"); } - return null; } @PostMapping("/login") diff --git a/src/main/java/com/guwan/backend/controller/CommonController.java b/src/main/java/com/guwan/backend/controller/CommonController.java index 098e6ea..a63db01 100644 --- a/src/main/java/com/guwan/backend/controller/CommonController.java +++ b/src/main/java/com/guwan/backend/controller/CommonController.java @@ -557,6 +557,14 @@ public class CommonController { } + @PostMapping("/sendCode") + public void sendCode(@RequestParam String code){ + + System.out.println("code = " + code); + + } + + } diff --git a/src/main/java/com/guwan/backend/controller/DockerCppRunner.java b/src/main/java/com/guwan/backend/controller/DockerCppRunner.java index 8a233ee..ea410e1 100644 --- a/src/main/java/com/guwan/backend/controller/DockerCppRunner.java +++ b/src/main/java/com/guwan/backend/controller/DockerCppRunner.java @@ -1,4 +1,3 @@ -/* package com.guwan.backend.controller; import com.github.dockerjava.api.DockerClient; @@ -7,10 +6,13 @@ import com.github.dockerjava.api.command.ExecCreateCmdResponse; import com.github.dockerjava.core.DockerClientBuilder; import com.github.dockerjava.core.command.ExecStartResultCallback; import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; +import lombok.RequiredArgsConstructor; import java.io.ByteArrayOutputStream; +import java.net.URI; import java.util.concurrent.TimeUnit; +@RequiredArgsConstructor public class DockerCppRunner { private static final String IMAGE_NAME = "cpp-runner"; @@ -22,10 +24,10 @@ public class DockerCppRunner { DockerClient dockerClient = DockerClientBuilder.getInstance() .withDockerHttpClient( new ApacheDockerHttpClient.Builder() - .dockerHost(DockerClientBuilder.getDefaultDockerHost()) + .dockerHost(URI.create("tcp://localhost:2375")) .build() ).build(); - + try { // 创建容器 CreateContainerResponse container = dockerClient.createContainerCmd(IMAGE_NAME) @@ -33,14 +35,14 @@ public class DockerCppRunner { .exec(); String containerId = container.getId(); - + // 启动容器 dockerClient.startContainerCmd(containerId).exec(); // 写入 C++ 代码到容器内 String cppCode = "#include \n" + "int main() { std::cout << \"Hello Docker!\\n\"; return 0; }"; - + // 将代码写入容器中的文件 dockerClient.execCreateCmd(containerId) .withCmd("sh", "-c", "echo '" + cppCode + "' > /app/main.cpp") @@ -55,13 +57,13 @@ public class DockerCppRunner { } finally { // 清理容器 - dockerClient.listContainersCmd().withShowAll(true).exec().forEach(c -> + dockerClient.listContainersCmd().withShowAll(true).exec().forEach(c -> dockerClient.removeContainerCmd(c.getId()).withForce(true).exec()); dockerClient.close(); } } - private static String execCommand(DockerClient dockerClient, String containerId, String command) + private static String execCommand(DockerClient dockerClient, String containerId, String command) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ExecCreateCmdResponse exec = dockerClient.execCreateCmd(containerId) @@ -76,4 +78,4 @@ public class DockerCppRunner { return outputStream.toString().trim(); } -}*/ +} diff --git a/src/main/java/com/guwan/backend/controller/FaceController.java b/src/main/java/com/guwan/backend/controller/FaceController.java index 83e9430..187e35f 100644 --- a/src/main/java/com/guwan/backend/controller/FaceController.java +++ b/src/main/java/com/guwan/backend/controller/FaceController.java @@ -1,4 +1,3 @@ -/* package com.guwan.backend.controller; import cn.hutool.core.collection.CollectionUtil; @@ -6,18 +5,19 @@ import com.arcsoft.face.FaceInfo; import com.arcsoft.face.enums.ExtractType; import com.arcsoft.face.toolkit.ImageFactory; import com.arcsoft.face.toolkit.ImageInfo; +import com.guwan.backend.face.dto.CompareFacesReqDTO; import com.guwan.backend.face.dto.FaceRecognitionResDTO; +import com.guwan.backend.face.rpc.Response; import com.guwan.backend.face.service.FaceEngineService; -import com.guwan.config.GlobalValue; -import com.guwan.config.MinioConfig; -import com.guwan.util.UUIDUtil; +import com.guwan.backend.face.util.Base64Util; +import io.minio.GetObjectArgs; +import io.minio.GetObjectResponse; import io.minio.MinioClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -28,27 +28,33 @@ import java.util.List; @Slf4j public class FaceController { - @Autowired - private MinioConfig minioConfig; + @Autowired private MinioClient minioClient; - @Autowired - private GlobalValue globalValue; + @Autowired private FaceEngineService faceEngineService; - @GetMapping("/11") + @GetMapping("/faceTest") public Integer test() { try { - String tempOrgImageFile = "photo/t_1f952219ae6848a48fbf282d7d464623.jpg"; + String tempOrgImageFile = "face/4badd5e9-fd09-4542-aa75-7536c1fa55f4.jpg"; // 调用statObject()来判断对象是否存在。如果不存在, statObject()抛出异常, 否则则代表对象存在。 - minioClient.statObject(minioConfig.getBucketName(), tempOrgImageFile); + // minioClient.statObject(minioConfig.getBucketName(), tempOrgImageFile); //判断人脸照片是否合格 //1 - InputStream tempInputStream = minioClient.getObject(minioConfig.getBucketName(), - tempOrgImageFile); +// InputStream tempInputStream = minioClient.getObject(minioConfig.getBucketName(), +// tempOrgImageFile); + + GetObjectResponse tempInputStream = minioClient.getObject( + GetObjectArgs.builder() + .bucket("photo") + .object(tempOrgImageFile) + .build() + ); + //----------------算法检测---------------------------------------------- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; @@ -86,22 +92,22 @@ public class FaceController { } - String orgImageFileName = "face/"+ "o_" + UUIDUtil.uuid() + ".jpg"; - //拷贝临时文件正式文件 - minioClient.copyObject( - minioConfig.getBucketName(), - orgImageFileName, - null, - null, - minioConfig.getBucketName(), - tempOrgImageFile, - null, - null); - - - - //删除临时文件oss - minioClient.removeObject(minioConfig.getBucketName(), tempOrgImageFile); +// String orgImageFileName = "face/"+ "o_" + UUIDUtil.uuid() + ".jpg"; +// //拷贝临时文件正式文件 +// minioClient.copyObject( +// minioConfig.getBucketName(), +// orgImageFileName, +// null, +// null, +// minioConfig.getBucketName(), +// tempOrgImageFile, +// null, +// null); +// +// +// +// //删除临时文件oss +// minioClient.removeObject(minioConfig.getBucketName(), tempOrgImageFile); //删除本地临时文件 // new File(tempFaceFilePath).delete(); } catch (Exception e) { @@ -112,5 +118,36 @@ public class FaceController { return 1; } + + @RequestMapping(value = "/compareFaces", method = RequestMethod.GET) + @ResponseBody +// public Response compareFaces(@RequestBody CompareFacesReqDTO compareFacesReqDTO) { +// +// String image1 = compareFacesReqDTO.getImage1(); +// String image2 = compareFacesReqDTO.getImage2(); +// +// byte[] bytes1 = Base64Util.base64ToBytes(image1); +// byte[] bytes2 = Base64Util.base64ToBytes(image2); +// ImageInfo rgbData1 = ImageFactory.getRGBData(bytes1); +// ImageInfo rgbData2 = ImageFactory.getRGBData(bytes2); +// +// Float similar = faceEngineService.compareFace(rgbData1, rgbData2); +// +// return Response.newSuccessResponse(similar); +// } + public Response compareFaces() { + + String image1 = "base64,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"; + String image2 = "base64,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"; + + byte[] bytes1 = Base64Util.base64ToBytes(image1); + byte[] bytes2 = Base64Util.base64ToBytes(image2); + ImageInfo rgbData1 = ImageFactory.getRGBData(bytes1); + ImageInfo rgbData2 = ImageFactory.getRGBData(bytes2); + + Float similar = faceEngineService.compareFace(rgbData1, rgbData2); + + return Response.newSuccessResponse(similar); + } + } -*/ diff --git a/src/main/java/com/guwan/backend/controller/MinioController.java b/src/main/java/com/guwan/backend/controller/MinioController.java new file mode 100644 index 0000000..a0fc8a8 --- /dev/null +++ b/src/main/java/com/guwan/backend/controller/MinioController.java @@ -0,0 +1,26 @@ +package com.guwan.backend.controller; + +import com.guwan.backend.common.Result; +import com.guwan.backend.util.MinioUtil; +import lombok.RequiredArgsConstructor; +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; + +@RestController +@RequestMapping("/minio") +@RequiredArgsConstructor +public class MinioController { + + private final MinioUtil minioUtil; + + @PostMapping("/uploadBase64Image") + public Result uploadBase64Image(@RequestParam String bucketName, + @RequestParam String base64Image, + @RequestParam String folder){ + String fileName = minioUtil.uploadBase64Image(bucketName, base64Image, folder); + return Result.success(fileName); + } + +} diff --git a/src/main/java/com/guwan/backend/controller/SetController.java b/src/main/java/com/guwan/backend/controller/SetController.java new file mode 100644 index 0000000..3e63ad3 --- /dev/null +++ b/src/main/java/com/guwan/backend/controller/SetController.java @@ -0,0 +1,16 @@ +package com.guwan.backend.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/setAuthentication") +@RequiredArgsConstructor +public class SetController { + @GetMapping + public void setAuthentication(){ + + } +} diff --git a/src/main/java/com/guwan/backend/controller/UserController.java b/src/main/java/com/guwan/backend/controller/UserController.java index ab3542a..65696ab 100644 --- a/src/main/java/com/guwan/backend/controller/UserController.java +++ b/src/main/java/com/guwan/backend/controller/UserController.java @@ -1,3 +1,4 @@ +/* package com.guwan.backend.controller; import cn.hutool.core.date.DateUtil; @@ -158,4 +159,4 @@ public class UserController { return Result.error(e.getMessage()); } } -} \ No newline at end of file +} */ diff --git a/src/main/java/com/guwan/backend/face/util/Base64Util.java b/src/main/java/com/guwan/backend/face/util/Base64Util.java index 7b94ab7..7d48c30 100644 --- a/src/main/java/com/guwan/backend/face/util/Base64Util.java +++ b/src/main/java/com/guwan/backend/face/util/Base64Util.java @@ -9,7 +9,9 @@ public class Base64Util { if (!ObjectUtils.isEmpty(base64Str)) { String photoBase64 = base64Str.substring(0, 30).toLowerCase(); int indexOf = photoBase64.indexOf("base64,"); - if (indexOf > 0) { + if (indexOf >= 0) { + //包括起始下标 beginIndex + //不包括结束下标 endIndex base64Str = base64Str.substring(indexOf + 7); } base64Str = base64Str.replaceAll(" ", "+"); diff --git a/src/main/java/com/guwan/backend/model/exam/controller/ExamController.java b/src/main/java/com/guwan/backend/model/exam/controller/ExamController.java index dbd2ae3..f7127a1 100644 --- a/src/main/java/com/guwan/backend/model/exam/controller/ExamController.java +++ b/src/main/java/com/guwan/backend/model/exam/controller/ExamController.java @@ -3,6 +3,7 @@ package com.guwan.backend.model.exam.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.guwan.backend.common.Result; +import com.guwan.backend.controller.BaseExamController; import com.guwan.backend.core.api.ApiRest; import com.guwan.backend.core.api.controller.BaseController; import com.guwan.backend.core.api.dto.BaseIdReqDTO; @@ -19,12 +20,18 @@ import com.guwan.backend.model.exam.entity.Exam; import com.guwan.backend.model.exam.service.ExamService; +import com.guwan.backend.pojo.entity.BaseExam; +import com.guwan.backend.service.BaseExamService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; //import org.apache.shiro.authz.annotation.RequiresRoles; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -40,11 +47,13 @@ import java.util.List; @Api(tags={"考试"}) @RestController @RequestMapping("/api/common/exam") +@RequiredArgsConstructor public class ExamController extends BaseController { - @Autowired - private ExamService examService; + private final ExamService examService; + + private final BaseExamService baseExamService; /** * 分页查找 @@ -71,15 +80,27 @@ public class ExamController extends BaseController { @GetMapping("/exam") public Result getExam() { + + + BaseExam baseExam = baseExamService.getById(1); + // 模拟数据,可以从数据库中查询 ExamResponseDTO response = new ExamResponseDTO(); - response.setId("1"); - response.setTitle("模拟考试试卷 (含新题型)"); - response.setTotalScore(100); - response.setTotalTime(120); - response.setLeftSeconds(7180); - response.setExamStartTime("2025-04-17 00:10:24"); - response.setExamDuration(60 * 60 * 2); + response.setTitle(baseExam.getTitle()); + response.setTotalScore(baseExam.getTotalScore()); + response.setTotalTime(baseExam.getTotalTime()); + //response.setLeftSeconds(7180); + + + LocalDateTime localDateTime = baseExam.getStartTime().toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + +// 格式化 + String formatted = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + + response.setExamStartTime(formatted); + // 填充题数据 List fillList = new ArrayList<>(); diff --git a/src/main/java/com/guwan/backend/model/exam/dto/ExamResponseDTO.java b/src/main/java/com/guwan/backend/model/exam/dto/ExamResponseDTO.java index efe4cfe..5a2339d 100644 --- a/src/main/java/com/guwan/backend/model/exam/dto/ExamResponseDTO.java +++ b/src/main/java/com/guwan/backend/model/exam/dto/ExamResponseDTO.java @@ -10,14 +10,11 @@ import java.util.List; @AllArgsConstructor @NoArgsConstructor public class ExamResponseDTO { - - private String id; private String title; private int totalScore; private int totalTime; private int leftSeconds; private String examStartTime; // 这里用字符串格式而不是标准时间 - private int examDuration; private List fillList; private List judgeList; private List radioList; diff --git a/src/main/java/com/guwan/backend/pojo/dto/user/BSRegisterDTO.java b/src/main/java/com/guwan/backend/pojo/dto/user/BSRegisterDTO.java index f338e35..2cbf84c 100644 --- a/src/main/java/com/guwan/backend/pojo/dto/user/BSRegisterDTO.java +++ b/src/main/java/com/guwan/backend/pojo/dto/user/BSRegisterDTO.java @@ -9,7 +9,10 @@ import lombok.Data; public class BSRegisterDTO { @NotBlank(message = "用户名不能为空") private String username; - @NotBlank(message = "密码不能为空") private String password; + @Email(message = "邮箱格式不正确") + private String email; + @NotBlank(message = "邮箱验证码不能为空") + private String emailCode; } \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/pojo/dto/user/RegisterDTO.java b/src/main/java/com/guwan/backend/pojo/dto/user/RegisterDTO.java index 0247e67..9a20e16 100644 --- a/src/main/java/com/guwan/backend/pojo/dto/user/RegisterDTO.java +++ b/src/main/java/com/guwan/backend/pojo/dto/user/RegisterDTO.java @@ -22,10 +22,10 @@ public class RegisterDTO { @NotBlank(message = "邮箱验证码不能为空") private String emailCode; - @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") +/* @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") private String phone; @NotBlank(message = "手机验证码不能为空") - private String phoneCode; + private String phoneCode;*/ } \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/service/UserService.java b/src/main/java/com/guwan/backend/service/UserService.java index 60f67c9..ae6459e 100644 --- a/src/main/java/com/guwan/backend/service/UserService.java +++ b/src/main/java/com/guwan/backend/service/UserService.java @@ -1,9 +1,6 @@ package com.guwan.backend.service; -import com.guwan.backend.pojo.dto.user.ChangePasswordDTO; -import com.guwan.backend.pojo.dto.user.LoginDto; -import com.guwan.backend.pojo.dto.user.RegisterDTO; -import com.guwan.backend.pojo.dto.user.UserDTO; +import com.guwan.backend.pojo.dto.user.*; public interface UserService { /** @@ -11,7 +8,7 @@ public interface UserService { * @param registerDTO * @return */ - UserDTO register(RegisterDTO registerDTO); + UserDTO register(BSRegisterDTO registerDTO); /** * 登录 diff --git a/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java b/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java index 93e2b4a..f2b5cde 100644 --- a/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java +++ b/src/main/java/com/guwan/backend/service/impl/UserServiceImpl.java @@ -5,10 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.guwan.backend.annotation.OperationLog; import com.guwan.backend.common.BusinessException; -import com.guwan.backend.pojo.dto.user.ChangePasswordDTO; -import com.guwan.backend.pojo.dto.user.LoginDto; -import com.guwan.backend.pojo.dto.user.RegisterDTO; -import com.guwan.backend.pojo.dto.user.UserDTO; +import com.guwan.backend.pojo.dto.user.*; import com.guwan.backend.pojo.entity.User; import com.guwan.backend.pojo.enums.UserEnums; import com.guwan.backend.mapper.UserMapper; @@ -49,7 +46,7 @@ public class UserServiceImpl extends ServiceImpl implements Us @Override @Transactional @OperationLog(description = "用户注册", operationType = "注册") - public UserDTO register(RegisterDTO request) { + public UserDTO register(BSRegisterDTO request) { // 检查用户名是否已存在 if (findByUsername(request.getUsername()) != null) { throw new IllegalArgumentException("用户名已存在"); @@ -59,11 +56,6 @@ public class UserServiceImpl extends ServiceImpl implements Us if (findByEmail(request.getEmail()) != null) { throw new IllegalArgumentException("邮箱已被注册"); } - - // 检查手机号是否已存在 - if (findByPhone(request.getPhone()) != null) { - throw new IllegalArgumentException("手机号已被注册"); - } // 校验邮箱验证码 String redisEmailCode = (String) redisUtil.get(request.getEmail()); @@ -72,25 +64,25 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new IllegalArgumentException("邮箱验证码错误"); } - // 校验手机号验证码 +/* // 校验手机号验证码 String redisPhoneCode = (String) redisUtil.get(request.getPhone()); if (!request.getPhoneCode().equals(redisPhoneCode)) { throw new IllegalArgumentException("手机验证码错误"); - } + }*/ User user = new User(); BeanUtils.copyProperties(request, user); user.setPassword(passwordEncoder.encode(request.getPassword())); - user.setPhone(request.getPhone()); + //user.setPhone(); user.setEmail(request.getEmail()); user.setStatus(1); userMapper.insert(user); redisUtil.del(request.getEmail()); - redisUtil.del(request.getPhone()); + // redisUtil.del(request.getPhone()); return convertToDTO(user); } @@ -99,6 +91,7 @@ public class UserServiceImpl extends ServiceImpl implements Us @OperationLog(description = "用户登录", operationType = "登录") public UserDTO login(LoginDto request) { User user = null; + System.out.println("request = " + request); if (request.getActiveTab().equals("account")) { @@ -139,7 +132,6 @@ public class UserServiceImpl extends ServiceImpl implements Us throw new IllegalArgumentException("账号已被禁用"); } - // 更新最后登录时间 user.setLastLoginTime(LocalDateTime.now()); userMapper.updateById(user); @@ -317,4 +309,4 @@ public class UserServiceImpl extends ServiceImpl implements Us // 删除数据时同时删除缓存 userMapper.deleteById(id); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/com/guwan/backend/util/MinioUtil.java b/src/main/java/com/guwan/backend/util/MinioUtil.java index 2ecf43e..8d33fb6 100644 --- a/src/main/java/com/guwan/backend/util/MinioUtil.java +++ b/src/main/java/com/guwan/backend/util/MinioUtil.java @@ -204,8 +204,6 @@ public class MinioUtil { // 使用 byte[] 创建 InputStream InputStream byteArrayInputStream = new ByteArrayInputStream(data); - - // 上传文件 minioClient.putObject( PutObjectArgs.builder() diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index adbc632..8f8ab5a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -126,10 +126,10 @@ springdoc: config: arcface-sdk: version: 4.1 - app-id: 5nPWymNAibvWTq6XPypUWxroyzjMScZ9RwVkDjCFgK32 - sdk-key: 7dsPvanADtYAP1TiiiFjTsms2mAU85m5duVwHChhumyV - active-key: 86C1-11T1-K131-FJQU - active-file: 86C111T1K131FJQU.dat + app-id: 2R54v3QUQ8uTynQr6ioF8wWHeqXJuJBv1VqhcWpj2Jmd + sdk-key: 6m5KtW1EV6x9hrnUGSiM1kQF2DXLf3hkRwqBKbvLyHFB + active-key: 86L1-11WX-R13T-CHZ6 + active-file: detect-pool-size: 16 compare-pool-size: 16 rec-face-thd: 0.8