汽车租赁系统


汽车租赁系统

1.用户模块

1.用户列表

1.修改 user/list.jsp

<%--操作--%> <script type="text/html" id="headBtns"> </script> <script type="text/html" id="rowBtns"> </script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/sysuser/page.do", page:true, toolbar: "#headBtns", cols:[[ {type:"checkbox"}, {field:"realname",title:"姓名",align:"center",width: 85}, {field:"loginName",title:"登录名",align:"center",width: 85}, {field:"phone",title:"电话",align:"center"}, {field:"idCard",title:"身份证",align:"center",minWidth:"170"}, {field:"sex",title:"性别",align:"center",width:65,templet:function (d) { var sex = d.sex; if (sex == 1){ return "

"; }else if (sex == 2){ return "

"; } }}, {field:"address",title:"地址",align:"center",width: 100}, {title:"头像",width: 65,templet:function (d) { var img = d.img; return "" }}, {field:"createTime",title:"创建时间",align:"center"}, {field: "操作",toolbar:"#rowBtns", minWidth: 230, fixed: "right"} ]], parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var realname = $("#realname").val(); var phone = $("#phone").val(); var address = $("#address").val(); tabIns.reload({ where:{ realname:realname, phone:phone, address:address } }) }) }); </script>

2.修改SysUserController

/**
 * 用户的分页查询
 *
 * @return
 */
@RequestMapping("page.do")
public Object page(SysUserQuery query) {

    return this.sysUserService.queryPage(query);
}

3.修改SysUserService

/**
 * 用户的分页查询
 *
 * @param query
 * @return
 */
Result queryPage(SysUserQuery query);

4.修改SysUserServiceImpl

/**
 * 用户的分页查询
 *
 * @param query
 * @return
 */
@Override
public Result queryPage(SysUserQuery query) {
    // 开启分页查询
    Page sysUserPage = PageHelper.startPage(query.getPage(), query.getLimit());
    // 根据参数查询用户列表
    sysUserMapper.selectList(query);
    return new Result(sysUserPage.toPageInfo());
}

5.修改SysUserMapper

/**
 * 根据参数查询用户列表
 *
 * @param query
 * @return
 */
List selectList(SysUserQuery query);

6.修改SysUserMapper.xml


2.新增用户

1.修改 user/list.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>



    
    用户管理
    
    
    
    
    
    
    
    


<%--操作--%> <script type="text/html" id="headBtns"> </script> <script type="text/html" id="rowBtns"> </script> <%--新增用户模板--%> <script type="text/html" id = "addUserTpl">
</script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/sysuser/page.do", page:true, toolbar: "#headBtns", cols:[[ {type:"checkbox"}, {field:"realname",title:"姓名",align:"center",width: 85}, {field:"loginName",title:"登录名",align:"center",width: 85}, {field:"phone",title:"电话",align:"center"}, {field:"idCard",title:"身份证",align:"center",minWidth:"170"}, {field:"sex",title:"性别",align:"center",width:65,templet:function (d) { var sex = d.sex; if (sex == 1){ return "

"; }else if (sex == 2){ return "

"; } }}, {field:"address",title:"地址",align:"center",width: 100}, {title:"头像",width: 65,templet:function (d) { var img = d.img; return "" }}, {field:"createTime",title:"创建时间",align:"center"}, {field: "操作",toolbar:"#rowBtns", minWidth: 230, fixed: "right"} ]], parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var realname = $("#realname").val(); var phone = $("#phone").val(); var address = $("#address").val(); tabIns.reload({ where:{ realname:realname, phone:phone, address:address } }) }) //表格头工具栏监听事件 table.on("toolbar(dataTableFilter)",function (d) { var event = d.event; if (event == "add"){ add(); } }) //新增用户的方法 function add() { //弹出层的参数 var layOps = { title:"新增用户", type:1, skin: "layui-layer-molv", content:$("#addUserTpl").html(), area:['680px','450px'], success:function (layero,index) { form.render("radio"); //表单的提交监听 form.on("submit(subBtnFilter)",function (d) { var formData = d.field; //使用ajax提交数据 $.post(cxt+"/sysuser/add.do",formData,function (rs) { layer.msg(rs.msg); //展示业务消息 if (rs.code != 200){ return false; } layer.close(index); //关闭弹层 //刷新表格 $("#searchBtn").click(); }) return false;//阻止默认提交行为 }) }, btn:['确认','取消'], btnAlign: "c", yes:function (index,layero) { //点击隐藏的提交按钮 触发 表单提交监听 $("#subBtn").click(); } }; layer.open(layOps); } }); </script>

2.修改SysUserController

/**
 * 用户的分页查询
 *
 * @return
 */
@RequestMapping("page.do")
public Object page(SysUserQuery query) {

    return this.sysUserService.queryPage(query);
}

/**
 * 新增用户
 *
 * @param sysUser
 * @return
 */
@RequestMapping("add.do")
public Object add(SysUser sysUser) {
    // 进行数据格式校验
    ValidatorUtil.validator(sysUser);
    return sysUserService.add(sysUser);
}

3.修改SysUser

package com.toddding.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Description: 用户实体类
 * @author: Todd Ding
 * @date 2020-11-30 14:50
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysUser {
    /**
     * 用户ID
     */
    private Integer id;

    /**
     * 登录名
     */
    @NotEmpty(message = "loginName:登录名不能为空")
    @Length(min = 6,max = 15,message = "loginName:登录名6~15位字符")
    private String loginName;

    /**
     * 登录密码
     */
    private String loginPassword;

    /**
     * 手机号
     */
    @NotEmpty(message = "phone:手机号不能为空")
    @Length(min = 11,max = 11,message = "phone:手机号11位字符")
    private String phone;

    /**
     * 真实姓名
     */
    @NotEmpty(message = "realname:姓名不能为空")
    @Length(max = 20,message = "realname:姓名最多20位字符")
    private String realname;

    /**
     * 身份证号
     */
    @NotEmpty(message = "idCard:身份证号不能为空")
    @Length(min=18,max = 18,message = "idCard:身份证号18位字符")
    private String idCard;

    /**
     * 性别  1 男  2 女
     */
    @NotNull(message = "sex:性别不能为空")
    @Range(min = 1,max = 2,message = "sex:性别只能是男(1)或者女(2)")
    private Integer sex;

    /**
     * 地址
     */
    @NotEmpty(message = "address:地址不能为空")
    @Length(max = 100,message = "address:地址最多100个字符")
    private String address;

    /**
     * 图像
     */
    private String img;

    /**
     * 创建时间
     */
    @JsonFormat(pattern="yyyy-MM-dd")
    private Date createTime;


}

4.修改SysUserService

