You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
homestay/minsu/minsuguanliw/src/main/java/com/controller/NewsController.java

336 lines
19 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 HttpServletRequestID便