基于guns开源框架的小区管理信息系统

xiaoya

发布日期: 2019-03-26 10:13:53 浏览量: 1933
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

1 需求分析

1.1 需求分析

本系统的最终用户为系统管理员和小区住户。该系统的成功开发,将可以巨大便利系统管理员对住户信息的统计与管理。根据查询资料及对相关人员的咨询,我们讨论分析,得出小区管理员和小区住户对本系统的实际要求:

1.1.1 小区资源的基本信息

小区管理员应对小区可用资源得信息进行及时地完善和更新,对小区内所有住房的居住情况和车位的租借情况统计整理,并向有需求的住户提供有效信息和便利服务。

住房居住的基本信息

小区管理员应对小区内所有住房被使用情况进行实时地完善与更新,以方便有需求的住户使用。这些住房信息应该包括住房号码,住房状态(使用状态和空闲状态),住房地址,住房所属区域。

车位租借的基本信息

小区管理员应对小区内的所有车位租借情况进行实时地完善与更新,以方便有需求的住户租借。车位租借的情况应包括车位号码,车位地址,租借状态(使用状态和空闲状态)

1.1.2 小区住户的基本信息

当住户入住该小区后,通过手机端APP,登记住户个人信息,以方便小区管理员对住户进行管理,与住户进行必要的业务交流。住户需要登记以下信息。

住户登录的基本信息

登录手机APP时,每位住户通过注册自己的手机号码和登录密码来获得小区 服务的权限,而系统会为每位住户指定一个唯一的用户ID,用于后台信息的 统计和管理。

小区住户的基本信息

每位小区住户都具有必要注册的个人信息,以保证小区内住户个人信息的完 整性,确保小区住户们的安全,其中包括系统为每位住户指定的唯一ID,身 份证号码,姓名,性别,手机号码,年龄,民族,职业,住房号码,登录APP 密码。

1.1.3 用户对系统的要求

1.1.3.1 小区住户

  • 信息要求

    • 小区住户需要及时得到小区空闲住房的信息,可租借车位的信息,租借车位需要租借时间,租借时长,支付费用等信息,需要得到小区官方的公告通知,需要对自己提交的投诉,报修或建议等事务查询官方回复
  • 处理要求

    • 注册和维护自己的登录信息和个人的基本信息。并要求因注册手机号的不同,系统为其再指定一个用于后台数据库操作的唯一ID
    • 注册个人信息时,通过获得小区管理员提供的未被注册的空闲住房,选定其中一个注册。小区管理员也可以根据这一操作,既是录入信息并更新住房信息
    • 住户可以随时更新公告信息,得到小区管理员的通知
    • 住户可以提出投诉,报修和建议等事务请求。提交事务后,便可以随时查看提交事务的实时信息及官方回复情况
    • 住户可以根据小区管理员提供的剩余车位信息,并租借一个想要的车位。系统将会提供该车位的信息,住户也可以停止租借该车位,同时支付必要的租用车位的费用
  • 安全性与完整性要求

    • 安全性要求
      • 系统应设计根据手机端APP提交的手机号和对应的密码鉴别是否是合法的用户,若不是,应拒接登陆请求。在住户注册个人的同时,应提醒注册登录密码信息
      • 每当手机端APP向服务器API发出数据库操作请求时,都需要提前申请token秘钥,以保证每次操作都是合理的
    • 完整性要求
      • 根据实体完整性的要求,各种主要信息记录要保持完整性,即内容不能为空
      • 各种数据间相互的联系要保持正确性
      • 相同的数据在不同记录中要保持一致性。

