基于SSM(Spring+SpringMVC+MyBatis)+Android实现汽修管理系统《建议收藏:附完整源码+数据库》
文章目录
一、登陆系统
(1)需用用户填写的登陆信息:
- 1、账号
- 2、密码
- 3、验证码
- 4、用户类型
(2)登陆操作进行了严格的判断:
a:当用户没有输入任何信息就直接点击“登陆”进行登陆的时候,会根据输入框的顺序依次进行判断:
然后分别会给出如下提示:
- 1、用户名不能为空;
- 2、密码不能为空;
- 3、验证码不能为空;
- 4、请选择用户类型!
b: 当用户开始输入信息点击“登陆”进行登陆的时候,会根据输入框的顺序再次进行判断:
然后分别会给出如下提示:
- 1、判断用户是否正确;
- 2、判断密码是否正确;
- 3、判断验证码是否正确;
- 4、判断用户类型是否正确。
假如输入的信息全部都是不正确的,便会根据判断进行提示:然后分别会给出如下提示:
- 1、用户不正确;
- 2、密码不正确;
- 3、验证码不正确;
- 4、用户类型不正确。
只有输入的信息全部都正确才可以顺利进入“智百盛汽修汽配”管理系统。
登陆页面如下图显示:
二、主页面
登陆进入主页面后,主页面的截图如下:
1、主页面在右上角的地方设置显示当前登陆的用户名(不是登陆的账户号,而是用户名),登陆时间(获取当前登陆的系统时间)和登陆时长(设置session,自动计时,不需要刷新页面,登陆的时长也会自动增加)
2、点击左边导航栏《汽修管理》按钮,进入汽修管理模块,页面截图如下:
三、《预约安排》模块
预约安排主要是针对需要前来修车的客户的预约登记,录入车主、维修车辆基本信息(若已是老客户,可直接导入信息)及修理项目。
♦登记车牌、车型、车主信息,方便后期查询车主资料。
♦修理单号、修理类别、金额、开单日期和预约维修日期、接车人。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
然后点击《预约安排》按钮或者图标,都可以进入预约安排的页面进行相关的操作,页面截图如下:
本页面可以操作的功能分别有“新增”,“删除”,“保存”,“打印”,“查询单据”,“转维修单”,“审核”,“反审核”,“退出”。
首先请看预约安排单页面中的内容:
预约单号:该单号是自动生成的(由大写字母BJ+年月日时分/yyMMdd HHmm+登陆的账户号+0001组成),然后根据每一天的日期来自增,每天首单都是自动从0001开始递增。
对应维修单号:是不能输入的,是用于回填的,它来源于单据转维修单后,也是自动生成的。
开单日期和预约维修日期都是绑定当前的系统时间,车牌文本框中的“Go!”按钮可以点击,然后进入车牌模态框,页面如下:
该模态框的数据是客户是信息,可以在此录入客户的基本信息,即新增客户的基本资料,新增完也可以回填修改(单击表格中的任意行,即可将数据回填到右边对应的文本框中),“请输入车牌号快速查找”是迷糊查询车牌的,可以输入完整的车牌号或者一个号码匹配相对应的数据车辆,方便操作者的操作;然后是“选中”按钮,该按钮是把表格的数据选中回填到主页面的,也相当于双击表格中的数据进行回填,这里既可以选择“选中”按钮进行操作,也可以双击表格进行回填,两个功能都可以实现;接着是“新增”按钮,该按钮并不是真正意义上是新增数据,而是当你单击表格中的任意行,即可将数据回填到右边对应的文本框中,将所有的文本框中的数据进行清空,说白了就是一个清空按钮;然后是“保存”按钮,该按钮可以进行两个操作,第一是新增数据到数据库,第二是修改数据。这里编码的时候要注意。接着是“刷新”操作,该操作是实现刷新页面的作用,这里忽略,最后是“关闭”按钮,点击就关闭模态框。
PS:右边表格中的客户编号也是利用自动生成编号的原理实现的效果,最右下角是“修改复选框”是用来勾选修改数据的,不勾选回填的数据不能进行修改,只有把复选框选中才可以对数据进行修改的操作。
现在我们单击一条数据进行回填,回填到页面的效果如下:
剩余的文本框和下拉框需要用户手动去输入和选择;
接下来下面是明细表格的操作:
1、修理项目明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除;
添加行后只需选中修理项目下拉框就可以把其他的数据进行绑定,然后只要再选择维修性质下拉框就可以了,若是需要更改,表格也是可以编辑的,直接在表格修改即可。
2、产品材料明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加弹出另一个产品模态框,供用户选择需要的产品材料,如下图,删除是从最后一行进行删除数据;
该产品模态框也可以进行多种商品类型的模糊查询,首选可以选择快速查找旁边是下拉框,选择对应是数据,然后再在下拉框旁边是文本框输入与下拉框匹配的信息进行筛选,也可以点击左边的货品分类目录,进行筛选对应是数据,筛选到需要的收据就可以勾选(多条)相对应是数据前面的复选框,然后点击“确定”按钮进行回填到产品材料明细表格中,如果找的数据不满足需求还可以点击“新增加”按钮进入另一个模态框,然后又可以在该模态框输入你想要的信息,也可以上传图片,如下图,再进行保存,数据新增成功后就会刷新出现在产品模态框中,然后可以重复上面是操作回填就可以了。
3、其他费用明细表格中:可以利用鼠标右键选择“添加”和“删除”两个操作,添加是继续添加一行,删除是从最后一行进行删除,添加行后只需选中费用名称下拉框就可以把其他的数据进行绑定,若是需要更改,表格也是可以编辑的,直接在表格修改即可。如图:
接着再看“查询单据”按钮的操作,查询单据是数据来源于刚才主页面保存后的数据,点击“查询单据”弹出单据模态框,如图:
在该模态框中可以进行预约单号模糊查询和审核状态下拉框匹配查询,然后可以双击表格回填数据到主页面(或者单击数据再点击“确定”按钮,也可以回填),回填后还可以在主页面进行“审核”和“反审核”操作;
审核后的数据不允许更改,如下图,
反审核后的数据可以再次修改,如下图。
四、《客户接待》模块
客户接待主要是对前来修车的客户及维修基本资料进行登记,把修理的明细录入,以便后期进行查询。
♦登记车牌、车型、进厂里程、油量、车主信息、发动机号码:方便后期查询车主资料。
♦修理编号、类别、金额、进厂日期和结算日期、送修人电话:方便管理人员管理,联系送修人在相应的时间来取车。
♦修理项目(明细)、估计配件、其他费用、备注、保险索赔:方便维修人员进行维修领料,以及修理时的注意事项,还有后期保险索赔的办理。
在主页面点击《客户接待》按钮或者图标,都可以进入客户接待的页面进行相关的操作,页面截图如下:
本页面同样也是登记维修客户的基本资料,然后录入各种明细,具体操作参考《预约安排》模块;
然后点击“查询单据”,弹出单据模态框。如图:
该模态框是记录保存进去的数据,双击数据可以进行数据回填,如图:
五、《维修派工》模块
在《客户接待》模块中点击“转派工单”可以将对应的数据绑定过来,也就是回填,这里以选择单据回填后的数据来说明,回填后直接点击“转派工单”就可以将《客户接待》页面的数据绑定过来了,如图:
在此页面还可以点击“派工”继续添加明细行,每次添加一行,也可以点击“删除”按钮进行删除。同样可以点击“查询单据”进入单据模态框,如图:
在该模态框中可以进行维修单号模糊查询、单据状态、付款下拉框和车牌匹配查询,然后可以双击表格回填数据到主页面。
六、《维修领料查询》模块
处理送修车辆的配件问题,可以查询送修车辆领料和退料以及领料人资料,以便后期结算。
主要查询维修车辆需要的信息,然后在该页面进行“领料”和“退料”操作;新数据刚过来此页面时,都是显示“未领料”的状态,如下图:
然后领过料的就是“已领料”的状态,退过料的就是“已退料”的状态。如图显示:
在该页面中可以进行时间段的模糊查询,可以选择领料状况下拉框和输入车牌信息进行筛选。例如时间段查询效果如下(根据结算单日期查询,因为结算了才算是出厂时间):
七、《维修领料》模块
然后需要领料的可以单击数据行,点击“领料”,进入《维修领料》模块,如下图:
在你点击“领料”的进入《维修领料》模块时,会将刚才单击数据行中对应的数据回填到该页面中,然后有些空的文本框和下拉框是需要你手动去输入数据或者选择,灰色的文本框是不能进行输入操作的,可以是保存后自己获取回填的,然后注意一下领料员输入框的操作:如图:
该输入框既可以手动输入数据,也可以选择下拉框进行选择,这里采用下拉框和文本框合并同时操作的功能,方便用户在进行数据输入时的操作;
接着再看明细表格中的内容:该进去此页面时,明细表是空的,这时候我们又可以可以利用鼠标右键选择“添加”和“删除”两个操作,添加弹出另一个产品模态框,供用户选择需要的产品材料(详情参考《预约安排》模块中产品材料明细表格的操作),删除是从最后一行进行删除数据;
当数据选择回填后,如图:需要你手动选择仓库下拉框和仓位信息的输入。
最后看一下“查询单据”的操作,点击“查询单据”进入查询单据模态框,如图:
该模态框查询的是前期已经领过料的维修客户的车辆信息,也是可以回填到主页面的,单击你选择的数据行,然后点击“确定”按钮,进行将数据回填到主页面了。如图:
八、《维修退料》模块
退料操作和领料操作差不多,都是在《维修领料查询》模块中的页面进行操作
在进行点击“退料”时,会根据数据中是领料状态来进行判断,如果是未领料的状态,点击“退料”就会提示“尚未领料,无法退料”,如图:
如果是已退料的状态,点击“退料”就会提示“该条数据已退料了,请核实!”,如图:
只有是已领料的状态,点击“退料”才能进入数据选择的模态框,然后再选择数据后才可以《维修退料》页面,模态框数据如图:
该模态框显示的是选择的单据中已经领过的料,这时候你需要退哪一条料或者退全部料,只需选中数据前的复选框,点击“确定”就可以进入《维修退料》页面进行退料操作了。
例如:我选择刚才模态框中是全部材料,点击确定后,刚才选择的材料将会回填在《维修退料》页面中,如图:
这个时候填写领料员等文本框信息再“保存”就完成退料了。如果你突然不想退全部材料,只想退一条,你可以在此页面中点击“删除明细”进行删除明细,从最后一条开始删除,每次只删除一条;如图:
删除完再继续保存操作就可以啦。
九、《完工确认》模块
在送修车辆维修完工之后,需要对车辆进行出厂质检,在《完工确认》模块中进行完工审核操作。如图:
在该页面中可以进行开单时间段(默认绑定当前系统时间,也可以点击文本框选择对应的时间段进行操作)的模糊查询,可以选择完工状况下拉框进行筛选。例如时间段查询效果如下(根据日期查询)
在此页面中最重要的操作还是“完工确认”和“取消完工”这两个操作;数据表格中,未确定完工的单,即为审核的单,完工时间是默认显示“0000-00-00”的,且单据状态为“未结算”,这个时候可以点击该行数据的完工时间为“0000-00-00”的进行完工确认操作,
完工确认前数据如图标识:
完工确认后数据如图标识:
点击“完工确认”后数据中是完工时间将由“0000-00-00”变为系统当前时间;单据状态将由原来的“未结算”变为“完工未结算”。有完工确认必然就有完工取消,再次选中刚才的数据,点击“完工取消”,这时数据中是完工时间将由系统当前时间变回“0000-00-00”;单据状态将由 “完工未结算”变回原来的“未结算”。
完工取消前数据如图标识:
完工取消后数据如图标识:
注意:有时间的(2018-09-06),像这种是不能点击“完工确认”的:点击也会给出提示(已完工的单据不需要重复操作!),如下图:
而完工时间为(0000-00-00),像这种是不能点击“完工取消”的:点击也会给出提示(未完工的单据不需要重复操作!),如下图:
十、《结算出厂》模块
对已经完成审核的车辆进行结算出厂。如果该维修单涉及到三包索赔或者保险,需要通过此处填写索赔信息。点击《结算出厂》按钮或者图标,进入预结算出厂的页面进行相关的操作,页面截图如下:
具体功能操作参考《预约安排》模块的操作使用;
十一:《快速修车》模块
快速修车的功能是为了解决业务不是特别复杂的维修登记过程,如果汽修厂没有严格标准的前台接车、维修派工,仓库领料,维修接单处理,财务结算等独立的业务岗位,可以通过快速修车功能同窗口、一体化解决。
《快速修车》是将《客户接待》到《维修领料》整合到一起,实现快速修车登记管理的目的。
页面截图如下:
具体功能操作参考《客户接待》模块和《维修领料》的操作使用;
部分代码展示:
@ResponseBody
@RequestMapping(value = "/login", produces = "application/json")
public Object login(HttpServletRequest request, String userNumber, String password, Integer userTypeId,
String validateCode) {
String strsmg = "";
JsonReturn jsonReturn = new JsonReturn();
HttpSession session = request.getSession();
Date date = new Date();// 获取当前时间的date对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strDate = dateFormat.format(date);
// main登陆时间
request.getSession().setAttribute("time", strDate);// ("自定义名,jsp接收",变量名)
if (!"".equals(userNumber)) {
if (!"".equals(password)) {
if (!"".equals(validateCode)) {
if (Integer.valueOf(userTypeId) != 0) {
SysUser user = userService.findByUsernameAndPassword(userNumber);
if (user != null) {
request.getSession().setAttribute("yonghu", user);// main获取登陆用户,从数据库查出来//或者用下面精细到某个字段
if (password.equals(user.getPassword())) {
if (session.getAttribute("randomString").toString().equalsIgnoreCase(validateCode)) {
if (Integer.valueOf(userTypeId).equals(user.getUsertypeid())) {
strsmg = "seccess";
jsonReturn.setState(true);
} else {
strsmg = "用户类型不正确!";
jsonReturn.setState(false);
}
} else {
strsmg = "验证码不正确!";
jsonReturn.setState(false);
}
} else {
strsmg = "密码不正确!";
jsonReturn.setState(false);
}
} else {
strsmg = "账户不正确!";
jsonReturn.setState(false);
}
} else {
strsmg = "请选择用户类型!";
jsonReturn.setState(false);
}
} else {
strsmg = "验证码不能为空!";
jsonReturn.setState(false);
}
} else {
strsmg = "密码不能为空!";
jsonReturn.setState(false);
}
} else {
strsmg = "账户不能为空!";
jsonReturn.setState(false);
}
jsonReturn.setMsg(strsmg);
return JSONSerializer.toJSON(jsonReturn);
}
附Android相关展示页面和代码
//文本-按钮 登陆 点击事件
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取参数
String phone = etPhone.getText() == null ? null : etPhone.getText().toString();
String smsValidCode = etSmsCode.getText() == null ? "" : etSmsCode.getText().toString();
String password = etPassword.getText() == null ? null : etPassword.getText().toString();
boolean isSmsLogin = llSms.getVisibility() == View.VISIBLE;
if (phone==null || "".equals(phone.trim())){
//Toast.makeText(mActivityContext, "手机号不能为空", Toast.LENGTH_LONG).show();
//提示框居中显示
Toast toast = Toast.makeText(getApplicationContext(), "手机号不能为空", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
return;
}
//验证数据
if (!Tools.isMobile(phone)) {
etPhone.setError("请输入正确的手机号");
return;
}
//在短信登录的情况下验证 验证码
if (isSmsLogin && !Tools.isNotNull(smsValidCode)) {
etSmsCode.setError("请输入验证码");
return;
}
//在密码登录情况下 验证密码是否为空
if (!isSmsLogin && !Tools.isNotNull(password)) {
etPassword.setError("请输入密码");
return;
}
//发送请求url
//String url = ServiceUrls.getMemberMethodUrl("UserController/appLogin");
String url = isSmsLogin ? ServiceUrls.getMemberMethodUrl("UserController/loginBySms") : ServiceUrls.getMemberMethodUrl("UserController/appLogin");
Map<String, Object> map = new HashMap<>();
map.put("phone", phone);
if (isSmsLogin) {
map.put("smsValidCode", smsValidCode);
} else {
map.put("password", MD5Util.getMD5(password));
}
//发送请求
OkHttpTool.httpPost(url, map, new OkHttpTool.ResponseCallback() {
@Override
public void onResponse(final boolean isSuccess, final int responseCode, final String response, Exception exception) {
//需要更新UI,所有要在UI线程中执行
mActivityContext.runOnUiThread(new Runnable() {
@Override
public void run() {
String strText = "无法访问服务器,请检查网络连接";
if (isSuccess && responseCode == 200){
try {
JSONObject jsonObject = new JSONObject(response);
//获取服务端数据
int code = jsonObject.getInt("code");
strText = jsonObject.getString("text");
if (code == 200) {
String strData = jsonObject.getString("data");
User user = gson.fromJson(strData, User.class);
if (user != null) {
//将用户信息保存到Application(内存)
myApplication.setLoginUser(user);
//将phone和Password存入SharedPreferences
//!!!!*实际项目中避免这样做做,安全性不高
SPUtils.put(mActivityContext, ServiceUrls.SP_USER_NUMBER, user.getUserNumber().trim());
SPUtils.put(mActivityContext, ServiceUrls.SP_USER_PASSWORD, user.getPassword().trim());
//Toast.makeText(mActivityContext, strText, Toast.LENGTH_LONG).show();
//提示框居中显示
Toast toast = Toast.makeText(getApplicationContext(), strText, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();//关闭并销毁当前activity
} else {
strText = "登录失败";
}
} else {
//strText = "登录失败";
//Toast.makeText(mActivityContext, strText, Toast.LENGTH_LONG).show();
//提示框居中显示
Toast toast = Toast.makeText(getApplicationContext(), strText, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
//Toast.makeText(mActivityContext, strText, Toast.LENGTH_LONG).show();
//提示框居中显示
Toast toast = Toast.makeText(getApplicationContext(), strText, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
});
}
});
}
});
完整源码+数据库:点击下载