package comxyp.controller; import comxyp.pojo.Dept; import comxyp.pojo.Vo; import comxyp.service.DeptService; import comxyp.service.EmployeeService; import comxyp.utils.DataGridViewResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.List; import java.util.Map; // 这个类是一个控制器类,专门用于处理与部门(Dept)相关的各种请求操作。 // 它使用了 Spring 框架的相关注解,通过 Spring 容器进行管理,能够接收和处理来自 Web 的请求, // 并将处理结果返回给客户端。 // 作为一个控制器,它在 Spring MVC 架构中扮演着重要的角色,负责接收用户请求、 // 调用相应的服务层方法处理请求,并将处理结果以合适的格式返回给用户。 // 这种控制器的设计遵循了 MVC 架构的设计原则,将用户界面和业务逻辑分离, // 提高了代码的可维护性、可扩展性和可测试性,使开发人员可以专注于不同层次的开发工作, // 例如,前端开发人员可以专注于界面的设计和开发,而后端开发人员可以专注于业务逻辑的实现。 @Controller // 此注解将该控制器映射到 "/dept" 路径下,意味着该控制器将处理所有以 "/dept" 开头的请求。 // 例如,"/dept/deptList"、"/dept/addDept" 等请求都将由这个控制器的相应方法来处理。 // 这样的映射方式有助于将不同模块的请求进行分类管理,方便维护和扩展。 // 它使得请求的路由清晰明确,当收到相应的请求时,Spring 框架会将请求分发到该控制器的相应方法进行处理, // 提高了请求处理的效率和准确性,同时也使得代码结构更加清晰,易于理解和维护。 @RequestMapping("/dept") public class DeptController { // 以下是自动注入的部门服务对象,通过 Spring 的依赖注入机制将其注入到该控制器中。 // 这种自动注入的方式是 Spring 框架的一个重要特性,它根据类型匹配的原则, // 在 Spring 容器中找到对应的 DeptService 实现类并注入到这里, // 使得我们可以方便地调用 DeptService 层提供的各种业务逻辑方法, // 而无需手动创建 DeptService 的实例,减少了代码的耦合性,提高了代码的可维护性和可测试性。 // 这有助于代码的模块化,将业务逻辑和控制逻辑分离,使得代码结构更加清晰。 // 当控制器需要执行部门相关的业务逻辑操作时,无需关心服务的具体实现细节, // 只需要调用注入的服务对象的相应方法即可,降低了代码的复杂性。 @Autowired private DeptService deptService; // 同样通过自动注入获取员工服务对象,这是为了在某些操作中, // 可能需要涉及员工信息的查询,例如在删除部门时,需要检查该部门下是否还有员工, // 或者在显示部门信息时可能会关联员工信息,从而方便调用相关的员工服务方法。 // 这样可以更好地实现不同服务层之间的协作,提高代码的复用性和可扩展性。 // 自动注入的机制确保了代码的简洁性,避免了繁琐的对象创建和管理过程, // 同时也遵循了依赖倒置原则,让高层模块(控制器)不依赖于低层模块(服务实现)的具体实现, // 而是依赖于抽象(服务接口),提高了代码的灵活性和可维护性。 @Autowired private EmployeeService employeeService; // 这个方法用于处理部门列表的请求。 // 当客户端发送一个请求到 "/dept/deptList" 时,该方法将被调用,并且会将结果以 JSON 格式返回给客户端。 // 它接收一个可选的 Vo 对象作为参数,这个 Vo 对象可能包含了一些筛选条件,例如部门名称、部门状态等, // 可以根据这些条件来查询相应的部门信息。 // 这种参数的设计使得该方法具有更强的灵活性,可以根据不同的筛选条件动态地查询部门信息。 // 这种动态查询的方式提高了系统的适应性,能够根据用户的不同需求返回相应的部门列表, // 满足了不同用户在不同场景下的需求,例如,用户可以根据部门名称筛选,也可以根据部门状态筛选等。 @RequestMapping("/deptList") @ResponseBody public DataGridViewResult deptList(@RequestParam(required = false) Vo vo) { // 首先,使用 PageHelper 进行分页设置。 // 这里设置从第 1 页开始,每页显示 20 条记录。 // PageHelper 是一个非常实用的分页插件,它会在后续的查询操作中自动添加分页所需的信息, // 比如在数据库查询时添加 LIMIT 子句,以实现分页功能。 // 这样可以避免手动编写复杂的分页 SQL 语句,提高开发效率。 // 分页功能的使用可以提高系统的性能,避免一次性加载大量数据, // 尤其是在部门数据量较大时,只加载当前页的数据,提高了用户的使用体验, // 同时也减轻了服务器的压力,避免资源的浪费。 PageHelper.startPage(1, 20); // 调用 DeptService 的 findAll 方法进行部门列表的查询操作。 // 该方法可能会根据传入的 vo 参数进行筛选,例如根据 vo 中的部门名称、状态等信息进行查询, // 并将查询结果存储在一个 List 集合中,其中包含了符合条件的部门信息。 // 这里体现了服务层和控制层的分工,控制层负责接收请求和处理结果,服务层负责具体的业务逻辑, // 如数据库查询、数据筛选等操作。 // 这种分层的设计使得不同层次的代码职责清晰,服务层专注于业务逻辑的实现, // 而控制层专注于请求的接收和结果的处理,提高了代码的可维护性和可扩展性。 List list = deptService.findAll(vo); // 使用 PageInfo 类将查询结果包装起来,创建一个分页对象。 // 这样做的目的是为了获取更多与分页相关的信息,例如总记录数、总页数、当前页的数据等, // 这些信息对于前端进行分页展示非常有用,比如可以显示当前是第几页、总共有多少页等信息。 // 这种分页信息的封装有助于前端更好地进行数据展示和用户交互, // 为用户提供良好的分页浏览体验,使用户能够方便地浏览大量的数据。 // 同时,PageInfo 提供了丰富的分页信息,方便前端进行分页导航的开发, // 例如,用户可以方便地跳转到上一页、下一页、指定页等操作。 PageInfo pageInfo = new PageInfo<>(list); // 将分页信息,包括总记录数和当前页的部门列表,封装到 DataGridViewResult 中返回。 // DataGridViewResult 可能是一个自定义的类,专门用于将分页数据进行统一的封装, // 方便前端进行解析和展示,使得前端能够以一种统一的数据格式接收和处理分页信息。 // 它将分页数据进行结构化封装,有助于前端代码的简洁性和可维护性, // 同时也方便前后端数据的交互和通信。 // 这种封装方式使得前后端之间的数据传输更加规范,避免了数据传输的混乱, // 提高了数据传输的可靠性和一致性,方便前端开发人员根据统一的格式进行数据的解析和处理。 return new DataGridViewResult(pageInfo.getTotal(), pageInfo.getList()); } // 这个方法用于处理添加部门的请求。 // 当客户端发送一个请求到 "/dept/addDept" 时,该方法会被调用,它接收一个 Dept 对象作为参数, // 这个 Dept 对象包含了要添加的部门的详细信息,如部门名称、部门描述、部门负责人等。 // 这种参数的传递方式使得添加部门的信息可以通过对象的形式进行传递,更加直观和易于管理。 // 以对象作为参数传递数据,可以方便地将多个属性封装在一起, // 提高了代码的可读性和可维护性,避免了多个零散参数的传递, // 同时也方便服务层对部门信息的整体处理,提高了代码的简洁性。 @RequestMapping("/addDept") @ResponseBody public String addDept(Dept dept) { // 创建一个 Map 来存储操作结果的信息,包括添加操作是否成功以及相应的提示消息。 // 这个 Map 可以存储不同类型的数据,使用键值对的形式存储,便于后续将其转换为 JSON 格式返回给客户端。 // 这样的存储方式非常灵活,可以方便地添加不同的信息,如操作结果、错误消息、警告信息等。 // 使用 Map 存储操作结果,为后续的结果处理提供了很大的灵活性, // 可以根据不同的情况添加不同的键值对,满足不同的信息需求, // 方便在前端进行各种不同情况的处理和显示。 Map map = new HashMap<>(); // 调用 DeptService 的 addDept 方法将部门信息添加到数据库中。 // 该方法会执行添加操作,并返回受影响的行数,受影响的行数表示操作的结果, // 例如,当返回值大于 0 时,表示成功添加了相应的部门记录; // 当返回值小于或等于 0 时,表示添加操作失败,可能是由于数据库操作错误或数据不合法等原因。 // 这里将控制层的请求处理和服务层的业务逻辑调用进行了分离, // 控制层负责调用服务层的方法并处理结果,服务层负责具体的数据库操作。 // 这种分层设计使得代码的职责更加明确,易于维护和扩展, // 服务层专注于业务逻辑的实现,控制层专注于请求的处理和结果的反馈。 int n = deptService.addDept(dept); // 如果添加操作成功,即受影响的行数大于 0。 if (n > 0) { // 在 Map 中设置 success 键为 true,表示添加操作成功。 // 这种使用键值对存储操作结果的方式便于在前端根据键名来获取操作结果的状态。 // 通过键值对的方式存储操作结果,可以方便前端开发人员根据键名获取相应的结果, // 并根据结果进行相应的操作,例如显示成功消息、更新界面等。 map.put("success", true); // 同时添加一条相应的消息,方便前端显示给用户,告知用户添加操作成功。 // 这条消息可以在前端以弹窗、提示框等形式展示给用户,让用户了解操作的结果。 // 为用户提供操作结果的反馈,提高了用户体验,使用户能够清楚地知道操作是否成功。 map.put("msg", "添加成功"); } else { // 如果添加操作失败,即受影响的行数小于或等于 0。 // 在 Map 中设置 success 键为 false,表示添加操作失败。 map.put("success", false); // 添加一条相应的消息,方便前端显示给用户,告知用户添加操作失败。 // 该消息可以为用户提供操作失败的反馈,帮助用户查找问题所在, // 例如,用户可以根据提示信息检查输入的数据是否正确, // 或者联系管理员解决可能的数据库问题。 map.put("msg", "添加失败"); } // 最后,使用阿里巴巴的 fastjson 工具将存储操作结果的 Map 转换为 JSON 字符串。 // 这样做是因为在 Web 开发中,通常将数据以 JSON 格式返回给客户端, // 以便客户端能够方便地解析和处理这些数据,而 fastjson 是一个高效的 JSON 处理工具。 // 它可以将 Java 对象快速地转换为 JSON 字符串,便于在网络中传输和前端解析。 // 使用 JSON 格式传输数据,是现代 Web 开发中前后端数据交互的常用方式, // 它具有良好的跨平台性和兼容性,方便不同编程语言和平台之间的数据交换, // 同时也方便前端使用 JavaScript 等语言进行数据的解析和处理。 return com.alibaba.fastjson.JSON.toJSONString(map); } // 这个方法用于处理修改部门信息的请求。 // 当客户端发送一个请求到 "/dept/updateDept" 时,该方法会被调用,它接收一个 Dept 对象作为参数, // 这个 Dept 对象包含了修改后的部门信息,如修改后的部门名称、部门描述、部门负责人等。 // 这种方式可以将修改后的信息统一封装在对象中传递,便于维护和管理。 // 以对象作为参数,可以更好地封装和传递复杂的数据结构, // 避免了多个参数的传递,提高了代码的可读性和可维护性, // 同时也方便服务层对修改后的部门信息进行整体处理。 @RequestMapping("/updateDept") @ResponseBody public String updateDept(Dept dept) { // 创建一个 Map 来存储操作结果的信息,包括修改操作是否成功以及相应的提示消息。 // 与添加部门操作类似,使用 Map 存储结果信息,方便后续的处理和结果返回。 // 使用 Map 存储操作结果,可以方便地存储和管理操作结果信息, // 为不同的操作结果提供了统一的存储和处理方式, // 同时也方便后续将结果转换为 JSON 格式进行数据传输。 Map map = new HashMap<>(); // 调用 DeptService 的 updateDept 方法来更新部门信息。 // 该方法会根据传入的 Dept 对象更新数据库中的部门信息,并返回受影响的行数, // 这个返回值可以用来判断更新操作是否成功。 // 服务层的 updateDept 方法负责根据传入的部门信息更新数据库中的数据, // 而控制层根据服务层的返回结果进行后续处理。 // 这种分层的设计将更新操作的业务逻辑和请求处理分离, // 使得服务层专注于更新操作的实现,控制层专注于结果的处理和反馈。 int n = deptService.updateDept(dept); // 如果更新操作成功,即受影响的行数大于 0。 if (n > 0) { // 在 Map 中设置 success 键为 true,表示更新操作成功。 map.put("success", true); // 同时添加一条相应的消息,方便前端显示给用户,告知用户更新操作成功。 // 此消息可以帮助用户了解操作是否完成,并提供用户操作反馈, // 让用户知道自己的操作是否已经生效,提高了用户体验。 map.put("msg", "修改成功"); } else { // 如果更新操作失败,即受影响的行数小于或等于 0。 // 在 Map 中设置 success 键为 false,表示更新操作失败。 map.put("success", false); // 添加一条相应的消息,方便前端显示给用户,告知用户更新操作失败。 // 这条消息可以帮助用户查找更新操作失败的原因,如数据不符合要求等。 // 用户可以根据消息进行相应的操作,例如检查修改的数据是否正确, // 或者尝试重新提交修改请求等。 map.put("msg", "修改失败"); } // 使用阿里巴巴的 fastjson 工具将存储操作结果的 Map 转换为 JSON 字符串, // 以便将结果以 JSON 格式返回给客户端,方便客户端进行解析和处理。 // 使用 fastjson 进行 JSON 转换,确保了数据的高效转换和传输, // 同时也遵循了前后端数据交互的通用规范,方便前端开发人员使用 JSON 数据进行界面更新和用户提示。 return com.alibaba.fastjson.JSON.toJSONString(map); } /** * 此方法用于检查某个部门下是否存在员工信息。 * * @param id 部门的唯一标识符,用于确定要检查的部门。 * @return 以 JSON 格式返回检查结果,包含是否存在员工信息和相应的消息。 * 当部门下存在员工时,将返回包含 exist 为 true 及相应消息的 JSON 数据; * 当部门下不存在员工时,将返回包含 exist 为 false 的 JSON 数据。 * 该方法主要用于在执行部门删除等操作前,对部门下的员工信息进行检查, * 以确保操作的安全性和合理性,避免误删有员工的部门, * 保障了数据的完整性和业务逻辑的正确性。 */ @RequestMapping("/checkDeptHasEmployee") @ResponseBody public String checkDeptHasEmployee(Integer id) { // 创建一个 Map 来存储检查结果的信息,包括是否存在员工以及相应的消息。 // 这里使用 Map 存储检查结果,方便后续转换为 JSON 格式返回给客户端。 // 使用 Map 存储检查结果,可以方便地存储和管理检查结果信息, // 为不同的检查结果提供了统一的存储和处理方式, // 同时也方便将结果转换为 JSON 格式