1.1.3.2 小区管理员

  • 信息要求

    • 小区管理员应需要录入小区可用资源的所有必要信息,例如空闲住房和空闲车位等,可以查看小区所有住户的个人信息和登录APP信息,还需要根据小区的实际情况,具有可公告的信息,需要可以接收小区住户的投诉,报修建议等事务信息,并具有及时回复的信息
  • 处理要求

    • 创建和维护小区管理员的登录信息
    • 根据小区住户提交的注册请求,创建和维护住户们的登录信息和个人信息
    • 发布公告信息,根据小区的实时情况,通知小区住户们必要的生活信息
    • 提供住房被使用的信息。在小区住户们注册个人信息时,需根据小区管理员提供的住房信息,注册未被正在使用的住房进行注册操作,小区管理员可根据住户操作及时更新小区住房的情况
    • 提供车位租借情况的信息。小区应向住户们提供车位正被使用的情况信息,以方便住户们租借空闲车位。小区管理员在接收到住户们的租借车位请求时,需要及时更新小区车位信息,以方便他人租借。住户可以随时停止租借车位,同时需要支付租借车位所需要的费用,系统也会提供给住户本次租借车位操作的信息
  • 安全性要求

    • 系统应要求小区管理员登录时,需要验证登录账号和登录密码正确且对应,以确保整个系统的安全性
    • 住户每次通过手机APP先服务器API发出操作请求时,所需要的token秘钥,需要小区管理员授权与分配,并实时更新授权秘钥

1.2 系统功能的设计和划分

根据如上得到的用户需求,我们将本系统按照所完成的功能分成以下两部分:

1.2.1 用户部分

  • 注册个人信息

  • 根据手机号与登录密码登录

  • 发起投诉或报修

  • 查看发起的投诉或报修

  • 查看剩余车位的数量

  • 租用车位

  • 结束租用车位

  • 获得最新的一条公告

1.2.2 管理员部分

  • 注册新的管理员

  • 根据账号密码登录管理平台,登记查看修改删除小区人员信息

  • 登记查看修改删除小区租房信息

  • 登记查看修改删除车位信息

  • 解决报修或投诉

  • 查看租借信息

  • 发布查看修改删除通知信息

  • 查看统计信息

1.3 数据流图

1.3.1 总数据流图

总数据流图如图所示:

1.3.2 各子系统的分数据流图

房间信息分数据流图如图所示:

用户信息分数据流图如图所示:

通知信息分数据流图如图所示:

车位信息分数据流图如图所示:

租借信息分数据流图如图所示:

报修投诉信息分数据流图如图所示:

管理员信息分数据流图如图所示:

2 系统的设计与实现

2.1 系统框架简介

本系统基于guns开源框架。框架基于SpringBoot 2,整合springmvc + mybatis-plus + echarts。Spring Boot是一种JAVA框架,旨在尽可能快地启动和运行,只需最少的Spring前端配置。Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。Echarts缩写来自Enterprise Charts,商业级数据图表,它最初是为了满足公司商业体系里各种业务系统的报表需求。

关于系统架构采用的是MVC架构 ,它全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。其逻辑图如下图所示:

  • 视图:将视图层存放在PeopleManage\src\main\webapp中,其子文件夹static\modular存放各个业务功能的JavaScript代码,另一个子文件夹WEB-INF\view 存放各个业务功能的HTML代码

  • 控制器:将控制器存放在PeopleManage\src\main\java\cn\stylefeng\guns\modular的各个业务功能的controler文件夹中

  • 模型:将模型存放在PeopleManage\src\main\java\cn\stylefeng\guns\modular\system\model中,各个模型通过其对应的Mapper.xml进行需要的sql查询,通过Mapper接口类来调取Mapper.xml,sql查询的结果。若模型的业务逻辑复杂,将多增加对应的Service类来组合形成更复杂的业务逻辑,使业务逻辑更清晰有条理

2.2 业务的实现

本系统的增删查改模式基本都类似,只是有些具体的业务有不同的需求,系统会有相应的处理,总体框架是没有变的。现在以住房管理为例,详细说明本系统增删查改的逻辑。

2.2.1 信息列表的显示

首先用户看到的应该是住房管理的主页面,如图所示:

本界面存储在 PeopleManage\src\main\webapp\WEBINF\view\room_info\info\info.html

