SpringCloud+Vue校园二手市场 附带详细运行指导视频

一、项目演示

项目演示地址:视频地址

二、项目介绍

项目描述:这是一个基于SpringCloud+Vue框架开发的校园二手市场系统。首先,这是一个前后端分离的项目,代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个校园二手市场系统该有的所有功能。

项目功能:此项目分为两个角色:普通用户管理员普通用户有登录注册、浏览商品信息、地址管理、添加购物车、结算支付订单、查看个人信息、查看个人订单详情、创建店铺、发布商品等等功能。管理员有管理所有商品信息、管理所有订单信息、管理所有用户信息、管理所有店铺信息、查看收益数据图表等等功能。

应用技术:SpringCloud + Vue + MySQL + MyBatis + Redis + ElementUI + 沙箱支付宝 + Nacos + openFeign + GateWay

运行环境:IntelliJ IDEA2019.3.5 + MySQL5.7(项目压缩包中自带) + Redis5.0.5(项目压缩包中自带) + JDK1.8 + Maven3.6.3(项目压缩包中自带)+ Node14.16.1(项目压缩包中自带)+ Nacos1.3.0(项目压缩包中自带)

注意:电脑内存最好16G,否则存在运行不起来的可能!!!

三、项目运行截图

项目运行截图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、主要代码

1.SpringCloud GateWay 网关拦截器代码:

package com.yjq.programmer.filter;

import com.yjq.programmer.constant.WhiteList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * @author 杨杨吖
 * @QQ 823208782
 * @WX yjqi12345678
 * @create 2021-05-12 17:44
 */

@Component
public class LoginWebGatewayFilter implements GlobalFilter, Ordered {
    
    