/**
 * 用户的分页查询
 *
 * @param query
 * @return
 */
Result queryPage(SysUserQuery query);

/**
 * 新增用户
 *
 * @param sysUser
 * @return
 */
Result add(SysUser sysUser);

5.修改SysUserServiceImpl

/**
 * 用户的分页查询
 *
 * @param query
 * @return
 */
@Override
public Result queryPage(SysUserQuery query) {
    // 开启分页查询
    Page sysUserPage = PageHelper.startPage(query.getPage(), query.getLimit());
    // 根据参数查询用户列表
    sysUserMapper.selectList(query);
    return new Result(sysUserPage.toPageInfo());
}

/**
 * 新增用户
 *
 * @param sysUser
 * @return
 */
@Override
public Result add(SysUser sysUser) {
    // 进行业务数据校验
    SysUserQuery query = new SysUserQuery();
    // 校验用户名是否重复
    query.setLoginName(sysUser.getLoginName());
    // 根据登录名查询用户
    SysUser user = sysUserMapper.selectUserByKeywords(query);
    if (user != null) {
        return new Result(CodeMsg.USER_LOGIN_NAME_EXIST_ERROR);
    }

    // 校验手机号是否重复
    query = new SysUserQuery();
    query.setPhone(sysUser.getPhone());
    // 根据手机号查询用户
    user = sysUserMapper.selectUserByKeywords(query);
    if (user != null) {
        return new Result(CodeMsg.USER_PHONE_EXIST_ERROR);
    }

    // 校验身份证号是否重复
    query = new SysUserQuery();
    query.setIdCard(sysUser.getIdCard());
    // 根据身份证号查询用户
    user = sysUserMapper.selectUserByKeywords(query);
    if (user != null) {
        return new Result(CodeMsg.USER_ID_CARD_EXIST_ERROR);
    }

    // 新增用户
    // 获取加密后的默认密码
    Md5Hash md5Hash = new Md5Hash(Constant.DEFAULT_PASSWORD, Constant.MD5_SALT, 2);
    sysUser.setLoginPassword(md5Hash.toString());
    sysUserMapper.insert(sysUser);
    return new Result();
}

6.修改CodeMsg

public enum CodeMsg {
USER_USER_PASSWORD_ERROR(4001001, "用户名或者密码错误!"),
USER_LOGIN_NAME_EXIST_ERROR(4001002, "用户登录名已被使用!"),
USER_PHONE_EXIST_ERROR(4001003, "用户手机号已被使用!"),
USER_ID_CARD_EXIST_ERROR(4001004, "用户身份证号已被使用!"),
USER_NOT_HAVE_PERMISSION_ERROR(4001005, "用户权限不足!"),
USER_UPDATE_PASSWORD_ERROR(4001006, "修改失败,原密码不正确"),

CUSTOMER_ID_CARD_EXIST_ERROR(4002001, "客户身份证号已被使用!"),
CUSTOMER_PHONE_EXIST_ERROR(4002002, "客户手机号已被使用!"),
}

7.修改Constant

public interface Constant {
/**
 * MD5加密的盐
 */
String MD5_SALT = "day day up";
/**
 * 默认的登录密码
 */
String DEFAULT_PASSWORD = "123456";
}

8.修改SysUserMapper

public interface SysUserMapper {
/**
 * 校验用户关键字是否重复
 *
 * @param query 包含 登录名/手机号/身份证号
 * @return
 */
SysUser selectUserByKeywords(SysUserQuery query);

/**
 * 新增用户
 *
 * @param sysUser
 */
void insert(SysUser sysUser);
}

