springboot,vue二手交易平台

news2025/1/20 3:46:59

开发工具:IDEA

服务器:Tomcat9.0, jdk1.8

项目构建:maven

数据库:mysql5.7

系统用户前台和管理后台两部分,项目采用前后端分离

前端技术:vue +elementUI

服务端技术:springboot+mybatis

项目功能描述:

一、前台功能

1、登录、注册、搜索商品、首页、商品详情

2、发送留言、回复留言、发布闲置、留言消息

3、下架闲置、收藏商品,取消收藏、立即购买

4、取消订单、立即支付、发货、确认收货

5、个人中心:修改头像、编辑个人信息、修改密码

6、我的发布、我的下架、我的收藏、我的卖出、我买到的

7、收货地址:添加、修改、删除、设置默认

退出登录等功能

二、后台功能

登录、闲置管理、订单管理、用户管理

前台截图:

后台截图:

package com.second.hand.trading.server.service.impl;

import com.second.hand.trading.server.dao.IdleItemDao;
import com.second.hand.trading.server.dao.OrderDao;
import com.second.hand.trading.server.model.IdleItemModel;
import com.second.hand.trading.server.model.OrderModel;
import com.second.hand.trading.server.service.OrderService;
import com.second.hand.trading.server.utils.OrderTask;
import com.second.hand.trading.server.utils.OrderTaskHandler;
import com.second.hand.trading.server.vo.PageVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderDao orderDao;

    @Resource
    private IdleItemDao idleItemDao;

    /**
     * 新增订单,同时下架闲置
     * 用了事务串行化,后续要优化,修改更新的sql,增加更新条件,而不是在代码中判断条件
     * 业务逻辑可优化,改为支付时才下架。
     * 新功能待做,需要新增订单超时处理
     * (订单超时:
     * 1、重新上架闲置;2、修改订单状态;
     * 3、确保订单取消前不会影响用户的支付,支付前要判断订单状态并加读锁,取消订单时要判断订单状态为未支付才能取消;
     * 4、保证延期任务一定执行,即确保任务不会因为系统异常而消失)
     * @param orderModel
     * @return
     */

    private static HashMap<Integer,ReentrantLock> lockMap=new HashMap<>();
    static {
//        ReentrantLock lock=new ReentrantLock(true);
        for(int i=0;i<100;i++){
            lockMap.put(i,new ReentrantLock(true));
        }
    }
    public boolean addOrder(OrderModel orderModel){
        IdleItemModel idleItemModel=idleItemDao.selectByPrimaryKey(orderModel.getIdleId());
        System.out.println(idleItemModel.getIdleStatus());
        if(idleItemModel.getIdleStatus()!=1){
            return false;
        }
        IdleItemModel idleItem=new IdleItemModel();
        idleItem.setId(orderModel.getIdleId());
        idleItem.setUserId(idleItemModel.getUserId());
        idleItem.setIdleStatus((byte)2);

        int key= (int) (orderModel.getIdleId()%100);
        ReentrantLock lock=lockMap.get(key);
        boolean flag;
        try {
            lock.lock();
            flag=addOrderHelp(idleItem,orderModel);
        }finally {
            lock.unlock();
        }
        return flag;
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean addOrderHelp(IdleItemModel idleItem,OrderModel orderModel){
        IdleItemModel idleItemModel=idleItemDao.selectByPrimaryKey(orderModel.getIdleId());
        if(idleItemModel.getIdleStatus()!=1){
            return false;
        }
        if(idleItemDao.updateByPrimaryKeySelective(idleItem)==1){
            if(orderDao.insert(orderModel)==1){
                orderModel.setOrderStatus((byte) 4);
                //半小时未支付则取消订单
                OrderTaskHandler.addOrder(new OrderTask(orderModel,30*60));
                return true;
            }else {
                new RuntimeException();
            }
        }
        return false;
    }

    /**
     * 获取订单信息,同时获取对应的闲置信息
     * @param id
     * @return
     */
    public OrderModel getOrder(Long id){
        OrderModel orderModel=orderDao.selectByPrimaryKey(id);
        orderModel.setIdleItem(idleItemDao.selectByPrimaryKey(orderModel.getIdleId()));
        return orderModel;
    }

    /**
     * 更新订单状态,无验证,后期修改为定制的更新sql
     * 后期改为在支付时下架闲置
     * @param orderModel
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOrder(OrderModel orderModel){
        //不可修改的信息
        orderModel.setOrderNumber(null);
        orderModel.setUserId(null);
        orderModel.setIdleId(null);
        orderModel.setCreateTime(null);
        if(orderModel.getOrderStatus()==4){
            //取消订单,需要优化,减少数据库查询次数
            OrderModel o=orderDao.selectByPrimaryKey(orderModel.getId());
            if(o.getOrderStatus()!=0){
                return false;
            }
            IdleItemModel idleItemModel=idleItemDao.selectByPrimaryKey(o.getIdleId());
            if(idleItemModel.getIdleStatus()==2){
                IdleItemModel idleItem=new IdleItemModel();
                idleItem.setId(o.getIdleId());
                idleItem.setUserId(idleItemModel.getUserId());
                idleItem.setIdleStatus((byte)1);
                if(orderDao.updateByPrimaryKeySelective(orderModel)==1){
                    if(idleItemDao.updateByPrimaryKeySelective(idleItem)==1){
                        return true;
                    }else {
                        new RuntimeException();
                    }
                }
                return false;
            }else{
                if(orderDao.updateByPrimaryKeySelective(orderModel)==1){
                    return true;
                }else {
                    new RuntimeException();
                }
            }
        }
        return orderDao.updateByPrimaryKeySelective(orderModel)==1;
    }

    /**
     * 获取我的所有订单
     * 同时查询出对应的闲置信息,
     * 未做分页
     * userId建索引
     * @param userId
     * @return
     */
    public List<OrderModel> getMyOrder(Long userId){
        List<OrderModel> list=orderDao.getMyOrder(userId);
        if(list.size()>0){
            List<Long> idleIdList=new ArrayList<>();
            for(OrderModel i:list){
                idleIdList.add(i.getIdleId());
            }
            List<IdleItemModel> idleItemModelList=idleItemDao.findIdleByList(idleIdList);
            Map<Long,IdleItemModel> map=new HashMap<>();
            for(IdleItemModel idle:idleItemModelList){
                map.put(idle.getId(),idle);
            }
            for(OrderModel i:list){
                i.setIdleItem(map.get(i.getIdleId()));
            }
        }
        return list;
    }

    /**
     * 查询用户卖出的闲置
     * @param userId
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public List<OrderModel> getMySoldIdle(Long userId){
        List<IdleItemModel> list=idleItemDao.getAllIdleItem(userId);
        List<OrderModel> orderList=null;
        if(list.size()>0){
            List<Long> idleIdList=new ArrayList<>();
            for(IdleItemModel i:list){
                idleIdList.add(i.getId());
            }
            orderList=orderDao.findOrderByIdleIdList(idleIdList);
            Map<Long,IdleItemModel> map=new HashMap<>();
            for(IdleItemModel idle:list){
                map.put(idle.getId(),idle);
            }
            for(OrderModel o:orderList){
                o.setIdleItem(map.get(o.getIdleId()));
            }
        }
        return orderList;
    }

    public PageVo<OrderModel> getAllOrder(int page, int nums){
        List<OrderModel> list=orderDao.getAllOrder((page-1)*nums,nums);
        if(list.size()>0){
            List<Long> idleIdList=new ArrayList<>();
            for(OrderModel i:list){
                idleIdList.add(i.getIdleId());
            }
            List<IdleItemModel> idleItemModelList=idleItemDao.findIdleByList(idleIdList);
            Map<Long,IdleItemModel> map=new HashMap<>();
            for(IdleItemModel idle:idleItemModelList){
                map.put(idle.getId(),idle);
            }
            for(OrderModel i:list){
                i.setIdleItem(map.get(i.getIdleId()));
            }
        }
        int count=orderDao.countAllOrder();
        return new PageVo<>(list,count);
    }

    public boolean deleteOrder(long id){
        return orderDao.deleteByPrimaryKey(id)==1;
    }
}
package com.second.hand.trading.server.service.impl;

import com.second.hand.trading.server.dao.UserDao;
import com.second.hand.trading.server.model.UserModel;
import com.second.hand.trading.server.service.UserService;
import com.second.hand.trading.server.vo.PageVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;



@Service
public class UserServiceImpl implements UserService {

@Resource
private UserDao userDao;

/**
* 查询一个用户的公开信息
* @param id
* @return
*/
public UserModel getUser(Long id){
return userDao.selectByPrimaryKey(id);
}

/**
* 登录,安全问题未解决
* @param accountNumber
* @param userPassword
* @return
*/
public UserModel userLogin(String accountNumber, String userPassword){
return userDao.userLogin(accountNumber,userPassword);
}

/**
*注册
* @param userModel
* @return
*/
public boolean userSignIn(UserModel userModel){
return userDao.insert(userModel) == 1;
}

/**
*修改用户公开信息,未验证用户身份
* @param userModel
* @return
*/
public boolean updateUserInfo(UserModel userModel){
return userDao.updateByPrimaryKeySelective(userModel)==1;
}

/**
* 修改密码
* @param newPassword
* @param oldPassword
* @param id
* @return
*/
public boolean updatePassword(String newPassword, String oldPassword,Long id){
return userDao.updatePassword(newPassword,oldPassword,id)==1;
}

public PageVo<UserModel> getUserByStatus(int status,int page ,int nums){
List<UserModel> list;
int count=0;
if(status==0){
count=userDao.countNormalUser();
list=userDao.getNormalUser((page-1)*nums, nums);
}else {
count=userDao.countBanUser();
list=userDao.getBanUser((page-1)*nums, nums);
}
return new PageVo<>(list,count);
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0基础快速掌握正则表达式

背景 在日常开发中&#xff0c;我们经常会遇到使用正则表达式的场景&#xff0c;比如一些常见的表单校验&#xff0c;会让你匹配用户输入的手机号或者身份信息是否规范&#xff0c;这就可以用正则表达式去匹配。相信大多数人在碰到这种场景的时候都是直接去网上找&#xff0c;…

在 2023 ETH Denver 与 Cartesi 一起建设

我们非常高兴的加入了 2023年ETHDenver&#xff0c;参加了BUIDLathon 赛道和现场研讨会等活动。作为规模最大、持续时间最长的ETH 活动之一&#xff0c;我们将向热衷于为全球区块链生态系统做出贡献的新开发者社区分享 Cartesi 技术。你想在2023年#BUIDL 做一些有趣有意义的事情…

基于springboot的景区旅游信息管理系统(源代码+数据库)

基于springboot的景区旅游信息管理系统(源代码数据库) 一、系统介绍 本项目分为管理员与普通用户两种角色 用户登录 前台功能&#xff1a;旅游路线、旅游景点、旅游酒店、旅游车票、旅游保险、旅游策略管理员登录 后台功能&#xff1a;用户管理、旅游路线管理、旅游景点管理…

Codeforces Round #843 (Div. 2)(A~C,E)

A1/A2. Gardener and the Capybaras (easy version)三个字符串&#xff0c;按照顺序连在一起&#xff0c;三个字符串满足第二个字符串大于等于第一个和第三个&#xff0c;或者第二个字符串小于等于第一个和第三个&#xff0c;输出满足情况的三个字符串。思路&#xff1a;对于长…

ubuntu18.04系统下挂载新的机械硬盘

ubuntu18.04系统下挂载新的机械硬盘1.显示硬盘以及所属分区情况sudo fdisk -lDisk /dev/sda doesnt contain a valid partition table硬盘分区 对机械硬盘进行操作 sudo fdisk /dev/sda下图表示的是具体流程截图&#xff1a; The partition table has been altered!硬盘格式…

AWS RDS开启审计日志

问题 需要对AWS的RDS开启相关日志。先检查RDS是否开启日志&#xff0c;如下图&#xff1a; 选中一个数据库实例&#xff0c;查看到只开启了数据库的错误日志。但是&#xff0c;我们需要开启其他类型的审计日志。下面开始怎么样开启其他类型日志&#xff0c;来启用高级审计模…

corrosion 靶机(ffuf模糊测试,命令执行)

环境准备 靶机链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;c2j6 虚拟机网络链接模式&#xff1a;桥接模式 攻击机系统&#xff1a;kali linux 2022.03 信息收集 1.探测目标靶机开放端口和服务情况 2.用gobuster扫描目录&#xff0c;并访问 gobuster dir -…

手把手编译FFmpeg

支持centos8.6、ubuntu20.04 export 建议开始之前&#xff0c;弄一台干净的机子&#xff0c;或者系统恢复到出厂设置&#xff0c;否则容易出问题 然后设置动态库默认加载目录&#xff08;注意/usr/local/lib不是系统默认的路径&#xff0c;/lib和/usr/lib才是&#xff09; …

jsp库存管理管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 库存管理管理系统 是一套完善的系统源码&#xff0c;对理解JSP java serlvet MVC编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;以及相应配套的设计文档&#xff0c;系统主要采用B/S 模式开发。 通过本系统建设&#xff0c…

ArcGIS基础实验操作100例--实验97计算河道方向坡度

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 空间分析篇--实验97 计算河道方向坡度 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&…

内存管理-模板初阶理解-string类的模拟实现

文章目录1. 内存管理operator new和operator delete面试题&#xff1a;malloc、free和new、delete的区别2. 内存泄漏1. 内存泄漏&#xff1a;2. 内存泄漏危害&#xff1a;3.堆内存泄漏4.系统资源泄漏3. 模板初阶函数模板类模板&#xff1a;模板运行时不检查数据类型&#xff0c…

黑马编程资源最新最全全清单:速来收藏~

今年是黑马坚持免费分享视频教程的第16年&#xff0c;每年到了这个时候&#xff0c;「成绩单」也不会缺席&#xff0c;不仅是对过往的回顾&#xff0c;更是对那些选择跟着黑马持续学习的小伙伴们的一种激励。 黑马视频教程2022年速报 截至年底&#xff0c;黑马程序员 B 站累计…

ArcGIS基础实验操作100例--实验96创建地形剖面图

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 空间分析篇--实验96 创建地形剖面图 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff08;1&am…

头戴式耳机跑步方便吗、公认最好的跑步耳机排行榜

平时&#xff0c;我们总能看到许多运动健身的人群&#xff0c;在锻炼时都佩戴着耳机。但运动耳机的选择&#xff0c;同样是大有学问的。如果佩戴传统的真无线蓝牙耳机&#xff0c;有可能出现佩戴不稳、耳道肿胀等问题&#xff0c;影响运动体验。所以今天我们特意给大家带来几款…

时间段查询将00:00:00更换成23:59:59

目录 一.问题描述 二.解决问题 2.1.思路一(时间戳赋值) 2.2思路二(LocalDateTime 方法赋值) 三.总结 一.问题描述 在我们作web项目的时候总会有时间段的查询条件 例如: 问题: 前端传到后台的时间: reportStartTime: 2023-01-01 00:00:00 reportEndTime: 2023-01-13 00…

Vue3和Vue2的区别

vue经历从2.0到3.0更新之后&#xff0c;简⽽⾔之就是变得更轻&#xff0c;更快&#xff0c;使⽤起来更加⽅便&#xff0c;每⼀次的版本迭代都是对上⼀个版本的升级优化&#xff0c;不管 是对于我们开发者还是对于⽤户体验都是不断地在越来越⽅便&#xff0c; 选项式Api与组合式…

【计数服务】计数服务落地

一、计数服务 计数服务是针对某个动作在不同维度行为次数的统计或者累加&#xff0c;计数服务需要满足计数的准确性&#xff0c;并且在满足准确性的同时&#xff0c;要注意其性能。 二、计数服务的实现 计数服务分为 非精准计数和精准计数 非精准计数&#xff1a;点赞量、浏…

【Blender UV映射03】如何处理复杂的结构 如何整理UV

写在前面 前面的学习记录&#xff1a; 【Blende UV映射01】创建UV 使用UV贴图处理纹理 【Blender UV映射02】智能UV映射 创建和应用法线纹理 依旧是跟着Blender 2.8 UV Mapping教程&#xff0c;本文是教程的P13-P19的过程记录。 1 善用L分析模型结构 拿到一个相对复杂的模…

压轴级教程!Java人必学的微服务项目上线!

给你说个冷知识下周末就要过年了……年关将至有人欢喜有人愁欢喜的是在外奔波一年终于可以和家人相聚愁的则是回家无非是&#xff1a;1.圆了亲戚的媒婆梦2.让亲戚过过嘴瘾3.成为晚辈的反面教材面对七大姑八大姨的灵魂拷问——有对象了吗&#xff1f;——现在做啥工作&#xff1…

2022年美赛B题O奖获奖分享

1.美赛获奖分享&#xff1a; ** 可以去我的网站逛逛点击传输 ** 首先是选题&#xff0c;今年MCM选择A,B题目的队伍相对较少&#xff0c;超60%的队伍选择C题&#xff0c;对题目的选择需要慎重&#xff0c;较难的题目参赛的队伍会少一些&#xff0c;获得O奖的概率理论上较高…