Crazy hai 6 meses
pai
achega
c1781fbf2c
Modificáronse 28 ficheiros con 1249 adicións e 98 borrados
  1. 6 0
      yudao-module-md/yudao-module-md-biz/pom.xml
  2. 1 36
      yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/controller/admin/AcsController.java
  3. 2 2
      yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/controller/admin/vo/UserImportExcelVO.java
  4. 47 35
      yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/service/AcsService.java
  5. 19 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java
  6. 109 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/StudentAttendanceController.java
  7. 43 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendancePageReqVO.java
  8. 53 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendanceRespVO.java
  9. 44 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendanceSaveReqVO.java
  10. 76 24
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
  11. 5 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java
  12. 140 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/UserAchievementController.java
  13. 37 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementPageReqVO.java
  14. 43 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementRespVO.java
  15. 37 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementSaveReqVO.java
  16. 2 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java
  17. 76 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/studentAttendance/StudentAttendanceDO.java
  18. 2 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java
  19. 56 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/userAchievement/UserAchievementDO.java
  20. 89 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/studentAttendance/StudentAttendanceMapper.java
  21. 2 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
  22. 51 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/userAchievement/UserAchievementMapper.java
  23. 59 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/studentAttendance/StudentAttendanceService.java
  24. 84 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/studentAttendance/StudentAttendanceServiceImpl.java
  25. 3 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java
  26. 6 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
  27. 60 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/userAchievement/UserAchievementService.java
  28. 97 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/userAchievement/UserAchievementServiceImpl.java

+ 6 - 0
yudao-module-md/yudao-module-md-biz/pom.xml

@@ -82,6 +82,12 @@
             <version>3.3.4</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-system-biz</artifactId>
+            <version>2.2.0-jdk8-snapshot</version>
+            <scope>compile</scope>
+        </dependency>
 
         <!-- Test 测试相关 -->
 <!--        <dependency>-->

+ 1 - 36
yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/controller/admin/AcsController.java

@@ -192,41 +192,6 @@ public class AcsController {
 
     }
 
-    //  TODO 感觉你们没沟通好,博物馆写过相当像的代码,直接拿过来用就可以了,我放在最下面
-
-    @PostMapping("/addPhotos")
-    @Operation(summary = "添加照片照片组")
-    public String addPhotos(@RequestPart("photoGroup") UserPhotosVO userPhotosVO ) throws Exception {
-        // 处理压缩包文件
-        if (userPhotosVO.getFile() != null) {
-            Path path = Files.createTempDirectory("photoGroup");
-            try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(userPhotosVO.getFile()))) {
-                ZipEntry entry = zipIn.getNextEntry();
-                while (entry != null) {
-                    String filePath = Paths.get(path.toString(), entry.getName()).toString();
-                    if (!Files.exists(Paths.get(filePath).getParent())) {
-                        Files.createDirectories(Paths.get(filePath).getParent());
-                    }
-                    try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(filePath)))) {
-                        byte[] bytesIn = new byte[4096];
-                        int read = 0;
-                        while ((read = zipIn.read(bytesIn)) != -1) {
-                            bos.write(bytesIn, 0, read);
-                        }
-                    }
-                    zipIn.closeEntry();
-                    entry = zipIn.getNextEntry();
-                }
-            }
-            // 处理解压后的照片
-            // 这里添加处理解压后照片的逻辑
-            // 例如,保存照片到数据库,或者进行人脸检测等操作
-        }
-
-        // 返回成功结果
-        return ("Batch upload successful");
-    }
-
     // TODO 他的目标是Excel导入标本的同时导入标本的图片,你只需要修改成导入用户的同时导入人脸识别图片,同时下发到机器中。
     @PostMapping("/import-data")
     @Operation(summary = "信息导入以及图片导入")
