diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..f6906f2e --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# 已忽略包含查询文件的默认文件夹 +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/backend/README.md b/backend/README.md index 47503b22..14fb2b8b 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,4 +1,4 @@ -# zhjx 智慧教学项目 +# jwgl 教务项目 # 项目介绍 ## 技术架构 * jdk 21 diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/RoomRootApplication.java b/backend/roomroot-admin/src/main/java/com/roomroot/RoomRootApplication.java index cdf9c2c6..12209f25 100644 --- a/backend/roomroot-admin/src/main/java/com/roomroot/RoomRootApplication.java +++ b/backend/roomroot-admin/src/main/java/com/roomroot/RoomRootApplication.java @@ -19,6 +19,6 @@ public class RoomRootApplication { // System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(RoomRootApplication.class, args); - System.out.println("(♥◠‿◠)ノ゙ 风影随行启动成功 ლ(´ڡ`ლ)゙ \n"); + System.out.println("(♥◠‿◠)ノ゙ 启动成功 ლ(´ڡ`ლ)゙ \n"); } } diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/common/CaptchaController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/common/CaptchaController.java index 7e770f1d..c102ae5f 100644 --- a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/common/CaptchaController.java +++ b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/common/CaptchaController.java @@ -1,94 +1,33 @@ package com.roomroot.web.controller.common; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.concurrent.TimeUnit; -import jakarta.annotation.Resource; -import javax.imageio.ImageIO; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.FastByteArrayOutputStream; +import java.io.IOException; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import com.google.code.kaptcha.Producer; -import com.roomroot.common.config.RoomRootConfig; -import com.roomroot.common.constant.CacheConstants; -import com.roomroot.common.constant.Constants; import com.roomroot.common.core.domain.AjaxResult; -import com.roomroot.common.core.redis.RedisCache; -import com.roomroot.common.utils.sign.Base64; -import com.roomroot.common.utils.uuid.IdUtils; -import com.roomroot.system.service.ISysConfigService; /** * 验证码操作处理 - * + *

+ * 已去除验证码登录,本接口仅返回 captchaEnabled=false, + * 前端据此隐藏登录页的验证码输入。 + *

