2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 【毕业设计全篇论文和源码】基于SSM的实体商城商户租赁以及信息管理系统的设计与

【毕业设计全篇论文和源码】基于SSM的实体商城商户租赁以及信息管理系统的设计与

时间:2018-07-15 01:52:41

相关推荐

【毕业设计全篇论文和源码】基于SSM的实体商城商户租赁以及信息管理系统的设计与

本设计包含了 多人在线聊天室,微信扫码支付,在线签字,PDF合同在线生成,商户评分,基本的商铺信息管理,合同管理,新闻和公告管理,用户管理等功能,具体功能请参看论文中截图

1 绪论

1.1课题背景

在我国城市化高速发展的今天,各种规模的商城相继出现。商城需要招商,进驻商家进行经营,商城的商铺需要出租和管理,商城各经营场所的招商信息,公告信息和活动信息的发布,进驻商家的各种信息的管理,都是人工手动进行管理的,既没有效率又容易出错,查找起来更是相当的麻烦。基于上述原因,需要借助于一款基于Web的商城商户信息管理系统,便于商铺的在线出租和对商城,商家,商铺的信息的查询与管理,有利于营造良好的商城营商环境,减轻商城管理人员的工作强度,因此设计一款基于Web的商城商户信息管理系统具有较好的实用价值。

1.2 实现技术

IntelliJ IDEA:是java编程语言开发的集成环境。在业界被公认为最好的java开发工具,尤其在智能代码助手、代码自动提示、重构、J2EE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是非常优秀的。

SSM框架:由Spring,SpringMVC,MyBatis组成的框架集,是一个优秀的web项目框架,是继SSH之后,目前比较主流的Java EE企业级框架。Spring的目的就是用来替代更加重量级的的企业级Java技术,用来简化java的开发难度。SpringMVC是在Spring框架内置的MVC实现的一个子框架,可以轻松的实现MVC架构的程序设计。MyBatis 是一个持久层框架,他可以灵活的书写SQL语句,他让我们省略了大部分的JDBC代码、设置参数和获取结果集的代码。只使用简单的XML 和注解来映射基本数据类型、Map 接口和POJO 到数据库记录。

Maven:基于项目对象模型(POM project object model)的一个强大的项目管理工具,可以通过pom.xml文件配置智能的管理jar包

WebSocket:是一种在单个TCP连接上进行全双工通信的协议,允许服务端主动向客户端推送数据。本设计使用WebSocket技术实现聊天大厅的功能。

Druid连接池:阿里巴巴开源平台上的一个项目,能够提供强大的监控和扩展功能,可以替换DBCP和C3P0连接池,提供了一个高效、功能强大、可扩展性好的数据库连接池。

2 需求分析

2.1 可行性分析

2.1.1 技术可行性

SSM框架是spring MVC,spring和mabatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层,是一个成熟的企业级应用开发框架,而且在性能方面,要优于大部分编程语言,跨平台性更是实现了一次编译,到处运行。

2.1.2 经济可行性

传统模式的店铺租赁,需要提前查看选定商铺,然后联系出租方,约定时间后,需要双方同时到达同一个地方,仔细阅读合同后,进行签字并支付现金。然后管理者手动进行记录,这种方式既费时又费力。将挑选店铺,签订合同,支付等集合在一起的本系统,可以省去这些麻烦,并且管理者可以更好的进行管理。

2.1.3 操作可行性

系统使用常见的,用户熟悉的友好界面,使用常见的编辑框,按钮等组件,不仅界面美观,而且容易操作,只要是会操作电脑即可使用。本系统简化了许多的操作逻辑,大部分操作只需要点击鼠标即可操作完成。

2.2流程分析

图3-1用户流程图

图3-2管理员流程图

2 概要设计

2.1 系统概要

基于Web的商城商户信息管理系统,采用MVC设计模式,整体使用Maven管理项目,后端使用SSM框架(Spring,SpringMVC,Mybits),前端使用HTML5,Layui,jQuery,CSS3,聊天大厅使用WebSocket技术,数据库使用MySQL配合阿里的Druid连接池,使用Spring声明式事务管理,设计并实现的一个集商铺在线出租,商铺搜索,合同在线手写签字,合同在线生成,在线支付,聊天大厅,入驻商家展示评分,用户管理,商家管理,商铺管理,首页Banner管理,商城公告活动的发布和管理,合同审核等功能的系统。

2.2 功能概要

基于Web的商城商户信息管理系统主要分为三个部分

1.管理部分:超级管理员对管理员的管理,管理员对用户的管理,管理员对商铺的管理,管理员对商家的管理,管理员对合同的管理,管理员对活动和公告的管理。

2.用户部分:用户查看商铺,用户租赁商铺,用户签订合同,用户对租赁的商铺的管理,用户之间的聊天

3.顾客部分:顾客可以对商家进行评论留言和评分,可以浏览店铺排行榜

图2-1 系统功能图

2.3 数据库设计

2.3.1 E-R图

图2-2用户E-R图

图2-3管理员E-R图

图2-4商铺E-R图

图2-5公告E-R图

图2-6合同E-R图

图2-7总E-R图

2.3.2 数据库表结构

表2-1 用户表(user)

表2-2 管理员表(admin)

表2-3 商铺表(shops)

表2-4 合同表(contract)

表2-5 公告和活动表(announcement)

表2-6 轮播图信息表(banner)

表2-7 评论表(comment)

表2-8 聊天记录表(chatgroup)

3 详细设计

3.1用户部分

3.1.1 用户注册

功能描述:

用户注册是用户通过手机号或者邮箱,注册为系统用户,填写用户名,手机时,使用Ajax后台判断是否已经注册过,并给出提示,避免重复注册。使用手机号码注册时,填入手机号,点击获取验证码按钮,验证码就会发送到手机,填入验证码即可注册成功。使用邮箱注册时,填入自己的邮箱地址,点击获取验证码,验证码就会发送到你的邮箱中,填入邮箱中的验证码即可注册成功。

图3-1用户注册界面图

图3-2注册用户名已存在

Service层:

public ResultInfo register(User user) {

// 校验用户名

User u1 = userDao.findByUsername(user.getUsername());

if (u1 != null) {

return new ResultInfo(false, "用户名已存在");

}

// 校验手机号

User u2 = userDao.findByTelephone(user.getTelephone());

if (u2 != null) {

return new ResultInfo(false, "手机号已存在");

}

// 校验邮箱

User u3 = userDao.findByEmail(user.getEmail());

if (u3 != null) {

return new ResultInfo(false, "邮箱已存在...");

}

// 密码加密

String md5Password = Md5Utils.encodeByMd5(user.getPassword());

user.setPassword(md5Password);

// 保存用户

userDao.save(user);

return new ResultInfo(true);

}

Controller层

// 用户注册

