Java项目:快递代拿系统(java+SSM+Bootstrap+Shiro+mysql)

源码获取:博客首页 "资源" 里下载!


使用技术

采用 Spring + SpringMVC + MyBatisPlus,连接池采用 Druid,安全框架使用 Shiro,前端采用 Bootstrap + layer 实现。

支付采用支付宝沙箱环境,支付APP下载链接,[点击这里](https://sandbox.alipaydev.com/user/downloadApp.htm)。

支付账号:uceskd4358@sandbox.com
登录密码、支付密码:111111

**注意:**

请务必使用以上链接下载`沙箱支付宝`,也务必使用以上账号登录。不要使用真实支付宝APP和真实支付宝账号登录。


运行环境

- 集成开发环境:IntelliJ IDEA

- 项目构建工具:Maven
- 数据库:MYSQL 5.7+
- JDK版本:1.8
- Tomcat版本:Tomcat8

(1)首先请创建数据库:
```shell
CREATE DATABASE IF NOT EXISTS `express-ssm` /*!40100 DEFAULT CHARACTER SET utf8 */
```
(2)导入项目 sql 文件夹下的 `express-ssm.sql` 文件。
(3)编辑项目中 `src/main/resources/cnf/mysql.properties` 文件,修改数据库连接信息:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/express-ssm?useUnicode=true&useSSL=false&characterEncoding=utf-8
jdbc.username=root # MYSQL 用户名
jdbc.password=root # MYSQL 密码


运行

项目运行时,在tomcat中配置项目运行路径为http://localhost:8080/ 注意:后面不要带项目名,否则会运行出错;


默认账户

注:以下为本项目默认存在的用户名密码,请将本仓库项目在本地运行后使用以下密码登录。

| 权限  | 用户名 | 密码 |
| 管理员 | admin | 123 |
| 配送员 | 李四  | 123 |
| 用户名 | 小红  | 123 |

 

 

 

 

 

基础数据控制层:

@Controller
@RequestMapping("/basicData")
public class BasicDataController {
    @Autowired
    private BasicDataService basicDataService;

    @RequestMapping("/list")
    @RequiresPermissions("basicData:list")
    public String basicDataList() {
        return "basicData/list";
    }

    /**
     * 该方法返回 admin 集合的 JSON 字符串,使用 PageHelper 工具进行分页
     * @param keyWord 搜索关键字
     * @param pageNum 页数,默认为 1
     * @param pageSize 每个页面用户容量,默认为 10/页
     * @return
     */
    @ResponseBody
    @RequestMapping("/getBasicDatas")
    @RequiresPermissions("basicData:list")
    public PageInfo<BasicData> getBasicDatas(String keyWord,
                                              @RequestParam(defaultValue = "1") Integer pageNum,
                                              @RequestParam(defaultValue = "10") Integer pageSize) {
        //开始分页,这里启动并设置页码,和每页结果数量后,后续结果会自动为分页后结果
        PageHelper.startPage(pageNum, pageSize);

         BasicDataExample basicDataExample = new BasicDataExample();

        /**
         * StringUtils.isNotBlank 可以判断 ""/" "/null 为 false
         */
        if (StringUtils.isNotBlank(keyWord)) {
            //权限名条件
            BasicDataExample.Criteria criteriaName = basicDataExample.createCriteria();
            criteriaName.andBaseNameLike("%" + keyWord + "%");
        }

        List<BasicData> basicDatas = basicDataService.selectByExample(basicDataExample);
        //获得分页对象
        PageInfo<BasicData> pageInfo = new PageInfo<>(basicDatas);

        return pageInfo;
    }

    @ResponseBody
    @RequestMapping("/delete")
    @RequiresPermissions("basicData:delete")
    public Map<String, String> delete(Long[] basicDataIds) {
        HashMap<String, String> map = new HashMap<>();
        if (basicDataIds.length == 1) {
            int res = basicDataService.deleteByPrimaryKey(basicDataIds[0]);
            if (res == 1) {
                map.put("status", "true");
                map.put("info", "删除成功!");
                return map;
            }
            map.put("status", "false");
            map.put("info", "删除失败!数据已经不存在");
            return map;
        }
        //批量删除
        int success = 0;
        int total = basicDataIds.length;
        for(Long basicDataId : basicDataIds) {
            success += basicDataService.deleteByPrimaryKey(basicDataId);
        }
        map.put("status", "true");
        map.put("info", "成功删除选中 " + total + " 数据中的 " + success + " 个数据");
        return map;
    }


    @RequestMapping("/add")
    @RequiresPermissions("basicData:insert")
    public String addAdmin(Model m) {
        BasicDataExample basicDataExample = new BasicDataExample();
        BasicDataExample.Criteria criteria = basicDataExample.createCriteria();
        criteria.andParentIdIsNull();
        List<BasicData> basicDatas = basicDataService.selectByExample(basicDataExample);
        m.addAttribute("basicDatas", basicDatas);
        return "basicData/add";
    }

    @ResponseBody
    @RequestMapping("/checkBasicData")
    @RequiresPermissions("basicData:list")
    public Boolean checkPermission(String name, String curName) {
        if (curName != null && name.equals(curName)) {
            return true;
        }
        BasicDataExample basicDataExample = new BasicDataExample();
        BasicDataExample.Criteria criteria = basicDataExample.createCriteria();
        criteria.andBaseNameEqualTo(name);
        if (basicDataService.selectByExample(basicDataExample).size() != 0) {
            return false;
        }
        return true;
    }

    @ResponseBody
    @RequestMapping("/insert")
    @RequiresPermissions("basicData:insert")
    public Boolean insert(BasicData basicData){
        int res = basicDataService.insert(basicData);
        if (res == 1) {
            return true;
        }
        return false;
    }

    @RequestMapping("/edit")
    @RequiresPermissions("basicData:update")
    public String edit(Model m, Long basicDataId) {
        m.addAttribute("myBasicData", basicDataService.selectByPrimaryKey(basicDataId));

        BasicDataExample basicDataExample = new BasicDataExample();
        BasicDataExample.Criteria criteria = basicDataExample.createCriteria();
        criteria.andParentIdIsNull();
        m.addAttribute("basicDatas", basicDataService.selectByExample(basicDataExample));
        return "basicData/edit";
    }

    @ResponseBody
    @RequestMapping("/update")
    @RequiresPermissions("basicData:update")
    public Boolean update(BasicData basicData) {
        int res = basicDataService.updateByPrimaryKey(basicData);
        if (res == 1) {
            return true;
        }
        return false;
    }
}

后台管理员控制层:

@Controller
@RequestMapping("/admin")
public class AdminController {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    @RequestMapping("/list")
    @RequiresPermissions("admin:list")
    public String adminList() {
        return "admin/list";
    }

    /**
     * 该方法返回 admin 集合的 JSON 字符串,使用 PageHelper 工具进行分页
     * @param keyWord 搜索关键字
     * @param pageNum 页数,默认为 1
     * @param pageSize 每个页面用户容量,默认为 10/页
     * @return
     */
    @ResponseBody
    @RequestMapping("/getAdmins")
    @RequiresPermissions("admin:list")
    public PageInfo<User> getAdmins(String keyWord,
                                @RequestParam(defaultValue = "1") Integer pageNum,
                                @RequestParam(defaultValue = "10") Integer pageSize) {
        //开始分页,这里启动并设置页码,和每页结果数量后,后续结果会自动为分页后结果
        PageHelper.startPage(pageNum, pageSize);

        UserExample userExample = new UserExample();

        /**
         * StringUtils.isNotBlank 可以判断 ""/" "/null 为 false
         */
        if (StringUtils.isNotBlank(keyWord)) {
            //用户名条件
            UserExample.Criteria criteriaUserName = userExample.createCriteria();
            criteriaUserName.andUsernameLike("%" + keyWord + "%");

            //真实名字条件
            UserExample.Criteria criteriaRealName = userExample.createCriteria();
            criteriaRealName.andRealnameLike("%" + keyWord + "%");

            //将两个条件用 or 组合
            userExample.or(criteriaRealName);
        }

        List<User> users = userService.selectByExample(userExample);
        //获得分页对象
        PageInfo<User> pageInfo = new PageInfo<>(users);

        return pageInfo;
    }

    @ResponseBody
    @RequestMapping("/delete")
    @RequiresPermissions("admin:delete")
    public Map<String, String> delete(Long[] userIds) {
        HashMap<String, String> map = new HashMap<>();
        if (userIds.length == 1) {
            int res = userService.deleteByPrimaryKey(userIds[0]);
            if (res == 1) {
                map.put("status", "true");
                map.put("info", "删除成功!");
                return map;
            }
            map.put("status", "false");
            map.put("info", "删除失败!用户已经不存在");
            return map;
        }
        //批量删除
        int success = 0;
        int total = userIds.length;
        for(Long userId : userIds) {
            success += userService.deleteByPrimaryKey(userId);
        }
        map.put("status", "true");
        map.put("info", "成功删除选中 " + total + " 个用户中的 " + success + " 个用户");
        return map;
    }

    @RequiresPermissions("admin:insert")
    @RequestMapping("/add")
    public String addAdmin(Model m) {
        RoleExample roleExample = new RoleExample();
        List<Role> roles = roleService.selectByExample(roleExample);
        m.addAttribute("roles", roles);
        return "admin/add";
    }

    @ResponseBody
    @RequestMapping("/checkUsername")
    @RequiresPermissions("admin:list")
    public Boolean checkUsername(String username) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(username);
        System.out.println(userService.selectByExample(userExample));
        if (userService.selectByExample(userExample).size() != 0) {
            return false;
        }
        return true;
    }

    @ResponseBody
    @RequestMapping("/insert")
    @RequiresPermissions("admin:insert")
    public Boolean insert(User user){
        String salt = UUID.randomUUID().toString().substring(0, 4);
        String hashedPassword = new SimpleHash("md5", user.getPassword(), salt,3).toString();
        user.setSalt(salt);
        user.setPassword(hashedPassword);
        user.setCreateDate(new Date());
        int res = userService.insert(user);
        if (res == 1) {
            return true;
        }
        return false;
    }

    @RequestMapping("/edit")
    @RequiresPermissions("admin:update")
    public String edit(Model m, Long userId) {
        m.addAttribute("user", userService.selectByPrimaryKey(userId));
        m.addAttribute("roles", roleService.selectByExample(new RoleExample()));
        return "admin/edit";
    }

    @ResponseBody
    @RequestMapping("/update")
    @RequiresPermissions("admin:update")
    public Boolean update(User user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            String salt = UUID.randomUUID().toString().substring(0, 4);
            String hashedPassword = new SimpleHash("md5", user.getPassword(), salt, 3).toString();
            user.setPassword(hashedPassword);
            user.setSalt(salt);
        }
        int res = userService.updateByPrimaryKeySelective(user);
        if (res == 1) {
            return true;
        }
        return false;
    }
}