+ * * @author roomroot */ @RestController public class CaptchaController { - @Resource(name = "captchaProducer") - private Producer captchaProducer; - - @Resource(name = "captchaProducerMath") - private Producer captchaProducerMath; - - @Autowired - private RedisCache redisCache; - - @Autowired - private ISysConfigService configService; /** * 生成验证码 + *

已去除验证码登录,接口始终返回 captchaEnabled=false,不再生成验证码。

*/ @GetMapping("/captchaImage") public AjaxResult getCode(HttpServletResponse response) throws IOException { + // 已去除验证码登录:始终返回 captchaEnabled=false,前端据此隐藏验证码输入。 AjaxResult ajax = AjaxResult.success(); - boolean captchaEnabled = configService.selectCaptchaEnabled(); - ajax.put("captchaEnabled", captchaEnabled); - if (!captchaEnabled) - { - return ajax; - } - - // 保存验证码信息 - String uuid = IdUtils.simpleUUID(); - String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; - - String capStr = null, code = null; - BufferedImage image = null; - - // 生成验证码 - String captchaType = RoomRootConfig.getCaptchaType(); - if ("math".equals(captchaType)) - { - String capText = captchaProducerMath.createText(); - capStr = capText.substring(0, capText.lastIndexOf("@")); - code = capText.substring(capText.lastIndexOf("@") + 1); - image = captchaProducerMath.createImage(capStr); - } - else if ("char".equals(captchaType)) - { - capStr = code = captchaProducer.createText(); - image = captchaProducer.createImage(capStr); - } - - redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); - // 转换流信息写出 - FastByteArrayOutputStream os = new FastByteArrayOutputStream(); - try - { - ImageIO.write(image, "jpg", os); - } - catch (IOException e) - { - return AjaxResult.error(e.getMessage()); - } - - ajax.put("uuid", uuid); - ajax.put("img", Base64.encode(os.toByteArray())); + ajax.put("captchaEnabled", false); return ajax; } } diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/FacultyController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/FacultyController.java index 2a51e176..cccc8028 100644 --- a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/FacultyController.java +++ b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/FacultyController.java @@ -101,104 +101,6 @@ public class FacultyController { return Result.success(pageResult); } - // ======================== 教员管理 ======================== - - /** - * 新增教员(同时写入教员表和教员属性表) - *

教员属性中的非空字段由前端一并传入。

- */ - @PostMapping("/teacher/add") - public Result addTeacher(@RequestBody AddTeacherDTO dto) { - facultyService.addJYB(dto); - return Result.success(); - } - - /** - * 离职(逻辑删除)教员 - * - * @param jybh 教员编号 - */ - @PostMapping("/teacher/disable") - public Result disableTeacher(@RequestParam("jybh") String jybh) { - facultyService.disableJYB(jybh); - return Result.success(); - } - - /** - * 更新教员基本信息 - *

支持教学单位调整(修改教研室代号)、职称调整(修改职称、专业技术职务等级)。

- */ - @PostMapping("/teacher/update") - public Result updateTeacher(@RequestBody JYB entity) { - facultyService.updateJYB(entity); - return Result.success(); - } - - /** - * 根据编号查询教员详情 - * - * @param jybh 教员编号 - */ - @GetMapping("/teacher/get") - public Result getTeacher(@RequestParam("jybh") String jybh) { - JYB entity = facultyService.getJYBById(jybh); - return Result.success(entity); - } - - /** - * 分页条件查询教员列表 - *

- * 支持模糊查询参数: - *

    - *
  • jyxm — 教员姓名(模糊匹配)
  • - *
  • jysdh — 教研室代号(精确匹配)
  • - *
  • zc — 职称(模糊匹配)
  • - *
  • jylb — 教员类别(精确匹配)
  • - *
- *

- */ - @GetMapping("/teacher/list") - public Result> listTeacher( - @RequestParam(defaultValue = "1") Integer pageNum, - @RequestParam(defaultValue = "20") Integer pageSize, - @RequestParam(required = false) String jyxm, - @RequestParam(required = false) String jysdh, - @RequestParam(required = false) String zc, - @RequestParam(required = false) String jylb) { - PageQuery query = new PageQuery(); - query.setPageNum(pageNum); - query.setPageSize(pageSize); - JYB cond = new JYB(); - cond.setJyxm(jyxm); - cond.setJysdh(jysdh); - cond.setZc(zc); - cond.setJylb(jylb); - PageResult pageResult = facultyService.pageJYBDetail(query, cond); - return Result.success(pageResult); - } - - // ======================== 教员属性管理 ======================== - - /** - * 查询教员属性 - * - * @param jybh 教员编号 - */ - @GetMapping("/teacher/attribute/get") - public Result getTeacherAttribute(@RequestParam("jybh") String jybh) { - JYSX entity = facultyService.getJYSXByJYBH(jybh); - return Result.success(entity); - } - - /** - * 更新教员属性 - *

支持岗位调整(修改职务、职务时间)和技术等级调整(修改技术等级、技术等级时间)。

- */ - @PostMapping("/teacher/attribute/update") - public Result updateTeacherAttribute(@RequestBody JYSX entity) { - facultyService.updateJYSX(entity); - return Result.success(); - } // ======================== 年度综合评定查询 ======================== diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java new file mode 100644 index 00000000..ff3503c9 --- /dev/null +++ b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java @@ -0,0 +1,215 @@ +package com.roomroot.web.controller.jwgl; + +import com.roomroot.jwgl.dto.faculty.AddTeacherDTO; +import com.roomroot.jwgl.entity.JYB; +import com.roomroot.jwgl.entity.JYSB; +import com.roomroot.jwgl.entity.JYSX; +import com.roomroot.jwgl.service.FacultyService; +import com.roomroot.jwgl.unit.PageQuery; +import com.roomroot.jwgl.unit.PageResult; +import com.roomroot.jwgl.unit.Result; +import com.roomroot.jwgl.vo.faculty.TeacherListVO; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +/** + * 教研室管理(教研室管理 + * 教员管理 + * 教学任务计划管理 + * 选修课管理 + * 班次学期信息管理 + * 课程科目) + */ +@RestController +@RequestMapping("/jys") +public class JYSController { + + @Resource + private FacultyService facultyService; + // ======================== 教研室管理 ======================== + + /** + * 新增教研室 + */ + @PostMapping("/office/add") + public Result addOffice(@RequestBody JYSB entity) { + facultyService.addJYSB(entity); + return Result.success(); + } + + /** + * 停用(逻辑删除)教研室 + *不填,则系统自动创建 必填 必填 + * 教研室标识号 序号 教研室名称 简称 部系 + * 001 001 军事基础教研室 军基 基础部 + * @param jysdh 教研室代号 + */ + @PostMapping("/office/disable") + public Result disableOffice(@RequestParam("jysdh") String jysdh) { + facultyService.disableJYSB(jysdh); + return Result.success(); + } + + /** + * 更新教研室 + */ + @PostMapping("/office/update") + public Result updateOffice(@RequestBody JYSB entity) { + facultyService.updateJYSB(entity); + return Result.success(); + } + + /** + * 根据代号查询教研室详情 + * + * @param jysdh 教研室代号 + */ + @GetMapping("/office/get") + public Result getOffice(@RequestParam("jysdh") String jysdh) { + JYSB entity = facultyService.getJYSBById(jysdh); + return Result.success(entity); + } + + /** + * 分页条件查询教研室列表 + *

+ * 支持模糊查询参数: + *

    + *
  • jysmc — 教研室名称(模糊匹配)
  • + *
  • bx — 部系(模糊匹配)
  • + *
+ *

+ */ + @GetMapping("/office/list") + public Result> listOffice( + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "20") Integer pageSize, + @RequestParam(required = false) String jysdh, + @RequestParam(required = false) String jysmc, + @RequestParam(required = false) String bx) { + PageQuery query = new PageQuery(); + query.setPageNum(pageNum); + query.setPageSize(pageSize); + JYSB cond = new JYSB(); + cond.setJysdh(jysdh); + cond.setJysmc(jysmc); + cond.setBx(bx); + PageResult pageResult = facultyService.pageJYSB(query, cond); + return Result.success(pageResult); + } + + /** + * 教研室数据文件导入 + *

+ * 文件格式为 .xls,抬头与字段顺序: + * 教研室标识号, 序号, 教研室名称, 简称, 部系。 + * 教研室标识号不填则由系统自动创建;教研室名称和简称为必填字段, + * 未填写时返回"XX未填写";序号、停用、虚实类型等非空字段由后台自动填充。 + *

+ */ + @PostMapping("/office/import") + public Result importOffice(@RequestParam("file") MultipartFile file) throws Exception { + int count = facultyService.importJYSBFromExcel(file); + return Result.success("导入成功,共" + count + "条记录", count); + } + // ======================== 教员管理 ======================== + + /** + * 新增教员(同时写入教员表和教员属性表) + *

教员属性中的非空字段由前端一并传入。

+ */ + @PostMapping("/teacher/add") + public Result addTeacher(@RequestBody AddTeacherDTO dto) { + facultyService.addJYB(dto); + return Result.success(); + } + + /** + * 离职(逻辑删除)教员 + * + * @param jybh 教员编号 + */ + @PostMapping("/teacher/disable") + public Result disableTeacher(@RequestParam("jybh") String jybh) { + facultyService.disableJYB(jybh); + return Result.success(); + } + + /** + * 更新教员基本信息 + *

支持教学单位调整(修改教研室代号)、职称调整(修改职称、专业技术职务等级)。

+ */ + @PostMapping("/teacher/update") + public Result updateTeacher(@RequestBody JYB entity) { + facultyService.updateJYB(entity); + return Result.success(); + } + + /** + * 根据编号查询教员详情 + * + * @param jybh 教员编号 + */ + @GetMapping("/teacher/get") + public Result getTeacher(@RequestParam("jybh") String jybh) { + JYB entity = facultyService.getJYBById(jybh); + return Result.success(entity); + } + + /** + * 分页条件查询教员列表 + *

+ * 支持模糊查询参数: + *

    + *
  • jyxm — 教员姓名(模糊匹配)
  • + *
  • jysdh — 教研室代号(精确匹配)
  • + *
  • zc — 职称(模糊匹配)
  • + *
  • jylb — 教员类别(精确匹配)
  • + *
+ *

+ */ + @GetMapping("/teacher/list") + public Result> listTeacher( + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "20") Integer pageSize, + @RequestParam(required = false) String jyxm, + @RequestParam(required = false) String jysdh, + @RequestParam(required = false) String zc, + @RequestParam(required = false) String jylb) { + PageQuery query = new PageQuery(); + query.setPageNum(pageNum); + query.setPageSize(pageSize); + JYB cond = new JYB(); + cond.setJyxm(jyxm); + cond.setJysdh(jysdh); + cond.setZc(zc); + cond.setJylb(jylb); + PageResult pageResult = facultyService.pageJYBDetail(query, cond); + return Result.success(pageResult); + } + + // ======================== 教员属性管理 ======================== + + /** + * 查询教员属性 + * + * @param jybh 教员编号 + */ + @GetMapping("/teacher/attribute/get") + public Result getTeacherAttribute(@RequestParam("jybh") String jybh) { + JYSX entity = facultyService.getJYSXByJYBH(jybh); + return Result.success(entity); + } + + /** + * 更新教员属性 + *

