package com.controller; import java.io.File; import java.math.BigDecimal; import java.net.URL; import java.text.SimpleDateFormat; import com.alibaba.fastjson.JSONObject; import java.util.*; import org.springframework.beans.BeanUtils; import javax.servlet.http.HttpServletRequest; import org.springframework.web.context.ContextLoader; import javax.servlet.ServletContext; import com.service.TokenService; import com.utils.*; import java.lang.reflect.InvocationTargetException; import com.service.DictionaryService; import org.apache.commons.lang3.StringUtils; import com.annotation.IgnoreAuth; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.entity.*; import com.entity.view.*; import com.service.*; import com.utils.PageUtils; import com.utils.R; import com.alibaba.fastjson.*; /** * 公告信息 * 后端接口 * 该类作为公告信息相关功能的控制层,负责接收前端发送的各种HTTP请求, * 调用对应的服务层方法来处理公告信息的查询、保存、修改、删除以及批量上传等业务操作, * 并与数据库进行交互,对返回结果进行相应处理后返回给前端。 * @author wangmuzi * */ @RestController @Controller @RequestMapping("/news") public class NewsController { // 创建一个日志记录器,用于记录该类中各个方法执行过程中的关键信息,方便后续调试和问题排查 private static final Logger logger = LoggerFactory.getLogger(NewsController.class); // 通过Spring的依赖注入, // 自动装配NewsService,用于处理公告信息相关的核心业务逻辑,比如数据库操作等 @Autowired private NewsService newsService; // 自动注入TokenService, // 可能用于处理与用户认证令牌相关的操作(具体功能需看对应服务层实现) @Autowired private TokenService tokenService; // 自动注入DictionaryService, // 用于处理字典表数据的转换操作,例如将字典表中的编码转换为有实际意义的展示值 @Autowired private DictionaryService dictionaryService; // 自动注入YonghuService, // 可能用于处理与用户(Yonghu,可能是特定业务中的一种用户类型)相关的级联表操作(具体使用场景看后续代码逻辑) @Autowired private YonghuService yonghuService; /** * 后端列表功能方法 * 接收前端传来的查询参数以及HttpServletRequest对象,根据用户角色添加相应查询条件,获取公告信息的分页列表数据, * 并对字典表相关字段进行数据转换后返回给前端。 * @param params 包含查询条件、分页等相关参数的Map集合,例如每页显示数量、页码、排序字段等 * @param request HttpServletRequest对象,用于获取请求相关的信息,如当前用户的角色、用户ID等,以便添加特定的查询条件 * @return R类型的结果对象,包含操作结果状态以及查询到的分页数据等信息(R应该是自定义的统一返回结果类型) */ @RequestMapping("/page") public R page(@RequestParam Map params, HttpServletRequest request) { // 记录page方法的调用信息, // 包括当前类名和传入的参数(将参数转换为JSON字符串形式记录,方便查看参数详情),用于调试目的 logger.debug("page方法:,,Controller:{},,params:{}", this.getClass().getName(), JSONObject.toJSONString(params)); // 从HttpServletRequest的会话中获取当前用户的角色信息, // 并转换为String类型 String role = String.valueOf(request.getSession().getAttribute("role")); if (false) return R.error(511, "永不会进入"); else if ("用户".equals(role)) // 如果当前用户角色是"用户", // 则将当前用户的ID添加到查询参数中,作为查询属于该用户的公告信息的条件(这里假设数据库中有对应的关联字段) params.put("yonghuId", request.getSession().getAttribute("userId")); // 如果传入的排序字段参数为空,则默认按照"id"字段进行排序 if (params.get("orderBy") == null || params.get("orderBy") == "") { params.put("orderBy", "id"); } // 调用newsService的queryPage方法, // 根据传入的参数获取公告信息的分页数据(该方法内部应该是与数据库交互来查询相应的数据列表等) PageUtils page = newsService.queryPage(params); // 获取分页数据中的列表数据(这里应该是NewsView类型的列表,NewsView可能是用于展示的视图对象) List list = (List) page.getList(); // 遍历列表数据,对每条数据进行字典表数据转换操作, // 将字典表中的编码等转换为对应的实际展示值(比如状态码转换为具体的状态文字描述) for (NewsView c : list) { dictionaryService.dictionaryConvert(c, request); } // 返回包含处理后数据的成功结果对象(R.ok()表示操作成功, // 并将数据放入返回对象中返回给前端) return R.ok().put("data", page); } /** * 后端详情功能方法 * 根据传入的公告信息记录的id,从数据库中查询对应的详细信息,进行实体转视图操作以及字典表数据转换后返回给前端。 * @param id 要查询的公告信息记录的唯一标识(Long类型的id) * @param request HttpServletRequest对象,用于获取请求相关的信息(如会话中的属性等),可能在字典表数据转换时会用到 * @return R类型的结果对象,包含操作结果状态以及查询到的详细数据等信息(若查询到数据则返回成功及数据,否则返回错误提示) */ @RequestMapping("/info/{id}") public R info(@PathVariable("id") Long id, HttpServletRequest request) { logger.debug("info方法:,,Controller:{},,id:{}", this.getClass().getName(), id); // 通过newsService根据传入的id从数据库中查询对应的NewsEntity对象(NewsEntity可能是数据库对应的实体类) NewsEntity news = newsService.selectById(id); if (news!= null) { // 创建NewsView对象, // 用于将查询到的实体数据转换为适合展示的视图数据(NewsView可能包含了部分需要展示给前端的字段等) NewsView view = new NewsView(); // 使用Spring的BeanUtils工具, // 将news实体对象中的属性值复制到view视图对象中,实现实体转视图的基本数据复制 BeanUtils.copyProperties(news, view); // 对view视图对象进行字典表数据转换操作, // 将字典表相关字段转换为有实际意义的展示值(比如将类型编码转换为类型名称等) dictionaryService.dictionaryConvert(view, request); // 返回包含处理后详细数据的成功结果对象(R.ok()表示操作成功, // 并将数据放入返回对象中返回给前端) return R.ok().put("data", view); } else { // 如果未查询到对应的数据, // 则返回包含错误码和错误提示信息的错误结果对象 return R.error(511, "查不到数据"); } } /** * 后端保存功能方法 * 接收前端传来的NewsEntity对象(包含要保存的公告信息相关数据)以及HttpServletRequest对象, * 检查数据是否重复后将数据插入到数据库中。 * @param news 包含要保存的公告信息相关数据的NewsEntity对象,包含如公告名称、类型等各种属性信息 * @param request HttpServletRequest对象,用于获取请求相关的信息(如会话中的用户角色等属性),不过此处暂时未体现更多使用场景 * @return R类型的结果对象,包含操作结果状态(成功或失败及对应的提示信息) */ @RequestMapping("/save") public R save(@RequestBody NewsEntity news, HttpServletRequest request) { logger.debug("save方法:,,Controller:{},,news:{}", this.getClass().getName(), news.toString()); String role = String.valueOf(request.getSession().getAttribute("role")); if (false) return R.error(511, "永远不会进入"); // 创建EntityWrapper对象,用于构建查询条件, // 检查数据库中是否已经存在相同的公告信息(根据公告名称和公告类型等字段进行等值判断) Wrapper queryWrapper = new EntityWrapper() .eq("news_name", news.getNewsName()) .eq("news_types", news.getNewsTypes()); logger.info("sql语句:" + queryWrapper.getSqlSegment()); // 根据构建的查询条件查询数据库中是否已经存在相同的数据(通过selectOne方法查询一条符合条件的数据) NewsEntity newsEntity = newsService.selectOne(queryWrapper); if (newsEntity == null) { // 如果不存在相同数据,则设置公告信息的插入时间和创建时间为当前时间, // 并将该公告信息插入到数据库中(通过insert方法) news.setInsertTime(new Date()); news.setCreateTime(new Date()); newsService.insert(news); return R.ok(); } else { // 如果存在相同数据,则返回包含错误码和提示信息的错误结果对象,表示表中已有相同数据 return R.error(511, "表中有相同数据"); } } /** * 后端修改功能方法 * 接收前端传来的NewsEntity对象(包含要修改的公告信息相关数据)以及HttpServletRequest对象, * 根据字段查询是否有相同数据,若不存在则根据id更新数据库中的对应公告信息记录,同时对图片字段进行空值处理。 * @param news 包含要修改的公告信息相关数据的NewsEntity对象,包含如公告名称、类型、图片等各种属性信息,且部分属性可能已被修改 * @param request HttpServletRequest对象,用于获取请求相关的信息(如会话中的用户角色等属性),不过此处暂时未体现更多使用场景 * @return R类型的结果对象,包含操作结果状态(成功或失败及对应的提示信息) */ @RequestMapping("/update") public R update(@RequestBody NewsEntity news, HttpServletRequest request) { logger.debug("update方法:,,Controller:{},,news:{}", this.getClass().getName(), news.toString()); String role = String.valueOf(request.getSession().getAttribute("role")); // if (false) // return R.error(511, "永远不会进入"); // 创建EntityWrapper对象,用于构建查询条件,检查数据库中除了当前要修改的记录(根据id排除)外是否存在相同的公告信息(根据公告名称和公告类型等字段进行等值判断) Wrapper queryWrapper = new EntityWrapper() .notIn("id", news.getId()) .andNew() .eq("news_name", news.getNewsName()) .eq("news_types", news.getNewsTypes()); logger.info("sql语句:" + queryWrapper.getSqlSegment()); // 根据构建的查询条件查询数据库中是否已经存在相同的数据(通过selectOne方法查询一条符合条件的数据) NewsEntity newsEntity = newsService.selectOne(queryWrapper); // 如果公告图片字段为空字符串或者值为"null" // (这里可能是前端传递过来的表示空值的情况),则将其设置为null,以便后续正确更新到数据库中 if ("".equals(news.getNewsPhoto()) || "null".equals(news.getNewsPhoto())) { news.setNewsPhoto(null); } if (newsEntity == null) { // 如果不存在相同数据, // 则根据传入的news对象的id更新数据库中的对应公告信息记录(通过updateById方法) newsService.updateById(news); return R.ok(); } else { // 如果存在相同数据, // 则返回包含错误码和提示信息的错误结果对象,表示表中已有相同数据 return R.error(511, "表中有相同数据"); } } /** * 删除功能方法 * 接收前端传来的要删除的公告信息记录的id数组,调用newsService的批量删除方法,从数据库中删除对应的数据记录, * 并返回操作结果给前端。 * @param ids 包含要删除的公告信息记录的id的整数数组,用于指定要删除的多条公告信息 * @return R类型的结果对象,包含操作结果状态(成功或失败及对应的提示信息) */ @RequestMapping("/delete") public R delete(@RequestBody Integer[] ids) { logger.debug("delete:,,Controller:{},,ids:{}", this.getClass().getName(), ids.toString()); // 调用newsService的deleteBatchIds方法, // 批量删除数据库中对应id的公告信息记录(传入的是将数组转换为List后的集合) newsService.deleteBatchIds(Arrays.asList(ids)); return R.ok(); } /** * 批量上传功能方法 * 接收文件名fileName以及HttpServletRequest对象,用于将指定的Excel文件中的公告信息数据批量插入到数据库中, * 在插入前进行一些文件格式校验、数据读取以及重复数据检查等操作。 * @param fileName 要上传的文件的名称(这里应该是位于特定目录下的文件名,预期是Excel文件) * @param request HttpServletRequest对象,用于获取请求相关的信息,如当前用户的ID等属性,可能在后续业务逻辑中有更多用途 * @return R类型的结果对象,包含操作结果状态(成功或失败及对应的提示信息) */ @RequestMapping("/batchInsert") public R save(String fileName, HttpServletRequest request) { logger.debug("batchInsert方法:,,Controller:{},,fileName:{}", this.getClass().getName(), fileName); // 从HttpServletRequest的会话中获取当前用户的ID, // 并转换为Integer类型(这里做了一些强制类型转换操作) Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { // 创建一个用于存储要插入数据库的NewsEntity对象列表(即从文件中读取到的多条公告信息记录) List newsList = new ArrayList<>(); // 创建一个Map, // 用于存储要查询是否重复的字段信息(具体的使用方式需看后续代码逻辑,可能用于去重判断等) Map> seachFields = new HashMap<>(); Date date = new Date(); int lastIndexOf = fileName.lastIndexOf("."); if (lastIndexOf == -1) { return R.error(511, "该文件没有后缀"); } else { String suffix = fileName.substring(lastIndexOf); if (!".xls".equals(suffix)) { return R.error(511, "只支持后缀为xls的excel文件"); } else { // 通过类加载器获取指定文件名对应的文件资源路径(这里应该是位于"static/upload/"目录下的文件) URL resource = this.getClass().getClassLoader().getResource("static/upload/" + fileName); File file = new File(resource.getFile()); if (!file.exists()) { return R.error(511, "找不到上传文件,请联系管理员"); } else { // 调用PoiUtil的poiImport方法读取Excel文件中的数据(返回的是一个嵌套的List, // 外层List表示行,内层List表示每行中的单元格数据) List> dataList = PoiUtil.poiImport(file.getPath()); // 删除读取到的数据列表中的第一行(可能是表头之类的提示信息,不需要插入数据库) dataList.remove(0); for (List data : dataList) { // 循环处理每一行数据,创建一个NewsEntity对象,用于存储要插入数据库的一条公告信息记录信息 NewsEntity newsEntity = new NewsEntity(); // // // // // // // // newsEntity.setNewsName(data.get(0)); //公告标题 要改的 // newsEntity.setNewsTypes(Integer.valueOf(data.get(0))); //公告类型 要改的 // newsEntity.setNewsPhoto("");//详情和图片 // newsEntity.setInsertTime(date);//时间 // newsEntity.setNewsContent("");//详情和图片 // newsEntity.setCreateTime(date);//时间 newsList.add(newsEntity); // 把要查询是否重复的字段放入map中(此处代码未完整实现具体放入逻辑,需补充) } // 查询是否重复(此处应该是根据放入seachFields中的字段去检查数据库中是否已存在相同记录, // 代码可能需完善) newsService.insertBatch(newsList); return R.ok(); } } } } catch (Exception e) { e.printStackTrace(); return R.error(511, "批量插入数据异常,请联系管理员"); } } /** * 前端列表功能方法 * 接收前端传来的查询参数以及HttpServletRequest对象,获取公告信息的分页列表数据, * 并对字典表相关字段进行数据转换后返回给前端,此方法不受权限验证限制(通过@IgnoreAuth注解标识)。 * @param params 包含查询条件、分页等相关参数的Map集合,例如每页显示数量、页码、排序字段等 * @param request HttpServletRequest对象,用于获取请求相关的信息,如当前用户的角色、用户ID等,以便添加特定的查询