订单管理控制层:

@Controller
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderViewService orderViewService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private UserService userService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private BasicDataService basicDataService;

    @Autowired
    private OrderDetailService orderDetailService;

    //工具方法
    public PageInfo<OrderView> getOrdersUtil(String keyWord, Integer pageNum, Integer pageSize) {
        //开始分页,这里启动并设置页码,和每页结果数量后,后续结果会自动为分页后结果
        PageHelper.startPage(pageNum, pageSize);

        OrderViewExample orderViewExample = new OrderViewExample();
        OrderViewExample.Criteria criteria = orderViewExample.createCriteria();
        /**
         * StringUtils.isNotBlank 可以判断 ""/" "/null 为 false
         */
        if (StringUtils.isNotBlank(keyWord)) {
            //客户名条件
            criteria.andCustomerNameLike("%" + keyWord + "%");
        }

        //判断当前登录用户是否为业务员,业务员只能查看自己的订单
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        if (user.getRoleId() == ConstantDataField.SALESMAN_ROLE_ID) {
            //客户的业务员用户名等于登录用户的用户名
            criteria.andUsernameEqualTo(user.getUsername());
        }

        List<OrderView> orders = orderViewService.selectByExample(orderViewExample);
        //获得分页对象
        PageInfo<OrderView> pageInfo = new PageInfo<>(orders);

        return pageInfo;
    }

    @RequestMapping("/list")
    @RequiresPermissions("order:list")
    public String list() {
        return "order/list";
    }

    @ResponseBody
    @RequestMapping("/getOrders")
    @RequiresPermissions("order:list")
    public PageInfo<OrderView> getOrders(String keyWord,
                                        @RequestParam(defaultValue = "1") Integer pageNum,
                                        @RequestParam(defaultValue = "10") Integer pageSize) {
        return getOrdersUtil(keyWord, pageNum, pageSize);
    }

    @ResponseBody
    @RequestMapping("/delete")
    @RequiresPermissions("order:delete")
    public Map<String, String> delete(Long[] orderIds) {
        HashMap<String, String> map = new HashMap<>();
        //单个删除
        if (orderIds.length == 1) {
            int res = orderService.deleteByPrimaryKey(orderIds[0]);
            if (res == 1) {
                map.put("status", "true");
                map.put("info", "删除成功!");
                return map;
            }
            map.put("status", "false");
            map.put("info", "删除失败!订单已经不存在");
            return map;
        }
        //批量删除
        int success = 0;
        int total = orderIds.length;
        for(Long orderId : orderIds) {
            success += orderService.deleteByPrimaryKey(orderId);
        }
        map.put("status", "true");
        map.put("info", "成功删除选中 " + total + " 个订单中的 " + success + " 个订单");
        return map;
    }

    @RequestMapping("/add")
    @RequiresPermissions("order:insert")
    public String add(Model m) {
        this.getOrderGeneralData(m);
        return "order/add";
    }


    /*
    用 @RequestBody 注解,将前台传入的 JSON 字符串解析成对象
     */
    @RequestMapping("/insert")
    @RequiresPermissions("order:insert")
    @ResponseBody
    @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, timeout = 5)
    public Boolean insert(@RequestBody Order order) {
        //插入 order,在此之后,order 获得了 orderId
        int res = orderService.insert(order);
        //获取订单详情集合
        List<OrderDetail> orderDetails = order.getorderDetails();
        orderDetails.forEach(orderDetail -> {
            orderDetail.setOrderId(order.getOrderId());
            orderDetailService.insert(orderDetail);
        });
        if (res == 1) {
            return true;
        }
        return false;
    }

    @RequestMapping("/edit")
    @RequiresPermissions("order:update")
    public String edit(Long orderId, Model m) {
        //获取常规数据
        getOrderGeneralData(m);

        //添加选中的订单
        Order selectedOrder = orderService.selectByPrimaryKey(orderId);
        m.addAttribute("selectedOrder", selectedOrder);

        //添加订单详情
        OrderDetailExample orderDetailExample = new OrderDetailExample();
        orderDetailExample.createCriteria().andOrderIdEqualTo(orderId);
        List<OrderDetail> orderDetails = orderDetailService.selectByExample(orderDetailExample);
        m.addAttribute("orderDetails", orderDetails);

        return "order/edit";
    }

    @RequiresPermissions("order:update")
    @RequestMapping("/update")
    @ResponseBody
    public Boolean update(@RequestBody Order order) {
        OrderDetailExample orderDetailExample = new OrderDetailExample();
        orderDetailExample.createCriteria().andOrderIdEqualTo(order.getOrderId());
        List<OrderDetail> dbOrderDetails = orderDetailService.selectByExample(orderDetailExample); //数据库中的orderDetails
        List<OrderDetail> formOrderDetails = order.getorderDetails(); //表单数据中的orderDetails

        //循环比较数据库数据和表单新数据,删除数据库中在修改中删除的数据
        dbOrderDetails.forEach(dbOrderDetail -> {
            if (!formOrderDetails.contains(dbOrderDetail)) {
                orderDetailService.deleteByPrimaryKey(dbOrderDetail.getOrderDetailId());
            }
        });

        //循环比较表单新数据和数据库数据,若存在则修改,不存在则新增
        formOrderDetails.forEach(formOrderDetail -> {
            if (dbOrderDetails.contains(formOrderDetail)) {
                orderDetailService.updateByPrimaryKeySelective(formOrderDetail);
            } else {
                formOrderDetail.setOrderId(order.getOrderId());
                orderDetailService.insert(formOrderDetail);
            }
        });

        //修改Order
        int res = orderService.updateByPrimaryKey(order);
        if (res == 1){
            return true;
        }
        return false;
    }

    //抽取的工具方法
    private void getOrderGeneralData(Model m){
        User user = (User)SecurityUtils.getSubject().getPrincipal(); //获取当前用户
        Long userRoleId = user.getRoleId(); //当前用户角色ID
        Long userId = user.getUserId(); //当前用户ID

        //查找业务员
        UserExample userExample = new UserExample();
        List<User> users = new ArrayList<>();
        //如果当前用户是业务员只能用自己用户添加
        if (userRoleId == ConstantDataField.SALESMAN_ROLE_ID) {
            users.add(userService.selectByPrimaryKey(userId));
        } else {
            userExample.createCriteria().andRoleIdEqualTo(ConstantDataField.SALESMAN_ROLE_ID);
            users = userService.selectByExample(userExample);
        }
        m.addAttribute("users", users);

        //查找客户
        CustomerExample customerExample = new CustomerExample();
        List<Customer> customers;
        //如果当前用户是业务员只能获得自己的客户
        if (userRoleId == ConstantDataField.SALESMAN_ROLE_ID) {
            customerExample.createCriteria().andUserIdEqualTo(userId);
            customers = customerService.selectByExample(customerExample);
        } else {
            customers = customerService.selectByExample(customerExample);
        }
        m.addAttribute("customers", customers);

        //查找地区
        BasicDataExample areaExample = new BasicDataExample();
        areaExample.createCriteria().andParentIdEqualTo(ConstantDataField.AREA_BASICDATA_ID);
        List<BasicData> areas = basicDataService.selectByExample(areaExample);
        m.addAttribute("areas", areas);

        //查找付款方式
        BasicDataExample paymentExample = new BasicDataExample();
        paymentExample.createCriteria().andParentIdEqualTo(ConstantDataField.PAYMENT_BASICDATA_ID);
        List<BasicData> payments = basicDataService.selectByExample(paymentExample);
        m.addAttribute("payments", payments);

        //查找运送方式
        BasicDataExample transportExample = new BasicDataExample();
        transportExample.createCriteria().andParentIdEqualTo(ConstantDataField.TRANSPORT_BASICDATA_ID);
        List<BasicData> transports = basicDataService.selectByExample(transportExample);
        m.addAttribute("transports", transports);

        //查找取件方式
        BasicDataExample pickupExample = new BasicDataExample();
        pickupExample.createCriteria().andParentIdEqualTo(ConstantDataField.PICKUP_BASICDATA_ID);
        List<BasicData> pickups = basicDataService.selectByExample(pickupExample);
        m.addAttribute("pickups", pickups);

        //查找单位
        BasicDataExample unitExample = new BasicDataExample();
        unitExample.createCriteria().andParentIdEqualTo(ConstantDataField.UNIT_BASICDATA_ID);
        List<BasicData> units = basicDataService.selectByExample(unitExample);
        m.addAttribute("units", units);
    }
}

 源码获取:博客首页 "资源" 里下载!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