支持岗位调整(修改职务、职务时间)和技术等级调整(修改技术等级、技术等级时间)。

+ */ + @PostMapping("/teacher/attribute/update") + public Result updateTeacherAttribute(@RequestBody JYSX entity) { + facultyService.updateJYSX(entity); + return Result.success(); + } + +} diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/LoginController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/LoginController.java deleted file mode 100644 index 775cedc6..00000000 --- a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/LoginController.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.roomroot.web.controller.jwgl; - -import com.roomroot.jwgl.dto.accountmanagement.AccountLoginDTO; -import com.roomroot.jwgl.dto.login.LoginDTO; -import com.roomroot.jwgl.entity.SSJG; -import com.roomroot.jwgl.mapper.SSJGMapper; -import com.roomroot.jwgl.service.AccountManagementService; -import com.roomroot.jwgl.unit.Result; -import com.roomroot.jwgl.utils.AccountManagementConstants; -import com.roomroot.jwgl.vo.accountmanagement.AccountLoginVO; -import com.roomroot.jwgl.vo.accountmanagement.AccountRoleVO; -import com.roomroot.jwgl.vo.login.LoginResultVO; -import com.roomroot.common.annotation.Anonymous; -import org.springframework.web.bind.annotation.*; - -import jakarta.annotation.Resource; -import java.util.List; -import java.util.stream.Collectors; - -/** - * 登录认证控制器 - *

- * 支持行政、教员、学员、管理员四种用户类型登录。 - * 管理员登录不需要单位(orgId),其余类型需选择单位。 - * 使用数据表:登录信息表(用户凭证)、教学管理机构/实施_机关(单位信息)。 - *

- */ -@RestController -@RequestMapping("/auth") -@Anonymous -public class LoginController { - - @Resource - private AccountManagementService accountManagementService; - - @Resource - private SSJGMapper ssjgMapper; - - /** - * 用户登录 - *

- * 根据登录名和密码验证身份,返回用户信息、角色和单位信息。 - *

- */ - @PostMapping("/login") - public Result login(@RequestBody LoginDTO loginDTO) { - // 1. 参数校验 - if (loginDTO.getLoginName() == null || loginDTO.getLoginName().isEmpty()) { - return Result.error(400, "登录名不能为空"); - } - if (loginDTO.getPassword() == null || loginDTO.getPassword().isEmpty()) { - return Result.error(400, "密码不能为空"); - } - if (loginDTO.getUserType() == null || loginDTO.getUserType().isEmpty()) { - return Result.error(400, "用户类型不能为空"); - } - - // 管理员登录不需要单位 - if (!"MANAGER".equals(loginDTO.getUserType()) && (loginDTO.getOrgId() == null || loginDTO.getOrgId().isEmpty())) { - return Result.error(400, "单位不能为空"); - } - - // 2. 参数转换(LoginDTO → AccountLoginDTO) - AccountLoginDTO accountLoginDTO = new AccountLoginDTO(); - accountLoginDTO.setLoginName(loginDTO.getLoginName()); - accountLoginDTO.setPassword(loginDTO.getPassword()); - - // 3. 委托 AccountManagementService 处理登录 - AccountLoginVO loginVO = accountManagementService.login(accountLoginDTO); - - // 4. 匹配用户类型 - String roleTypeCode = mapUserTypeToRoleCode(loginDTO.getUserType()); - List roles = loginVO.getRoles(); - boolean hasRole = roles.stream().anyMatch(r -> roleTypeCode.equals(r.getRoleType())); - if (!hasRole) { - return Result.error(403, "当前用户没有" + loginDTO.getUserType() + "权限"); - } - - // 5. 查询单位信息 - String orgName = null; - if (!"MANAGER".equals(loginDTO.getUserType())) { - for (AccountRoleVO role : roles) { - if (roleTypeCode.equals(role.getRoleType())) { - SSJG org = ssjgMapper.selectById(role.getTargetId()); - if (org != null) { - orgName = org.getJGMC(); - } - break; - } - } - } - - // 6. 返回值转换(AccountLoginVO → LoginResultVO) - LoginResultVO result = new LoginResultVO(); - result.setUserId(loginVO.getAccountId()); - result.setUserName(loginVO.getUserName()); - result.setLoginName(loginVO.getLoginName()); - result.setUserType(loginDTO.getUserType()); - result.setOrgId(loginDTO.getOrgId()); - result.setOrgName(orgName); - - List roleInfos = roles.stream().map(r -> { - LoginResultVO.RoleInfo ri = new LoginResultVO.RoleInfo(); - ri.setRoleType(r.getRoleType()); - ri.setRoleName(r.getRoleName()); - ri.setTargetId(r.getTargetId()); - ri.setTargetName(r.getTargetName()); - return ri; - }).collect(Collectors.toList()); - result.setRoles(roleInfos); - - return Result.success(result); - } - - /** - * 将前端用户类型映射为角色编码 - */ - private String mapUserTypeToRoleCode(String userType) { - switch (userType) { - case "ADMIN": - return AccountManagementConstants.ROLE_DEPARTMENT_PERSONNEL; - case "TEACHER": - return AccountManagementConstants.ROLE_TEACHER; - case "STUDENT": - return AccountManagementConstants.ROLE_STUDENT; - case "MANAGER": - return AccountManagementConstants.ROLE_DEPARTMENT_PERSONNEL; - default: - return userType; - } - } -} diff --git a/backend/roomroot-admin/src/main/resources/application.yml b/backend/roomroot-admin/src/main/resources/application.yml index 7f9bf86a..0352a5cc 100644 --- a/backend/roomroot-admin/src/main/resources/application.yml +++ b/backend/roomroot-admin/src/main/resources/application.yml @@ -106,7 +106,7 @@ mybatis-plus: # 搜索指定包别名 typeAliasesPackage: com.roomroot.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 - mapperLocations: classpath*:mapper/**/*Mapper.xml + mapperLocations: classpath*:mapper/**/*Mapper.xml,classpath*:com/roomroot/**/mapper/*.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml diff --git a/backend/roomroot-framework/src/main/java/com/roomroot/framework/config/SecurityConfig.java b/backend/roomroot-framework/src/main/java/com/roomroot/framework/config/SecurityConfig.java index 80ca0daa..3d8fe7d8 100644 --- a/backend/roomroot-framework/src/main/java/com/roomroot/framework/config/SecurityConfig.java +++ b/backend/roomroot-framework/src/main/java/com/roomroot/framework/config/SecurityConfig.java @@ -100,7 +100,7 @@ public class SecurityConfig .authorizeHttpRequests((requests) -> { permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll()); // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - requests.requestMatchers("/login", "/register", "/captchaImage").permitAll() + requests.requestMatchers("/login", "/register", "/captchaImage","/jys/teacher/list").permitAll() // 静态资源,可匿名访问 .requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll() .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll() diff --git a/backend/roomroot-framework/src/main/java/com/roomroot/framework/web/service/SysLoginService.java b/backend/roomroot-framework/src/main/java/com/roomroot/framework/web/service/SysLoginService.java index 21e59d9d..0a463067 100644 --- a/backend/roomroot-framework/src/main/java/com/roomroot/framework/web/service/SysLoginService.java +++ b/backend/roomroot-framework/src/main/java/com/roomroot/framework/web/service/SysLoginService.java @@ -62,9 +62,7 @@ public class SysLoginService */ public String login(String username, String password, String code, String uuid) { - // 验证码校验 - validateCaptcha(username, code, uuid); - // 登录前置校验 + // 已去除验证码校验:登录不再要求填写验证码 loginPreCheck(username, password); // 用户验证 Authentication authentication = null; diff --git a/backend/roomroot-jwgl/pom.xml b/backend/roomroot-jwgl/pom.xml index 3607a885..dcd89db5 100644 --- a/backend/roomroot-jwgl/pom.xml +++ b/backend/roomroot-jwgl/pom.xml @@ -35,4 +35,20 @@ test + + + + + src/main/resources + + + + src/main/java + + **/*.xml + + + + \ No newline at end of file diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/dto/login/LoginDTO.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/dto/login/LoginDTO.java deleted file mode 100644 index 0fb1313b..00000000 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/dto/login/LoginDTO.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.roomroot.jwgl.dto.login; - -import lombok.Data; - -/** - * 登录请求参数 - */ -@Data -public class LoginDTO { - - /** 单位编号(管理员登录时可为空) */ - private String orgId; - - /** 登录名/账号 */ - private String loginName; - - /** 密码 */ - private String password; - - /** 用户类型: ADMIN-行政 TEACHER-教员 STUDENT-学员 MANAGER-管理员 */ - private String userType; -} diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/entity/JYSB.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/entity/JYSB.java index 97970baa..ba54ca81 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/entity/JYSB.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/entity/JYSB.java @@ -26,7 +26,7 @@ public class JYSB { /** 停用 */ @TableField("停用") - private Boolean ty; + private Integer ty; /** 停用时间 */ @TableField("停用时间") @@ -42,7 +42,7 @@ public class JYSB { /** 虚实类型 */ @TableField("虚实类型") - private Boolean xslx; + private Integer xslx; /** 简称 */ @TableField("简称") @@ -50,6 +50,6 @@ public class JYSB { /** 机关性质 */ @TableField("机关性质") - private Boolean jgxz; + private Integer jgxz; } diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/XYJXQJBMapper.xml b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/XYJXQJBMapper.xml index 2ff00805..e2e3baa8 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/XYJXQJBMapper.xml +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/mapper/XYJXQJBMapper.xml @@ -140,7 +140,7 @@ ORDER BY q."创建时间" DESC - + diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/FacultyService.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/FacultyService.java index df330d3a..f203db27 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/FacultyService.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/FacultyService.java @@ -5,6 +5,7 @@ import com.roomroot.jwgl.entity.*; import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageResult; import com.roomroot.jwgl.vo.faculty.TeacherListVO; +import org.springframework.web.multipart.MultipartFile; /** * 教研室与教员管理服务接口 @@ -42,6 +43,16 @@ public interface FacultyService { */ PageResult pageJYSB(PageQuery query, JYSB cond); + /** + * 从 Excel 文件导入教研室数据。 + *

教研室标识号不填时系统自动创建;教研室名称、简称为必填字段,未填写返回"XX未填写"; + * 序号、停用、虚实类型等非空字段由后台按默认值填充。

+ * + * @param file 上传的 .xls 文件 + * @return 成功导入的记录数 + */ + int importJYSBFromExcel(MultipartFile file) throws Exception; + // ==================== 教员管理 ==================== /** diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/AffiliationSettingServiceImpl.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/AffiliationSettingServiceImpl.java index 7842b2d9..21f4703e 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/AffiliationSettingServiceImpl.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/AffiliationSettingServiceImpl.java @@ -986,7 +986,7 @@ public class AffiliationSettingServiceImpl implements AffiliationSettingService vo.setDepartment(researchOffice.getBx()); // 第三步:将停用标志转换为更直观的启用状态,并保留停用时间。 - vo.setEnabled(!Boolean.TRUE.equals(researchOffice.getTy())); + vo.setEnabled(1); vo.setDisabledAt(researchOffice.getTysj()); // 第四步:复制虚实类型、备注、序号和机关性质。 @@ -1032,7 +1032,7 @@ public class AffiliationSettingServiceImpl implements AffiliationSettingService vo.setResearchOfficeName(researchOffice.getJysmc()); vo.setAbbreviation(researchOffice.getJc()); vo.setDepartment(researchOffice.getBx()); - vo.setEnabled(!Boolean.TRUE.equals(researchOffice.getTy())); + vo.setEnabled(1); vo.setDisabledAt(researchOffice.getTysj()); vo.setVirtual(researchOffice.getXslx()); vo.setRemark(researchOffice.getBz()); diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/FacultyServiceImpl.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/FacultyServiceImpl.java index 509ee427..e57c7c43 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/FacultyServiceImpl.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/FacultyServiceImpl.java @@ -6,14 +6,19 @@ import com.roomroot.jwgl.entity.*; import com.roomroot.jwgl.mapper.*; import com.roomroot.jwgl.mapper.*; import com.roomroot.jwgl.service.FacultyService; +import com.roomroot.jwgl.unit.BusinessException; import com.roomroot.jwgl.unit.PageQuery; import com.roomroot.jwgl.unit.PageResult; +import com.roomroot.jwgl.utils.ExcelParseUtil; +import com.roomroot.jwgl.utils.UuidUtil; import com.roomroot.jwgl.vo.faculty.TeacherListVO; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import jakarta.annotation.Resource; import java.time.LocalDateTime; +import java.util.List; /** * 教研室与教员管理服务实现类 @@ -44,9 +49,9 @@ public class FacultyServiceImpl implements FacultyService { @Override @Transactional public void addJYSB(JYSB entity) { - if (entity.getTy() == null) { - entity.setTy(false); - } + entity.setTy(0); + entity.setXslx(0); + entity.setJgxz(0); jysbMapper.insert(entity); } @@ -55,7 +60,7 @@ public class FacultyServiceImpl implements FacultyService { public void disableJYSB(String jysdh) { JYSB entity = new JYSB(); entity.setJysdh(jysdh); - entity.setTy(true); + entity.setTy(1); entity.setTysj(LocalDateTime.now()); jysbMapper.updateById(entity); } @@ -79,6 +84,45 @@ public class FacultyServiceImpl implements FacultyService { query.getPageNum(), query.getPageSize()); } + @Override + @Transactional(rollbackFor = Exception.class) + public int importJYSBFromExcel(MultipartFile file) throws Exception { + if (file == null || file.isEmpty()) { + throw new BusinessException("导入文件不能为空"); + } + List list = ExcelParseUtil.parseJYSBExcel( + file.getInputStream(), file.getOriginalFilename()); + if (list.isEmpty()) { + throw new BusinessException("Excel中无有效数据"); + } + for (int i = 0; i < list.size(); i++) { + JYSB entity = list.get(i); + // 必填字段校验:教研室名称、简称 + if (entity.getJysmc() == null || entity.getJysmc().trim().isEmpty()) { + throw new BusinessException("教研室名称未填写"); + } + if (entity.getJc() == null || entity.getJc().trim().isEmpty()) { + throw new BusinessException("简称未填写"); + } + // 教研室标识号不填,则系统自动创建 + if (entity.getJysdh() == null || entity.getJysdh().trim().isEmpty()) { + entity.setJysdh(UuidUtil.getUUID()); + } + // 序号为空时默认取行号 + if (entity.getXh() == null || entity.getXh().trim().isEmpty()) { + entity.setXh(String.valueOf(i + 1)); + } + // 停用默认为0 + entity.setTy(0); + // 虚实类型默认为0 + entity.setXslx(0); + //机关类型默认为0 + entity.setJgxz(0); + jysbMapper.insert(entity); + } + return list.size(); + } + // ==================== 教员管理 ==================== @Override diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/utils/ExcelParseUtil.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/utils/ExcelParseUtil.java index cfdd1a9b..00dc84fc 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/utils/ExcelParseUtil.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/utils/ExcelParseUtil.java @@ -5,6 +5,7 @@ import com.roomroot.jwgl.dto.courserunning.SemesterImportDTO; import com.roomroot.jwgl.dto.courserunning.SingleCourseImportDTO; import com.roomroot.jwgl.dto.departmentpersonnel.DepartmentPersonnelCreateDTO; import com.roomroot.jwgl.entity.JXSSJH; +import com.roomroot.jwgl.entity.JYSB; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; @@ -169,6 +170,51 @@ public class ExcelParseUtil { return result; } + /** + * 解析教研室数据导入 Excel 文件。 + * Excel 表头顺序:教研室标识号、序号、教研室名称、简称、部系 + * + * @param inputStream Excel 文件输入流 + * @param fileName 文件名 + * @return 教研室实体列表(默认字段与必填校验由外部完成) + * @throws Exception 解析异常 + */ + public static List parseJYSBExcel(InputStream inputStream, String fileName) throws Exception { + List result = new ArrayList<>(); + + Workbook workbook = createWorkbook(inputStream, fileName); + try { + Sheet sheet = workbook.getSheetAt(0); + int firstDataRow = 1; + int lastRowNum = sheet.getLastRowNum(); + + for (int rowNum = firstDataRow; rowNum <= lastRowNum; rowNum++) { + Row row = sheet.getRow(rowNum); + if (row == null) { + continue; + } + + JYSB entity = new JYSB(); + // 教研室标识号 + entity.setJysdh(getCellStringValue(row.getCell(0))); + // 序号 + entity.setXh(getCellStringValue(row.getCell(1))); + // 教研室名称 + entity.setJysmc(getCellStringValue(row.getCell(2))); + // 简称 + entity.setJc(getCellStringValue(row.getCell(3))); + // 部系 + entity.setBx(getCellStringValue(row.getCell(4))); + + result.add(entity); + } + } finally { + workbook.close(); + } + + return result; + } + private static Workbook createWorkbook(InputStream inputStream, String fileName) throws Exception { String name = fileName == null ? "" : fileName.toLowerCase(); if (!name.endsWith(".xlsx") && !name.endsWith(".xls")) { diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeAffiliationVO.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeAffiliationVO.java index f8b36a3c..5283eac1 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeAffiliationVO.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeAffiliationVO.java @@ -48,7 +48,7 @@ public class ResearchOfficeAffiliationVO { /** * 是否启用,由数据库“停用”字段反向转换得到。 */ - private Boolean enabled; + private Integer enabled; /** * 停用时间。 @@ -58,7 +58,7 @@ public class ResearchOfficeAffiliationVO { /** * 是否为虚拟教研室。 */ - private Boolean virtual; + private Integer virtual; /** * 教研室备注。 @@ -73,5 +73,5 @@ public class ResearchOfficeAffiliationVO { /** * 是否具有机关性质。 */ - private Boolean organNature; + private Integer organNature; } diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeVO.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeVO.java index a1a7ac51..70422e31 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeVO.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/affiliationsetting/ResearchOfficeVO.java @@ -33,7 +33,7 @@ public class ResearchOfficeVO { /** * 是否启用,由数据库“停用”字段反向转换得到。 */ - private Boolean enabled; + private Integer enabled; /** * 停用时间。 @@ -43,7 +43,7 @@ public class ResearchOfficeVO { /** * 是否为虚拟教研室。 */ - private Boolean virtual; + private Integer virtual; /** * 教研室备注。 @@ -56,7 +56,7 @@ public class ResearchOfficeVO { private String sequenceNumber; /** - * 是否具有机关性质。 + * 机关性质。 */ - private Boolean organNature; + private Integer organNature; } diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/login/LoginResultVO.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/login/LoginResultVO.java deleted file mode 100644 index c0449ee9..00000000 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/vo/login/LoginResultVO.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.roomroot.jwgl.vo.login; - -import lombok.Data; - -import java.util.List; - -/** - * 登录响应结果 - */ -@Data -public class LoginResultVO { - - /** 用户编号(登录信息表编号) */ - private String userId; - - /** 用户姓名 */ - private String userName; - - /** 登录账号 */ - private String loginName; - - /** 用户类型: ADMIN-行政 TEACHER-教员 STUDENT-学员 MANAGER-管理员 */ - private String userType; - - /** 单位编号 */ - private String orgId; - - /** 单位名称 */ - private String orgName; - - /** 角色列表 */ - private List roles; - - @Data - public static class RoleInfo { - private String roleType; - private String roleName; - private String targetId; - private String targetName; - } -}