在公司一起集成了个项目,使用多模块开发,使用svn的代码版本控制工具.
技术选型:ssm+layui+maven+generator
一、项目集成搭建各个模块:
注意:各个模块之间的相互调用
项目需求文档,从项目经理老大那里拿到,并得到自己负责的模块,分析模块需求,创建相对应的表(注意:表关联,与相对应的人员进行进行建表关联)【我负责的是订单结算模块(这里解释这个模块)、还车模块、支付模块(没接入对应api接口)】
xml version="1.0" encoding="UTF-8"?>
generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple">
<property name="autoDelimitKeywords" value="false" />
<property name="javaFileEncoding" value="UTF-8" />
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true" />
commentGenerator>
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://ip地址:3306/数据库名" userId="数据库连接用户名" password="密码">
jdbcConnection>
<javaModelGenerator targetPackage="包路径.domain" targetProject="src/main/java">
<property name="constructorBased" value="false" />
<property name="immutable" value="false" />
javaModelGenerator>
<sqlMapGenerator targetPackage="包路径.mapper"
targetProject="src/main/resources">
<property name="enableSubPackages" value="true" />
sqlMapGenerator>
<javaClientGenerator targetPackage="cn.itsource.mapper"
type="XMLMAPPER" targetProject="src/main/java">
<property name="enableSubPackages" value="true" />
javaClientGenerator>
<table tableName="数据库表名" domainObjectName="生成的domain名" >
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC" />
table>
context>
generatorConfiguration>
①创建mapper service query类并继承公共类 分别在crm-mapper 和service模块
②创建控制层代码进行引用(generator自动生成mapper.xml所以不创建)
③引用项目经理的的spring配置(当然不需要我们去集成,因为已经集成好了),然后test一把,之后就可以在页面上引用了
结算表:SettlementOrder
查询所有的核心代码:
@RequestMapping("/selectAll")
@ResponseBody//json
public PageResult list(SettlementOrderQuery settlementOrderQuery) {
// System.out.println(settlementOrderQuery.getOrder());
return settlementOrderService.selectForList(settlementOrderQuery);
}
Mapper.xml里面的sql:
<sql id="base_keywords">
<where>
<if test="keyword != null">
and (c.name LIKE concat('%',#{keyword},'%'))
if>
where>
<if test="order != null">
ORDER BY ${field} ${order}
if>
sql>
<select id="selectAll" resultMap="BaseResultMap">
select
o.s_id as sId
, o.main_id as cid
, o.setted_time
,o.state
,o.pay_amount as payAmount
,o.re_amount as reAmount
, o.remarks
, p.id as pid
, p.payment_name as paymentName
,c.*
from settlement_order o
LEFT JOIN customer c ON o.main_id = c.id
LEFT JOIN payment p ON o.pay_id = p.id
<include refid="base_keywords"/>
在页面上进行表格渲染(web前端使用的是layui的控件)
<div class="layui-inline">
<a data-method="del" id="search" type="button" class="layui-btn layui-btn-sm layui-btn-radius layui-btn-warm">
<img src="/static/images/jianhao.png" width="20px" alt="一"/> 取消结算
a>
div>
<table class="layui-hide" id="test" lay-filter="test">table>
完整的Js:
$(function () { 排序:在js里面已经写了ajax以及在mapper.xml里面的查询所有中,加了高级查询和分页、排序, 在维修管理模块:也需要一个结算弹出div层 ,进行对订单的结算(这里忽略,根据具体的逻辑来实现) 页面显示中,需要显示不同的订单状态,以及修改维修单的状态(以下是部分效果图) 成员之间集成问题有点大,在功能需求逻辑讨论时有点不统一,引用配置出现小问题,权限开放的不怎么好,常被拦截新创建的ajax提交 例如:在mapper.xml中关联数据对象,所用的结果关联请求返回的数据格式有点不一致,在项目经理的调节意见才统一 我觉得项目开发中,这些是经常遇到的事情,如果后面想往这方面发展可以看着自己的老大怎么处理这些事情,以及第一时间怎么处理 在项目开发过程中,对整个负责的模块的掌控以及整个模块和关联模块的逻辑开发,需要多方来谈论,不能单干,而且需要读懂项目经理的配置,添加一些控件(不求美观,求能实现想要的功能需求样式),也需要对mybatis的sql掌控和表之间的关联,在数据量变多的时候还要适当的时候加入全文检索,还可以加入webservice提供一个端口进行游客查询相关订单。需求就这么多,只实现个大概,希望在开发路上越走越远,越接近底层; 以上就是我微不足道的总结经验。
/*数据表格显示*/
layui.use('table', function () {
var stateText;
var table = layui.table;
table.render({
elem: '#test'
, url: '/settlementOrder/selectAll/'
,totalRow: true
, page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档
layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定义分页布局
//,curr: 5 //设定初始在第 5 页
, groups: 1 //只显示 1 个连续页码
//,first: false //不显示首页
//,last: false //不显示尾页
}
, cols: [[
{field: 'sId', width: 80, title: 'ID', sort: true,totalRowText: '合计:'}
/* {field: 'LAY_INDEX', width: 80, title: 'ID', sort: true,templet: function (d) {
//vslue是一行的数据 行索引
return d.LAY_INDEX;
}}*/
, {field: 'name', width: 100, title: '客户',templet: function (d) {
//vslue是一行的数据
//console.debug(d);
return d['customer'].name;
}}
, {field: 'cid', width: 120, title: '维修工单号', sort: true}
, {field: 'reAmount', width: 100, title: '应付金额',totalRow: true }
, {field: 'payAmount', width: 100, title: '实付金额' ,totalRow: true }
, {field: 'payment', width: 180, title: '支付方式', templet: function (d) {
//vslue是一行的数据
return d['payment'].paymentName; }}
, {field: 'settedTime',width: 180, title: '结算时间'}
, {field: 'state', width: 80, title: '状态', sort: true,templet: function (d) {
//vslue是一行的数据
//console.debug(d);
return colorState(d); }}
, {field: 'remarks', title: '备注', sort: true}]]
});
//监听行单击事件(单击事件为:rowDouble)
table.on('row(test)', function (obj) {
var data = obj.data;
/*layer.alert(JSON.stringify(data), {
title: '当前行数据:'
});*/
stateText=obj.data['state'];
//标注选中样式
obj.tr.addClass('layui-table-click').siblings().removeClass('layui-table-click');});
//监听表头排序事件
table.on('sort(test)', function (obj) { //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
console.log(obj.field); //当前排序的字段名
console.log(obj.type); //当前排序类型:asc(降序)、asc(升序)、null(空对象,默认排序)
console.log(this); //当前排序的 th 对象
//获取关键字
var keyword = $("#keyword").val();
table.reload('test', {
initSort: obj //记录初始排序,如果不设的话,将无法标记表头的排序状态。
, url: '/settlementOrder/selectAll/'
, where: { //请求参数
field: obj.field //排序字段 在接口作为参数字段 field order
,order: obj.type //排序方式 在接口作为参数字段 field order
,keyword:keyword
}
});
});
//统一绑定事件
$("a[data-method]").click(function () {
var method = $(this).data("method");
methodObj[method]();
});
var methodObj = {
search: function () {
//获取关键字
var keyword = $("#keyword").val();
//查询
table.reload('test', {
url: '/settlementOrder/selectAll/'
, initSort: {
field: 'sId' //排序字段,对应 cols 设定的各字段名
,type: 'asc' //排序方式 asc: 升序、asc: 降序、null: 默认排序
} //记录初始排序,如果不设的话,将无法标记表头的排序状态。
, where: { //设定异步数据接口的额外参数,任意设
keyword: keyword
}
, page: {curr: 1}//重新从第 1 页开始
});
},
del: function () {
var keyword = $("#keyword").val();
//弹出添加的dialog
var dat = $("tbody tr[class='layui-table-click'] td[data-field='sId']").text();
console.debug(stateText);
if(stateText==0){
if(dat){
layer.open({
title:'确定要取消结算订单:'+dat
,content:'
' 取消原因' +
' '
,btn: ['取消结算', '关闭']
,yes: function(index, layero){
//按钮【按钮一】的回调
// alert(dat+$('#remarks').val());
relaodTable(dat,$('#remarks').val());
layer.closeAll();
}
,btn2: function(index, layero){
//按钮【按钮二】的回调
//return false 开启该代码可禁止点击该按钮关闭
}
,no: function(index, layero){
//按钮【按钮一】的回调
// console.debug(layero);
}
,cancel: function(){
//右上角关闭回调
layer.closeAll();
//return false 开启该代码可禁止点击该按钮关闭
}
});
}
}else if (stateText==1){
layer.msg("已经取消结算了,不能再取消了");
}else if (stateText==2){
layer.msg("已经还车了,交易完成不能再取消了");
} }}
// 提交取消方法
function relaodTable(dat,rek) {
$.post("/settlementOrder/delete/", { id: dat, remarks: rek } );
location.reload();
}
//状态颜色格式化
function colorState(d) {
switch (d['state']){
case 1:
return "
case 0:
return "
case 2:
return "
}}
});
});