@RequestMapping(value ="/register",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo register(User user, String smscode,String emailcode,Integer type) {

if(type==1) {

// 手机验证码

String sessionCode = (String) session.getAttribute("smsCode_" + user.getTelephone());

if (sessionCode == null || !sessionCode.equals(smscode)) {

return new ResultInfo(false, "手机验证码错误!");

}

}else if(type==2)

{ //邮箱验证码

String sessionCode = (String) session.getAttribute("emailCode_" + user.getEmail());

if (sessionCode == null || !sessionCode.equals(emailcode)) {

return new ResultInfo(false, "邮箱验证码错误!");

}

}else{

return new ResultInfo(false, "其他错误!");

}

// 调用service完成注册 昵称默认为用户ID

user.setNickname("用户"+user.getUid());

ResultInfo resultInfo = userService.register(user);

// 进行判断和页面跳转

if (resultInfo.getCode()==0) {

// 注册成功,清除session的验证码

session.removeAttribute("smsCode_"+user.getTelephone());

session.removeAttribute("emailCode_" + user.getEmail());

return new ResultInfo(true);

} else {

// 注册失败

return resultInfo;

}

}

3.1.2 用户登录

功能描述:

用户使用注册的用户名和密码登录系统,或者使用注册时的手机号,通过短信验证码登录系统。登录页面使用Ajax方式后台异步发送请求,在收到结果后可以直接提示成功或失败,不需要再跳转到其他页面,使用手机登录时,输入注册时使用的手机号,然后点击获取验证码按钮,验证码短信就会发送到手机上,输入验证码即可登录到系统。忘记密码可以使用此功能登录。或者使用密码找回功能找回密码。

图3-3用户账号登录界面图

图3-4用户手机登录界面图

Service层

密码登录:

public ResultInfo pwdLogin(User user) {

User u1 = userDao.findByUsername(user.getUsername());

if (null==u1) {

return new ResultInfo(false, "此用户不存在");

}

String md5Pwd = Md5Utils.encodeByMd5(user.getPassword());

if (!md5Pwd.equals(u1.getPassword())) {

return new ResultInfo(false, "密码不正确");

}

return new ResultInfo(true, "登录成功", u1);

}

短信验证码登录:

public ResultInfo smsLogin(String telephone) {

User u1 = userDao.findByTelephone(telephone);

if (u1 == null) {

return new ResultInfo(false, "此手机号未注册");

}

return new ResultInfo(true, "登录成功", u1);

}

Controller层

密码登录:

/**

* 密码登录

* @param user 用户信息

* @param code 图形验证码

* @return ResultInfo

*/

@RequestMapping(value = "/pwdLogin",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo pwdLogin(User user,String code)

{

String sessionCode = session.getAttribute("imgCode").toString();

if(code!=null && !"".equals(code) && code.toUpperCase().equals(sessionCode)) {

ResultInfo resultInfo = userService.pwdLogin(user);

if (resultInfo.getCode()==0) {

session.setAttribute("User", resultInfo.getData());

session.removeAttribute("imgCode");

}

return resultInfo;

}else{

return new ResultInfo(false,"验证码错误!");

}

}

手机验证码登录:

/**

* 手机登录

* @param telephone 电话

* @param smscode 验证码

* @return ResultInfo

*/

@RequestMapping(value = "/smsLogin",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo smsLogin(String telephone,String smscode)

{

String code = (String) session.getAttribute("smsCode_" + telephone);

if(code!=null && !"".equals(code) && code.equals(smscode)) {

ResultInfo resultInfo = userService.smsLogin(telephone);

// 写入session

if (resultInfo.getCode()==0) {

session.setAttribute("User", resultInfo.getData());

session.removeAttribute("smsCode_"+telephone);

}

return resultInfo;

}else{

return new ResultInfo(false,"验证码错误!");

}

}

3.1.3 找回密码

功能描述:

用户忘记密码后通过此功能可找回密码,可以通过注册时使用的手机找回,也可以使用注册时使用的邮箱找回,在使用手机找回时,输入注册时使用的手机号,点击获取验证码按钮,手机将会收到一条验证码信息,输入验证码后进入下一步,通过邮箱找回时,点击获取验证码按钮,邮箱将会收到验证码,输入验证码信息也可进入下一步。

图3-5找回密码界面图

输入验证码后,就来到了此界面,自动查询出手机或邮箱绑定的用户名,防止用户因忘记用户名而无法登录,然后在下方输入新的密码,确认新的密码,点击重置密码按钮即可重置完成密码操作。

图3-6确认找回密码界面图

Service层

public User forget(User user) {

if(user.getTelephone()!=null)

{

return userDao.findByTelephone(user.getTelephone());

}else if(user.getEmail()!=null)

{

return userDao.findByEmail(user.getEmail());

}

return null;

}

Controller层

@RequestMapping("/forget")

public String forget(User user, String smscode,String emailcode,Integer type) {

Integer smsId = 1;

Integer emailId = 2;

if(user==null||type==null)

{

request.setAttribute("errormsg","非法访问!");

return "/error.jsp";

}

if(type.equals(smsId)) {

// 手机验证码

String sessionCode = (String) session.getAttribute("smsCode_" + user.getTelephone());

if (sessionCode == null || !sessionCode.equals(smscode)) {

request.setAttribute("errormsg","手机验证码错误!");

return "/error.jsp";

}

}else if(type.equals(emailId))

{ //邮箱验证码

String sessionCode = (String) session.getAttribute("emailCode_" + user.getEmail());

if (sessionCode == null || !sessionCode.equals(emailcode)) {

request.setAttribute("errormsg","邮箱验证码错误!");

return "/error.jsp";

}

}else{

request.setAttribute("errormsg","其他错误!");

return "/error.jsp";

}

session.setAttribute("fUser",userService.forget(user));

return "/forgetChange.jsp";

}

/**

* 找回密码第二步,改密码

* @param password 新密码

* @return ResultInfo

*/

@RequestMapping(value = "/forgetChange", produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo forgetChange(String password,String rePassword) {

if(!password.equals(rePassword)) {

return new ResultInfo(false,"两次密码不一致!");

}

User user = (User) session.getAttribute("fUser");

if(user==null)

{

return new ResultInfo(false,"非法请求!");

}

user.setPassword(Md5Utils.encodeByMd5(password));

userService.updateInfo(user);

session.removeAttribute("fUser");

return new ResultInfo(true);

}

3.2个人中心

3.2.1 个人信息

功能描述:

在此页面,可以查看和修改用户的基本信息。包括姓名,手机号,邮箱,性别,身份证等信息,采用Ajax的方式提交到服务器,可以在页面上通过信息框提示是否更新成功,不必跳转页面。

图3-7个人信息界面图

Controller层

@RequestMapping(value = "/updateInfo", produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo updateInfo(User user){

userService.updateInfo(user);

//重新写入session

User u1 = userService.findByUid(user.getUid());

session.setAttribute("User", u1);

return new ResultInfo(true);

}

3.2.2 更换头像

功能描述:

更换头像功能,可以更换用户的头像图片,首先点击上传头像按钮,弹出选择文件对话框,选中要上传的头像图片,点击确定,方框中就会显示选择的图片,此时,头像图片并未上传至服务器,而是读取了文件的内容,将其显示在浏览器中,当点击提交头像时,图片才被送到服务器中保存。

图3-8更换头像界面图

Controller层

@RequestMapping(value = "/updatePic", produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo updatePic(MultipartFile file) throws IOException {

if (!file.isEmpty()) {

User user = (User) session.getAttribute("User");

if (user != null) {

String picPath = "/pic/" + user.getUid() + ".jpg";

File myFile = new File(request.getServletContext().getRealPath("/") + picPath);

file.transferTo(myFile);

user.setPic(picPath);

userService.updateInfo(user);

//重新写入session

User u1 = userService.findByUid(user.getUid());

session.setAttribute("User", u1);

return new ResultInfo(true);

}

return new ResultInfo(false);

}

return new ResultInfo(false);

}

前端

layui.use('upload', function(){

var $ = layui.jquery

,upload = layui.upload;

//头像上传

var uploadInst = upload.render({

elem: '#test1'

,url: '${pageContext.request.contextPath}/user/updatePic' //上传接口

,bindAction:'#test2'//执行文件上传动作

,auto: false

,choose:function (obj) {

obj.preview(function(index, file, result){

$('#demo1').attr('src', result); //图片转为base64赋给src属性

});

}

,done: function(res){

//如果上传失败

if(res.code > 0){

return layer.msg('上传失败');

}

//上传成功

$('#touxiang').attr('src', '${pageContext.request.contextPath}/${User.pic}?'+new Date().getTime());

$('#htouxiang').attr('src', '${pageContext.request.contextPath}/${User.pic}?'+new Date().getTime());

return layer.msg('上传成功');

}

,error: function(){

//失败重传

var demoText = $('#demoText');

demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');

demoText.find('.demo-reload').on('click', function(){

uploadInst.upload();

});

}

});

})

3.2.3 修改密码

功能描述:

用户的修改密码功能,输入自己的旧密码,然后输入新密码,确认新密码,点击确认修改按钮,即可成功修改密码。修改密码后,登录信息将失效,需要重新登录,自动打开登录窗口,并提示用户重新登录。

图3-9修改密码界面图

Controller层

@RequestMapping(value = "/updatePass", produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo updatePass(String oldPassword,String newPassword,String againPassword) {

ResultInfo result;

if (!newPassword.equals(againPassword)) {

result = new ResultInfo(false, "两次密码输入不一致!");

} else {

User user = (User) session.getAttribute("User");

if (user != null) {

if (user.getPassword().equals(Md5Utils.encodeByMd5(oldPassword))) {

if (oldPassword.equals(newPassword)) {

result = new ResultInfo(false, "旧密码不能与新密码一致!");

} else {

user.setPassword(Md5Utils.encodeByMd5(newPassword));

userService.updateInfo(user);

session.removeAttribute("User");

result = new ResultInfo(true);

}

} else {

result = new ResultInfo(false, "旧密码输入错误!");

}

} else {

result = new ResultInfo(false, "非法请求!");

}

}

return result;

}

3.2.4 用户合同管理

功能描述:

用户合同管理功能,在此页面中,可以看到当前用户所签订的所有合同信息,包括(合同编号,合同商铺,开始时间,终止时间,成交价格,合同状态),并且可以下载合同源文件。合同状态分别为 未付款,审核中,已生效,已过期 四个状态。由系统内的定时任务自动管理,每十分钟刷新一次状态。在已生效和已过期状态时,可以下载合同,未支付状态时,可以跳转到付款页面。

图3-10我的合同界面图

Controller层

@RequestMapping("/userHetong")

public String userHetong(){

User user = (User) session.getAttribute("User");

if (user == null){

return "redirect:/index.jsp";

}else{

List<Contract> contracts = contractService.findByUserid(user.getUid());

request.setAttribute("contracts",contracts);

return "/home_hetong.jsp";

}

}

3.2.5 用户商铺管理

功能描述:

用户商铺管理功能,在此页面中,可以看到用户正在经营的商铺信息,包括商铺编号,商铺名称,商铺位置,商铺面积 ,商铺类型,营业时间 ,商铺评分等信息。评分由顾客评价后给出的评分根据一定算法进行计算,用户只能看到分数。同时,用户可以编辑商铺的信息,包括名称,类型,营业时间,简介,详细介绍,封面图,图集等内容。在租赁商铺后可以更新为自己所经营的信息。

图3-11我的商铺界面图

Controller层

@RequestMapping("/userShop")

public String userShop(){

User user = (User) session.getAttribute("User");

if (user == null){

return "redirect:/index.jsp";

}else{

List<Shop> shops = shopService.findShopsByUid(user.getUid());

request.setAttribute("shops",shops);

return "/home_shop.jsp";

}

}

@RequestMapping("/editShop/{sid}")

public String editShop(@PathVariable("sid") Integer sid)

{

User user = (User) session.getAttribute("User");

if(user==null)

{

return "/Login.jsp";

}

Shop shop = shopService.findShopsBySid(sid);

if(shop.getUserid()==user.getUid())

{

request.setAttribute("Shop",shop);

return "/home_shop_edit.jsp";

}

return null;

}

@RequestMapping(value = "/setShop", produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setShop(Shop shop){

User user = (User) session.getAttribute("User");

if(user==null)

{

return new ResultInfo(false);

}

return shopService.update(shop);

}

3.3商铺租赁

3.3.1 出租商铺展示

功能描述:

展示当前正在出租的商铺信息,包括位置,价格,面积,详细介绍等。可选择租赁期限,点击立即租赁,即可进入商铺租赁流程。若当前未登录账号,则弹出账号登录模态框,登录账号后依然停留在本页面,可以继续操作。

图3-12商铺列表页图

图3-13商铺详情页图

ShopsController层

@RequestMapping("/rent")

public String rent(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "12") Integer pageSize) {

PageBean pageBean = shopsService.listRent(pageNum, pageSize);

request.setAttribute("pb", pageBean);

return "/rent_list.jsp";

}

ShopSevice层

public PageBean listRent(Integer pageNum, Integer pageSize)

{

Integer total = shopsDao.findRentCount();

Integer index = (pageNum - 1) * pageSize;

List<Shop> list = shopsDao.findRentByPage(index, pageSize);

return new PageBean(total, list, pageNum, pageSize);

}

前端

<div class="layui-row layui-col-space10">

<s:if test="${empty pb.data}">

<div style="text-align: center;padding-top: 50px">暂无商家</div>

</s:if>

<s:forEach items="${pb.data}" var="shop">

<div class="layui-col-md3 layui-col-sm4">

<div class="item">

<a href="${pageContext.request.contextPath}/detail/${shop.sid}">

<img width="100%" height="200px" src="${pageContext.request.contextPath}${shop.pic}">

</a>

<a href="${pageContext.request.contextPath}/detail/${shop.sid}">

<div style="height:47px;padding: 2px">

<p class="text">${shop.sname}</p>

<div class="layui-row">

<div class="layui-col-xs8 layui-col-md9 layui-col-lg10">

<b>${shop.stime}</b>

</div>

<div class="layui-col-xs4 layui-col-md3 layui-col-lg2" style="text-align: right;color: red">

<b>${shop.score}</b>

</div>

</div>

</div>

</a>

</div>

</div>

</s:forEach>

</div>

3.3.2 签署租赁合同

功能描述:

租赁商铺时,选择好商铺和租赁时间,点击立即租赁后,即可进入在线签署租赁合同页面,生成合同内容,用户在详细阅读合同后,在下方签字处手写签字,然后点击提交,即可完成签署合同。用户提交后,后台使用itext组件,生成PDF文档,并将签名插入到指定位置,保存在/pdf目录下。同时修改商铺状态为已被租赁,然后跳转到支付页面,用户进行支付操作。若用户未完成支付操作,没有商铺操作权限,若用户10分钟后仍未完成支付,商铺将被系统回收,重置为租赁状态。

图3-14签署合同页图

Controller层

@RequestMapping("/create")

public String nameimg(Integer sid,String starttime,String endtime, String namepic,Double price) {

User user = (User) session.getAttribute("User");

if(user!=null && !"".equals(namepic))

{

Shop shop = shopsService.findShopsBySid(sid);

String picPath = "upload\\" + Md5Utils.encodeByMd5(namepic) + ".png";

String realPicPath = request.getServletContext().getRealPath("/") + picPath;

Base64Util.base64ToImage(namepic,realPicPath);

String path = "pdf/"+UUID.randomUUID()+".pdf";

String savepath = request.getServletContext().getRealPath("/") +path;

Contract contract = new Contract();

contract.setId(UuidUtils.getUuid());

contract.setName(user.getNickname());

contract.setUserid(user.getUid());

contract.setShopid(shop.getSid());

contract.setStarttime(starttime);

contract.setEndtime(endtime);

contract.setContract(path);

contract.setState(0);

contract.setPrice(price);

/*添加合同记录 并 修改店铺状态和userid*/

contractService.add(contract,shop,user);

try{

PdfUtil.createPDF(user.getNickname(),shop.getLocation(),shop.getArea(),starttime,endtime,price.toString(),NumToCnUtil.toChinese(price.toString()),realPicPath,savepath);

}catch (Exception e)

{

request.setAttribute("errormsg","合同生成失败!");

return "/error.jsp";

}

return "redirect:/contract/pay/"+contract.getId();

}

return "/error.jsp";

}

Service层

public void add(Contract contract, Shop shop, User user)

{

contractDao.save(contract);

shop.setState(2);

shop.setUserid(user.getUid());

shopsDao.update(shop);

}

前端

$(function () {

$("#box").jSignature();//初始化画板

});

layui.use('form', function(){

var form = layui.form;

//监听表单提交

form.on('submit(tijiao)', function (data) {

var datapair = $("#box").jSignature("getData","image");

$("#namepic").val(datapair[1]);

return true;

});

});

function chongxie(){

$("#box").jSignature("reset");

$("#image").attr('src','');

}

3.3.3 在线支付

功能描述:

本功能调用微信支付完成,签完合同后,弹出支付页面,用户使用手机扫码在线支付。在支付时,后台使用定时器每秒钟查询一次支付状态,若支付成功,跳转到成功页面,在线支付完成。若超时10分钟未支付,页面提示超时,订单将被删除,商铺被回收,重新置为租赁状态。若支付成功,商铺进入审核状态,后台管理员审核通过后,即可正常使用。

图3-15在线支付页图

Controller层

@RequestMapping("/pay/{id}")

public String pay(@PathVariable("id") String id)

{

Contract contract = contractService.findByid(id);

if(contract!=null)

{

String payurl = PayUtils.createOrder(id,contract.getPrice()*100); //支付金额 单位:分

request.setAttribute("payUrl",payurl);

request.setAttribute("contract",contract);

return "/pay.jsp";

}else{

request.setAttribute("errormsg","订单不存在!");

return "/error.jsp";

}

}

/**

* 支付成功回调

* @return

* @throws Exception

*/

@RequestMapping(value = "/payNotify", produces = MediaType.APPLICATION_XML_VALUE)

@ResponseBody

public Map<String, String> payNotify() throws Exception

{

ServletInputStream inputStream = request.getInputStream();

XmlMapper xmlMapper = new XmlMapper();

Map param = xmlMapper.readValue(inputStream, Map.class);

contractService.updateState(param);

Map<String, String> result = new HashMap<>(10);

result.put("return_code", "SUCCESS");

result.put("return_msg", "OK");

return result;

}

/**

* 查看支付状态

*/

@RequestMapping(value = "/checkPay",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo checkPay(String id) {

Contract contract = contractService.findByid(id);

if (contract.getState() == 1) {

return new ResultInfo(true);

} else {

return new ResultInfo(false);

}

}

Service层

public void updateState(Map param) {

//支付成功通知的订单号

String orderId = (String) param.get("out_trade_no");

Contract contract = contractDao.findById(orderId);

contract.setState(3);

contractDao.update(contract);

}

前端

生成二维码

var qr = window.qr = new QRious({

element: document.getElementById('qrious'),

size: 300,

value: '${payUrl}'

});

10分钟倒计时

var num=60*10;

setInterval(function () {

// 发送ajax请求,查询是否支付成功

var url = '${pageContext.request.contextPath}/contract/checkPay?id=${contract.id}';

$.get(url, function (resp) {

if (resp.code==0) {

location.href = '${pageContext.request.contextPath}/success.jsp';

}

});

num--;

$('#jishiqi').html(parseINT(num/60)+'分'+num%60+'秒后失效,请及时付款!')

}, 1000);

超时跳转到错误页

setTimeout(function () {

location.href = '${pageContext.request.contextPath}/error.jsp';

}, 600000);

3.4商家展示

3.4.1 入驻商家展示

功能描述:

列表页展示入驻的全部商家,分页显示,按照评分从高到低排名,也可以按商家分类展示。详情页展示已经在本商城入驻的商家信息,包括简介,商家位置,分类,营业时间,商家评分,详细介绍等。

图3-16商家列表页图

图3-17商家详情页图

Controller层

商家列表

@RequestMapping("/shop")

public String shop(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "12") Integer pageSize,@RequestParam(defaultValue = "-1") Integer type) {

PageBean pageBean;

if(type==-1)

{

pageBean = shopsService.listShop(pageNum, pageSize);

}else{

pageBean = shopsService.listShop(pageNum, pageSize,type);

}

request.setAttribute("pb", pageBean);

return "/shop_list.jsp";

}

商家详情

@RequestMapping("/detail/{sid}")

public String detail(@PathVariable("sid") Integer sid) {

Shop shop = shopsService.findShopsBySid(sid);

request.setAttribute("shop", shop);

if(shop.getState()==1)

{

List<Comment> comments = commentService.findByShopid(sid);

request.setAttribute("Comments", comments);

return "/shop_detail.jsp";

}else{

return "/rent_detail.jsp";

}

}

Service层

public PageBean listShop(Integer pageNum, Integer pageSize)

{

Integer total = shopsDao.findShopCount();

Integer index = (pageNum - 1) * pageSize;

List<Shop> list = shopsDao.findShopByPage(index, pageSize);

return new PageBean(total, list, pageNum, pageSize);

}

3.4.2 评论商家

功能描述:

顾客可以对已经入驻的商家进行留言评论和评分,商家评分根据顾客的评分按照评分公式自动计算,商家无法修改。若评分小于等于1星,商家将被警告。

图3-18商家详情页评论图

Controller层

@RequestMapping(value="/shop/comment",produces = "application/json")

@ResponseBody

public ResultInfo comment(Comment comment)

{

commentService.save(comment);

return new ResultInfo(true);

}

Service层

public void save(Comment comment) {

comment.setTime(new Date());

commentDao.save(comment);

}

前端

<form class="layui-form layui-form-pane" action="">

<input name="shopid" type="hidden" value="${shop.sid}">

<input id="score" name="score" type="hidden" value="5">

<input id="content" name="content" type="hidden">

<div class="">

<div id="myEditor" style="display: none;"></div>

<div class="layui-inline">

<label class="layui-form-label">姓名:</label>

<div class="layui-input-inline">

<input style="width: 150px" name="name" lay-verify="required" autocomplete="off" class="layui-input">

</div>

</div>

<div class="layui-inline">

<label style="margin-top: 3px" class="layui-form-label">评分:</label>

<div id="myPingFen"></div>

</div>

<div style="width: 200px;float:right" id="send" class="layui-btn" lay-submit lay-filter="pinglun-tijiao" >提交</div>

</div>

</form>

<br><br>

<div class="layui-card-header">

评论列表

</div>

<s:if test="${empty Comments}">

<div id="noping" class="layui-card">

<div class="layui-card-body">暂无评论,快来评论吧!</div>

</div>

</s:if>

<div id="pinglist">

<s:forEach items="${Comments}" var="Comment">

<div class="layui-card">

<div class="layui-card-header"><b>${Comment.name}</b><img src="${pageContext.request.contextPath}/imgs/star/${Comment.score}.png" alt=""> ( ${Comment.score}分 ) <i style="color: #BBBBBB">${Comment.time}</i></div>

<div class="layui-card-body">${Comment.content}</div>

</div>

</s:forEach>

</div>

3.5聊天大厅

聊天大厅使用WebSocket技术,实现聊天信息的实时传输。

图3-19聊天大厅图

3.5.1 配置监听路径

功能描述:

此处配置WebSocket的监听路径,聊天大厅连接此处监听的路径,可以向此路径发送数据,服务器监听向此路径发送的数据,收到数据后进行处理。

WebSocketConfig 配置

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(webSocketMessageHandler(),"/websocket").addInterceptors(new MyWebSocketHandshakeInterceptor());

registry.addHandler(webSocketMessageHandler(), "/sockjs/websocket").addInterceptors(new MyWebSocketHandshakeInterceptor()).withSockJS();

}

3.5.2 处理Sesssion

功能描述:

在websocket连接前,对websocket的session进行处理,添加httpsession里的有关用户登录认证的字段:User,以便在聊天大厅获取用户名等信息,将websocket的用户和网站用户联系起来。

WebSocketHandshakeInterceptor握手拦截器

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,

Map<String, Object> attributes) throws Exception {

//Before Handshake--websocket 握手之前的方法

if (request instanceof ServletServerHttpRequest) {

ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;

HttpSession httpSession = servletRequest.getServletRequest().getSession(false);

if (httpSession != null) {

attributes.put("httpsession",httpSession);

User user = (User) httpSession.getAttribute("User");

if (user != null) {

attributes.put("userid", String.valueOf(user.getUid()));

}else{

attributes.put("userid", "0");

}

}

}

return super.beforeHandshake(request, response, wsHandler, attributes);

}

3.5.3 服务端消息处理

功能描述:

处理收到的聊天消息,定义了自己的发送规则,服务器向客户端发送消息时,使用mtype标志,mtype为1时,表示用户发送聊天消息。mtype为2时,表示系统发送提示信息。mtype为3时,表示用户上线。mtype为4时,表示用户下线。mtype为5时,表示发送在线用户列表。客户端向服务器发送消息时,使用ttype标志,ttype值为“消息”时,表示发送的是聊天消息。

WebSocketMessageHandler消息处理器

@Component

public class WebSocketMessageHandler extends TextWebSocketHandler {

@Autowired

private ChatGroupService chatGroupService;

private static final Map<String, ChatUser> USERS = new ConcurrentHashMap<>();

/**

* 建立连接后的处理

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

HttpSession httpsession = (HttpSession) session.getAttributes().get("httpsession");

if(httpsession!=null)

{

User user = (User) httpsession.getAttribute("User");

if(user!=null) {

ChatUser chatuser = new ChatUser();

chatuser.setUser(user);

chatuser.setSession(session);

USERS.put(String.valueOf(chatuser.getUser().getUid()), chatuser);

putChatList(String.valueOf(chatuser.getUser().getUid()));

putOnline(chatuser);

}

}

super.afterConnectionEstablished(session);

}

/**

* 向所有用户发送用户下线

* @param cu ChatUser

*/

private void putOffline(ChatUser cu)

{

HashMap<String,Object> map = new HashMap<>(10);

map.put("mtype",4);

map.put("username",cu.getUser().getUsername());

sendMessageToAllUsers(JSONUtils.toJSONString(map));

}

/**

* 向所有用户发送用户上线

* @param cu ChatUser

*/

private void putOnline(ChatUser cu)

{

HashMap<String,Object> map = new HashMap<>(10);

map.put("mtype",3);

map.put("username",cu.getUser().getUsername());

map.put("nickname",cu.getUser().getNickname());

map.put("pic",cu.getUser().getPic());

sendMessageToAllUsers(JSONUtils.toJSONString(map),String.valueOf(cu.getUser().getUid()));

}

/**

* 向指定用户发送在线用户列表

* @param uid 用户ID

*/

private void putChatList(String uid){

Map<String,Object> map = new HashMap<>(10);

Map<String,Object> map2 = new HashMap<>(10);

map.put("mtype",5);

map.put("count",USERS.size());

Integer i=0;

for(Map.Entry<String, ChatUser> entry : USERS.entrySet()){

Map<String,Object> map3 = new HashMap<>(10);

map3.put("nickname",entry.getValue().getUser().getNickname());

map3.put("username",entry.getValue().getUser().getUsername());

map3.put("pic",entry.getValue().getUser().getPic());

map2.put(String.valueOf(i),map3);

i++;

}

map.put("data",map2);

String json = JSONUtils.toJSONString(map);

try {

USERS.get(uid).getSession().sendMessage(convertWebSocketTextMessage(json));

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 连接关闭后的处理

* @param session 被关闭的session

* @param status 状态

* @throws Exception 发送失败异常

*/

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

String userid = (String) session.getAttributes().get("userid");

//通知全部用户有人下线

if(userid!=null)

{

putOffline(USERS.get(userid));

USERS.remove(userid);

}

super.afterConnectionClosed(session, status);

}

/**

* 文本消息处理

* @param session 发送者session

* @param message 发送内容

*/

@Override

protected void handleTextMessage(WebSocketSession session, TextMessage message){

String typeMsg = "消息";

String userid = (String) session.getAttributes().get("userid");

String payload = message.getPayload();

@SuppressWarnings("unchecked")

HashMap<String, Object> map = (HashMap<String, Object>) JSONUtils.parse(payload);

String ttype = (String) map.get("ttype");

if(typeMsg.equals(ttype))

{

Date d = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

map.put("date",sdf.format(d));

map.put("mtype",1);

putMessages(userid,map);

}

}

/**

* 向指定用户发送消息

* @param userid 用户id

* @param map 消息

*/

private void putMessages(String userid, Map<String,Object> map)

{

//保存聊天记录到数据库

ChatHistory chatHistory = new ChatHistory();

chatHistory.setNickname((String) map.get("nickname"));

chatHistory.setUsername((String) map.get("username"));

chatHistory.setPic((String) map.get("pic"));

chatHistory.setContent((String) map.get("content"));

chatHistory.setDate((String) map.get("date"));

chatGroupService.save(chatHistory);

for(Map.Entry<String, ChatUser> entry : USERS.entrySet()){

WebSocketSession session = entry.getValue().getSession();

if (session.isOpen()) {

try {

map.put("isSelf",entry.getKey().equals(userid));

session.sendMessage(convertWebSocketTextMessage(JSONUtils.toJSONString(map)));

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

private TextMessage convertWebSocketTextMessage(String textMessage) {

return new TextMessage(textMessage);

}

/**

* 发送消息给所有用户

* @param textMessage 消息

*/

private void sendMessageToAllUsers(String textMessage) {

for(Map.Entry<String, ChatUser> entry : USERS.entrySet()){

WebSocketSession session = entry.getValue().getSession();

if (session.isOpen()) {

try {

session.sendMessage(convertWebSocketTextMessage(textMessage));

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

3.5.4 连接服务器

功能描述:

聊天大厅页面连接服务器,然后可以发送消息给服务器。使用两种连接方式,一种是HTML5的Websocket连接,若用户的浏览器不知吹HTML5,则使用SockJS来模拟Websocket连接,这样就可以兼容多种浏览器。因为Websocket无活动60秒后会自动断开连接,所以前端使用javascript设置一个定时器,每55秒发送一次心跳数据,用来保持Websocket连接,服务器无需回复这个信息。

varwsPath='ws://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/';

var socket;

try {

if ('WebSocket' in window) {

socket = new WebSocket(wsPath+"websocket");

} else {

socket = new SockJS(wsPath+"sockjs/websocket");

}

} catch (e) {

console.log('创建连接失败!'+e);

}

socket.onmessage=function(ev){

var obj = eval('('+ev.data+')');

addMessage(obj)

};

setInterval(function () {

var str = JSON.stringify({

ttype:'心跳'

});

socket.send(str);

},55000);

3.5.5 发送消息

功能描述:

用户在输入框输入内容后,点击发送按钮,聊天大厅使用JS判断用户是否登录,消息内容是否为空,通过后把消息内容拼接成json格式,然后通过Websocket发送给服务器。消息可以支持文字,表情,超链接,图片等格式。

$("#send").click(function(){

var u = '${User}';

if(u=='') {

layer.msg("您不能发送消息,请登录!");

return false;

}

var txt = layedit.getContent(index);

if(txt==''||txt==' ') {

layer.msg("消息不能为空!");

return false;

}

var str = JSON.stringify({

nickname:nickname,

username:username,

pic:pic,

content:txt,

ttype:'消息'

});

if(isEmpty(txt))

{

layer.msg("没有输入内容!");

}else {

socket.send(str);

layedit.setContent(index,'');

}

});

3.5.6 接收消息

功能描述:

客户端收到消息后,判断消息类型,mtype为1时代表是聊天消息。将接收到的聊天消息格式化后,填充到消息模板里,然后追加到容器中,显示在页面上,同时判断这条消息是不是自己发的,如果是,则不播放消息提示音,如果不是则播放收到消息的提示音,提醒用户收到消息。

var audio= new Audio("${pageContext.request.contextPath}/audio/default.mp3");

if(msg.mtype==1)

{

var box = $("#msgtmp").clone();

box.show();

box.appendTo("#chatContent");

box.find('[ff="nickname"]').html(msg.isSelf? ('<i>'+msg.date+'</i>'+msg.nickname+' ('+msg.username+')'):(msg.nickname+' ('+msg.username+')'+'<i>'+msg.date+'</i>'));

box.find('[ff="pic"]').html('<img src="'+msg.pic+'">');

box.find('[ff="msgdate"]').html(msg.date);

box.find('[ff="content"]').html(msg.content);

box.addClass(msg.isSelf? 'layim-chat-mine':'');

scroll_To(1000);

//不是自己发的消息播放叮咚声

if(!msg.isSelf)

{

audio.play();

}

}

3.6定时任务

定时任务主要处理的是长时间未支付的合同和计算过期合同,使用Spring框架的@Scheduled注解实现。定时任务是每隔一段时间自动运行一次的任务,启动后无需人工管理,即可自动执行。

3.6.1 未支付合同处理

功能描述:

定时处理超过支付时间但是仍未支付的合同订单。每10分钟扫描一次,若有超时未支付的合同订单,将相关联的商铺重新置为租赁状态,然后删除这个合同,将相关联的用户置为空。

private void timeOutTiming(){

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

List<Contract> cons = contractService.findByNoPay();

for (Contract con : cons) {

String starttime = con.getStarttime();

try{

long startDate = format.parse(starttime).getTime();

long nowDate = System.currentTimeMillis();

long minute = (nowDate-startDate)/1000/60;

if(minute>=10)

{

//十分钟未支付,删除合同并恢复租赁

contractService.delete(con.getId());

}

}catch (Exception e){

e.printStackTrace();

}

}

}

Service层

public ResultInfo delete(String id) {

//改为租赁状态

shopsDao.updateState(contractDao.findById(id).getShopid(),0);

shopsDao.updateUid(contractDao.findById(id).getShopid(),0);

contractDao.delete(id);

return new ResultInfo(true);

}

3.6.2 到期合同处理

功能描述:

定时处理到期合同,合同到期后,将商铺重置为过期审核状态,供后台管理员审核和修改,然后将合同置为过期状态,将相关联的用户置为空。

private void expiredTiming(){

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

List<Contract> cons = contractService.findByValid();

for (Contract con : cons) {

String endtime = con.getEndtime();

try{

long endDate = format.parse(endtime).getTime();

long nowDate = System.currentTimeMillis();

long expired = nowDate-endDate;

if(expired>0){

//合同过期 恢复租赁状态

contractService.updateStateById(con.getId(),2);

}

}catch (Exception e){

e.printStackTrace();

}

}

}

Service层

public void updateStateById(String id,Integer state) {

Contract contract = contractDao.findById(id);

contract.setId(id);

contract.setState(state);

contractDao.update(contract);

//店铺租赁过期状态

shopsDao.updateState(contract.getShopid(),2);

shopsDao.updateUid(contract.getShopid(),0);

}

3.7后台管理

3.7.1 最新合同审核

功能描述:

对用户提交的合同进行审核,在后台可以查看合同全部内容,验证合同内容和签字是否规范。对签字不规范的合同可以进行驳回处理,对签字规范的合同进行通过处理。

图3-20最新合同审核页图

图3-21合同查看

Controller层

private boolean check(){

Admin admin = (Admin) session.getAttribute("Admin");

return admin != null;

}

@RequestMapping(value = "/data/getCheckCont",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getCheckCont(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return contractService.findCheckByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setYesCont",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setYesCont(Contract contract)

{

if(check()) {

Contract contract1 = contractService.findByid(contract.getId());

Shop shop = shopsService.findShopsBySid(contract1.getShopid());

shop.setState(1);

shopsService.addOrUpdate(shop);

contract.setState(1);

return contractService.addOrUpdate(contract);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/setNoCont",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setNoCont(Contract contract)

{

if(check()) {

contract.setState(4);

return contractService.addOrUpdate(contract);

}

return new ResultInfo(false,"没有操作权限!");

}

Service层

public ResultInfo addOrUpdate(Contract contract) {

Contract c = contractDao.findById(contract.getId());

try {

if (c == null) {

contractDao.save(contract);

} else {

contractDao.update(contract);

}

return new ResultInfo(true);

}catch (Exception e){

return new ResultInfo(false);

}

}

public PageBean findCheckByPage(Integer pageNum, Integer pageSize) {

Integer count = contractDao.findCheckCount();

Integer index = (pageNum - 1) * pageSize;

List<Contract> data = contractDao.findCheckByPage(index, pageSize);

return new PageBean(count, data, pageNum, pageSize);

}

3.7.2 过期商铺审核

功能描述:

管理员对过期的商铺进行审核,重新设置商铺的相关信息,然后将商铺状态改为租赁状态,在网站上进行出租。先点击修改按钮,在弹出的窗口中重新设置店铺信息,然后点击出租按钮,即可进行出租。

图3-22过期商铺审核页图

图3-23过期商铺审核编辑页图

Controller层

@RequestMapping(value = "/data/getCheckRent",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getCheckRent(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return shopsService.listCheckRent(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setToRent",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setToRent(Shop shop)

{

if(check()) {

return shopsService.updateState(shop.getSid(),0);

}

return new ResultInfo(false,"没有操作权限!");

}

Service层

public PageBean listCheckRent(Integer pageNum, Integer pageSize)

{

Integer total = shopsDao.findCheckRentCount();

Integer index = (pageNum - 1) * pageSize;

List<Shop> list = shopsDao.findCheckRentByPage(index, pageSize);

return new PageBean(total, list, pageNum, pageSize);

}

3.7.3 用户管理

功能描述:

管理员对商城注册用户的管理,可以添加用户,修改用户信息,删除用户等。

图3-24用户管理页图

图3-25用户管理修改页图

Controller层

@RequestMapping(value = "/data/getUser",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getUser(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return userService.findByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setUser",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setUser(User user)

{

if(check()) {

return userService.addOrUpdateUser(user);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delUser",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delUser(Integer id)

{

if(check()) {

return userService.delUser(id);

}

return new ResultInfo(false,"没有操作权限!");

}

Service层

public PageBean findByPage(Integer pageNum, Integer pageSize) {

Integer count = userDao.findCount();

Integer index = (pageNum - 1) * pageSize;

List<User> data = userDao.findByPage(index, pageSize);

return new PageBean(count, data, pageNum, pageSize);

}

public ResultInfo addOrUpdateUser(User user) {

User u = userDao.findByUid(user.getUid());

try {

if (u == null) {

user.setPassword(Md5Utils.encodeByMd5("123456"));

userDao.save(user);

} else {

userDao.update(user);

}

return new ResultInfo(true);

}catch (Exception e){

return new ResultInfo(false);

}

}

public ResultInfo delUser(Integer id) {

userDao.delete(id);

return new ResultInfo(true);

}

3.7.4 管理员管理

功能描述:

超级管理员对管理员的管理,可以添加管理员,修改管理员信息,删除管理员等。

图3-26管理员管理页图

图3-27管理员管理修改页图

Controller层

@RequestMapping(value = "/data/getAdmin",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getAdmin(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return adminService.findByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setAdmin",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setAdmin(Admin admin)

{

if(isSuper()) {

return adminService.addOrUpdate(admin);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delAdmin",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delAdmin(Integer id)

{

if(isSuper()) {

return adminService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

前端

layui.use('table', function(){

var table = layui.table;

table.on('tool(demo)', function(obj){

var data = obj.data;

if(obj.event === 'del'){

layer.confirm('真的要删除吗?', function(index){

$.post('${pageContext.request.contextPath}/data/delAdmin?id='+data.id, {}, function(str){

if(str.code === 0)

{

obj.del();

layer.alert("删除成功");

}else(str.code === 1);

{

layer.alert(str.msg);

}

});

layer.close(index);

});

} else if(obj.event === 'edit'){

layer.open({

type: 2,

title:'修改管理员',

area: ['350px', '300px'],

content: 'AdminForm.jsp?type=1&id='+data.id+'&username='+data.username+'&password='+data.password+'&quanxian='+data.quanxian

});

}

});

var $ = layui.$, active = {

addAdmin: function(){ //获取选中数据

layer.open({

type: 2,

title:'添加管理员',

area: ['350px', '300px'],

content: 'AdminForm.jsp'

});

}

};

3.7.5 商家管理

功能描述:

管理员管理已在商城入驻的商家,可以修改商家的全部信息,删除商家等

图3-28商家管理页图

图3-29商家管理修改页图

Controller层

@RequestMapping(value = "/data/getShop",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getShop(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return shopsService.listShop(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setShop",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setShop(Shop shop)

{

if(check()) {

return shopsService.addOrUpdate(shop);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delShop",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delShop(Integer id)

{

if(check()) {

return shopsService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/ShopForm")

public String shopForm(Integer id)

{

if(check()) {

Shop shop = shopsService.findShopsBySid(id);

request.setAttribute("Shop",shop);

return "/admin/page/ShopForm.jsp";

}

return null;

}

Service层

public PageBean listShop(Integer pageNum, Integer pageSize)

{

Integer total = shopsDao.findShopCount();

Integer index = (pageNum - 1) * pageSize;

List<Shop> list = shopsDao.findShopByPage(index, pageSize);

return new PageBean(total, list, pageNum, pageSize);

}

public Shop findShopsBySid(Integer sid) {

return shopsDao.findBySid(sid);

}

3.7.6 商铺管理

功能描述:

管理员对商铺的管理,包括正在出租的商铺和已经营业的商铺。可以添加新商铺,修改商铺,删除商铺。

图3-30商铺管理页图

图3-31商铺管理修改页图

Controller层

@RequestMapping(value = "/data/getRent",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getRent(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return shopsService.listRent(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setRent",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setRent(Shop shop)

{

if(check()) {

return shopsService.addOrUpdate(shop);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delRent",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delRent(Integer id)

{

if(check()) {

return shopsService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/RentForm")

public String rentForm(Integer id)

{

if(check()) {

Shop shop = shopsService.findShopsBySid(id);

request.setAttribute("Shop",shop);

return "/admin/page/RentForm.jsp";

}

return null;

}

前端

layui.use('table', function(){

var table = layui.table;

table.on('tool(demo)', function(obj){

var data = obj.data;

if(obj.event === 'del'){

layer.confirm('真的要删除吗?', function(index){

$.post('${pageContext.request.contextPath}/data/delRent?id='+data.sid, {}, function(str){

if(str.code === 0)

{

obj.del();

layer.alert("删除成功");

}else if(str.code === 1)

{

layer.alert("找不到数据,删除失败");

}else if(str.code === 2)

{

layer.alert("权限不足,删除失败");

}

});

layer.close(index);

});

} else if(obj.event === 'edit'){

layer.open({

type: 2,

title:'修改商铺',

area: ['100%', '100%'],

content: '${pageContext.request.contextPath}/data/RentForm?id='+data.sid

});

}

});

3.7.7 合同管理

功能描述:

管理员对已经签订的合同的管理,可以查看合同,也可以删除合同。

图3-32合同管理页图

图3-33合同查看页图

Controller层

@RequestMapping(value = "/data/getCont",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getCont(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return contractService.findByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setCont",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setCont(Contract contract)

{

if(check()) {

return contractService.addOrUpdate(contract);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delCont",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delCont(String id)

{

if(check()) {

return contractService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

3.7.8 首页轮播图管理

功能描述:

对网站首页轮播图的管理,可以添加和修改,删除轮播图,并且能够管理轮播图指向的链接,若指向链接为空,则不使用链接。可以选择上传本地的图片,也可以使用网络图片。

图3-34首页轮播图管理页图

图3-35首页轮播图修改页图

Controller层

@RequestMapping(value = "/data/getBanner",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getBanner(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return bannerService.findByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setBanner",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setBanner(Banner banner)

{

if(check()) {

return bannerService.addOrUpdate(banner);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delBanner",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delBanner(Integer id)

{

if(check()) {

return bannerService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

3.7.9 活动和公告管理

功能描述:

对商城活动和公告的管理,可以发布活动和公告招商等信息,信息将展示在首页显眼的位置。管理员可以添加新的活动和公告,修改活动和公告,删除活动和公告。

图3-36公告和活动管理页图

图3-37公告和活动修改页图

Controller层

@RequestMapping(value = "/data/getAnno",produces = "application/json;charset=utf-8")

@ResponseBody

public PageBean getAnno(@RequestParam(defaultValue = "1")Integer page, @RequestParam(defaultValue = "10")Integer limit)

{

if(check()) {

return announcementService.findByPage(page, limit);

}

return null;

}

@RequestMapping(value = "/data/setAnno",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo setAnno(Announcement announcement)

{

if(check()) {

return announcementService.addOrUpdate(announcement);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/delAnno",produces = "application/json;charset=utf-8")

@ResponseBody

public ResultInfo delAnno(Integer id)

{

if(check()) {

return announcementService.delete(id);

}

return new ResultInfo(false,"没有操作权限!");

}

@RequestMapping(value = "/data/AnnoForm")

public String annoForm(Integer id)

{

if(check()) {

Announcement announcement = announcementService.findById(id);

request.setAttribute("Anno",announcement);

return "/admin/page/AnnoForm.jsp";

}

return null;

}

3.8事务管理

3.8.1 声明式事务

事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。Spring中的事务分为编程式事务和声明式事务,本系统使用的是声明式事务,Spring也推荐使用声明式事务。声明式事务是将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。通过在xml文件中写一段配置实现,在需要使用事务时在指定方法或者类中添加@Transactional注解即可,方法执行之前启动事务,遇到运行时错误时自动回滚,没有遇到错误则提交事务。

XML配置

<aop:aspectj-autoproxy expose-proxy="true" />

<tx:annotation-driven transaction-manager="txManager" />

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">

<tx:attributes>

<tx:method name="save*" propagation="REQUIRED" />

<tx:method name="add*" propagation="REQUIRED" />

<tx:method name="update*" propagation="REQUIRED" />

<tx:method name="del*" propagation="REQUIRED" />

<tx:method name="reg*" propagation="REQUIRED" />

<tx:method name="*" read-only="true" />

</tx:attributes>

</tx:advice>

<aop:config expose-proxy="true">

<aop:pointcut id="txPointcut"

expression="execution(* com.qiang.mall.service.*.*(..))" />

<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />

</aop:config>

4 系统测试

4.1 测试用例

表4-1 用户账号登录测试用例表

表4-2用户手机登录测试用例表

4.2 功能测试

表4-3功能测试表

5 总结

至此,毕业设计全部完成,..........

源码下载地址:/download/sunqiang4/21180240

打不开就是在审核

【毕业设计全篇论文和源码】基于SSM的实体商城商户在线租赁以及信息管理系统的设计与实现(多人在线聊天室 微信扫码支付 在线签字 PDF合同在线生成 商户评分)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。