普通用户也能访问管理员订单列表接口
问题描述:
以用户身份登录后再次请求订单列表接口(管理员用),也能返回数据
相关截图:
OrderAdminController:
package com.fanyu.mall.controller;
import com.fanyu.mall.common.ApiRestResponse;
import com.fanyu.mall.service.OrderService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/order")
public class OrderAdminController {
@Autowired
OrderService orderService;
@GetMapping("/admin/list")
@ApiOperation("后台查看订单列表")
public ApiRestResponse list(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize) {
PageInfo pageInfo = orderService.listForAdmin(pageNum,pageSize);
return ApiRestResponse.success(pageInfo);
}
}
OrderServiceImpl:
package com.fanyu.mall.service.impl;
import com.fanyu.mall.common.Constant;
import com.fanyu.mall.exception.FanyuMallException;
import com.fanyu.mall.exception.FanyuMallExceptionEnum;
import com.fanyu.mall.filter.UserFilter;
import com.fanyu.mall.model.dao.OrderItemMapper;
import com.fanyu.mall.model.dao.OrderMapper;
import com.fanyu.mall.model.dao.ProductMapper;
import com.fanyu.mall.model.pojo.Order;
import com.fanyu.mall.model.pojo.OrderItem;
import com.fanyu.mall.model.pojo.Product;
import com.fanyu.mall.model.request.CreateOrderReq;
import com.fanyu.mall.service.OrderService;
import com.fanyu.mall.util.OrderCodeFactory;
import com.fanyu.mall.util.QRCodeGenerator;
import com.fanyu.mall.vo.CartVO;
import com.fanyu.mall.vo.OrderItemVO;
import com.fanyu.mall.vo.OrderVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.zxing.WriterException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
CartServiceImpl cartService;
@Autowired
ProductMapper productMapper;
@Autowired
OrderItemMapper orderItemMapper;
@Autowired
OrderMapper orderMapper;
@Value("${file.upload.ip}")
String ip;
//数据库事务
@Transactional(rollbackFor = Exception.class)
@Override
public String create(CreateOrderReq createOrderReq){
//获取userid
Integer userId = UserFilter.currentUser.getId();
//根据userID从购物车查询【勾选的】商品信息
List<CartVO> cartVOList = cartService.list(userId);
List<CartVO> selectedCartVOList = new ArrayList<>();
for (int i = 0; i < cartVOList.size(); i++) {
CartVO cartVO = cartVOList.get(i);
if(cartVO.getSelected().equals(Constant.selectedStatus.SELECTED)){
selectedCartVOList.add(cartVO);
}
}
cartVOList = selectedCartVOList;
//购物车中勾选的商品为空则报错
// if(cartVOList == null || cartVOList.size() == 0){
//CollectionUtils.isNotEmpty() 包含null,size=0等多种情况
//而== null 只能用来判断是否为null
if(CollectionUtils.isEmpty(cartVOList)){
throw new FanyuMallException(FanyuMallExceptionEnum.NO_SELECTED_PRODUCT);
}
//判断购物车对应存在商品,且状态可售,且库存数充足
validCartVOList(cartVOList);
//购物车对象转化为orderitem对象
List<OrderItem> orderItemList = cartVOListToOrderItemList(cartVOList);
//扣除库存
for (int i = 0; i < orderItemList.size(); i++) {
OrderItem orderItem = orderItemList.get(i);
Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
int count = product.getStock() - orderItem.getQuantity();
if(count < 0){
throw new FanyuMallException(FanyuMallExceptionEnum.NOT_ENOUGH);
}
product.setStock(count);
product.setUpdateTime(new Date());///////更新时间变化了
productMapper.updateByPrimaryKeySelective(product);
}
//将勾选的商品从购物车删除
flushCarts(userId,cartVOList);
//生成订单
Order order = new Order();
//设置订单各属性(未定的属性先不设置),尤其是订单号,关注如何生成
String orderNo = OrderCodeFactory.getOrderCode(Long.valueOf(userId));
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalPrice(totalPrice(orderItemList));//需要自己计算
order.setReceiverName(createOrderReq.getReceiverName());
order.setReceiverMobile(createOrderReq.getReceiverMobile());
order.setReceiverAddress(createOrderReq.getReceiverAddress());
order.setOrderStatus(Constant.OrderStatusEnum.NOT_PAID.getCode());//定义枚举类出错,先通过硬编码方式
order.setPostage(0);
order.setPaymentType(1);
//忘记插入了
orderMapper.insertSelective(order);
//将orderitemlist挨个插入到orderitem表里
for (int i = 0; i < orderItemList.size(); i++) {
OrderItem orderItem = orderItemList.get(i);
orderItem.setOrderNo(orderNo);
orderItemMapper.insertSelective(orderItem);
}
//返回生成的订单号
return orderNo;
}
private Integer totalPrice(List<OrderItem> orderItemList) {
Integer totalPrice = 0;
for (int i = 0; i < orderItemList.size(); i++) {
OrderItem orderItem = orderItemList.get(i);
totalPrice += orderItem.getTotalPrice();
}
return totalPrice;
}
private void flushCarts(Integer userId,List<CartVO> cartVOList) {
for (int i = 0; i < cartVOList.size(); i++) {
CartVO cartVO = cartVOList.get(i);
cartService.delete(userId,cartVO.getProductId());
}
}
private void validCartVOList(List<CartVO> cartVOList){
CartVO cartVOTemp;
Product productTemp;
for (int i = 0; i < cartVOList.size(); i++) {
cartVOTemp = cartVOList.get(i);
productTemp = productMapper.selectByPrimaryKey(cartVOTemp.getProductId());
//校验商品
if(productTemp == null || productTemp.getStatus().equals(Constant.saleStatus.NOT_SALE)){
throw new FanyuMallException(FanyuMallExceptionEnum.NOT_SALE);
}
//校验库存
if(cartVOTemp.getQuantity() > productTemp.getStock()){
throw new FanyuMallException(FanyuMallExceptionEnum.NOT_ENOUGH);
}
}
}
private List<OrderItem> cartVOListToOrderItemList(List<CartVO> cartVOList){
List<OrderItem> orderItemList = new ArrayList<>();
for (int i = 0; i < cartVOList.size(); i++) {
CartVO cartVO = cartVOList.get(i);
OrderItem orderItem = new OrderItem();
orderItem.setProductId(cartVO.getProductId());
//此时还未获取到orderNo未设置值
//保存此商品名称,价格,图片等的快照
orderItem.setProductImg(cartVO.getProductImage());
orderItem.setProductName(cartVO.getProductName());
orderItem.setQuantity(cartVO.getQuantity());
orderItem.setUnitPrice(cartVO.getPrice());
orderItem.setTotalPrice(cartVO.getTotalPrice());
orderItemList.add(orderItem);
}
return orderItemList;
}
@Override
public OrderVO detail(String orderNo){
//调用mapper根据orderNo查询出order对象
Order order = orderMapper.selectByOrderNo(orderNo);
//order对象是否存在
if(order == null){
throw new FanyuMallException(FanyuMallExceptionEnum.NO_ORDER);
}
//order对象存在的前提下判断订单所属人是否和当前登录人为同一人
Integer userId = UserFilter.currentUser.getId();
if(!userId.equals(order.getUserId())){
throw new FanyuMallException(FanyuMallExceptionEnum.NOT_YOUR_ORDER);
}
//子方法,根据order对象获得orderVO对象并返回
OrderVO orderVO = getOrderVOFromOrder(order);
return orderVO;
}
private OrderVO getOrderVOFromOrder(Order order) {
//copy共同属性从order到orderVO
OrderVO orderVO = new OrderVO();
BeanUtils.copyProperties(order,orderVO);
//为orderstatusname设置值
//codeOF方法的作用是根据code码获得这个枚举类对象
orderVO.setOrderStatusName(Constant.OrderStatusEnum.codeOf(order.getOrderStatus()).getMessage());
//根据orderNo获得此订单下的所有的orderitem的list
List<OrderItem> orderItemList = orderItemMapper.selectByOrderNo(order.getOrderNo());
//循环遍历该orderitemlist把每一个orderitem转换为orderitemvo,构成list
List<OrderItemVO> orderItemVOList = new ArrayList<>();
for (int i = 0; i < orderItemList.size(); i++) {
OrderItem orderItem = orderItemList.get(i);
OrderItemVO orderItemVO = new OrderItemVO();
BeanUtils.copyProperties(orderItem,orderItemVO);
orderItemVOList.add(orderItemVO);
}
// 为ordervo设置orderitemvo的list的值
orderVO.setOrderItemVOList(orderItemVOList);
//返回
return orderVO;
}
@Override
public PageInfo listForCustomer(Integer pageNum, Integer pageSize){
//获取到userid
Integer userId = UserFilter.currentUser.getId();
//设置pagehelper(在实际查询数据库操作的前一步)
PageHelper.startPage(pageNum,pageSize);
//查询order表里面与这个人关联的所有的order组成list
List<Order> orderList = orderMapper.selectByUserId(userId);
////////////////
System.out.println("orderServiceImpl.listForCustomer userId:" + userId + "返回的orderlist.size为" + orderList.size());
for (int i = 0; i < orderList.size(); i++) {
System.out.println(orderList.get(i));
}
////////////////////
//orderlist转换为ordervolist
List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
//封装进pageinfo并返回
PageInfo pageInfo = new PageInfo(orderList);
pageInfo.setList(orderVOList);
return pageInfo;
}
private List<OrderVO> orderListToOrderVOList(List<Order> orderList) {
List<OrderVO> orderVOList = new ArrayList<>();
for (int i = 0; i < orderList.size(); i++) {
Order order = orderList.get(i);
OrderVO orderVO = getOrderVOFromOrder(order);
orderVOList.add(orderVO);
}
return orderVOList;
}
@Transactional(rollbackFor = Exception.class)
@Override
public void cancel(String orderNo){
//查询出order对象
Order order = orderMapper.selectByOrderNo(orderNo);
//判断是否为null
if(order == null){
throw new FanyuMallException(FanyuMallExceptionEnum.NO_ORDER);
}
//判断订单所属
Integer userId = UserFilter.currentUser.getId();
if(!userId.equals(order.getUserId())){
System.out.println("当前登录id:" + userId);
System.out.println("order所属user:" + order.getUserId());
throw new FanyuMallException(FanyuMallExceptionEnum.NOT_YOUR_ORDER);
}
//业务上只有未付款的订单可取消
if(!order.getOrderStatus().equals(Constant.OrderStatusEnum.NOT_PAID.getCode())){
throw new FanyuMallException(FanyuMallExceptionEnum.NEED_UNPAID);
}
//更新orderstatus和updatetime,endtime的值
order.setOrderStatus(Constant.OrderStatusEnum.CANCELED.getCode());
order.setUpdateTime(new Date());
order.setEndTime(new Date());
orderMapper.updateByPrimaryKeySelective(order);
//查询该订单对应的orderitem,循环遍历获得productid,更新product表updatetime和stock
List<OrderItem> orderItemList = orderItemMapper.selectByOrderNo(orderNo);
for (int i = 0; i < orderItemList.size(); i++) {
OrderItem orderItem = orderItemList.get(i);
Product product = productMapper.selectByPrimaryKey(orderItem.getProductId());
product.setStock(product.getStock() + orderItem.getQuantity());
product.setUpdateTime(new Date());
productMapper.updateByPrimaryKeySelective(product);
}
}
@Override
public String qrcode(String orderNo){
//引入生成二维码相关依赖
//util包下建生成二维码工具类QRCodeGenerator
//获取到和IP,port等相关的request信息***********难点
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)attributes;
ServletRequest servletRequest = requestAttributes.getRequest();
//拼接组成二维码的URL
int port = servletRequest.getLocalPort();
String address = ip + ":" + port;
String payUrl = "http://" + address + "/pay?orderNo=" + orderNo;
//调用生成二维码接口
try {
QRCodeGenerator.generateQRCodeImage(payUrl,350,350,Constant.FILE_UPLOAD_DIR + orderNo + ".png");
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//返回的是访问这个二维码的URL地址
return "http://" + address + "/mall/images/" + orderNo + ".png";
}
@Override
public PageInfo listForAdmin(Integer pageNum, Integer pageSize){
// //获取到userid
// Integer userId = UserFilter.currentUser.getId();
//设置pagehelper(在实际查询数据库操作的前一步)
PageHelper.startPage(pageNum,pageSize);
//查询order表里面与这个人关联的所有的order组成list
List<Order> orderList = orderMapper.selectAllForAdmin();
////////////////
System.out.println("orderServiceImpl.listForAdmin:" + "返回的orderlist.size为" + orderList.size());
for (int i = 0; i < orderList.size(); i++) {
System.out.println(orderList.get(i));
}
////////////////////
//orderlist转换为ordervolist
List<OrderVO> orderVOList = orderListToOrderVOList(orderList);
//封装进pageinfo并返回
PageInfo pageInfo = new PageInfo(orderList);
pageInfo.setList(orderVOList);
return pageInfo;
}
}
UserFilter:
package com.fanyu.mall.filter;
import com.fanyu.mall.common.Constant;
import com.fanyu.mall.model.pojo.User;
import com.fanyu.mall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
//普通用户校验过滤器
public class UserFilter implements Filter {
@Autowired
UserService userService;
public static User currentUser;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//无需实现
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpSession session = request.getSession();
System.out.println("进来了userfilter===============");
currentUser = (User)session.getAttribute(Constant.FANYU_MALL_USER);
if(currentUser == null){
// return ApiRestResponse.error(FanyuMallExceptionEnum.NEED_LOGIN);
//不能这样返回,因为方法是固定的返回void
//可利用writer达到相同效果(还没进入controller之前所使用的的方法)
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse)servletResponse).getWriter();
out.write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"NEED_LOGIN\",\n" +
" \"data\": null\n" +
"}");//内容就是我们想要返回的postman里的json数据
out.flush();
out.close();
return;//方法执行到此已结束,不会进入到后续的过滤器或者controller层
}
//放行,即校验通过,会进入后续
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
//无需实现
}
}
UserFilterConfig:
package com.fanyu.mall.config;
import com.fanyu.mall.filter.UserFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserFilterConfig {
//1.先定义出来这个filter
@Bean
public UserFilter userFilter(){
return new UserFilter();
}
//2.把这个filter放到链路中
@Bean(name = "userFilterConf")
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
//为过滤器配置设置过滤器
filterRegistrationBean.setFilter(userFilter());
//为过滤器配置设置过滤URL
filterRegistrationBean.addUrlPatterns("/cart/*");
filterRegistrationBean.addUrlPatterns("/order/*");
//为过滤器配置设置名字,以区分不同的配置
//注意这个名字不能设置成和此类一样,否则这两个bean就冲突了
filterRegistrationBean.setName("userFilterConf");
// filterRegistrationBean.setOrder(2);
return filterRegistrationBean;
}
}
AdminFilter:
package com.fanyu.mall.filter;
import com.fanyu.mall.common.Constant;
import com.fanyu.mall.model.pojo.User;
import com.fanyu.mall.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
//管理员校验过滤器
public class AdminFilter implements Filter {
@Autowired
UserService userService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//无需实现
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpSession session = request.getSession();
System.out.println("进来了adminfilter===============");
User currentUser = (User)session.getAttribute(Constant.FANYU_MALL_USER);
if(currentUser == null){
// return ApiRestResponse.error(FanyuMallExceptionEnum.NEED_LOGIN);
//不能这样返回,因为方法是固定的返回void
//可利用writer达到相同效果(还没进入controller之前所使用的的方法)
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse)servletResponse).getWriter();
out.write("{\n" +
" \"status\": 10007,\n" +
" \"msg\": \"NEED_LOGIN\",\n" +
" \"data\": null\n" +
"}");//内容就是我们想要返回的postman里的json数据
out.flush();
out.close();
return;//方法执行到此已结束,不会进入到后续的过滤器或者controller层
}
System.out.println("当前用户是:" + currentUser.getUsername() + "身份是" + currentUser.getRole());
boolean adminRole = userService.checkAdminRole(currentUser);
if(adminRole){
//放行,即校验通过,会进入后续
System.out.println("是管理员开始放行***************");
filterChain.doFilter(servletRequest,servletResponse);
}else {
System.out.println("不是管理员进行拦截***************");
PrintWriter out = new HttpServletResponseWrapper((HttpServletResponse)servletResponse).getWriter();
out.write(" {\n" +
" \"status\": 10009,\n" +
" \"msg\": \"NEED_ADMIN\",\n" +
" \"data\": null\n" +
"}");//内容就是我们想要返回的postman里的json数据
out.flush();
out.close();
return;//方法执行到此已结束,不会进入到后续的过滤器或者controller层(这一个return也可以不加)
}
}
@Override
public void destroy() {
//无需实现
}
}
AdminFilterConfig:
package com.fanyu.mall.config;
import com.fanyu.mall.filter.AdminFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AdminFilterConfig {
//1.先定义出来这个filter
@Bean
public AdminFilter adminFilter(){
return new AdminFilter();
}
//2.把这个filter放到链路中
@Bean(name = "adminFilterConf")
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
//为过滤器配置设置过滤器
filterRegistrationBean.setFilter(adminFilter());
//为过滤器配置设置过滤URL
filterRegistrationBean.addUrlPatterns("/admin/category/*");
filterRegistrationBean.addUrlPatterns("/admin/product/*");
filterRegistrationBean.addUrlPatterns("/admin/order/*");
//为过滤器配置设置名字,以区分不同的配置
//注意这个名字不能设置成和此类一样,否则这两个bean就冲突了
filterRegistrationBean.setName("adminFilterConf");
//filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
}
23
收起
正在回答
2回答
同学你好,这两个过滤器拦截的url不重合,/admin/order/*拦截的是后台订单的url,而/order/*拦截的是前台订单的url,拦截的内容不重叠,如:
后台拦截的url,如:
前台拦截的url:
祝学习愉快~
java工程师2020版
- 参与学习 人
- 提交作业 9400 份
- 解答问题 16556 个
综合就业常年第一,编程排行常年霸榜,无需脱产即可学习,北上广深月薪过万 无论你是未就业的学生还是想转行的在职人员,不需要基础,只要你有梦想,想高薪
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星