其HTML代码如下:

  1. <div class="ibox float-e-margins">
  2. <div class="ibox-title">
  3. <h5>住房管理</h5>
  4. </div>
  5. <div class="ibox-content">
  6. <div class="row row-lg">
  7. <div class="col-sm-12">
  8. <div class="row">
  9. <div class="col-sm-3">
  10. <#NameCon id="condition" name="名称" />
  11. </div>
  12. <div class="col-sm-3">
  13. <#button name="搜索" icon="fa-search" clickFun="Info.search()"/>
  14. </div>
  15. </div>
  16. <div class="hidden-xs" id="InfoTableToolbar" role="group">
  17. @if(shiro.hasPermission("/info/add")){
  18. <#button name="添加" icon="fa-plus" clickFun="Info.openAddInfo()"/>
  19. @}
  20. @if(shiro.hasPermission("/info/update")){
  21. <#button name="修改" icon="fa-edit" clickFun="Info.openInfoDetail()" space="true"/>
  22. @}
  23. @if(shiro.hasPermission("/info/delete")){
  24. <#button name="删除" icon="fa-remove" clickFun="Info.delete()" space="true"/>
  25. @}
  26. </div>
  27. <#table id="InfoTable"/>
  28. </div>
  29. </div>
  30. </div>

表格显示的位置在<#tableid=”InfoTable”/>,表格由其对应的JavaScript向Controller发出请求获得数据。控制住房管理的JavaScript存放在 PeopleManage\src\main\webapp\static\modular\room_info\info\info.js 中。

其代码如下:

  1. /**
  2. * 住房管理初始化
  3. */
  4. var Info = {
  5. id: "InfoTable", //表格id
  6. seItem: null, //选中的条目
  7. table: null,
  8. layerIndex: -1
  9. };
  10. /**
  11. * 初始化表格的列
  12. */
  13. Info.initColumn = function () {
  14. return [
  15. {field: 'selectItem', radio: true},
  16. {title: '区域标识号', field: 'room_id', visible: true, align: 'center', valign: 'middle',width:"100px"},
  17. {title: '名称', field: 'name', visible: true, align: 'center', valign: 'middle'},
  18. {title: '地址', field: 'address', visible: true, align: 'center', valign: 'middle'},
  19. {title: '类型', field: 'type', visible: true, align: 'center', valign: 'middle',
  20. formatter: function(value,row,index){
  21. if(row.type==true)
  22. {
  23. value='<div style="text-align: center;" ><i class="fa fa-bed"></i>&nbsp;房间</div>';
  24. }
  25. else value='<div style="text-align: center;" >区域</div>';
  26. return value ;
  27. }},
  28. {title: '父节点', field: 'parent_id', visible: false, align: 'center', valign: 'middle'}
  29. ];
  30. };
  31. $(function () {
  32. var defaultColunms = Info.initColumn();
  33. var table = new BSTreeTable(Info.id, "/info/list", defaultColunms);
  34. table.setExpandColumn(2);
  35. table.setIdField("room_id");
  36. table.setCodeField("room_id");
  37. table.setParentCodeField("parent_id");
  38. table.setExpandAll(true);
  39. table.init();
  40. Info.table = table;
  41. });

JavaScript页面中的表格控制工具BSTreeTable向Controler发出请求,请求地址为info/list,Controler接收到请求后返回所需的信息,BSTreeTable根据后端返回的信息对后端返回的信息进行处理,table.init初始化函数对返回的数据进行处理,formatter函数对房间类型进行处理,当房间类型为1时显示为房间,当房间类型为0时显示为区域。

