德胜汽修管理系统

汽修系统

1.项目简介

本系统采用多模块开发思想,提供汽车的维修服务,维修配件的入库,维修配件的检索,车辆维修工单,维修明细单,结算单的管理,并提供维修之后的还车业务,还提供公共的维修结算工单查询,以及基础数据管理,报表的查询,以及权限管理等模块功能

2.技术支持

本系统采用MySQL数据库,使用Java EE进行开发,采取SSM平台的B/S架构,。程序使用MVC模式,多模块开发模式,采用三层架构,保证系统的可维护性和可扩展性。

3.项目大体模块

维修单管理模块
结算工单管理模块
登录管理模块
还车管理模块
汽车配件管理模块
系统管理模块
整体项目使用框架ssm(springmvc+spring+mabtis)
整个项目框架:
在这里插入图片描述

准备工作:配置文件如service中的applicationContext.xml文件需要引入mapper(controller层同理)
在这里插入图片描述

工具的类的抽取

BaseMapper
public interface BaseMapper <T>{

    int deleteByPrimaryKey(Long id);

    int insert(T record);

    T selectByPrimaryKey(Long id);

    List<T> selectForList(BaseQueryObject qo);

    int updateByPrimaryKey(T record);
}

BaseQuery
public class BaseQuery  {
    //当前页
    private int page = 1;
    //每页显示条数
    private int rows = 10;
    //高级查询传入参数
    private String keyword;


    public String getKeyword() {
        if(keyword.length()!=0){
            return keyword.trim();
        }
        return null;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }
    
    public void setRows(int rows) {
        this.rows = rows;
    }
    //从哪一页开始显示数据
    public int getStart(){
        return (this.page-1)*rows;
    }

}

分页PageResult
public class PageResult<T>  {

    private long total = 0;

    private List rows = new ArrayList();

    public PageResult() {
    }

    public PageResult(long total, List rows) {
        this.total = total;
        this.rows = rows;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public List getRows() {
        return rows;
    }

    public void setRows(List rows) {
        this.rows = rows;
    }

    @Override
    public String toString() {
        return "PageResult{" +
                "total=" + total +
                ", rows=" + rows +
                '}';
    }
}

生成相应的mapper/domain/service/controller/js/jsp文件(完成基本的CRUD)
 velocity模板生成技术
public class VelocityMain {
    //模板文件数组定义:顺序是你自己的
    static String[] templateName = {
            "domain.js", "domain.jsp", "DomainController.java"
            , "DomainQuery.java", "DomainServiceImpl.java", "IDomainService.java"
    };

//    static String[] templateName = {
//            "domain.js", "domain.jsp"
//    };
    //项目路径:
    static final String jsFilePath = "D:/ideal-project/cars/cars-web/src/main/webapp/static/js/model/";
    static final String jspFilePath = "D:/ideal-project/cars/cars-web/src/main/webapp/WEB-INF/views/";
    static final String controllerFilePath = "D:/ideal-project/cars/cars-web/src/main/java/cn/itsources/web/controller/";
    static final String queryFilePath = "D:/ideal-project/cars/cars-common/src/main/java/cn/itsources/query/";
    static final String serviceImplFilePath = "D:/ideal-project/cars/cars-service/src/main/java/cn/itsources/service/impl/";
    static final String serviceFilePath = "D:/ideal-project/cars/cars-service/src/main/java/cn/itsources/service/";

    //生成文件的路径数据定义:这个要和templateName对应起来
    static String[] outFileRootPath = {
            jsFilePath, jspFilePath, controllerFilePath, queryFilePath
            , serviceImplFilePath,serviceFilePath
    };
//
//    static String[] outFileRootPath = {
//            jsFilePath, jspFilePath
//    };

    //可能有多个domain需要生成
    static String[] domain = {"Setted"};