9.修改SysUserMapper.xml



    insert into
        sys_user (login_name, login_password, phone, realname, id_card, sex, address)
    value
        (#{loginName}, #{loginPassword}, #{phone}, #{realname}, #{idCard}, #{sex}, #{address})

3.重置密码

1.修改user/list.jsp

 
<script type="text/html" id="rowBtns"> </script> //表格行工具栏事件 table.on("tool(dataTableFilter)",function (d) { var event = d.event; var rowData = d.data; if (event == "resetPwd"){ resetPwd(rowData); } }) //重置密码方法 function resetPwd(rowData) { layer.confirm("确定要重置密码吗?",function (index) { $.get(cxt+"/sysuser/reset.do",{id:rowData.id},function (rs) { //展示业务消息 layer.msg(rs.msg); layer.close(index); //关闭弹出层 $("#searchBtn").click(); //重载表格 }) }) }

2.修改SysUserController

/**
 * 重置用户密码
 *
 * @param id
 * @return
 */
@RequestMapping("reset.do")
public Object reset(Integer id) {

    return sysUserService.resetPassword(id);
}

3.修改SysUserService

/**
 * 重置用户密码
 *
 * @param id
 * @return
 */
Result resetPassword(Integer id);

4.修改SysUserServiceImpl

/**
 * 重置用户密码
 *
 * @param id
 * @return
 */
@Override
public Result resetPassword(Integer id) {
    Md5Hash md5Hash = new Md5Hash(Constant.DEFAULT_PASSWORD, Constant.MD5_SALT, 2);
    sysUserMapper.updatePassword(id, md5Hash.toString());
    return new Result();
}

5.修改SysUserMapper

/**
 * 修改用户密码
 *
 * @param id
 * @param password
 */
void updatePassword(@Param("id") Integer id, @Param("password") String password);

6.修改SysUserMapper.xml


    update sys_user set login_password = #{password} where id = #{id}

4.显示用户头像

? 查看用户头像,就是将用户头像url地址进行显示

1.修改user/list.jsp

{title:"头像",width: 65,templet:function (d) {
                    var img = d.img;
                    return ""
                    }}


//显示头像的方法
// url : 图像的网络路径
window.showUserImg = function (url) {
    var  imgData = {
        "title": "用户头像", //相册标题
        "start": 0, //初始显示的图片序号,默认0
        "data": [   //相册包含的图片,数组格式
            {
                "alt": "用户头像",
                "src": cxt + "/" + url, //原图地址
                "thumb":  cxt + "/" + url //缩略图地址
            }
        ]
    }
    layer.photos({
        photos: imgData
    });
}

2.车辆模块

1.车辆列表

1.新建car/list.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>



    
    汽车管理
    
    
    
    
    
    
    
    


-
-
<%--操作--%> <script type="text/html" id="headBtns"> </script> <script type="text/html" id="rowBtns"> <%-- --%> </script> <%--新增用户模板--%> <script type="text/html" id = "addUserTpl">
</script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table','upload'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; var upload = layui.upload; //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/car/page.do", page:true, toolbar: "#headBtns", cols:[[ {type:"checkbox"}, {field:"num",title:"车牌号",align:"center",width: 115}, {field:"type",title:"车型",align:"center",width: 95,templet:function (d) { var type = d.type; if (type == 1){ return "

轿车

"; }else if (type == 2){ return "

SUV

"; }else if(type == 3){ return "

跑车

"; } }}, {field:"color",title:"颜色",align:"center"}, {field:"price",title:"价格",align:"center",width: 100}, {field:"rentPrice",title:"出租价格",align:"center",width:100}, {field:"deposit",title:"押金",align:"center",width: 100}, {field:"isRent",title:"出租状态",align:"center",width: 100,templet:function (d) { var isRent = d.isRent; if (isRent == 1) { return "

未出租

"; }else if (isRent == 2){ return "

未出租

"; } }}, {field:"descp",title:"描述",align:"center",width: 110}, {field:"img",title:"车辆图片",align:"center",width: 90,templet:function (d) { var img = d.img; return "" }}, {field:"version",title:"版本",align:"center",width: 80}, {field:"createTime",title:"创建时间",align:"center",width: 160}, {field: "操作",toolbar:"#rowBtns", minWidth: 60, fixed: "right"} ]], parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var num = $("#num").val(); var type = $("#type").val(); var color = $("#color").val(); var minPrice = $("#minPrice").val(); var maxPrice = $("#maxPrice").val(); var minRentPrice = $("#minRentPrice").val(); var maxRentPrice = $("#maxRentPrice").val(); var isRent = $("#isRent").val(); var descp = $("#descp").val(); tabIns.reload({ where:{ num:num, type:type, color:color, minPrice:minPrice, maxPrice:maxPrice, minRentPrice:minRentPrice, maxRentPrice:maxRentPrice, isRent:isRent, descp:descp, } }) }) //表格头工具栏监听事件 table.on("toolbar(dataTableFilter)",function (d) { var event = d.event; if (event == "add"){ add(); } }) //新增用户的方法 function add() { //弹出层的参数 var layOps = { title:"新增用户", type:1, skin: "layui-layer-molv", content:$("#addUserTpl").html(), area:['680px','450px'], success:function (layero,index) { form.render("radio"); //表单的提交监听 form.on("submit(subBtnFilter)",function (d) { var formData = d.field; //使用ajax提交数据 $.post(cxt+"/sysuser/add.do",formData,function (rs) { layer.msg(rs.msg); //展示业务消息 if (rs.code != 200){ return false; } layer.close(index); //关闭弹层 //刷新表格 $("#searchBtn").click(); }) return false;//阻止默认提交行为 }) }, btn:['确认','取消'], btnAlign: "c", yes:function (index,layero) { //点击隐藏的提交按钮 触发 表单提交监听 $("#subBtn").click(); } }; layer.open(layOps); } //表格行工具栏事件 table.on("tool(dataTableFilter)",function (d) { var event = d.event; var rowData = d.data; if (event == "resetPwd"){ resetPwd(rowData); } }) //重置密码方法 function resetPwd(rowData) { layer.confirm("确定要重置密码吗?",function (index) { $.get(cxt+"/sysuser/reset.do",{id:rowData.id},function (rs) { //展示业务消息 layer.msg(rs.msg); layer.close(index); //关闭弹出层 $("#searchBtn").click(); //重载表格 }) }) } //显示头像的方法 // url : 图像的网络路径 window.showUserImg = function (url) { var imgData = { "title": "用户头像", //相册标题 "start": 0, //初始显示的图片序号,默认0 "data": [ //相册包含的图片,数组格式 { "alt": "用户头像", "src": cxt + "/" + url, //原图地址 "thumb": cxt + "/" + url //缩略图地址 } ] } layer.photos({ photos: imgData }); } }); </script>

2.修改PageController

/**
 * 跳转车辆列表
 *
 * @return
 */
@RequestMapping("car/list.do")
public String carList() {
    return "car/list.jsp";
}

3.新建BusCar

package com.toddding.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Description: 车辆实体类
 * @Author: Todd Ding
 * @Date 2020-12-02 19:21
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BusCar {
    /**
     * 汽车ID
     */
    private Integer id;


    /**
     * 车牌号
     */
    @NotEmpty(message = "车牌号不能为空")
    @Length(min = 7, max = 8, message = "车牌号7-8位")
    private String num;

    /**
     * 类型  1 轿车  2 SUV  3 跑车
     */
    @NotNull(message = "车型不能为空")
    @Range(min = 1, max = 3, message = "车辆类型只能1-3")
    private Integer type;

    /**
     * 颜色
     */
    @NotEmpty(message = "汽车颜色不能为空")
    @Length(max = 10, message = "汽车颜色最多10位字符")
    private String color;

    /**
     * 价格
     */
    @NotNull(message = "汽车金额不能为空")
    @Range(min = 1, max = 999999999, message = "汽车金额1-999999999")
    private Integer price;

    /**
     * 出租金额
     */
    @NotNull(message = "汽车租金不能为空")
    @Range(min = 1, max = 999999999, message = "汽车租金1-999999999")
    private Integer rentPrice;

    /**
     * 押金
     */
    @NotNull(message = "汽车押金不能为空")
    @Range(min = 1, max = 999999999, message = "汽车押金1-999999999")
    private Integer deposit;

    /**
     * 出租状态 1 未出租  2 已出租
     */
    private Integer isRent;

    /**
     * 描述
     */
    @Length(max = 100, message = "汽车描述最多100个字符")
    private String descp;

    /**
     * 汽车图片
     */
    @NotEmpty(message = "汽车图片不能为空")
    @Length(max = 100, message = "汽车图片地址最多100位字符")
    private String img;

    /**
     * 版本号
     */
    private Integer version;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
    private Date createTime;
}

4.新建BusCarQuery

package com.toddding.query;

import lombok.Data;

/**
 * @Description: 车辆列表的查询参数封装类
 * @Author: Todd Ding
 * @Date 2020-12-02 19:54
 */
@Data
public class BusCarQuery extends Query {
    /**
     * 车牌号
     */
    private String num;
    /**
     * 车型
     */
    private Integer type;
    /**
     * 颜色
     */
    private String color;
    /**
     * 最低价格
     */
    private Integer minPrice;
    /**
     * 最高价格
     */
    private Integer maxPrice;
    /**
     * 最低租金
     */
    private Integer minRentPrice;
    /**
     * 最高租金
     */
    private Integer maxRentPrice;
    /**
     * 出租状态
     */
    private Integer isRent;
    /**
     * 描述
     */
    private String descp;

}

5.新建BusCarController

package com.toddding.controller;

import com.toddding.query.BusCarQuery;
import com.toddding.service.BusCarService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("car")
@RestController
public class BusCarController {

    @Autowired
    BusCarService busCarService;

    //分页查询数据
    @RequestMapping("page.do")
    public  Object page(BusCarQuery query){
       return busCarService.queryPage(query);
    }
}

6.新建BusCarService

package com.toddding.service;

import com.toddding.common.Result;
import com.toddding.query.BusCarQuery;

public interface BusCarService {

    Result queryPage(BusCarQuery query);
}

7.新建BusCarServiceImpl

@Service
public class BusCarServiceImpl implements BusCarService {
    @Autowired
    private BusCarMapper busCarMapper;

    @Override
    public Result queryPage(BusCarQuery query) {
        Page busCarVoPage = PageHelper.startPage(query.getPage(), query.getLimit());
        busCarMapper.selectList(query);
        return new Result(busCarVoPage.toPageInfo());
    }

8.新建BusCarMapper

public interface BusCarMapper {
    /**
     * 根据条件查询车辆列表
     *
     * @param query
     * @return
     */
    List selectList(BusCarQuery query);
}    

9.新建BusCarMapper.xml


2.新增车辆

1.修改car/list.jsp

<%--操作--%> <script type="text/html" id="headBtns"> </script> <script type="text/html" id="rowBtns"> <%-- --%> </script>
<%-- 新增车辆 --%> <script type="text/html" id="addTpl">
<%-- 隐藏的input 用于接收上传的文件的URL地址 --%>
</script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table','upload'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; var upload = layui.upload; //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/car/page.do", page:true, toolbar: "#headBtns", cols:[[ {type:"checkbox"}, {field:"num",title:"车牌号",align:"center",width: 115}, {field:"type",title:"车型",align:"center",width: 95,templet:function (d) { var type = d.type; if (type == 1){ return "

轿车

"; }else if (type == 2){ return "

SUV

"; }else if(type == 3){ return "

跑车

"; } }}, {field:"color",title:"颜色",align:"center"}, {field:"price",title:"价格",align:"center",width: 100}, {field:"rentPrice",title:"出租价格",align:"center",width:100}, {field:"deposit",title:"押金",align:"center",width: 100}, {field:"isRent",title:"出租状态",align:"center",width: 100,templet:function (d) { var isRent = d.isRent; if (isRent == 1) { return "

未出租

"; }else if (isRent == 2){ return "

未出租

"; } }}, {field:"descp",title:"描述",align:"center",width: 110}, {title:"车辆图片",align:"center",width: 90,templet:function (d) { var img = d.img; return "" }}, {field:"version",title:"版本",align:"center",width: 80}, {field:"createTime",title:"创建时间",align:"center",width: 160}, {field: "操作",toolbar:"#rowBtns", minWidth: 60, fixed: "right"} ]], parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var num = $("#num").val(); var type = $("#type").val(); var color = $("#color").val(); var minPrice = $("#minPrice").val(); var maxPrice = $("#maxPrice").val(); var minRentPrice = $("#minRentPrice").val(); var maxRentPrice = $("#maxRentPrice").val(); var isRent = $("#isRent").val(); var descp = $("#descp").val(); tabIns.reload({ where:{ num:num, type:type, color:color, minPrice:minPrice, maxPrice:maxPrice, minRentPrice:minRentPrice, maxRentPrice:maxRentPrice, isRent:isRent, descp:descp, } }) }) //表格头工具栏监听事件 table.on("toolbar(dataTableFilter)",function (d) { var event = d.event; if (event == "add"){ add(); } }) //新增用户的方法 function add() { //弹出层的参数 var layOps = { title:"新增车辆", type:1, skin: "layui-layer-molv", content:$("#addTpl").html(), area:['710px','580px'], success:function (layero,index) { form.render(); /* 初始化上传组件 */ //初始化文件上传 let uploadOpt = { elem: "#uploadImg", url: cxt + "/file/uploadImage.do",//处理文件上传的接口 auto: true,//自动上传 field: "image",//指定文件上传的数据域名称 choose: function (obj) { //文件预览 obj.preview(function (index, file, result) { //修改图片src属性值 实现预览 $("#uploadImg").attr("src", result); }) }, done: function (rs, fileIndex, upload) { //将业务消息展示 layer.msg(rs.msg); if (rs.code == 200) { //给隐藏框赋值 $("#img").val(rs.data); } } }; upload.render(uploadOpt); //表单的提交监听 form.on("submit(subBtnFilter)",function (d) { var formData = d.field; //使用ajax提交数据 $.post(cxt+"/car/add.do",formData,function (rs) { layer.msg(rs.msg); //展示业务消息 if (rs.code != 200){ return false; } layer.close(index); //关闭弹层 //刷新表格 $("#searchBtn").click(); }) return false;//阻止默认提交行为 }) }, btn:['确认','取消'], btnAlign: "c", yes:function (index,layero) { //点击隐藏的提交按钮 触发 表单提交监听 $("#subBtn").click(); } }; layer.open(layOps); } //显示头像的方法 // url : 图像的网络路径 window.showUserImg = function (url) { var imgData = { "title": "用户头像", //相册标题 "start": 0, //初始显示的图片序号,默认0 "data": [ //相册包含的图片,数组格式 { "alt": "用户头像", "src": cxt + "/" + url, //原图地址 "thumb": cxt + "/" + url //缩略图地址 } ] } layer.photos({ photos: imgData }); } }); </script>

2.新建FileUploadController

package com.toddding.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.toddding.common.CodeMsg;
import com.toddding.common.Constant;
import com.toddding.common.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping("file")
public class FileUploadController {

    @RequestMapping("uploadImage.do")
    public Object uploadImage(@RequestParam("image") MultipartFile image, HttpServletRequest request){
        //原图片名称
        String originalFilename = image.getOriginalFilename();
        //获取图片的后缀
        String extName = FileUtil.extName(originalFilename);
        //产生图片新的名称
        String newFileName = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");
        newFileName = newFileName + "."+extName;
        //获取upload文件夹的物理路径
        String realPath = request.getServletContext().getRealPath(Constant.UPLOAD_FOLDER);
        //文件保存的物理路径
        String fileRealPath = realPath + File.separator + newFileName;
        //文件还需要URL路径  upload/xxxxx.jpg
        String url = Constant.UPLOAD_FOLDER + "/" + newFileName;

        try {
            image.transferTo(new File(fileRealPath));
            //将图片的网络路径返回
            return  new Result(url);
        } catch (IOException e) {
            e.printStackTrace();

        }
        return  new Result(CodeMsg.CAR_UPLOAD_IMG_ERROR);

    }

}

3.修改springmvc.xml



4.修改BusCarController

//添加车辆数据
@RequestMapping("add.do")
public Object add(BusCar busCar) {
    //进行数据格式的效验
    ValidatorUtil.validator(busCar);
    return busCarService.add(busCar);

}

5.新建BusCar

package com.toddding.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Description: 车辆实体类
 * @Author: Todd Ding
 * @Date 2020-12-02 19:21
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BusCar {
    /**
     * 汽车ID
     */
    private Integer id;


    /**
     * 车牌号
     */
    @NotEmpty(message = "车牌号不能为空")
    @Length(min = 7, max = 8, message = "车牌号7-8位")
    private String num;

    /**
     * 类型  1 轿车  2 SUV  3 跑车
     */
    @NotNull(message = "车型不能为空")
    @Range(min = 1, max = 3, message = "车辆类型只能1-3")
    private Integer type;

    /**
     * 颜色
     */
    @NotEmpty(message = "汽车颜色不能为空")
    @Length(max = 10, message = "汽车颜色最多10位字符")
    private String color;

    /**
     * 价格
     */
    @NotNull(message = "汽车金额不能为空")
    @Range(min = 1, max = 999999999, message = "汽车金额1-999999999")
    private Integer price;

    /**
     * 出租金额
     */
    @NotNull(message = "汽车租金不能为空")
    @Range(min = 1, max = 999999999, message = "汽车租金1-999999999")
    private Integer rentPrice;

    /**
     * 押金
     */
    @NotNull(message = "汽车押金不能为空")
    @Range(min = 1, max = 999999999, message = "汽车押金1-999999999")
    private Integer deposit;

    /**
     * 出租状态 1 未出租  2 已出租
     */
    private Integer isRent;

    /**
     * 描述
     */
    @Length(max = 100, message = "汽车描述最多100个字符")
    private String descp;

    /**
     * 汽车图片
     */
    @NotEmpty(message = "汽车图片不能为空")
    @Length(max = 100, message = "汽车图片地址最多100位字符")
    private String img;

    /**
     * 版本号
     */
    private Integer version;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
    private Date createTime;
}

5.修改BusCarService

Result add(BusCar busCar);

6.修改BusCarServiceImpl

@Override
public Result add(BusCar busCar) {
    //进行业务数据效验
    //车牌号不能重复
    BusCar busCar1 = busCarMapper.selectOneByNum(busCar.getNum());
    if (busCar1 != null){
        return  new Result(CodeMsg.CAR_NUM_EXIST_ERROR);
    }

    busCarMapper.insert(busCar);

    return new Result();
}

7.修改CodeMsg

CAR_UPLOAD_IMG_ERROR(4003001, "汽车图片上传失败!"),
CAR_NUM_EXIST_ERROR(4003002, "汽车车牌号已被使用!"),

8.修改Constant

/**
 * 保存上传文件的文件夹
 */
String UPLOAD_FOLDER = "upload";

9.修改BusCarMapper

/**
 * 根据车牌号查询车辆信息
 *
 * @param num
 * @return
 */
BusCar selectOneByNum(@Param("num") String num);

/**
 * 新增车辆信息
 *
 * @param busCar
 */
void insert(BusCar busCar);

10.修改BusCarMapper.xml



    insert  into bus_car
        (num, `type`, color, price, rent_price, deposit, descp, img)
    value
        (#{num}, #{type}, #{color}, #{price}, #{rentPrice}, #{deposit}, #{descp}, #{img})

3.车辆出租

1.修改/car/list.jsp

 <script  type="text/html" id="rowBtns">
        
</script>

<%-- 出租车辆 --%>
<script type="text/html" id="rentTpl" >
    
<%--设置为 readonly 就不能改里面的信息了 --%>
</script> <script > layui.use(['jquery','form','layer','table','upload','laydate'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; var upload = layui.upload; var laydate = layui.laydate; //表格行工具栏事件 table.on("tool(dataTableFilter)",function (d) { var event = d.event; var rowData = d.data; if (event == "rent"){ rent(rowData); //具体出租方法 } }) //出租方法 function rent(rowData){ //弹出层的参数 var layOps = { title:"出租车辆", type:1, skin: "layui-layer-molv", content:$("#rentTpl").html(), area:['710px','580px'], success:function (layero,index) { //为表单赋值 form.val("rentFormFilter",rowData) //为图片设置数据 $("#carImg").attr("src",cxt + "/"+rowData.img); //渲染时间组件 laydate.render({ elem:"#rentTime", range:"~" }); //表单的提交监听 form.on("submit(subBtnFilter)",function (d) { var formData = d.field; //使用ajax提交数据 $.post(cxt+"/rent/add.do",formData,function (rs) { layer.msg(rs.msg); //展示业务消息 if (rs.code != 200){ return false; } layer.close(index); //关闭弹层 //刷新表格 $("#searchBtn").click(); }) return false;//阻止默认提交行为 }) }, btn:['确认','取消'], btnAlign: "c", yes:function (index,layero) { //点击隐藏的提交按钮 触发 表单提交监听 $("#subBtn").click(); } }; layer.open(layOps); } </script>

2.新建BusRentController

package com.toddding.controller;

import com.toddding.common.validator.ValidatorUtil;
import com.toddding.domain.BusRent;
import com.toddding.service.BusRentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("rent")
public class BusRentController {

    @Autowired
    private BusRentService busRentService;

    //新增车辆出租记录
    @RequestMapping("add.do")
    public  Object add(BusRent busRent){
        //数据效验
        ValidatorUtil.validator(busRent);
        return busRentService.add(busRent);
    }

}

3.新建BusRentService

package com.toddding.service;

import com.toddding.common.Result;
import com.toddding.domain.BusRent;

public interface BusRentService {

    //新增出租记录
    Result add(BusRent busRent);
}

4.新建BusRentServiceImpl

package com.toddding.service.impl;

@Service
public class BusRentServiceImpl implements BusRentService {
    @Autowired
    private BusRentMapper busRentMapper;

    @Autowired
    private BusCustomerMapper busCustomerMapper;

    @Autowired
    private BusCarMapper busCarMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(BusRent busRent) {
        //业务数据效验
        //校验客户是否存在
        //根据身份证号,  查询客户  效验客户是否存在
        BusCustomerQuery query = new BusCustomerQuery();
        query.setIdCard(busRent.getIdCard());
        BusCustomer busCustomer = busCustomerMapper.selectCustomerByKeywords(query);
        if (busCustomer == null){
            return new Result(CodeMsg.RENT_CUSTOMER_ID_CARD_ERROR);
        }

        //效验车辆信息
        //根据车牌号查询车辆信息
        BusCar busCar = busCarMapper.selectOneByNum(busRent.getNum());
        //获取出租状态   判断出租状态是否是  未出租
        if (busCar.getIsRent().equals(Constant.CAR_RENT_ED)){
            return  new Result(CodeMsg.RENT_CAR_RENTED_ERROR);
        }

        //乐观锁处理并发问题
        //修改车辆状态
        Integer rows = busCarMapper.updateRentState(busCar.getId(), Constant.CAR_RENT_ED, busCar.getVersion());
        if (rows != 1){
            throw  new BussiException(CodeMsg.RENT_FAILED_ERROR.code,CodeMsg.RENT_FAILED_ERROR.msg);
        }

        String rentTime = busRent.getRentTime();
        String[] split = rentTime.split("~");
        busRent.setBeginTime(split[0].trim());  //去掉空格
        busRent.setEndTime(split[1].trim());
        //客户名称
        busRent.setName(busCustomer.getName());
        //设置业务员ID
        Subject subject = SecurityUtils.getSubject();
        ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
        busRent.setUserId(activeUser.getSysUser().getId());

        //新增出租记录
        busRentMapper.insert(busRent);
        return new Result();
    }
}

5.修改CodeMsg

RENT_CAR_RENTED_ERROR(4004002, "车辆已经出租!"),
RENT_FAILED_ERROR(4004003, "车辆出租失败,车辆信息发生了变化!"),

6.修改Constant

/**
 * 未出租
 */
Integer CAR_RENT_NOT = 1;

/**
 * 已经出租
 */
Integer CAR_RENT_ED = 2;

7.新建BusRent

package com.toddding.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Description: 车辆出租记录实体类
 * @Author: Todd Ding
 * @Date 2020-12-03 10:59
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BusRent {
    /**
     * 出租记录ID
     */
    private Integer id;

    /**
     * 车牌号
     */
    @NotEmpty(message = "车牌号不能为空")
    @Length(max = 8,message = "车牌号最多8位")
    private String num;

    /**
     * 车型  1 轿车 2 SUV  3跑车
     */
    @NotNull(message = "车型不能为空")
    @Range(min = 1,max = 3,message = "车型的值1~3")
    private Integer type;

    /**
     * 租金
     */
    @NotNull(message = "租金不能为空")
    @Range(min = 1,max = 999999999,message = "租金范围:1~999999999")
    private Integer rentPrice;

    /**
     * 押金
     */
    @NotNull(message = "押金不能为空")
    @Range(min = 1,max = 999999999,message = "押金范围:1~999999999")
    private Integer deposit;

    /**
     * 客户名称
     */
    private String name;

    /**
     * 客户身份证号
     */
    @NotEmpty(message = "身份证号不能为空")
    @Length(min = 18,max = 18,message = "身份证号18位")
    private String idCard;

    @NotEmpty(message = "出租时间不能为空")
    private String rentTime;

    /**
     * 计划租车开始时间
     */
    private String beginTime;

    /**
     * 计划租车的结束时间
     */
    private String endTime;

    /**
     * 状态  1 未还车  2 已还车
     */
    private Integer flag;

    /**
     * 业务员ID
     */
    private Integer userId;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone = "GMT+8")
    private Date createTime;

    /**
     * 修改时间
     */
    private Date updateTime;
}

8.新建BusRentMapper

/**
 * @Description: 车辆出租记录数据操作接口
 * @Author: Todd Ding
 * @Date 2020-12-03 11:06
 */
public interface BusRentMapper {
    /**
     * 新增车辆出租记录
     *
     * @param busRent
     */
    void insert(BusRent busRent);
}    

9.新建BusRentMapper.xml

<?xml version="1.0" encoding="UTF-8"?>


    
        
        
        
        
        
        
        
        
        
        
        
        
        
    
    
        
        id, num, `type`, rent_price, deposit, `name`, id_card, begin_time, end_time, flag, user_id, create_time, update_time
    
    
        insert into bus_rent
            (num, `type`, rent_price, deposit, `name`, id_card, begin_time, end_time, user_id)
        value
           (#{num}, #{type}, #{rentPrice}, #{deposit}, #{name}, #{idCard}, #{beginTime}, #{endTime}, #{userId})
    
    

10.修改BusCarMapper

/**
     * 修改车辆状态
     *
     * @param id
     * @param rent
     * @param version
     * @return
     */
    Integer updateRentState(@Param("id") Integer id, @Param("rent") Integer rent, @Param("version") Integer version);

11.修改BusCarMapper.xml



    update bus_car set is_rent = #{rent} ,version = version + 1 where id = #{id} and version = #{version}

4.车辆出租列表

1.新建 /rent/list.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>



    
    出租列表
    
    
    
    
    
    
    
    


<%--操作--%> <script type="text/html" id="rowBtns"> </script> <%--新增用户模板--%> <script type="text/html" id = "addUserTpl">
</script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table','laydate'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; var laydate = layui.laydate; //渲染时间控件 laydate.render({ elem: "#beginTime", range:"~" }) //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/rent/page.do", page:true, toolbar: "#headBtns", cols:[[ {field: "num", align: "center", title: "车牌号"}, { field: "type", align: "center", title: "车型", templet: function (d) { let type = d.type; if (type == 1) { return "

轿车

"; } else if (type == 2) { return "

SUV

"; } else if (type == 3) { return "

超跑

"; } } }, {field: "rentPrice", align: "center", title: "租金"}, {field: "deposit", align: "center", title: "押金"}, {field: "name", align: "center", title: "客户"}, {field: "beginTime", align: "center", title: "开始时间"}, {field: "endTime", align: "center", title: "结束时间"}, { field: "flag", align: "center", title: "状态", width: 80, templet: function (d) { let flag = d.flag; if (flag == 1) { return "

未归还

"; } else if (flag == 2) { return "

已归还

"; } } }, {field: "createTime", align: "center", title: "创建时间", width: 150}, {title: "操作", align: "center", toolbar: "#rowBtns", fixed: "right"} ]], //列数据 parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var num = $("#num").val(); var name = $("#name").val(); var flag = $("#flag").val(); var beginTime = $("#beginTime").val(); tabIns.reload({ where:{ "num":num, "name":name, "flag":flag, "beginTime":beginTime } }) }) //表格行工具栏事件 table.on("tool(dataTableFilter)",function (d) { var event = d.event; var rowData = d.data; if (event == "returnCar"){ returnCar(rowData); } }) //显示头像的方法 // url : 图像的网络路径 window.showUserImg = function (url) { var imgData = { "title": "用户头像", //相册标题 "start": 0, //初始显示的图片序号,默认0 "data": [ //相册包含的图片,数组格式 { "alt": "用户头像", "src": cxt + "/" + url, //原图地址 "thumb": cxt + "/" + url //缩略图地址 } ] } layer.photos({ photos: imgData }); } }); </script>

2..修改navs.json

{
   "title": "出租记录",
   "icon": "",
   "href": "rent/list.do",
   "spread": false,
   "target": "_self"
},

3.修改PageController

/**
 * 跳转租车记录列表
 *
 * @return
 */
@RequestMapping("rent/list.do")
public String rentList() {
    return "rent/list.jsp";
}

4.修改BusRentController

//出租记录列表的分页查询
@RequestMapping("page.do")
public  Object page(BusRentQuery query){

    return busRentService.queryPage(query);
}

5.修改BusRentService

//查询出租记录
Result queryPage(BusRentQuery query);

6.修改BusRentServiceImpl

@Override
public Result queryPage(BusRentQuery query) {
    Page busRentVOPage = PageHelper.startPage(query.getPage(), query.getLimit());

    //如果开始时间不为空
    if (StrUtil.isNotEmpty(query.getBeginTime())){
        String[] split = query.getBeginTime().split("~");
        System.out.println("-----------------------------------------"+split);
        query.setMinBeginTime(split[0].trim());
        query.setMaxBeginTime(split[1].trim());
    }
    busRentMapper.selectList(query);

    return new Result(busRentVOPage.toPageInfo());
}

7.新建BusRentQuery

package com.toddding.query;

import lombok.Data;

/**
 * @Description: 出租记录列表的查询参数封装类
 * @Author: Todd Ding
 * @Date 2020-12-03 15:07
 */
@Data
public class BusRentQuery extends Query {
    /**
     * 车牌号
     */
    private String num;

    /**
     * 客户名称
     */
    private String name;

    /**
     * 出租状态
     */
    private Integer flag;

    /**
     * 开始时间
     */
    private String beginTime;

    private String minBeginTime; // 最小开始时间

    private String maxBeginTime; // 最大的开始时间
}

8.修改BusRentMapper

/**
 * 根据参数查询车辆出租记录
 *
 * @param query
 * @return
 */
List selectList(BusRentQuery query);

9.修改BusRentMapper.xml


5.还车

1.修改rent/list.jsp

 <%--操作--%>
    <script  type="text/html" id="rowBtns">
        
    </script>
                
<%--新增还车记录模板--%>
<script type="text/html" id = "returnTpl">
    
</script> //表格行工具栏事件 table.on("tool(dataTableFilter)",function (d) { var event = d.event; var rowData = d.data; if (event == "returnCar"){ returnCar(rowData); } }) //还车方法 function returnCar(rowData){ //弹出层的参数 var layOps = { title:"还车", type:1, skin: "layui-layer-molv", content:$("#returnTpl").html(), area:['680px','450px'], success:function (layero,index) { form.val("returnFormFilter",rowData) //渲染还车时间 laydate.render({ elem:"#returnTime" }); //表单的提交监听 form.on("submit(subBtnFilter)",function (d) { var formData = d.field; formData.rentId=rowData.id; //出租记录id //使用ajax提交数据 $.post(cxt+"/return/add.do",formData,function (rs) { layer.msg(rs.msg); //展示业务消息 if (rs.code != 200){ return false; } layer.close(index); //关闭弹层 //刷新表格 $("#searchBtn").click(); }) return false;//阻止默认提交行为 }) }, btn:['确认','取消'], btnAlign: "c", yes:function (index,layero) { //点击隐藏的提交按钮 触发 表单提交监听 $("#subBtn").click(); } }; layer.open(layOps); }

2.新建BusReturnController

package com.toddding.controller;

import com.toddding.common.validator.ValidatorUtil;
import com.toddding.domain.BusReturn;
import com.toddding.service.BusReturnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("return")
public class BusReturnController {

    @Autowired
    private BusReturnService busReturnService;

    //新增还车记录请求
    @RequestMapping("add.do")
    public Object add(BusReturn busReturn){
        ValidatorUtil.validator(busReturn);
        return busReturnService.add(busReturn);
    }

}

3.新建BusReturnService

package com.toddding.service;

import com.toddding.common.Result;
import com.toddding.domain.BusReturn;

public interface BusReturnService {

    //新增还车记录
    Result add(BusReturn busReturn);
}

4.新建BusReturnServiceImpl

package com.toddding.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.toddding.common.CodeMsg;
import com.toddding.common.Constant;
import com.toddding.common.Result;
import com.toddding.common.exception.BussiException;
import com.toddding.domain.BusCar;
import com.toddding.domain.BusRent;
import com.toddding.domain.BusReturn;
import com.toddding.mapper.BusCarMapper;
import com.toddding.mapper.BusRentMapper;
import com.toddding.mapper.BusReturnMapper;
import com.toddding.service.BusReturnService;
import com.toddding.shiro.ActiveUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.RollbackException;

@Service
public class BusReturnServiceImpl implements BusReturnService {

    @Autowired
    private BusReturnMapper busReturnMapper;

    @Autowired
    private BusRentMapper busRentMapper;

    @Autowired
    private BusCarMapper busCarMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(BusReturn busReturn) {
        //业务数据效验
        //查询出租记录
        //判断出租记录状态
        /*
           1.查询出租记录
           2.检查出租记录是否还车
           3.只有没有还车时,才能还车
           4.修改出租记录状态  改为已还车
           5.插入还车记录
           6.修改车辆状态  从已出租改为未出租
              计算   出租的总金额
         */
        //1.查询出租记录
        BusRent busRent = busRentMapper.selectByRentId(busReturn.getRentId());
        //如果出租状态已经还车是已还车,则
        if (busRent.getFlag().equals(Constant.CAR_RETURN_ED)){
            return  new Result(CodeMsg.RETURN_CAR_ERROR);
        }
        //如果没有还  则修改还车记录状态
       int rows =  busRentMapper.updateRentFlag(busReturn.getRentId(),busRent.getFlag(),Constant.CAR_RENT_ED);
        if (rows != 1){
            return  new Result(CodeMsg.RETURN_FAILED_RENT_CHANGED_ERROR);
        }
        //修改车辆状态
        BusCar busCar = busCarMapper.selectOneByNum(busReturn.getNum());
        rows = busCarMapper.updateRentState(busCar.getId(), Constant.CAR_RENT_NOT, busCar.getVersion());
        if (rows != 1){
            throw new BussiException(CodeMsg.RETURN_FAILED_CAR_CHANG_ERROR.code,CodeMsg.RETURN_FAILED_CAR_CHANG_ERROR.msg);
        }
        //计算出租总金额
        String beginTime = busRent.getBeginTime()+" 00:00:00";  //格式转换
        String returnTime = busReturn.getReturnTime()+" 23:59:59";
        int rentPrice = busRent.getRentPrice();  // 单日租金
        Date begin = DateUtil.parse(beginTime, "yyyy-MM-dd HH:mm:ss");
        Date end = DateUtil.parse(returnTime, "yyyy-MM-dd HH:mm:ss");
        int days = (int) DateUtil.betweenDay(begin, end, true)+1;  //不是同一天 对比后加1
        if (DateUtil.isSameDay(begin,end)){
            days = 1;   //如果是同一天的话 设置为1
        }
        rentPrice= rentPrice * days; //计算总租金
        //总金额
        int totalMoney = rentPrice + busReturn.getPayMoney();
        //总租金
        busReturn.setRentPrice(rentPrice);
        busReturn.setTotalMoney(totalMoney);
        //获取操作员id
        Subject subject = SecurityUtils.getSubject();
        ActiveUser activeUser = (ActiveUser) subject.getPrincipal();
        busReturn.setUserId(activeUser.getSysUser().getId());
        //新增还车记录
        busReturnMapper.insert(busReturn);

        return new Result()  ;
    }
}

5.修改CodeMsg

RETURN_CAR_ERROR(4005001, "车辆已经归还,请不要重复还车!"),
RETURN_FAILED_RENT_CHANGED_ERROR(4005002, "还车失败,出租记录发生变化!"),
RETURN_FAILED_CAR_CHANG_ERROR(4005003, "还车失败,车辆状态修改失败!"),

6.修改Constant

/**
 * 未还车
 */
Integer CAR_RETURN_NOT = 1;

/**
 * 已还车
 */
Integer CAR_RETURN_ED = 2;

7.新建BusReturn

package com.toddding.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * @Description: 车辆归还记录实体类
 * @Author: Todd Ding
 * @Date 2020-12-03 11:01
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BusReturn {
    /**
     * 还车记录ID
     */
    private Integer id;

    /**
     * 车牌号
     */
    @NotEmpty(message = "车牌号不能为空")
    @Length(min = 7,max = 8,message = "车牌号7~8位")
    private String num;

    /**
     * 出租记录ID
     */
    @NotNull(message = "出租记录ID不能为空")
    private Integer rentId;

    /**
     * 还车时间
     */
    @NotEmpty(message = "还车时间不能为空")
    private String returnTime;

    /**
     * 租金
     */
    private Integer rentPrice;

    /**
     * 赔付金额
     */
    @NotNull(message = "赔付金额不能为空")
    @Min(value = 0,message = "赔付金额最少0")
    private Integer payMoney;

    /**
     * 问题
     */
    private String problem;

    /**
     * 总金额
     */
    private Integer totalMoney;

    /**
     * 业务员ID
     */
    private Integer userId;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
    private Date createTime;
}

8.新建BusReturnMapper

public interface BusReturnMapper {
    /**
     * 新增还车记录
     *
     * @param busReturn
     */
    void insert(BusReturn busReturn);
 }   

9.新建BusReturnMapper.xml


    
        
        
        
        
        
        
        
        
        
        
    
    
        id, num, rent_id, return_time, rent_price, pay_money, problem, total_money, user_id, create_time
    
    
        insert into bus_return
            (num, rent_id, return_time, rent_price, pay_money, problem, total_money, user_id)
        value
            (#{num}, #{rentId}, #{returnTime}, #{rentPrice}, #{payMoney}, #{problem}, #{totalMoney}, #{userId})
    
    

10.修改BusRentMapper

/**
 * 根据 ID 查询出租记录
 *
 * @param rentId
 * @return
 */
BusRent selectByRentId(@Param("id") Integer rentId);

/**
 * 修改还车记录状态
 *
 * @param rentId  出租记录ID
 * @param oldFlag 原出租状态
 * @param flag    新出租状态
 * @return
 */
int updateRentFlag(@Param("id") Integer rentId, @Param("oldFlag") Integer oldFlag, @Param("flag") Integer flag);

11修改BusRentMapper.xml



    update bus_rent set flag = #{flag} where id = #{id} and flag = #{oldFlag}

6.还车记录列表

1.新建/return/list.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" language="java" %>



    
    还车管理
    
    
    
    
    
    
    
    


<%--操作--%> <%-- <script type="text/html" id="rowBtns"> </script>--%> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/layui/layui.js"> </script> <script > layui.use(['jquery','form','layer','table'],function () { var cxt = '${pageContext.request.contextPath}'; var $ =layui.jquery; var form = layui.form; var layer = layui.layer; var table = layui.table; //渲染数据表格 //表格参数 var tabOps ={ id:"dataTableId", elem:"#dataTable", url:cxt + "/return/page.do", page:true, toolbar: "#headBtns", cols:[[ {field: "num", align: "center", title: "车牌号"}, {field: "rentId", align: "center", title: "出租ID"}, {field: "returnTime", align: "center", title: "还车时间"}, {field: "rentPrice", align: "center", title: "总租金"}, {field: "payMoney", align: "center", title: "赔付金额"}, {field: "totalMoney", align: "center", title: "总金额"}, {field: "problem", align: "center", title: "问题"}, {field: "createTime", align: "center", title: "创建时间", width: 150}, ]], //列数据 parseData:function (rs) { return{ code: rs.code, msg:rs.msg, count:rs.data.total, data:rs.data.list } }, response:{ statusCode:200 } }; //进行渲染 var tabIns = table.render(tabOps); //按钮查询 $("#searchBtn").click(function () { var num = $("#num").val(); tabIns.reload({ where:{ "num":num } }) }) }); </script>

2.修改PageController

/**
 * 跳转还车记录列表
 *
 * @return
 */
@RequestMapping("return/list.do")
public String returnList() {
    return "return/list.jsp";
}

3.修改navs.json

{
   "title": "还车记录",
   "icon": "",
   "href": "return/list.do",
   "spread": false,
   "target": "_self"
}

4.修改BusReturnController

@RequestMapping("page.do")
public Object page(BusReturnQuery query){
    return busReturnService.queryPage(query);
}

5.新建BusReturnQuery

package com.toddding.query;

import lombok.Data;

/**
 * @Description: 还车记录列表的查询参数封装类
 * @Author: Todd Ding
 * @Date 2020-12-03 17:11
 */
@Data
public class BusReturnQuery extends Query {
    /**
     * 车牌号
     */
    private String num;
}

6.修改BusReturnService

//分页查询还车记录
Result queryPage(BusReturnQuery query);

7.修改BusReturnServiceImpl

 /**
     * 还车记录的分页查询
     *
     * @param query
     * @return
     */
@Override
public Result queryPage(BusReturnQuery query) {
    Page busReturnVO = PageHelper.startPage(query.getPage(), query.getLimit());
    busReturnMapper.selectList(query);
    return new Result(busReturnVO.toPageInfo());

}

8.修改BusReturnMapper

/**
 * 还车记录的分页查询
 *
 * @param query
 * @return
 */
List selectList(BusReturnQuery query);

9.修改BusReturnMapper.xml