|
|
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<String, Object> 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<NewsView> list = (List<NewsView>) 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<NewsEntity> queryWrapper = new EntityWrapper<NewsEntity>()
|
|
|
.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<NewsEntity> queryWrapper = new EntityWrapper<NewsEntity>()
|
|
|
.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<NewsEntity> newsList = new ArrayList<>();
|
|
|
// 创建一个Map,
|
|
|
|
|
|
// 用于存储要查询是否重复的字段信息(具体的使用方式需看后续代码逻辑,可能用于去重判断等)
|
|
|
Map<String, List<String>> 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<List<String>> dataList = PoiUtil.poiImport(file.getPath());
|
|
|
// 删除读取到的数据列表中的第一行(可能是表头之类的提示信息,不需要插入数据库)
|
|
|
dataList.remove(0);
|
|
|
for (List<String> 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等,以便添加特定的查询 |