    private static final Logger logger = LoggerFactory.getLogger(LoginWebGatewayFilter.class);

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        String path = exchange.getRequest().getURI().getPath();
        // 判断该路径是否需要验证
        for(String str : WhiteList.userNotNeedConfirmUrl){
    
    
            if(path.equals(str)){
    
    
                return chain.filter(exchange);
            }
        }
        //获取header的token参数
        String token = exchange.getRequest().getHeaders().getFirst("token");
        logger.info("前台登录验证开始,token:{}", token);
        if (token == null || token.isEmpty()) {
    
    
            logger.info( "token为空,请求被拦截" );
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        Object object = stringRedisTemplate.opsForValue().get("USER_" + token);
        if (object == null) {
    
    
            logger.warn( "token无效,请求被拦截" );
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder()
    {
    
    
        // 过滤器执行优先级 值越小优先级越高
        return 1;
    }
}

2.沙箱支付宝支付订单业务逻辑代码:

 /**
  * 使用沙箱支付宝支付订单
  * @param orderDTO
  * @return
  */
 @Override
    public ResponseDTO<String> aliPayOrder(OrderDTO orderDTO) {
    
    
        // 判断是否进行继续支付
        if(!CommonUtil.isEmpty(orderDTO.getId())) {
    
    
            Orders orders = ordersMapper.selectByPrimaryKey(orderDTO.getId());
            return initAliPay(orders.getNo(),  orders.getTotalPrice());
        }
        if(orderDTO.getCartIdList() == null || orderDTO.getCartIdList().size() == 0) {
    
    
            return ResponseDTO.errorByMsg(CodeMsg.DATA_ERROR);
        }
        if(CommonUtil.isEmpty(orderDTO.getUserId())) {
    
    
            return ResponseDTO.errorByMsg(CodeMsg.USER_SESSION_EXPIRED);
        }
        List<OrderItem> orderItemList = new ArrayList<>();
        BigDecimal totalPrice = new BigDecimal("0.00");
        String orderNo = String.valueOf(new SnowFlake(2, 3).nextId());
        String orderId = UuidUtil.getShortUuid();
        // 获取用户挑选的商品信息
        for(String cartId : orderDTO.getCartIdList()) {
    
    
            CartDTO cartDTO = new CartDTO();
            cartDTO.setId(cartId);
            ResponseDTO<CartDTO> responseDTO = userClient.getCartById(cartDTO);
            if(!responseDTO.getCode().equals(CodeMsg.SUCCESS.getCode())) {
    
    
                return ResponseDTO.errorByMsg(CodeMsg.ORDER_PRODUCT_ERROR);
            }
            cartDTO = responseDTO.getData();
            // 判断商品库存是否足够
            if(cartDTO.getQuantity() > cartDTO.getProductDTO().getStock()) {
    
    
                CodeMsg codeMsg = CodeMsg.PRODUCT_STOCK_ERROR;
                codeMsg.setMsg("商品(" + cartDTO.getProductDTO().getName() + ")库存不足!" );
                return ResponseDTO.errorByMsg(codeMsg);
            }
            // 判断商品状态
            if(!ProductStateEnum.SUCCESS.getCode().equals(cartDTO.getProductDTO().getState())) {
    
    
                CodeMsg codeMsg = CodeMsg.PRODUCT_STATE_ERROR;
                codeMsg.setMsg("商品(" + cartDTO.getProductDTO().getName() + ")状态异常!" );
                return ResponseDTO.errorByMsg(codeMsg);
            }
            // 封装订单详情数据
            OrderItem orderItem = new OrderItem();
            orderItem.setId(UuidUtil.getShortUuid());
            orderItem.setProductName(cartDTO.getProductDTO().getName());
            orderItem.setProductId(cartDTO.getProductDTO().getId());
            orderItem.setProductPhoto(cartDTO.getProductDTO().getPhoto());
            orderItem.setProductPrice(cartDTO.getProductDTO().getPrice());
            orderItem.setOrderId(orderId);
            orderItem.setState(OrderStateEnum.WAIT.getCode());
            orderItem.setStoreId(cartDTO.getProductDTO().getStoreId());
            orderItem.setQuantity(cartDTO.getQuantity());
            orderItem.setSumPrice(new BigDecimal(orderItem.getQuantity()).multiply(orderItem.getProductPrice()));
            orderItemList.add(orderItem);
            totalPrice = totalPrice.add(orderItem.getSumPrice());
            // 移除购物车数据
            userClient.removeCart(cartDTO);
        }
        // 订单详情数据入库
        for(OrderItem orderItem : orderItemList){
    
    
            if(orderItemMapper.insertSelective(orderItem) == 0) {
    
    
                throw new RuntimeException(CodeMsg.ORDER_ADD_ERROR.getMsg());
            }
        }
        // 封装订单数据  并入库
        Orders orders = CopyUtil.copy(orderDTO, Orders.class);
        orders.setId(orderId);
        orders.setCreateTime(new Date());
        orders.setNo(orderNo);
        orders.setTotalPrice(totalPrice);
        orders.setState(OrderStateEnum.WAIT.getCode());
        if(ordersMapper.insertSelective(orders) == 0) {
    
    
            throw new RuntimeException(CodeMsg.ORDER_ADD_ERROR.getMsg());
        }

        return initAliPay(orderNo, totalPrice);
    }

3.其他服务调用商品服务的代码(openFeign):

package com.yjq.programmer.feignclient;

import com.yjq.programmer.dto.ProductDTO;
import com.yjq.programmer.dto.ResponseDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.List;

/**
 * @author 杨杨吖
 * @QQ 823208782
 * @WX yjqi12345678
 * @create 2022-07-08 9:52
 */
@FeignClient("ProductService")
public interface ProductClient {
    
    

    @PostMapping("/product/store/get")
    ResponseDTO<List<ProductDTO>> getByStore(@RequestBody ProductDTO productDTO);

    @PostMapping("/product/get")
    ResponseDTO<ProductDTO> getById(@RequestBody ProductDTO productDTO);

    @PostMapping("/product/save")
    ResponseDTO<Boolean> saveProduct(@RequestBody ProductDTO productDTO);

    @PostMapping("/product/remove/store_id")
    ResponseDTO<Boolean> removeProductByStoreId(@RequestBody ProductDTO productDTO);
}

4.用户登录业务逻辑代码:

    /**
     * 前台用户登录
     * @param userDTO
     * @return
     */
    @Override
    public ResponseDTO<UserDTO> homeLogin(UserDTO userDTO) {
    
    
        // 进行是否为空判断
        if(CommonUtil.isEmpty(userDTO.getUsername())){
    
    
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_EMPTY);
        }
        if(CommonUtil.isEmpty(userDTO.getPassword())){
    
    
            return ResponseDTO.errorByMsg(CodeMsg.PASSWORD_EMPTY);
        }
        // 对比昵称和密码是否正确
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(userDTO.getUsername()).andPasswordEqualTo(userDTO.getPassword());
        List<User> userList = userMapper.selectByExample(userExample);
        if(userList == null || userList.size() != 1){
    
    
            return ResponseDTO.errorByMsg(CodeMsg.USERNAME_PASSWORD_ERROR);
        }
        // 生成登录token并存入Redis中
        UserDTO selectedUserDto = CopyUtil.copy(userList.get(0), UserDTO.class);
        String token = UuidUtil.getShortUuid();
        selectedUserDto.setToken(token);
        //把token存入redis中 有效期1小时
        stringRedisTemplate.opsForValue().set("USER_" + token, JSON.toJSONString(selectedUserDto), 3600, TimeUnit.SECONDS);
        return ResponseDTO.successByMsg(selectedUserDto, "登录成功!");
    }

猜你喜欢

转载自blog.csdn.net/dgfdhgghd/article/details/127848666