【资源说明】 课程设计基于Java实现的校园快递代拿系统源码+sql数据库+项目详细说明.zip 1、该资源内项目代码都是经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果有一点儿基础,亦可在此代码基础上进行修改,以实现其他功能。 项目核心功能简述: 在此之前最好先看下notes、plan目录下的txt文件 本项目是一个自己臆想出需求(当然,大部分以课程设计文档需求为主)的大学快递代拿服务系统, 后端使用了springboot,mybatis-plus,redis(含lua),rocketmq等进行功能开发实现。 除此之外也整合了nacos,sentinel实现了简单的微服务 至于前端,本人前端水平有限,只能使用老一套的jq,bootstrap实现 分配配送员完整思路 各组件使用情况: 1. springboot作为项目使用的基础建设框架 2. mybatis-plus作为crud核心(为什么不用tk?因为mybatis-plus的使用更为简单,尤其是乐观锁、逻辑删除等) 3. spring security+oauth2使用rsa加密实现认证中心(我这里没有使用io.jsonwebtoken,实际上应该使用,nacos的源码也有使用jjwt,我没使用只是为了更好的熟悉security的部分源码) 4. redis除了用作基本缓存以外,还是程序实现自动分配配送员的核心(详细看plan目录下的编写计划),简单概括下就是zset+lua实现区域按权重分配配送员 5. rocketmq则是用作订单超时自动取消、用户支付后发送分配配送员的事务消息,用户评价后发送分数校准的事务消息 6. nacos作为注册中心服务发现 7. sentinel作为服务熔断/限流降级 8. 实现了配送员签到/加班功能,能统计连签天数 9. 也实现了不同会员下单时打折的功能 10. 也有整合swagger(layui),访问地址是 ip:port + context-path + /docs.html,例如localhost:40200/order/docs.html或http://localhost:40300/docs.html,如果提示Access token expired请清除cookie 额外说明: 1. 启动express-order之前要启动express-ucenter, 2. 因为初始化配送员权重的代码写到order去了,order需要远程调用ucenter。 3. 代码还可能出现大改 4. 2019/11/22日之前rocketmq的两阶段提交还没学透,所以在这之前写的rocketmq事务处理方式是错的 5. 账号到数据库看,密码不是 mimajiushi 就是 123 6. express-auth 暂时没实现注册,登录页面 http://localhost:40400/page/index 7. 项目启动需要nacos是启动的,nacos的ip改成自己的, sentinel暂时可有可无 8. 项目中的反馈功能还未实现,因为只是简单的crud(包括某些查询)没什么新知识,所以暂时放着不管 9. 本项目偏向于个人的未知领域探索实现(绝对不是因为偷懒,笑),比如分布式事务如何保证最终一致性等,所以对个别功能定了计划但并没有实现, 比如:百度地图的区域可视化,收获地址管理等(以前的作品都实现过的功能我就不再实现了) 缺点: 1. 部份表可能显得比较肿,主要原因还是时间有限,不想重复过多无意义的dao代码 2. 我前端比较垃圾 3. 授权粒度只细化到角色级别,白话就是角色即权限,这么做一方面本项目没有前后分离也没有实现前后分离的动态路由,所以没必要细化到各角色权限也能实现该有的功能 4. 一些开源组件实现可能还存在比较细节的错误 一些容易出错的坑和项目主要关注的点: 1. 一个大坑就是rocketmq,我是现学现用的,曾因为理论不完善而导致代码多次出现大改, 1.1. 主要坑有两个,一个两阶段提交如何确保事务最终一致性(其实就是这学期nosql的理论实践)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beyondwild

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值