    /**
     * 1:定义模板
     * 2:使用Velocity生成模板:
     * 2.1:初始化Velocity:设置加载方式:classpath下加载
     * 2.2:设置Velocity的上下文
     * 2.3:从classpath下读取模板,输出到文件
     *
     * @param args
     */
    public static void main(String[] args) throws ClassNotFoundException {
        for (String domainMame : domain) {
            // domainName = Employee

            Properties p = new Properties();
            // 2.1:初始化Velocity:设置加载方式:classpath下加载
            // 使用classpath加载:org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
            p.setProperty(Velocity.RESOURCE_LOADER, "class");
            p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            Velocity.init(p);

            //2.2:设置Velocity的上下文
            VelocityContext context = new VelocityContext();
            //  domainName = Employee
            // domainLower= employee
            String domainLower = domainMame.substring(0, 1).toLowerCase() + domainMame.substring(1);
            //使用Department代替模板文件中:Domain
            context.put("Domain", domainMame);  //Department
            context.put("domain", domainLower); //department
            //
            context.put("fieldList",scanDomain(domainMame));

            //遍历模板,每一个模板都生成一个文件
            for (int i=0;i<templateName.length;i++) {
                //2.3:读取模板,输出到文件
                //从classpath下读取模板
                String tempName = templateName[i];

                // i=0==>tempName=domain.js
                String templateFile = "template/" + tempName;
                // templateFile=template\domain.js
                //根据模板的索引读取对应生成文件的路径:
                String outFilePath = outFileRootPath[i];
                // outFilePath=F:\java0830\itsource-parent\crm-web\src\main\webapp\static\js\

                //"F:/java0830/itsource-parent/crm-web/src/main/webapp/WEB-INF/views/";
                boolean views= outFilePath.contains("views")||outFilePath.contains("js");
                if(views){
                    // F:/java0830/itsource-parent/crm-web/src/main/webapp/WEB-INF/views/employee/
                    outFilePath=outFilePath+"/"+domainLower+"/";
                }
                // outFile=outFilePath+domain.js==>outFilePath+employee.js
                String outFile = outFilePath + tempName;
                outFile=outFile.replaceAll("Domain",domainMame).replaceAll("domain",domainLower);


                try {
                    File file = new File(outFile);
                    File parentFile = file.getParentFile();
                    //文件不存在,就创建
                    if (!parentFile.exists()) {
                        parentFile.mkdirs();
                    }
                    //文件输出
                    FileWriter fileWriter = new FileWriter(file);
                    Template template = Velocity.getTemplate(templateFile, "utf-8");
                    template.merge(context, fileWriter);
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
       /* List<FieldVo> voList = scanDomain("Employee");
        for (FieldVo fieldVo : voList) {
            System.out.println(fieldVo);
        }*/
    }

    private static List<FieldVo> scanDomain(String domainMame) throws ClassNotFoundException {
        List<FieldVo> voList=new ArrayList<>();
        // domainMame=Employee
        // cn.itsource.crm.domain.Employee
        String clazzPath="cn.itsources.domain."+domainMame;
        Class<?> c = Class.forName(clazzPath);
        System.out.println(c);

        //获取字段
        Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            //判断这个字段上是否有EasyuiColumn
            if(declaredField.isAnnotationPresent(EasyuiColumn.class)){
                EasyuiColumn easyuiColumn = declaredField.getAnnotation(EasyuiColumn.class);

                //获取到注解的title的值
                String title = easyuiColumn.title();
                String name = declaredField.getName();
                FieldVo fieldVo=new FieldVo();
                fieldVo.setField(name);
                fieldVo.setTitle(title);
                voList.add(fieldVo);

            }
        }
        for (FieldVo fieldVo : voList) {
            System.out.println(fieldVo);
        }

        return voList;
    }
}

FieldVo 结合VelocityMain 完成jsp

public class FieldVo  {

    //domain的field
    private String title;

    //domain的title:标签上的值
    private String field;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

在这里插入图片描述

4.负责模块 结算工单管理模块

当维修人员维修车辆完成之后,交互给结算人员,由结算人员填写结算单据,通知客户进行付款操作;
结算单结算管理(Setted)
业务概述
车辆维修完毕之后,由结算人员填写结算单据,进行车辆的结算。结算之后,更新维修工单状态;
前台jsp代码展示:

<div id="settedDialog" class="easyui-dialog" title="数据操作" data-options="closed:true,modal:true"
     style="width:400px;padding:10px">
    <form id="settedForm" method="post">
        <input id="settedId" type="hidden" name="id">
        <table cellpadding="5">
            <tr>
                <td>客户名称:</td>
                <td><input class="easyui-validatebox" type="text" name="custormer"
                           data-options="required:true,validType:'custormer'"></input></td>
            </tr>
            <tr>
                <td>应付金额:</td>
                <td><input id="reAmount" class="easyui-validatebox" type="text" name="reAmount"
                           data-options="required:true"></input></td>
            </tr>
            <tr>
                <td>实付金额:</td>
                <td><input class="easyui-validatebox" type="text" name="payAmount"
                           validType="equalTo['#reAmount']" invalidMessage="与应付金额不同"
                           data-options="required:true"></input></td>
            </tr>
            <tr>
                <td>支付方式:</td>
                <td>
                    <%--//下拉选择支付方式--%>
                    <select style="width: 120px" data-options=" panelHeight:'auto'" name="payId" class="easyui-combobox">
                        <option name="1" value="1">现金支付</option>
                        <option name="2" value="2">银行卡支付</option>
                        <option name="3" value="3">信用卡支付</option>
                        <option name="4" value="4">微信支付</option>
                        <option name="5" value="5">支付宝支付</option>
                    <%--</select><a href="javascript:void(0)" class="easyui-linkbutton c6" data-cmd="settedSave">支付</a>--%>
                </td>
            </tr>
        </table>
        <div style="text-align:center;padding:5px">
            <a href="javascript:void(0)" class="easyui-linkbutton c1" data-cmd="settedSave">支付</a>
            <a href="javascript:void(0)" class="easyui-linkbutton c2" onclick="$('#settedDialog').dialog('close')">取消</a>
        </div>
    </form>
</div>
<%--验证金额是否形同--%>
<script type="text/javascript">
    $.extend($.fn.validatebox.defaults.rules, {
        /*必须和某个字段相等*/
        equalTo: {
            validator: function (value, param) {
                return $(param[0]).val() == value;
            }, message: '字段不匹配'
        }
    });
</script>

js代码js— //变量的抽取:省略

 'setted': function () {
            //获取选中当前行的数据
            var row = repairorderDatagrid.datagrid("getSelected");
            //判断是否选中行
            if (!row) {
                $.messager.alert('提示', '请选择', 'info');
            } else {
                //打开结算面板
                settedDialog.dialog("open").dialog('center').dialog('setTitle', '结算维修单');
                //通过ajax请求通过客户姓名后台查询出相应的数据
                $.ajax({
                    url: "/setted/findSetted",
                    type: "post",
                    data: {
                        "custormer": row.custormer
                    },
                    //返回数据类型转为json
                    dataType: "json",
                    //成功接收后台数据
                    success: function (data) {
                        //将数据加载到表单中
                        console.debug(data)
                        settedForm.form("load", data);
                    }
                });
            }
        },
        //支付并把结算清单保存
        'settedSave': function () {
            $.messager.confirm('交易平台', '确认付款', function (r) {
                //支付操作
                settedForm.form('submit', {
                    url: "/setted/saveOrUpdate",
                    success: function (data) {
                        var result = JSON.parse(data);
                        if (result.success) {
                            repairorderDatagrid.datagrid('reload');
                            settedDialog.dialog("close");
                        //    跳转页面/setted/index
                            //刷新
                            window.location.href="/setted/index";

                        } else {
                            $.messager.alert("提交失败", result.msg, 'error')
                        }
                    }
                })
            });
        },

结算单的金额验证---- 支付方式选择---- 提交前再次确认

界面展示
在这里插入图片描述

取消结算单(Setted)
jsp

<table id="settedDatagrid"></table>

js— //变量的抽取:省略

 'deleteState':function () {
            //先获取数据
            var row = settedDatagrid.datagrid('getSelected');
            //做一个判断:是否选中
            if (row){
                if(row.settlementStatus==0){
                    $.messager.alert('操作提示',"已经是未结算状态!",'error');
                }
                else if(row.settlementStatus==1) {
                    $.messager.confirm('温馨提示','请仔细核对:[<font color="pink">'+row.custormer+"</font>]未结算?",function(r){
                        // 选中:确认的操作:调用后台的删除方法:发送ajax调用
                        if (r){
                            // 发送ajax调用 $.get(url,params,function(d){},type)
                            $.get('/setted/deleteState?sId='+row.sId,function (d) {
                                if(d.success){
                                    //true:成功
                                    $.messager.alert('操作提示',d.msg,'info');
                                    //页面刷新
                                    cmdObj.refresh();
                                }else{
                                    //false:失败:提示
                                    $.messager.alert('错误提示',d.msg,'error');
                                }

                            },'json')

                        }
                    })
                };
            }else{
                $.messager.alert('温馨提示','请选中!!!','warning');
            }
        },

业务概述
如果结算有问题,可以取消结算单
界面概要
在这里插入图片描述
setted.所有方法的mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.itsources.mapper.SettedMapper">
  <resultMap id="BaseResultMap" type="cn.itsources.domain.Setted">
    <id column="s_id" jdbcType="BIGINT" property="sId" />
    <result column="custormer" jdbcType="VARCHAR" property="custormer" />
    <result column="main_id" jdbcType="VARCHAR" property="mainId" />
    <result column="setted_time" jdbcType="TIMESTAMP" property="settedTime" />
    <result column="re_amount" jdbcType="DECIMAL" property="reAmount" />
    <result column="pay_amount" jdbcType="DECIMAL" property="payAmount" />
    <result column="pay_id" jdbcType="INTEGER" property="payId" />
    <result column="settlement_status" jdbcType="INTEGER" property="settlementStatus" />
    <result column="send_status" jdbcType="INTEGER" property="sendStatus" />
  </resultMap>

  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from setted
    where s_id = #{sId,jdbcType=BIGINT}
  </delete>
<!--更新结算状态-->
  <update id="deleteState" parameterType="cn.itsources.domain.Setted">
    UPDATE setted set settlement_status =0
    where s_id = #{sId,jdbcType=BIGINT}
  </update>
  <!--更新还车状态-->
  <update id="sendState" parameterType="cn.itsources.domain.Setted">
    UPDATE setted set send_status = 1
    where main_id = #{mainId,jdbcType=BIGINT}
  </update>

  <insert id="insert" parameterType="cn.itsources.domain.Setted">
    insert into setted (s_id, custormer, main_id, 
      setted_time, re_amount, pay_amount, 
      pay_id, settlement_status, send_status
      )
    values (#{sId,jdbcType=BIGINT}, #{custormer,jdbcType=VARCHAR}, #{mainId,jdbcType=VARCHAR}, 
      #{settedTime,jdbcType=TIMESTAMP}, #{reAmount,jdbcType=DECIMAL}, #{payAmount,jdbcType=DECIMAL}, 
      #{payId,jdbcType=INTEGER}, #{settlementStatus,jdbcType=INTEGER}, #{sendStatus,jdbcType=INTEGER}
      )
  </insert>
  <update id="updateByPrimaryKey" parameterType="cn.itsources.domain.Setted">
    update setted
    set send_status = #{sendStatus,jdbcType=INTEGER}
    where custormer = #{custormer,jdbcType=BIGINT}
  </update>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select s_id, custormer, main_id, setted_time, re_amount, pay_amount, pay_id, settlement_status, 
    send_status
    from setted
    where s_id = #{sId,jdbcType=BIGINT}
  </select>
  <!--分页查询-->
  <!---->
  <sql id="base_where">
    <where>
      <if test="keyword != null">
        and ( custormer like concat("%",#{keyword},"%") or settlement_status like concat("%",#{keyword},"%") )
      </if>
    </where>
  </sql>
  <select id="selectForList" resultMap="BaseResultMap">
    select s_id, custormer, main_id, setted_time, re_amount, pay_amount, pay_id, settlement_status, 
    send_status
    from setted
    <include refid="base_where" />
  </select>

  <!--嵌套结果-->
  <select id="findMainId" parameterType="string" resultType="long">
    SELECT red.main_id
    FROM repairorder r
    LEFT JOIN repairorderitem red ON r.id = red.main_id
    WHERE r.custormer =  #{custormer}
    GROUP BY r.id
  </select>

  <select id="findSetted" parameterType="string" resultType="cn.itsources.util.SettedVo">
    SELECT re.id,re.custormer,SUM(red.totalamt) as reAmount,SUM(red.totalamt) as payAmount
    FROM repairorder re
    LEFT JOIN repairorderitem red	ON re.id = red.main_id
    where re.custormer = #{custormer}
  </select>
    <!--订单号查询索引-->
  <select id="selectAll"  resultType="cn.itsources.util.SettedVo" >
    select s.custormer,  s.pay_amount, rc.address , s.setted_time
      from setted s
      left join returncar rc on s.main_id = rc.main_id
      <where>
          <if test="keyword!=null">
            and  s.main_id = #{keyword}
          </if>
      </where>
      GROUP BY s.main_id
  </select>
  
</mapper>

心得:代码不是问题 思路才是重要的,用velocity代码生成器,多用时间走业务逻辑,CRUD是个java程序员都会。所以要注重思路。过程各种bug都是正常的,静下心都能发现问题。本项目问题最多的是刚接触的全文搜索引擎lucene,尤其是搜索索引。
本文也结合lucene做出了简单的更新查询功能采用了IKAnalyzer分词器。
团队开发刚使用svn各种冲突,用多了都是没有问题的

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值