SSM 框架搭建的CRM客户管理系统

网友投稿 588 2022-10-25

SSM 框架搭建的CRM客户管理系统

SSM 框架搭建的CRM客户管理系统

【CRM客户管理系统】

调研

产品

需求

参考《01_CRM需求概要文档V1.0》

UI

开发

登录页面跳转

登录

登录功能-首页访问--完善功能

代码如下: UserLoginController.java: /** * 登录首页 * @author likang * @date 2018-4-19 下午5:33:34 */ @Controller public class UserLoginController { @Autowired private IUserService userService; /** * 跳转登录页面 * @param model * @return */ @RequestMapping(value = "/login.do",method = RequestMethod.GET) public String index(Model model){ if (UserContext.getLoginUser() != null) { return "redirect:/main.do"; } return JumpViewConstants.SYSTEM_LOGIN; } /** * 主页面 * @param model * @return */ @RequestMapping(value = "/main.do",method = RequestMethod.GET) public String main(Model model){ if (UserContext.getLoginUser() != null) { return JumpViewConstants.SYSTEM_INDEX; } return JumpViewConstants.SYSTEM_LOGIN; } /** * 登录功能 * @param request * @param email 用户名 * @param password 密码 * @param sign * @return */ @RequestMapping(value = "/login.do",method = RequestMethod.POST) public String login(HttpServletRequest request,String email,String password,String sign,Model model){ // if (email != null && !"".equals(email)) { // // } //isnotblank:判断参数是否为空和“” //isNotEmpty:只会判断参数是否为null if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(password)) { //利用spring容器获取map中的属性值 email = email + ContextUtil.getInitConfig("email_suffix"); //验证用户名是否存在 User user = userService.queryUserByEmail(email); if (user == null) {//用户不存在 // model.addAttribute(ReturnConstants.USER_NOT_EXIST); model.addAttribute("msg", ReturnConstants.USER_NOT_EXIST); return JumpViewConstants.SYSTEM_LOGIN; } //验证密码是否匹配 boolean isExis = userService.isExisPassword(String.valueOf(user.getUserid()), password); if (!isExis) { // model.addAttribute(ReturnConstants.PASSWORD_ERROR); model.addAttribute("msg", ReturnConstants.PASSWORD_ERROR); return JumpViewConstants.SYSTEM_LOGIN; } //cookie //TODO...... //处理session UserContext.setLoginUser(user); request.getSession(true).setAttribute("loginName", user.getUsername()); request.getSession(true).setAttribute("ischange", user.getIschange()); //跳转成功首页 // return JumpViewConstants.SYSTEM_INDEX; return "redirect:/main.do"; } return ReturnConstants.PARAM_NULL;//接收参数为空 } }

登录功能-cookie问题

开发步骤:1:为了解决用户端禁用浏览器cookie第三方数据的问题2:只需要在服务器中保存一份cookie即可,同步到浏览器客户端 示例代码: UserLoginController.java: private static final String COOKIE_KEY = "_auth_"; private static final String COOKIE_SPI = "_#_"; /** * 登录功能 * @param request * @param email 用户名 * @param password 密码 * @param sign * @return */ @RequestMapping(value = "/login.do",method = RequestMethod.POST) public String login(HttpServletRequest request,HttpServletResponse response,String email,String password,String sign,Model model){ // if (email != null && !"".equals(email)) { // // } //isnotblank:判断参数是否为空和“” //isNotEmpty:只会判断参数是否为null if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(password)) { //利用spring容器获取map中的属性值 email = email + ContextUtil.getInitConfig("email_suffix"); //验证用户名是否存在 User user = userService.queryUserByEmail(email); if (user == null) {//用户不存在 // model.addAttribute(ReturnConstants.USER_NOT_EXIST); model.addAttribute("msg", ReturnConstants.USER_NOT_EXIST); return JumpViewConstants.SYSTEM_LOGIN; } //验证密码是否匹配 boolean isExis = userService.isExisPassword(String.valueOf(user.getUserid()), password); if (!isExis) { // model.addAttribute(ReturnConstants.PASSWORD_ERROR); model.addAttribute("msg", ReturnConstants.PASSWORD_ERROR); return JumpViewConstants.SYSTEM_LOGIN; } //cookie Cookie cok = new Cookie(COOKIE_KEY, URLEncoder.encode(user.getUsername())+COOKIE_SPI+MD5Tools.encode(user.getEmail())); cok.setPath("/"); cok.setMaxAge(-1);//-1:立即创建,并且在登录成功之后,就生效 //0:在客户端关闭浏览器之后,即失效 response.addCookie(cok); //处理session UserContext.setLoginUser(user); request.getSession(true).setAttribute("loginName", user.getUsername()); request.getSession(true).setAttribute("ischange", user.getIschange()); //跳转成功首页 // return JumpViewConstants.SYSTEM_INDEX; return "redirect:/main.do"; } return ReturnConstants.PARAM_NULL;//接收参数为空 }

退出功能

开发步骤:1:清除session信息2:清除存放于服务器中的cookie数据3:清除客户端中的cookie数据4:跳转登录页面即可 示例代码: UserLoginController.java: /** * 退出 * @param request * @return */ @RequestMapping(value = "/logout.do",method = RequestMethod.GET) public String logout(HttpServletRequest request,HttpServletResponse response){ //清除session UserContext.clearLoginUser(); //清除服务器中的cookie数据 Cookie cok = new Cookie(COOKIE_KEY,null); cok.setMaxAge(0); cok.setPath("/"); response.addCookie(cok); //清除客户端中的cookie数据 Cookie coksessionID = new Cookie("jsESSIONID",null); coksessionID.setMaxAge(0); coksessionID.setPath(request.getContextPath()); response.addCookie(coksessionID); //跳转登录页面 return "redirect:/main.do"; }

登录成功-权限管理-左侧菜单展示功能

开发步骤:1:根据登录成功用户的角色ID,查询对应的菜单信息,参考第一天的sql语句2:首先查询一级菜单信息3:循环遍历一级菜单信息,查询当前一级菜单对应的二级菜单信息 示例代码: UserLoginController.java: /** * 主页面 * @param model * @return */ @RequestMapping(value = "/main.do",method = RequestMethod.GET) public String main(Model model){ if (UserContext.getLoginUser() != null) { //根据当前登录用户的角色,查询当前角色对应的菜单信息 List

list = userService.queryMenusByRoleId(UserContext.getLoginUser().getRoleid().toString()); model.addAttribute("menus", list); return JumpViewConstants.SYSTEM_INDEX; } return JumpViewConstants.SYSTEM_LOGIN; } IUserService.java: /** * 根据角色主键ID,查询当前角色对应的菜单信息 * @param roleId 角色主键ID * @return */ public List queryMenusByRoleId(String roleId); UserServiceImpl.java: @Autowired IDataAccess menuDao; public List queryMenusByRoleId(String roleId) { Map param = new HashMap(); param.put("roleId", roleId); param.put("isparid", "true");//判断sql语句的标识,不封装到sql执行语句当中 //只查询一级菜单信息 List list = menuDao.queryByStatment("queryMenusByRoleId", param, null); if (list != null && list.size() > 0) { for (int i = 0; i < list.size(); i++) { Long menuid = list.get(i).getMenuid();//一级菜单主键ID param.clear(); param.put("roleId", roleId); param.put("menuparaid", menuid);//将一级菜单ID,当做二级菜单的父ID param.put("isparid", null); List listch = menuDao.queryByStatment("queryMenusByRoleId", param, null); list.get(i).setChildren(listch); } } return list; } UserMapper.xml:

页面展示:

用户管理

页面跳转

开发步骤:1:通过前端找到接口地址2:为菜单的查询添加url的字段 示例代码: UserController.java: /** * 跳转用户管理页面 * @param model * @return */ @RequestMapping(value = "/system/userMang.do",method = RequestMethod.GET) public String userManger(Model model){ if (UserContext.getLoginUser() != null) { return JumpViewConstants.SYSTEM_USER_MANAGE; } return JumpViewConstants.SYSTEM_LOGIN; }

列表查询

开发步骤:1:通过浏览器debug,获取接口地址(红色的404接口)2:支持分页查询 示例代码: UserController.java: /** * 用户管理模块 * @author likang * @date 2018-4-23 下午4:55:12 */ @Controller public class UserController extends BaseController{ @Autowired private IUserService userService; /** * 跳转用户管理页面 * @param model * @return */ @RequestMapping(value = "/system/userMang.do",method = RequestMethod.GET) public String userManger(Model model){ if (UserContext.getLoginUser() != null) { return JumpViewConstants.SYSTEM_USER_MANAGE; } return JumpViewConstants.SYSTEM_LOGIN; } /** * 查询用户信息列表 * @param request * @param currentPage * @param pageSize * @return */ @RequestMapping(value = "/system/userlist.do",method = RequestMethod.GET) public @ResponseBody String queryUserList(HttpServletRequest request,Integer currentPage,Integer pageSize){ List list = userService.queryAllUser(processPageBean(pageSize, currentPage)); return jsonToPage(list); } } IUserService.java: /** * 查询用户信息列表 * @param pageBean * @return */ public List queryAllUser(PageBean pageBean); UserServiceImpl.java: public List queryAllUser(PageBean pageBean) { List list = userDao.queryByStatment("queryAllUser", null, pageBean); return list; } UserMapper.xml:

增加、修改

开发步骤:1:通过前端获取增加、修改的接口地址2:添加查询所有部门信息接口3:添加根据部门ID查询当前部门下所有角色信息的接口4:添加保存、修改的方法controller5:根据是否存在用户主键ID,来区分到底是修改还是增加6:增加和修改无需写sql语句 示例代码: DeptController.java: /** * 部门管理模块 * @author likang * @date 2018-4-24 上午9:06:29 */ @Controller public class DeptController extends BaseController{ @Autowired private IDeptService deptService; /** * 查询所有部门信息 * @param request * @return */ @RequestMapping(value = "/dept/queryDept.do",method = RequestMethod.GET) public @ResponseBody String queryAllDepts(HttpServletRequest request){ List list = deptService.queryAllDepts(); return jsonToPage(list); } /** * 根据部门ID,查询当前部门下的角色信息列表 * @param request * @param deptid 部门ID * @return */ @RequestMapping(value = "/role/queryRoleByDeptid.do",method =RequestMethod.GET) public @ResponseBody String queryRolesByDeptId(HttpServletRequest request,String deptid){ List list = deptService.queryRolesByDeptId(deptid); return jsonToPage(list); } } IDeptService.java: /** * 部门信息接口 * @author likang * @date 2018-4-24 上午9:08:04 */ public interface IDeptService { /** * 查询所有的部门信息 * @return */ public List queryAllDepts(); /** * 根据部门ID,查询角色信息 * @param deptid 部门ID * @return */ public List queryRolesByDeptId(String deptid); } DeptServiceImpl.java: @Service @Transactional(rollbackFor = Exception.class) public class DeptServiceImpl implements IDeptService{ @Autowired IDataAccess deptDao; @Autowired IDataAccess roleDao; public List queryAllDepts() { List list = deptDao.queryByStatment("queryAllDepts", null, null); return list; } public List queryRolesByDeptId(String deptid) { Map param = new HashMap(); param.put("deptid", deptid); List list = roleDao.queryByStatment("queryRolesByDeptId", param, null); return list; } } DeptMapper.xml: mybatis-config.xml: UserController.java: /** * 增加\修改用户信息 * @param request * @param user * @return */ @RequestMapping(value = "/system/saveOrUpdate.do",method = RequestMethod.POST) public @ResponseBody String saveOrUpdateUser(HttpServletRequest request,User user){ if (user != null) { userService.saveOrUpdateUser(user); return ReturnConstants.SUCCESS; } return ReturnConstants.PARAM_NULL; } IUserService.java: /** * 增加、修改用户信息 * @param user */ public void saveOrUpdateUser(User user);

UserServiceImpl.java:

public void saveOrUpdateUser(User user) {      if (user != null) {          if (user.getUserid() != null) {//修改              user.setUpdate_id(UserContext.getLoginUser().getUserid());              user.setUpdate_time(new Timestamp(System.currentTimeMillis()));              userDao.update(user);          }else{//增加              user.setCreate_id(UserContext.getLoginUser().getUserid());              user.setCreate_time(new Timestamp(System.currentTimeMillis()));              userDao.insert(user);          }      }  }

删除

开发步骤:1:通过前端找到删除的接口地址(支持批量删除,真正企业做的时候,接口是后台来定义)2:增加删除的接口和方法 示例代码: UserController.java: /** * 删除用户信息,支持批量删除 * @param request * @param ids 用户主键ID,多个用逗号隔开 * @return */ @RequestMapping(value = "/system/deleteUser.do",method = RequestMethod.POST) public @ResponseBody String deleteUsers(HttpServletRequest request,String ids){ if (StringUtils.isNotBlank(ids)) { userService.deleteUserByIds(ids); return ReturnConstants.SUCCESS; } return ReturnConstants.PARAM_NULL; } IUserService.java: /** * 删除用户信息,批量删除 * @param ids 用户主键ID,多个用逗号隔开 */ public void deleteUserByIds(String ids); UserServiceImpl.java: public void deleteUserByIds(String ids) { if (StringUtils.isNotBlank(ids)) { userDao.deleteByIds(User.class, ids); } } 提示:1:回顾mysql的删除别名问题2:练习mybatis中的for标签

页面展示

测试环境项目部署过程

系统环境:linux-CentOS7 使用工具:CRT\SCP 部署步骤:1:首先确认本地访问运行没有任何问题2:导出本地的数据库脚本,将脚本文件在虚拟机服务器的数据库中执行3:使用scp工具连接服务器,将本地tomcat的webapps目录下的项目,拖到虚拟机服务器tomcat的webapps目录下(可选:修改项目访问名称,ROOT在访问时,不需要输入)4:修改虚拟机服务器中项目的jdbc配置文件,修改为虚拟机数据库的连接信息5:使用crt工具,启动tomcat6:本地访问服务器项目信息 注意事项: 1:本地连接服务器的数据库,需要开启3306端口号(防火墙允许3306端口允许) 命令:/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT 2:需要开启tomcat访问的端口号,命令如下: /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT 3:如果新增增量补丁,如下地方是需要重启tomcat服务的 - 接口代码 - 配置文件、属性文件 - xml对应的sql语句 4:查看服务器mysql是否开启的命令 ps -ef|grep mysql

菜单管理

跳转页面

略,参考工程文件

查询

略,参考工程文件

增加、修改

略,参考工程文件

删除

需求: 1:如果菜单存在下一级菜单,则不允许删除 2:如果菜单已经被分配,则不允许删除 开发步骤: 1://查询菜单ID,是否存在下一级菜单 2://查询菜单ID,是否存在权限分配 3://如果当前菜单ID,既不存在下一级菜单,又不存在权限分配,则可以直接删除成功 4://如果满足其中一条信息,则都不允许删除,返回错误信息 5://如果都不满足,删除成功 示例代码: MenuController.java: /** * 菜单删除功能 * * 1:如果菜单存在下一级菜单,则不允许删除 * 2:如果菜单已经被分配,则不允许删除 * * error1 = [菜单:用户管理,菜单管理] 存在下一级菜单信息,不允许删除 * error2 = [菜单:角色管理,部门管理] 存在权限分配,不允许删除 * * @param request * @param ids 菜单主键ID,多个用逗号隔开 * @return */ @RequestMapping(value = "/menu/delete.do",method = RequestMethod.POST) public @ResponseBody String deleteMenus(HttpServletRequest request,String ids){ if (StringUtils.isNotBlank(ids)) { StringBuffer error1 = new StringBuffer(); StringBuffer error2 = new StringBuffer(); boolean ishasCh = false; boolean ishasrm = false; for (String id : ids.split(",")) { //查询菜单ID,是否存在下一级菜单 if (menuService.isHasChiredMenu(id)) {//true:存在下一级菜单 if (!ishasCh) { ishasCh = true; } if (error1.length() == 0){ error1.append("[菜单:"); } error1.append(menuService.queryMenuById(id) != null ?menuService.queryMenuById(id).getMenuname() : "" ).append(","); continue; } //查询菜单ID,是否存在权限分配 if (menuService.isHasRoleMenu(id)) {//true:存在权限分配 if (!ishasrm) { ishasrm = true; } if (error2.length() == 0){ error2.append("[菜单:"); } error2.append(menuService.queryMenuById(id) != null ?menuService.queryMenuById(id).getMenuname() : "" ).append(","); continue; } menuService.deleleMenuById(id);//如果当前菜单ID,既不存在下一级菜单,又不存在权限分配,则可以直接删除成功 } //如果满足其中一条信息,则都不允许删除,返回错误信息 if (ishasCh){ error1.deleteCharAt(error1.length() - 1).append("] 存在下一级菜单信息,不允许删除"); } if (ishasrm){ error2.deleteCharAt(error2.length() - 1).append("] 存在权限分配,不允许删除"); } // String msgbegin = ishasCh ? error1.toString() : "" + ishasrm ? ishasCh?error1.toString() : "":""+error2.toString():""; String msg = error1.toString()+error2.toString(); if (StringUtils.isNotBlank(msg)) { return msg; } //如果都不满足,删除成功 return ReturnConstants.SUCCESS; } return ReturnConstants.PARAM_NULL; } IMenuService.java: /** * 根据菜单主键ID,判断当前菜单是否存在下一级菜单 * @param id 菜单主键ID * @return */ public boolean isHasChiredMenu(String id); /** * 根据菜单主键ID,判断当前菜单是否存在权限分配 * @param id 菜单主键ID * @return */ public boolean isHasRoleMenu(String id); /** * 根据菜单id,查询菜单信息 * @param id 主键ID * @return */ public Menu queryMenuById(String id); /** * 根据主键ID,删除菜单信息 * @param id */ public void deleleMenuById(String id); MenuServiceImpl.java: public boolean isHasChiredMenu(String id) { Map param = new HashMap(); param.put("mid", id); List

list = menuDao.queryByStatment("isHasChiredMenu", param, null); if (list != null && list.size() > 0) { return true; } return false; } public boolean isHasRoleMenu(String id) { Map param = new HashMap(); param.put("mid", id); List list = rmDao.queryByStatment("isHasRoleMenu", param, null); if (list != null && list.size() > 0) { return true; } return false; } public Menu queryMenuById(String id) { Map param = new HashMap(); param.put("mid", id); List list = menuDao.queryByStatment("queryMenuById", param, null); if (list != null && list.size() > 0) { return list.get(0); } return null; } public void deleleMenuById(String id) { if (StringUtils.isNotBlank(id)) { menuDao.deleteByIds(Menu.class, id); } } RoleMapper.xml:

角色管理

跳转页面

略,参考工程文件

查询

略,参考工程文件

增加、修改

略,参考工程文件

删除

略,参考工程文件

###权限分配

CRM第三方缓存技术

开发步骤: 1:在resource文件内,导入缓存的配置文件 2:在事务开启执行之前,使用注解,进行数据缓存 常用注解: //增加缓存 @Cacheable(value="baseCache",key="'queryAllDepts'") 其中value代表存放的缓存区域块名称 key:代表区域块中缓存的唯一标识,可有三种取值方式: 1:使用普通的字符串 2:使用方法参数中参数值 #参数名称 3:使用方法中实体对象的属性 //更新缓存---写操作 @CachePut(value = "",key = "") 不管缓存是否有数据,都会更新一遍 //更新缓存---根据条件更新 @CacheEvict(value ="",key="",allEntries=false,beforeInvocation = false) allEntries:true:更新所有的缓存区域块数据,false,则代表只会更新key值的数据 beforeInvocation:true,代表是在方法执行之前进行更新数据,执行之后,不太操作缓存数据 示例代码: 参考配置文件applicationContext-ehcache.xml和ecache.xml applicationcontext.xml: DeptServceImpl.java: @Cacheable(value="baseCache",key="'queryAllDepts'") public List queryAllDepts() { List list = deptDao.queryByStatment("queryAllDepts", null, null); return list; }

调度任务Quartz

开发步骤: 1:导入调度任务的配置模块文件 2:在spring的配置文件中,引入调度任务的配置信息 示例代码: applicationcontext.xml: applicationContext-quartz.xml: 参考文件 注意: cron表达式,可以百度,找一个在线生成器生成即可

百度编辑器(富文本编辑器)

后台字段设计为:text

自定义注解

excel导入、导出

解析:POI 本地---数据库 导入: 1:读取本地excel文件 2:将文件上传到应用服务器tomcat 3:读取服务器中的excel文件数据,并将数据存放到数据库 导出: 数据库---本地 1:获取要导出的数据 2:在应用服务器中创建一个空的excel文件,并将导出的数据写入 3:将应用服务器中excel文件,-本地

项目总结

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Linux系列】——虚拟机下配置网络环境NAT
下一篇:一个基于mobx、react-navigation、teaset的react-native框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~