房间管理的控制器位置在 PeopleManage\src\main\java\cn\stylefeng\guns\modular\room_info\controller\InfoController.java,控制器收到/info/list请求地址后执行list函数,list函数调用infoService.list方法后返回房间管理的列表,再使用RoomWarpper处理数据,最后返回给BSTreeTable显示到前端页面中。控制器代码如下:

  1. /**
  2. * 住房管理控制器
  3. */
  4. @Controller
  5. @RequestMapping("/info")
  6. public class InfoController extends BaseController {
  7. private String PREFIX = "/room_info/info/";
  8. /**
  9. * 获取住房管理列表
  10. */
  11. @RequestMapping(value = "/list")
  12. @ResponseBody
  13. public Object list(String condition) {
  14. List<Map<String, Object>> list = this.infoService.list(condition);
  15. return super.warpObject(new RoomWarpper(list));
  16. }
  17. }
  18. infoService中的list方法,在InfoMapper.xml中实现,其代码如下所示:
  19. <select id="list" resultType="map">
  20. select * from info_room
  21. <if test="condition != null and condition != ''">
  22. where address like CONCAT('%',#{condition},'%')
  23. </if>
  24. </select>

经过上述各个步骤,数据才能从数据库中取出来,放到前端界面进行展示。

2.2.2 新增信息

在info.html页面点击添加按钮,info.javascrpit会向控制器发送一个添加请求,请求地址为/info/info_add,其代码如下所示:

  1. Info.openAddInfo = function () {
  2. var index = layer.open({
  3. type: 2,
  4. title: '添加住房',
  5. area: ['800px', '420px'], //宽高
  6. fix: false, //不固定
  7. maxmin: true,
  8. content: Feng.ctxPath + '/info/info_add'
  9. });
  10. this.layerIndex = index;
  11. };

当InfoController接收到/info/info_add请求后会返会info_add.html页面,其代码如下所示:

  1. @RequestMapping("/info_add")
  2. public String infoAdd() {
  3. return PREFIX + "info_add.html";
  4. }

info_add.html页面如图所示:

控制此页面的JavaScript是info_info.javascript,其主要代码如下所示:

  1. /**
  2. * 初始化住房管理详情对话框
  3. */
  4. var InfoInfoDlg = {
  5. infoInfoData : {}
  6. };
  7. /**
  8. * 收集数据
  9. */
  10. InfoInfoDlg.collectData = function() {
  11. this
  12. .set('roomId')
  13. .set('type')
  14. .set('name')
  15. .set('parentId')
  16. .set('address')
  17. }
  18. /**
  19. * 提交添加
  20. */
  21. InfoInfoDlg.addSubmit = function() {
  22. this.clearData();
  23. this.collectData();
  24. //提交信息
  25. var ajax = new $ax(Feng.ctxPath + "/info/add", function(data){
  26. Feng.success("添加成功!");
  27. window.parent.Info.table.refresh();
  28. InfoInfoDlg.close();
  29. },function(data){
  30. Feng.error("添加失败!" + data.responseJSON.message + "!");
  31. });
  32. ajax.set(this.infoInfoData);
  33. ajax.start();
  34. }

当用户填完所有信息,点击提交按钮时,会向后端送请求,请求地址为info/add,参数为填写的信息。

当InfoControler接收到此信息时会调用add函数,add函数会判断其是不是顶层区域,如果是顶层区域,此房间的地址就是房间名,如果不是顶层区域,此房间的地址就是上一层房间的地址再加上此房间名。然后使用mybatis简化的插入方法,infoService.insert(info)函数将信息插入到数据库中。其实现代码如下所示:

  1. @RequestMapping(value = "/add")
  2. @ResponseBody
  3. public Object add(Info info) {
  4. if(info.getParentId()!=0)
  5. info.setAddress(infoService.selectById(info.getParentId()).getAddress()+info.getName());
  6. else info.setAddress(info.getName());
  7. infoService.insert(info);
  8. return SUCCESS_TIP;
  9. }

2.2.3 修改信息

在info.html选中一条记录,再在页面点击修改按钮,info.javascrpit会找到选择记录的id,然后向Controller发送修改请求,请求地址info/info_update,当请求完成后打开新的子页面,如图其代码如下所示:

  1. Info.openInfoDetail = function () {
  2. if (this.check()) {
  3. var index = layer.open({
  4. type: 2,
  5. title: '住房详情',
  6. area: ['800px', '420px'], //宽高
  7. fix: false, //不固定
  8. maxmin: true,
  9. content: Feng.ctxPath + '/info/info_update/' + Info.seItem.id
  10. });
  11. this.layerIndex = index;
  12. }
  13. };

当控制器接收到修改请求后,先根据选中条目id获得完整的房间信息,然后将信息注入到info_edit.html页面中,然后再返回info_edit.html页面。其代码实现如下所示:

  1. @RequestMapping("/info_update/{infoId}")
  2. public String infoUpdate(@PathVariable Integer infoId, Model model) {
  3. Info info = infoService.selectById(infoId);
  4. model.addAttribute("item",info);
  5. if(info.getParentId()!=0)
  6. model.addAttribute("pName", infoService.selectById(info.getParentId()).getName());
  7. else model.addAttribute("pName","顶级");
  8. LogObjectHolder.me().set(info);
  9. return PREFIX + "info_edit.html";
  10. }

info_edit.html界面如下图所示:

当修改成功后,info_info.html会收集用户更改的信息,然后向控制器发送更改请求,请求地址为/info/update其代码如下:

  1. InfoInfoDlg.editSubmit = function() {
  2. this.clearData();
  3. this.collectData();
  4. //提交信息
  5. var ajax = new $ax(Feng.ctxPath + "/info/update", function(data){
  6. Feng.success("修改成功!");
  7. window.parent.Info.table.refresh();
  8. InfoInfoDlg.close();
  9. },function(data){
  10. Feng.error("修改失败!" + data.responseJSON.message + "!");
  11. });
  12. ajax.set(this.infoInfoData);
  13. ajax.start();
  14. }

当控制器接收到修改请求后先找出原来的房间信息,然后查看房间名有没有被修改过,如果房间名被修改了,那此房间所有的子节点的地址都要修改,这样才能保持地址的正确性,然后使用mybatis提供的更新方法,将新数据更新到数据库中。

  1. @RequestMapping(value = "/update")
  2. @ResponseBody
  3. public Object update(Info info) {
  4. Info oldinfo=infoService.selectById(info.getRoomId());
  5. String name=info.getName();
  6. String oldaddress=oldinfo.getAddress();
  7. String newaddress;
  8. if(info.getParentId()==0)newaddress=name;
  9. else newaddress=oldaddress.substring(0,oldaddress.length()-oldinfo.getName().length())+name;
  10. info.setAddress(newaddress);
  11. infoService.updateById(info);
  12. ChangeChildAddress(newaddress,oldaddress,info.getRoomId());
  13. return SUCCESS_TIP;
  14. }

2.2.4 删除信息

用户选择某一条记录,然后点击删除按钮,前端会发送一个删除请求到控制器,请求地址为/info/delete其实现代码如下所示:

  1. Info.delete = function () {
  2. if (this.check()) {
  3. var ajax = new $ax(Feng.ctxPath + "/info/delete", function (data) {
  4. Feng.success("删除成功!");
  5. Info.table.refresh();
  6. }, function (data) {
  7. Feng.error("删除失败!" + data.responseJSON.message + "!");
  8. });
  9. ajax.set("infoId",this.seItem.id);
  10. ajax.start();
  11. }
  12. };

当控制器接收到删除请求时,先通过TreeTool的removeTreeNode方法找出本房间的所有子节点,方法返回所有子节点的id与自己的id,然后通过返回的所有id删除房间信息。

  1. @RequestMapping(value = "/delete")
  2. @ResponseBody
  3. public Object delete(@RequestParam Integer infoId) {
  4. List<Integer> list= TreeTool.removeTreeNode(infoService.list(null),infoId);
  5. for(Integer i :list)
  6. infoService.deleteById(i);
  7. return SUCCESS_TIP;
  8. }

3 结论和展望

在这次的课程设计中,我花费了很多的心思与精力。只要努力就有收获,这个成品我还是比较满意的。在这个过程中,我不但对JAVA Springboot2框架和数据库有了深刻的认识和了解,同时还学会了自学与独立思考的能力。此外,在我所负责的领域中,还有几个地方考虑不足:

  • 报修与投诉管理员回复一次默认已经解决了问题,但是实际情况可能需要管理员多次与住户进行交流才能够完全解决问题

  • 租借流程中缺少管理员对租借的确认,如果系统分配的车位因为一些不可预知的原因不能租借,管理员不能及时反馈给用户

  • 通知信息无法插入图片

  • 插入信息没有控制其格式,可能会导致插入失败

我会根据上述说的不足加以改进,使系统更人性化。

参考文献

[1] 王珊,数据库系统概论[M].高等教育出版社, 2014.

[2] 埃克尔,JAVA编程思想(第4版)[M].机械工业出版社, 2007.

[3] 杨开振,深入浅出SpringBoot 2.x[M].人民邮电出版社, 2019.

[4] 朱要光,SpringMVC+MyBatis开发从入门到项目实战[M].电子工业出版社, 2018.

上传的附件 cloud_download 基于guns开源框架的小区管理信息系统.7z ( 3.79mb, 72次下载 )
error_outline 下载需要10点积分

发送私信

嘎嘎嘎

15
文章数
16
评论数
最近文章
eject