@@ -242,7 +207,7 @@ public class AcsController {
                                                    @RequestParam(value = "updateSupport", required = false, defaultValue = "true") Boolean updateSupport) {
         try {
             acsService.importData(excelFile, imageFile, updateSupport);
-            return CommonResult.success("标本及图片导入成功");
+            return CommonResult.success("用户信息及图片导入成功");
         } catch (Exception e) {
             return CommonResult.error(500, "导入过程中发生错误: " + e.getMessage());
         }

+ 2 - 2
yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/controller/admin/vo/UserImportExcelVO.java

@@ -23,8 +23,8 @@ public class UserImportExcelVO {
     @ExcelProperty("学号")
     private String employeeNo;
 
-    @ExcelProperty("人脸照片")
-    private String faceURL;
+//    @ExcelProperty("人脸照片")
+//    private String faceURL;
 
 //    @ExcelProperty("手机号码")
 //    private String mobile;

+ 47 - 35
yudao-module-md/yudao-module-md-biz/src/main/java/cn/iocoder/yudao/module/md/service/AcsService.java

@@ -15,6 +15,9 @@ import cn.iocoder.yudao.module.md.controller.admin.vo.UserImportExcelVO;
 import cn.iocoder.yudao.module.md.controller.admin.vo.UserImportRespVO;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import com.sun.jna.Native;
 import org.apache.tomcat.util.http.fileupload.FileUtils;
 import org.json.JSONException;
@@ -314,20 +317,28 @@ public class AcsService {
 //            AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
 //            if (existUser == null) {
             // 异步添加用户信息
+            AdminUserDO user = userService.findUserByUserNumber(importUser.getEmployeeNo());
             CompletableFuture<Void> addUserFuture = CompletableFuture.runAsync(() -> {
                 try {
-                    UserManage.addUserInfo(lUserID, importUser.getEmployeeNo(), importUser.getName());
-
+                    //用户名称与那users表里的相同
+                    if (user.getNickname().equals(importUser.getName())) {
+                        UserManage.addUserInfo(lUserID, user.getUserNumber(), user.getNickname());
+                        System.out.println("添加用户成功");
+                    }
                 } catch (UnsupportedEncodingException | InterruptedException | JSONException e) {
                     throw new RuntimeException("添加用户信息失败: " + e.getMessage(), e);
                 }
             });
 
-            // 在用户信息添加成功后添加人脸
+            // 在用户信息添加成功后添加人脸,人脸照片通过学号去找
             addUserFuture.thenRun(() -> {
                 try {
-                    FaceManage.addFaceByUrl(lUserID, importUser.getEmployeeNo(), importUser.getFaceURL());
-                    System.out.println("照片路由"+importUser.getFaceURL());
+                    String photoUrl =user.getPhotoUrl();
+                    //照片不为空
+                    if ( photoUrl!=null){
+                        FaceManage.addFaceByUrl(lUserID, user.getUserNumber(), photoUrl);
+                        System.out.println("照片路由"+photoUrl);
+                    }
                 } catch (JSONException e) {
                     throw new RuntimeException("添加人脸失败: " + e.getMessage(), e);
                 }
@@ -352,6 +363,9 @@ public class AcsService {
     }
 
 
+    @Resource
+    private AdminUserService userService;
+
     @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
     public String importImages(MultipartFile file) throws Exception {
         // 校验文件类型
@@ -364,6 +378,11 @@ public class AcsService {
             ZipEntry entry;
             while ((entry = zipInputStream.getNextEntry()) != null) {
                 if (!entry.isDirectory()) {
+
+                    //获取去除后缀名的文件名,需要设置成学号
+                    String newFileName = entry.getName().substring(0, entry.getName().lastIndexOf('.'));
+                    System.out.println("文件名:"+newFileName);
+
                     File newFile = new File(tempDir, entry.getName());
                     // 进行解压
                     try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
@@ -373,37 +392,30 @@ public class AcsService {
                             bos.write(buffer, 0, len);
                         }
                     }
+                    File[] imageFiles = tempDir.listFiles();
+                    if (imageFiles != null) {
+                        for (File imageFile : imageFiles) {
+                            String imageName = imageFile.getName();
+                            if (!isValidImageName(imageName)) {
+                                // 如果不符合格式,抛出异常或记录日志
+                                System.err.println("无效的图片格式: " + imageName);
+                                continue;
+                            }
+                            // 上传文件并获取 URL
+                            AdminUserDO user = userService.findUserByUserNumber(newFileName);
+                            String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+                            user.setPhotoUrl(photoUrl);
+                            userService.updateUser( (BeanUtils.toBean(user, UserSaveReqVO.class)));
+                            System.out.println("照片路径: " + photoUrl);
+                            //给对应学号的人的照片添加
+                            addFaceByUrl(newFileName,photoUrl);
+                        }
+                    }
+                    System.out.println(111111);
                 }
             }
         }
 
-        // 处理每个图片文件
-        File[] imageFiles = tempDir.listFiles();
-        if (imageFiles != null) {
-            for (File imageFile : imageFiles) {
-                String imageName = imageFile.getName();
-                if (!isValidImageName(imageName)) {
-                    // 如果不符合格式,抛出异常或记录日志
-                    System.err.println("无效的图片格式: " + imageName);
-                    continue;
-                }
-
-                // TODO 这里根据图片名称获取对应的学生信息,然后更新学生信息,并且将这些信息下发到机器
-                //  查询方法我先不写了
-//                AdminUserRespDTO user = adminUserApi.getUser(imageName);
-
-                String imagePath = fileApi.createFile(Files.readAllBytes(imageFile.toPath()));
-
-                // user.setImagePath(imagePath); TODO 插入新的人脸图片路径
-                // 更新标本信息中的图片路径
-
-                // TODO 更新信息 adminUserApi.updateUser(specimenInfo);
-
-                // TODO  在这一步就可以导入人脸信息了 addFaceByUrl(user.getSudentId,imagePath)
-
-            }
-        }
-
         // 清理临时文件
         FileUtils.deleteDirectory(tempDir);
         return "导入成功";
@@ -425,7 +437,7 @@ public class AcsService {
     public void importData(MultipartFile excelFile, MultipartFile imageFile, boolean updateSupport) throws Exception {
 
         // TODO 这里用的字段太少了,下午和晚上要把字段完善,能够导入
-        // 1. 导入标本
+        // 1. 导入用户信息
         List<UserImportExcelVO> list = ExcelUtils.read(excelFile, UserImportExcelVO.class);
         UserImportRespVO importRespVO = importUserList(list, updateSupport);
 
@@ -433,8 +445,8 @@ public class AcsService {
         String imageImportResult = importImages(imageFile);
 
         // 可以根据需要记录导入结果
-        System.out.println("标本导入结果: " + importRespVO);
-        System.out.println("标本图片导入结果: " + imageImportResult);
+        System.out.println("用户信息导入结果: " + importRespVO);
+        System.out.println("图片导入结果: " + imageImportResult);
     }
 
 }

+ 19 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/DeptController.java

@@ -8,7 +8,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptRespVO;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSimpleRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -30,6 +32,8 @@ public class DeptController {
 
     @Resource
     private DeptService deptService;
+    @Resource
+    private AdminUserService adminUserService;
 
     @PostMapping("create")
     @Operation(summary = "创建部门")
@@ -78,6 +82,21 @@ public class DeptController {
     @PreAuthorize("@ss.hasPermission('system:dept:query')")
     public CommonResult<DeptRespVO> getDept(@RequestParam("id") Long id) {
         DeptDO dept = deptService.getDept(id);
+        //新加的负责人用户信息
+        AdminUserDO user  =adminUserService.getUser(dept.getLeaderUserId());
+        dept.setUser(user);
+        System.out.println(dept);
+        return success(BeanUtils.toBean(dept, DeptRespVO.class));
+    }
+
+    @GetMapping("/GetUserDept")
+    @Operation(summary = "获得登录人员工作间信息")
+    public CommonResult<DeptRespVO> getUserDept() {
+        DeptDO dept = deptService.getUserDept();
+        //新加的负责人用户信息
+        AdminUserDO user  =adminUserService.getUser(dept.getLeaderUserId());
+        dept.setUser(user);
+        System.out.println(dept);
         return success(BeanUtils.toBean(dept, DeptRespVO.class));
     }
 

+ 109 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/StudentAttendanceController.java

@@ -0,0 +1,109 @@
+package cn.iocoder.yudao.module.system.controller.admin.studentAttendance;
+
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.studentAttendance.StudentAttendanceDO;
+import cn.iocoder.yudao.module.system.service.studentAttendance.StudentAttendanceService;
+
+@Tag(name = "管理后台 - 学生考勤记录")
+@RestController
+@RequestMapping("/system/student-attendance")
+@Validated
+public class StudentAttendanceController {
+
+    @Resource
+    private StudentAttendanceService studentAttendanceService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建学生考勤记录")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:create')")
+    public CommonResult<Integer> createStudentAttendance(@Valid @RequestBody StudentAttendanceSaveReqVO createReqVO) {
+        return success(studentAttendanceService.createStudentAttendance(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新学生考勤记录")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:update')")
+    public CommonResult<Boolean> updateStudentAttendance(@Valid @RequestBody StudentAttendanceSaveReqVO updateReqVO) {
+        studentAttendanceService.updateStudentAttendance(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除学生考勤记录")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:delete')")
+    public CommonResult<Boolean> deleteStudentAttendance(@RequestParam("id") Integer id) {
+        studentAttendanceService.deleteStudentAttendance(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得学生考勤记录")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:query')")
+    public CommonResult<StudentAttendanceRespVO> getStudentAttendance(@RequestParam("id") Integer id) {
+        StudentAttendanceDO studentAttendance = studentAttendanceService.getStudentAttendance(id);
+        return success(BeanUtils.toBean(studentAttendance, StudentAttendanceRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得学生考勤记录分页")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:query')")
+    public CommonResult<PageResult<StudentAttendanceRespVO>> getStudentAttendancePage(@Valid StudentAttendancePageReqVO pageReqVO) {
+        PageResult<StudentAttendanceDO> pageResult = studentAttendanceService.getStudentAttendancePage(pageReqVO);
+        System.out.println(pageResult);
+        return success(BeanUtils.toBean(pageResult, StudentAttendanceRespVO.class));
+    }
+    @GetMapping("/errorPage")
+    @Operation(summary = "获得学生考勤异常记录分页")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:ErrorQuery')")
+    public CommonResult<PageResult<StudentAttendanceRespVO>> getStudentAttendanceErrorPage(@Valid StudentAttendancePageReqVO pageReqVO) {
+        PageResult<StudentAttendanceDO> pageResult = studentAttendanceService.getStudentAttendanceErrorPage(pageReqVO);
+        System.out.println(pageResult);
+        return success(BeanUtils.toBean(pageResult, StudentAttendanceRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出学生考勤记录 Excel")
+    @PreAuthorize("@ss.hasPermission('system:student-attendance:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportStudentAttendanceExcel(@Valid StudentAttendancePageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<StudentAttendanceDO> list = studentAttendanceService.getStudentAttendancePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "学生考勤记录.xls", "数据", StudentAttendanceRespVO.class,
+                        BeanUtils.toBean(list, StudentAttendanceRespVO.class));
+    }
+
+//    @GetMapping("/test")
+//    public CommonResult<PageResult<StudentAttendanceRespVO>> test(@Valid StudentAttendancePageReqVO pageReqVO) {
+//
+//    }
+
+}

+ 43 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendancePageReqVO.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo;
+
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 学生考勤记录分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class StudentAttendancePageReqVO extends PageParam {
+
+    @Schema(description = "学生id", example = "8981")
+    private Integer studentId;
+
+    @Schema(description = "学生名称", example = "赵六")
+    private String studentName;
+
+    @Schema(description = "工作间id", example = "114")
+    private String deptId;
+
+    @Schema(description = "日期")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDate[] date;
+
+    @Schema(description = "打卡状态 0正常,1迟到、2早退、3缺勤、4请假", example = "1")
+    private String clockInStatus;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    @Schema(description = "备注原因", example = "你猜")
+    private String remark;
+
+}

+ 53 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendanceRespVO.java

@@ -0,0 +1,53 @@
+package cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 学生考勤记录 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class StudentAttendanceRespVO {
+
+    @Schema(description = "自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30731")
+    @ExcelProperty("自增id")
+    private Integer id;
+
+    @Schema(description = "学生id", requiredMode = Schema.RequiredMode.REQUIRED, example = "8981")
+    @ExcelProperty("学生id")
+    private Integer studentId;
+
+    @Schema(description = "学生名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @ExcelProperty("学生名称")
+    private String studentName;
+
+    @Schema(description = "工作间id", requiredMode = Schema.RequiredMode.REQUIRED, example = "22266")
+    @ExcelProperty("工作间id")
+    private String deptId;
+
+    @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("日期")
+    private LocalDate date;
+
+    @Schema(description = "打卡时间")
+    @ExcelProperty("打卡时间")
+    private LocalDateTime clockInTime;
+
+    @Schema(description = "打卡状态 0正常,1迟到、2早退、3缺勤、4请假", example = "1")
+    @ExcelProperty("打卡状态 0正常,1迟到、2早退、3缺勤、4请假")
+    private String clockInStatus;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "备注原因", example = "你猜")
+    @ExcelProperty("备注原因")
+    private String remark;
+
+}

+ 44 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/studentAttendance/vo/StudentAttendanceSaveReqVO.java

@@ -0,0 +1,44 @@
+package cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 学生考勤记录新增/修改 Request VO")
+@Data
+public class StudentAttendanceSaveReqVO {
+
+    @Schema(description = "自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "30731")
+    private Integer id;
+
+    @Schema(description = "学生id", requiredMode = Schema.RequiredMode.REQUIRED, example = "8981")
+    @NotNull(message = "学生id不能为空")
+    private Integer studentId;
+
+    @Schema(description = "学生名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @NotEmpty(message = "学生名称不能为空")
+    private String studentName;
+
+    @Schema(description = "工作间id", requiredMode = Schema.RequiredMode.REQUIRED, example = "22266")
+    @NotEmpty(message = "工作间id不能为空")
+    private String deptId;
+
+    @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "日期不能为空")
+    private LocalDate date;
+
+    @Schema(description = "打卡时间")
+    private LocalDateTime clockInTime;
+
+    @Schema(description = "打卡状态 0正常,1迟到、2早退、3缺勤、4请假", example = "1")
+    private String clockInStatus;
+
+    @Schema(description = "备注原因", example = "你猜")
+    private String remark;
+
+}

+ 76 - 24
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.service.file.FileService;
@@ -366,28 +367,79 @@ public class UserController {
         ExcelUtils.write(response, "用户导入模板.xls", "用户列表", graduateStudentImportExcelVO.class, list);
     }
 
+
+    //废弃了的照片组
+//    @PostMapping("/addPhotos")
+//    @Operation(summary = "增加照片组")
+//    public CommonResult<Long> addPhotos(@RequestParam("groupName") String groupName,
+//                                        @RequestParam("groupDescription") String groupDescription,
+//                                        @RequestParam("file") MultipartFile file) throws Exception {
+//        if (!file.getOriginalFilename().endsWith(".zip")) {
+//            throw new IllegalArgumentException("上传文件必须是压缩包");
+//        }
+//        // 创建照片组
+//        UserPhotoGroupSaveReqVO createVO = new UserPhotoGroupSaveReqVO();
+//        createVO.setGroupName(groupName);
+//        createVO.setGroupDescription(groupDescription);
+//        Long groupId = userPhotoGroupService.createUserPhotoGroup(createVO);
+//
+//        // 文件格式检查
+//        try (InputStream inputStream = file.getInputStream()) {
+//            java.util.zip.ZipInputStream zipStream = new ZipInputStream(inputStream);
+//            ZipEntry entry;
+//            while ((entry = zipStream.getNextEntry())!= null) {
+//                System.out.println("文件格式错误");
+//            }
+//        }
+//
+//        // 创建临时目录存放解压后的文件
+//        File tempDir = Files.createTempDirectory("photo_group_images").toFile();
+//        try (ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream())) {
+//            ZipEntry entry;
+//            while ((entry = zipInputStream.getNextEntry())!= null) {
+//                if (!entry.isDirectory()) {
+//                    File newFile = new File(tempDir, entry.getName());
+//                    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
+//                        byte[] buffer = new byte[1024];
+//                        int len;
+//                        while ((len = zipInputStream.read(buffer)) > 0) {
+//                            bos.write(buffer, 0, len);
+//                        }
+//                    }
+//                    System.out.println("到这里");
+//                    try {
+//                        // 上传文件并获取 URL
+//                        String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+//                        System.out.println("照片路径: " + photoUrl);
+//                        // 保存照片信息到数据库
+//                        UserPhotosSaveReqVO photo = new UserPhotosSaveReqVO();
+//                        photo.setPhotoGroupId(groupId);
+//                        photo.setPhotoUrl(photoUrl);
+//                        userPhotosService.createUserPhotos(photo);
+//                    } catch (Exception e) {
+//                        throw new RuntimeException("上传照片失败:" + e.getMessage());
+//                    }
+//                }
+//                zipInputStream.closeEntry();
+//            }
+//        } finally {
+//            // 删除临时目录
+//            Files.walk(tempDir.toPath())
+//                    .sorted(Comparator.reverseOrder())
+//                    .map(Path::toFile)
+//                    .forEach(File::delete);
+//        }
+//        return success(groupId);
+//    }
+
+    //完成
     @PostMapping("/addPhotos")
-    @Operation(summary = "增加照片组")
-    public CommonResult<Long> addPhotos(@RequestParam("groupName") String groupName,
-                                        @RequestParam("groupDescription") String groupDescription,
+    @Operation(summary = "批量增加照片")
+    public CommonResult<String> addPhotos(
                                         @RequestParam("file") MultipartFile file) throws Exception {
         if (!file.getOriginalFilename().endsWith(".zip")) {
             throw new IllegalArgumentException("上传文件必须是压缩包");
         }
-        // 创建照片组
-        UserPhotoGroupSaveReqVO createVO = new UserPhotoGroupSaveReqVO();
-        createVO.setGroupName(groupName);
-        createVO.setGroupDescription(groupDescription);
-        Long groupId = userPhotoGroupService.createUserPhotoGroup(createVO);
-
-        // 文件格式检查
-        try (InputStream inputStream = file.getInputStream()) {
-            java.util.zip.ZipInputStream zipStream = new ZipInputStream(inputStream);
-            ZipEntry entry;
-            while ((entry = zipStream.getNextEntry())!= null) {
-                System.out.println("文件格式错误");
-            }
-        }
 
         // 创建临时目录存放解压后的文件
         File tempDir = Files.createTempDirectory("photo_group_images").toFile();
@@ -395,6 +447,9 @@ public class UserController {
             ZipEntry entry;
             while ((entry = zipInputStream.getNextEntry())!= null) {
                 if (!entry.isDirectory()) {
+                    //获取去除后缀名的文件名,需要设置成学号
+                    String newFileName = entry.getName().substring(0, entry.getName().lastIndexOf('.'));
+                    System.out.println("文件名:"+newFileName);
                     File newFile = new File(tempDir, entry.getName());
                     try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) {
                         byte[] buffer = new byte[1024];
@@ -403,17 +458,14 @@ public class UserController {
                             bos.write(buffer, 0, len);
                         }
                     }
-                    System.out.println("到这里");
                     try {
                         // 上传文件并获取 URL
+                        AdminUserDO user = userService.findUserByUserNumber(newFileName);
                         String photoUrl = fileApi.createFile(Files.readAllBytes(newFile.toPath()));
+                        user.setPhotoUrl(photoUrl);
+                        userService.updateUser( (BeanUtils.toBean(user, UserSaveReqVO.class)));
                         System.out.println("照片路径: " + photoUrl);
-                        // 获取新创建的照片组 ID
                         // 保存照片信息到数据库
-                        UserPhotosSaveReqVO photo = new UserPhotosSaveReqVO();
-                        photo.setPhotoGroupId(groupId);
-                        photo.setPhotoUrl(photoUrl);
-                        userPhotosService.createUserPhotos(photo);
                     } catch (Exception e) {
                         throw new RuntimeException("上传照片失败:" + e.getMessage());
                     }
@@ -427,6 +479,6 @@ public class UserController {
                     .map(Path::toFile)
                     .forEach(File::delete);
         }
-        return success(groupId);
+        return success("操作成功");
     }
 }

+ 5 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserSaveReqVO.java

@@ -77,4 +77,9 @@ public class UserSaveReqVO {
                 || (ObjectUtil.isAllNotEmpty(password)); // 新增时,必须都传递 password
     }
 
+    //新加的
+    @Schema(description ="照片url")
+    @DiffLogField(name = "照片url")
+    private String  photoUrl;
+
 }

+ 140 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/UserAchievementController.java

@@ -0,0 +1,140 @@
+package cn.iocoder.yudao.module.system.controller.admin.userAchievement;
+
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.system.service.dept.DeptService;
+import cn.iocoder.yudao.module.system.service.user.AdminUserService;
+import cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+import cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.userAchievement.UserAchievementDO;
+import cn.iocoder.yudao.module.system.service.userAchievement.UserAchievementService;
+
+@Tag(name = "管理后台 - 成果")
+@RestController
+@RequestMapping("/system/user-achievement")
+@Validated
+public class UserAchievementController {
+
+    @Resource
+    private UserAchievementService userAchievementService;
+
+
+    @Resource
+    private DeptService deptService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建成果")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:create')")
+    public CommonResult<Integer> createUserAchievement(@Valid @RequestBody UserAchievementSaveReqVO createReqVO) {
+        Long deptId = SecurityFrameworkUtils.getLoginUserDeptId(); //获取当前登录人的id
+        createReqVO.setDept_id(deptId);
+        return success(userAchievementService.createUserAchievement(createReqVO));
+    }
+
+    @PostMapping("/selfCreate")
+    @Operation(summary = "创建自己的成果")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:selfCreate')")
+    public CommonResult<Integer> createSelfAchievement(@Valid @RequestBody SelfAchievementSaveReqVO createReqVO) {
+        Long deptId = SecurityFrameworkUtils.getLoginUserDeptId(); //获取当前登录人的部门id
+        Long userId = SecurityFrameworkUtils.getLoginUserId();
+        String username = SecurityFrameworkUtils.getLoginUserNickname();
+
+        createReqVO.setUserId(userId);
+        createReqVO.setDept_id(deptId);
+        createReqVO.setUserName(username);
+
+        return success(userAchievementService.createSelfAchievement(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新成果")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:update')")
+    public CommonResult<Boolean> updateUserAchievement(@Valid @RequestBody UserAchievementSaveReqVO updateReqVO) {
+        userAchievementService.updateUserAchievement(updateReqVO);
+        return success(true);
+    }
+
+    @PutMapping("/selfUpdate")
+    @Operation(summary = "更新自己的成果")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:selfUpdate')")
+    public CommonResult<Boolean> updateUserAchievement(@Valid @RequestBody SelfAchievementSaveReqVO updateReqVO) {
+        userAchievementService.updateSelfAchievement(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除成果")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:delete')")
+    public CommonResult<Boolean> deleteUserAchievement(@RequestParam("id") Integer id) {
+        userAchievementService.deleteUserAchievement(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得成果")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:detail')")
+    public CommonResult<UserAchievementRespVO> getUserAchievement(@RequestParam("id") Integer id) {
+        UserAchievementDO userAchievement = userAchievementService.getUserAchievement(id);
+        return success(BeanUtils.toBean(userAchievement, UserAchievementRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得工作间下成员成果分页")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:query')")
+    public CommonResult<PageResult<UserAchievementRespVO>> getUserAchievementPage(@Valid UserAchievementPageReqVO pageReqVO) {
+        PageResult<UserAchievementDO>pageResult = userAchievementService.getUserAchievementPage(pageReqVO);
+
+        System.out.println(pageResult);
+        return success(BeanUtils.toBean(pageResult, UserAchievementRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出成果 Excel")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportUserAchievementExcel(@Valid UserAchievementPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<UserAchievementDO> list = userAchievementService.getUserAchievementPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "成果.xls", "数据", UserAchievementRespVO.class,
+                        BeanUtils.toBean(list, UserAchievementRespVO.class));
+    }
+
+    @GetMapping("/selfPage")
+    @Operation(summary = "获得自己的成果分页")
+    @PreAuthorize("@ss.hasPermission('system:user-achievement:selfQuery')")
+    public CommonResult<PageResult<UserAchievementRespVO>> getSelfAchievementPage(@Valid UserAchievementPageReqVO pageReqVO) {
+        PageResult<UserAchievementDO>pageResult = userAchievementService.getSelfAchievementPage(pageReqVO);
+
+        System.out.println(pageResult);
+        return success(BeanUtils.toBean(pageResult, UserAchievementRespVO.class));
+    }
+
+}

+ 37 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementPageReqVO.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 成果分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class UserAchievementPageReqVO extends PageParam {
+
+    @Schema(description = "用户id", example = "25783")
+    private Long userId;
+
+    @Schema(description = "成果名称", example = "赵六")
+    private String achievementName;
+
+    @Schema(description = "1论文,2专利,3著作", example = "2")
+    private String achievementType;
+
+    @Schema(description = "用户名称", example = "张三")
+    private String userName;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    @Schema(description = "照片详情url")
+    private String detail;
+
+}

+ 43 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementRespVO.java

@@ -0,0 +1,43 @@
+package cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 成果 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class UserAchievementRespVO {
+
+    @Schema(description = "自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7131")
+    @ExcelProperty("自增id")
+    private Integer id;
+
+    @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25783")
+    @ExcelProperty("用户id")
+    private Long userId;
+
+    @Schema(description = "成果名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @ExcelProperty("成果名称")
+    private String achievementName;
+
+    @Schema(description = "1论文,2专利,3著作", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @ExcelProperty("1论文,2专利,3著作")
+    private String achievementType;
+
+    @Schema(description = "用户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    @ExcelProperty("用户名称")
+    private String userName;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "照片详情url")
+    @ExcelProperty("照片详情url")
+    private String detail;
+
+}

+ 37 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/userAchievement/vo/UserAchievementSaveReqVO.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import javax.validation.constraints.*;
+
+@Schema(description = "管理后台 - 成果新增/修改 Request VO")
+@Data
+public class UserAchievementSaveReqVO {
+
+    @Schema(description = "自增id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7131")
+    private Integer id;
+
+    @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "25783")
+    @NotNull(message = "用户id不能为空")
+    private Long userId;
+
+    @Schema(description = "成果名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @NotEmpty(message = "成果名称不能为空")
+    private String achievementName;
+
+    @Schema(description = "1论文,2专利,3著作", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    @NotEmpty(message = "成果类型不能为空")
+    private String achievementType;
+
+    @Schema(description = "用户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    @NotEmpty(message = "用户名称不能为空")
+    private String userName;
+
+    @Schema(description = "照片详情url")
+    private String detail;
+
+    @Schema(description = "工作间id")
+    private Long dept_id;
+
+}

+ 2 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/DeptDO.java

@@ -63,4 +63,6 @@ public class DeptDO extends TenantBaseDO {
      */
     private Integer status;
 
+    private AdminUserDO user;
+
 }

+ 76 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/studentAttendance/StudentAttendanceDO.java

@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.studentAttendance;
+
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 学生考勤记录 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("system_student_attendance")
+@KeySequence("system_student_attendance_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class StudentAttendanceDO extends BaseDO {
+
+    /**
+     * 自增id
+     */
+    @TableId
+    private Integer id;
+    /**
+     * 学生id
+     */
+    private Integer studentId;
+
+    /**
+     * 学生名称
+     */
+    private String studentName;
+    /**
+     * 工作间id
+     */
+    private String deptId;
+    /**
+     * 日期
+     */
+    private LocalDate date;
+    /**
+     * 打卡时间
+     */
+    private LocalDateTime clockInTime;
+    /**
+     * 打卡状态 0正常,1迟到、2早退、3缺勤、4请假
+     */
+    private String clockInStatus;
+    /**
+     * 备注原因
+     */
+    private String remark;
+
+//    邮箱测试
+//    @TableField(exist = false)
+//    private String email;
+
+    // 手机号测试
+    @TableField(exist = false)
+    private String phone;
+
+    //测试字段内嵌,即这个用户的信息都在里面
+    @TableField(exist = false)
+    private AdminUserDO user;
+
+}

+ 2 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java

@@ -134,4 +134,6 @@ public class AdminUserDO extends TenantBaseDO {
     @TableField(exist = false)
     private String supervisorMobile;
 
+    private String photoUrl;
+
 }

+ 56 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/userAchievement/UserAchievementDO.java

@@ -0,0 +1,56 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.userAchievement;
+
+import lombok.*;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 成果 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("system_user_achievement")
+@KeySequence("system_user_achievement_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserAchievementDO extends BaseDO {
+
+    /**
+     * 自增id
+     */
+    @TableId
+    private Integer id;
+    /**
+     * 用户id
+     */
+    private Integer userId;
+    /**
+     * 成果名称
+     */
+    private String achievementName;
+    /**
+     * 1论文,2专利,3著作
+     */
+    private String achievementType;
+    /**
+     * 用户名称
+     */
+    private String userName;
+
+    /**
+     * 工作间id
+     */
+    private Long deptId;
+    /**
+     * 照片详情url
+     */
+    private String detail;
+
+}

+ 89 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/studentAttendance/StudentAttendanceMapper.java

@@ -0,0 +1,89 @@
+package cn.iocoder.yudao.module.system.dal.mysql.studentAttendance;
+
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.system.dal.dataobject.studentAttendance.StudentAttendanceDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo.*;
+import org.apache.ibatis.annotations.Select;
+
+/**
+ * 学生考勤记录 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface StudentAttendanceMapper extends BaseMapperX<StudentAttendanceDO> {
+
+    default PageResult<StudentAttendanceDO> selectPage(StudentAttendancePageReqVO reqVO) {
+        Long dept_id = SecurityFrameworkUtils.getLoginUserDeptId();
+        // 创建查询包装器
+        LambdaQueryWrapperX<StudentAttendanceDO> queryWrapper = new LambdaQueryWrapperX<>();
+
+        // 添加查询条件
+        queryWrapper.eqIfPresent(StudentAttendanceDO::getStudentId, reqVO.getStudentId())
+                .likeIfPresent(StudentAttendanceDO::getStudentName, reqVO.getStudentName())
+                .eqIfPresent(StudentAttendanceDO::getDeptId, reqVO.getDeptId())
+                .betweenIfPresent(StudentAttendanceDO::getDate, reqVO.getDate())
+                .eqIfPresent(StudentAttendanceDO::getClockInStatus, reqVO.getClockInStatus())
+                .betweenIfPresent(StudentAttendanceDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(StudentAttendanceDO::getRemark, reqVO.getRemark())
+                // 只出现在老师工作间下面的学生考勤情况
+                .inSql(StudentAttendanceDO::getDeptId, String.valueOf(dept_id))
+                .orderByDesc(StudentAttendanceDO::getId);
+
+
+        return selectPage(reqVO, queryWrapper);
+    }
+
+
+    default PageResult<StudentAttendanceDO> selectErrorPage(StudentAttendancePageReqVO reqVO) {
+        Long dept_id = SecurityFrameworkUtils.getLoginUserDeptId();
+
+        LambdaQueryWrapperX<StudentAttendanceDO> queryWrapperX =new LambdaQueryWrapperX<>();
+         return selectPage(reqVO, queryWrapperX
+                 .likeIfPresent(StudentAttendanceDO::getStudentName, reqVO.getStudentName())
+                 .betweenIfPresent(StudentAttendanceDO::getDate, reqVO.getDate())
+                 .betweenIfPresent(StudentAttendanceDO::getCreateTime, reqVO.getCreateTime())
+                 .eqIfPresent(StudentAttendanceDO::getClockInStatus, reqVO.getClockInStatus())
+                 // 只出现在老师工作间下面的学生考勤情况
+                 .inSql(StudentAttendanceDO::getDeptId, String.valueOf(dept_id))
+                 // 大于等于1
+                 .ge(StudentAttendanceDO::getClockInStatus,1)
+                 .orderByDesc(StudentAttendanceDO::getId));
+
+    }
+
+    // 测试关联查询,映射到对应实体类字段
+    default PageResult<StudentAttendanceDO> test(StudentAttendancePageReqVO reqVO) {
+        Long deptId = SecurityFrameworkUtils.getLoginUserDeptId();
+        // 创建 MPJLambdaWrapper 用于联合查询
+        MPJLambdaWrapper<StudentAttendanceDO> wrapper = new MPJLambdaWrapper<>();
+
+        // 添加查询条件到 wrapper
+        wrapper.selectAll(StudentAttendanceDO.class)
+                //.select(AdminUserDO::getEmail)// 选择 email 的所有字段自动注入到email里面
+
+                //.selectAs(AdminUserDO::getEmail,StudentAttendanceDO::getPhone) // 选择 AdminUserDO 中的邮箱字段注入到phone里面
+
+                //内嵌email字段,
+                .selectAssociation(AdminUserDO.class,StudentAttendanceDO::getUser)
+
+                .leftJoin(AdminUserDO.class, AdminUserDO::getId, StudentAttendanceDO::getStudentId) // 左连接
+                .likeIfExists(StudentAttendanceDO::getStudentName, reqVO.getStudentName())
+                .eqIfExists(StudentAttendanceDO::getClockInStatus, reqVO.getClockInStatus())
+                // 只出现在老师工作间下面的学生考勤情况
+                .inSql(StudentAttendanceDO::getDeptId, String.valueOf(deptId))
+                // 考勤状态大于等于1
+                .ge(StudentAttendanceDO::getClockInStatus, 1)
+                .orderByDesc(StudentAttendanceDO::getId);
+        // 使用 selectPage 方法返回分页结果
+        return selectJoinPage( reqVO,StudentAttendanceDO.class,wrapper);
+    }
+}

+ 2 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java

@@ -166,5 +166,7 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
     default List<AdminUserDO> selectListByDeptIds(Collection<Long> deptIds) {
         return selectList(AdminUserDO::getDeptId, deptIds);
     }
+    @Select("SELECT * FROM system_users WHERE user_number = #{userNumber}")
+    AdminUserDO findUserByUserNumber(String userNumber);
 
 }

+ 51 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/userAchievement/UserAchievementMapper.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.system.dal.mysql.userAchievement;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.system.dal.dataobject.userAchievement.UserAchievementDO;
+import org.apache.ibatis.annotations.Mapper;
+import cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo.*;
+
+/**
+ * 成果 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface UserAchievementMapper extends BaseMapperX<UserAchievementDO> {
+
+    default PageResult<UserAchievementDO> selectPage(UserAchievementPageReqVO reqVO) {
+        Long loginID = SecurityFrameworkUtils.getLoginUserId(); //
+        System.out.println(loginID);
+        return selectPage(reqVO, new LambdaQueryWrapperX<UserAchievementDO>()
+                .eqIfPresent(UserAchievementDO::getUserId, reqVO.getUserId())
+                .likeIfPresent(UserAchievementDO::getAchievementName, reqVO.getAchievementName())
+                .eqIfPresent(UserAchievementDO::getAchievementType, reqVO.getAchievementType())
+                .likeIfPresent(UserAchievementDO::getUserName, reqVO.getUserName())
+                .betweenIfPresent(UserAchievementDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(UserAchievementDO::getDetail, reqVO.getDetail())
+                //找到这个工作室下的人员成果
+                .inSql(UserAchievementDO::getDeptId,String.format("SELECT dept_id FROM system_users WHERE id = %d", loginID))
+                .orderByDesc(UserAchievementDO::getId));
+    }
+    //获取登录人员自己的
+    default PageResult<UserAchievementDO> selectSelfPage(UserAchievementPageReqVO reqVO) {
+        Long loginID = SecurityFrameworkUtils.getLoginUserId(); //
+        System.out.println(loginID);
+        return selectPage(reqVO, new LambdaQueryWrapperX<UserAchievementDO>()
+                .eqIfPresent(UserAchievementDO::getUserId, reqVO.getUserId())
+                .likeIfPresent(UserAchievementDO::getAchievementName, reqVO.getAchievementName())
+                .eqIfPresent(UserAchievementDO::getAchievementType, reqVO.getAchievementType())
+                .likeIfPresent(UserAchievementDO::getUserName, reqVO.getUserName())
+                .betweenIfPresent(UserAchievementDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(UserAchievementDO::getDetail, reqVO.getDetail())
+                //找到这个自己的成果
+                .inSql(UserAchievementDO::getUserId,String.format("SELECT id FROM system_users WHERE id = %d", loginID))
+                .orderByDesc(UserAchievementDO::getId));
+    }
+
+}

+ 59 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/studentAttendance/StudentAttendanceService.java

@@ -0,0 +1,59 @@
+package cn.iocoder.yudao.module.system.service.studentAttendance;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.studentAttendance.StudentAttendanceDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+
+/**
+ * 学生考勤记录 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface StudentAttendanceService {
+
+    /**
+     * 创建学生考勤记录
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Integer createStudentAttendance(@Valid StudentAttendanceSaveReqVO createReqVO);
+
+    /**
+     * 更新学生考勤记录
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateStudentAttendance(@Valid StudentAttendanceSaveReqVO updateReqVO);
+
+    /**
+     * 删除学生考勤记录
+     *
+     * @param id 编号
+     */
+    void deleteStudentAttendance(Integer id);
+
+    /**
+     * 获得学生考勤记录
+     *
+     * @param id 编号
+     * @return 学生考勤记录
+     */
+    StudentAttendanceDO getStudentAttendance(Integer id);
+
+    /**
+     * 获得学生考勤记录分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 学生考勤记录分页
+     */
+    PageResult<StudentAttendanceDO> getStudentAttendancePage(StudentAttendancePageReqVO pageReqVO);
+
+    PageResult<StudentAttendanceDO> getStudentAttendanceErrorPage(StudentAttendancePageReqVO pageReqVO);
+
+    PageResult<StudentAttendanceDO> test(StudentAttendancePageReqVO pageReqVO);
+
+}

+ 84 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/studentAttendance/StudentAttendanceServiceImpl.java

@@ -0,0 +1,84 @@
+package cn.iocoder.yudao.module.system.service.studentAttendance;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import cn.iocoder.yudao.module.system.controller.admin.studentAttendance.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.studentAttendance.StudentAttendanceDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import cn.iocoder.yudao.module.system.dal.mysql.studentAttendance.StudentAttendanceMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
+
+/**
+ * 学生考勤记录 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class StudentAttendanceServiceImpl implements StudentAttendanceService {
+
+    @Resource
+    private StudentAttendanceMapper studentAttendanceMapper;
+
+    @Override
+    public Integer createStudentAttendance(StudentAttendanceSaveReqVO createReqVO) {
+        // 插入
+        StudentAttendanceDO studentAttendance = BeanUtils.toBean(createReqVO, StudentAttendanceDO.class);
+        studentAttendanceMapper.insert(studentAttendance);
+        // 返回
+        return studentAttendance.getId();
+    }
+
+    @Override
+    public void updateStudentAttendance(StudentAttendanceSaveReqVO updateReqVO) {
+        // 校验存在
+        validateStudentAttendanceExists(updateReqVO.getId());
+        // 更新
+        StudentAttendanceDO updateObj = BeanUtils.toBean(updateReqVO, StudentAttendanceDO.class);
+        studentAttendanceMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteStudentAttendance(Integer id) {
+        // 校验存在
+        validateStudentAttendanceExists(id);
+        // 删除
+        studentAttendanceMapper.deleteById(id);
+    }
+
+    private void validateStudentAttendanceExists(Integer id) {
+        if (studentAttendanceMapper.selectById(id) == null) {
+            throw exception(STUDENT_ATTENDANCE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public StudentAttendanceDO getStudentAttendance(Integer id) {
+        return studentAttendanceMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<StudentAttendanceDO> getStudentAttendancePage(StudentAttendancePageReqVO pageReqVO) {
+        return studentAttendanceMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public PageResult<StudentAttendanceDO> getStudentAttendanceErrorPage(StudentAttendancePageReqVO pageReqVO) {
+        return studentAttendanceMapper.selectErrorPage(pageReqVO);
+    }
+
+    @Override
+    public PageResult<StudentAttendanceDO> test(StudentAttendancePageReqVO pageReqVO) {
+        return studentAttendanceMapper.test(pageReqVO);
+    }
+
+}

+ 3 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfi
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
 
 import javax.validation.Valid;
 import java.io.InputStream;
@@ -217,6 +218,8 @@ public interface AdminUserService {
      */
     boolean isPasswordMatch(String rawPassword, String encodedPassword);
 
+    AdminUserDO findUserByUserNumber(String userNumber);
+
 }
 
 

+ 6 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java

@@ -33,7 +33,6 @@ import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
@@ -554,5 +553,11 @@ public class AdminUserServiceImpl implements AdminUserService {
         return passwordEncoder.encode(password);
     }
 
+    //查学号查到学生
+    @Override
+    public AdminUserDO findUserByUserNumber(String userNumber){
+        return  userMapper.findUserByUserNumber(userNumber);
+    }
+
 }
 

+ 60 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/userAchievement/UserAchievementService.java

@@ -0,0 +1,60 @@
+package cn.iocoder.yudao.module.system.service.userAchievement;
+
+import java.util.*;
+import javax.validation.*;
+import cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.userAchievement.UserAchievementDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+
+/**
+ * 成果 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface UserAchievementService {
+
+    /**
+     * 创建成果
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Integer createUserAchievement(@Valid UserAchievementSaveReqVO createReqVO);
+
+    Integer createSelfAchievement(@Valid SelfAchievementSaveReqVO createReqVO);
+
+    /**
+     * 更新成果
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateUserAchievement(@Valid UserAchievementSaveReqVO updateReqVO);
+    void updateSelfAchievement(@Valid SelfAchievementSaveReqVO updateReqVO);
+
+    /**
+     * 删除成果
+     *
+     * @param id 编号
+     */
+    void deleteUserAchievement(Integer id);
+
+    /**
+     * 获得成果
+     *
+     * @param id 编号
+     * @return 成果
+     */
+    UserAchievementDO getUserAchievement(Integer id);
+
+    /**
+     * 获得成果分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 成果分页
+     */
+    PageResult<UserAchievementDO> getUserAchievementPage(UserAchievementPageReqVO pageReqVO);
+
+    PageResult<UserAchievementDO> getSelfAchievementPage(UserAchievementPageReqVO pageReqVO);
+
+}

+ 97 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/userAchievement/UserAchievementServiceImpl.java

@@ -0,0 +1,97 @@
+package cn.iocoder.yudao.module.system.service.userAchievement;
+
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import cn.iocoder.yudao.module.system.controller.admin.userAchievement.vo.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.userAchievement.UserAchievementDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import cn.iocoder.yudao.module.system.dal.mysql.userAchievement.UserAchievementMapper;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
+
+/**
+ * 成果 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class UserAchievementServiceImpl implements UserAchievementService {
+
+    @Resource
+    private UserAchievementMapper userAchievementMapper;
+
+    @Override
+    public Integer createUserAchievement(UserAchievementSaveReqVO createReqVO) {
+        // 插入
+        UserAchievementDO userAchievement = BeanUtils.toBean(createReqVO, UserAchievementDO.class);
+        userAchievementMapper.insert(userAchievement);
+        // 返回
+        return userAchievement.getId();
+    }
+
+    public Integer createSelfAchievement(SelfAchievementSaveReqVO createReqVO) {
+        // 插入
+        UserAchievementDO userAchievement = BeanUtils.toBean(createReqVO, UserAchievementDO.class);
+        userAchievementMapper.insert(userAchievement);
+        // 返回
+        return userAchievement.getId();
+    }
+
+    @Override
+    public void updateUserAchievement(UserAchievementSaveReqVO updateReqVO) {
+        // 校验存在
+        validateUserAchievementExists(updateReqVO.getId());
+        // 更新
+        UserAchievementDO updateObj = BeanUtils.toBean(updateReqVO, UserAchievementDO.class);
+        userAchievementMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void updateSelfAchievement(SelfAchievementSaveReqVO updateReqVO) {
+        // 校验存在
+        validateUserAchievementExists(updateReqVO.getId());
+        // 更新
+        UserAchievementDO updateObj = BeanUtils.toBean(updateReqVO, UserAchievementDO.class);
+        userAchievementMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteUserAchievement(Integer id) {
+        // 校验存在
+        validateUserAchievementExists(id);
+        // 删除
+        userAchievementMapper.deleteById(id);
+    }
+
+    private void validateUserAchievementExists(Integer id) {
+        if (userAchievementMapper.selectById(id) == null) {
+            throw exception(USER_ACHIEVEMENT_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public UserAchievementDO getUserAchievement(Integer id) {
+        return userAchievementMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<UserAchievementDO> getUserAchievementPage(UserAchievementPageReqVO pageReqVO) {
+        return userAchievementMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public PageResult<UserAchievementDO> getSelfAchievementPage(UserAchievementPageReqVO pageReqVO) {
+        return userAchievementMapper.selectSelfPage(pageReqVO);
+    }
+
+
+}