一 模块需求细化

登录的用户,默认情况有三个不同角色,分别为:系统管理员,前台客服,信息管理员。

用户登录后能够根据其角色来进行相关工作,进行完工作需要能够注销。

细化需求如下:

  • 用户登录之后按角色分配权限信息。

  • 登录日志表自动保存登录信息。

  • 需要把权限信息保存在Session中。

  • 需要登录检测,Session中保存用户id和最后登录时间等。

  • 在member表中也需要更新最后一次登录的日期时间。

  • 用户登录后可进行密码修改。

  • 需要用户登录后能够注销。

二 模块相关数据库实现细节

1 输入数据表

用户表:member

角色:role

角色-权限关系表:role-groups

权限组-权限关系表:groups-action

权限组表:group

权限表:action

2 输出数据表

用户登录日志表:logs

用户:member

三 用户登录界面设计

1 登录页面代码login.jsp

<%@ page language="java" import="java.util.*"  pageEncoding="UTF-8"%>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" +  request.getServerPort()+ path + "/";String loginUrl = basePath + "LoginServletBack/login" ;System.out.println(loginUrl);
%>
<html>
<head>
<base href="<%=basePath%>">
<title>CRM管理系统</title>
<jsp:include page="/pages/plugins/import_file.jsp"/>
<script src="<%=basePath%>js/cloud.js"  type="text/javascript"></script>
<script src="<%=basePath%>js/login.js"  type="text/javascript"></script>
</head>
<body style="background-color:#df7611;  background-image:url(images/light.png);  background-repeat:no-repeat; background-position:center top;  overflow:hidden;"><div id="mainBody"><div id="cloud1" class="cloud"></div><div id="cloud2" class="cloud"></div></div><div class="logintop"><span>欢迎登录CRM管理界面平台</span><ul><li><a href="#">回首页</a></li><li><a href="#">帮助</a></li><li><a href="#">关于</a></li></ul></div><div class="loginbody"><span class="systemlogo"></span><div class="loginbox"><form action="<%=loginUrl%>" method="post"  id="loginForm"><ul><li><input name="member.mid"  id="member.mid" type="text" class="loginuser"placeholder="输入登录用户名"/></li><li><input name="member.password"  id="member.password" type="password" class="loginpwd"placeholder="请输入登录密码"/></li><li><input type="submit" class="loginbtn"  value="登录"/></li></ul></form></div></div><div class="loginbm"></div>
</body>
</html>

2 界面展示

3 输入用户名和密码,点击确认

会跳到loginUrl去处理,loginUrl的值为:http://localhost:8080/CRMProject/LoginServletBack/login

LoginServletBack/login的处理入口见控制层代码。

4 如果用户名和密码正确,控制层代码会将页面转向/pages/back/index.jsp

<%@ page language="java" import="java.util.*"  pageEncoding="UTF-8"%>
<%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" +  request.getServerPort()+ path + "/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>CRM管理系统</title>
<jsp:include page="/pages/plugins/import_file.jsp"/>
</head>
<frameset rows="88,*,31" cols="*" frameborder="no" border="0"framespacing="0"><frame src="<%=basePath%>pages/back/top.jsp"  name="topFrame" scrolling="No"noresize="noresize" id="topFrame" title="topFrame" /><frameset cols="187,*" frameborder="no" border="0"  framespacing="0"><frame src="<%=basePath%>pages/back/left.jsp"  name="leftFrame" scrolling="No"noresize="noresize" id="leftFrame"  title="leftFrame" /><frame  src="<%=basePath%>pages/back/DefaultServletBack/show"  name="rightFrame" id="rightFrame"title="rightFrame" /></frameset><frame src="<%=basePath%>pages/back/footer.jsp"  name="bottomFrame" scrolling="No"noresize="noresize" id="bottomFrame"  title="bottomFrame" />
</frameset>
<noframes>
</html>

5 该页面展示如下:

上面代码关键是<%=basePath%>pages/back/DefaultServletBack/show,它是控制层实现的。我们去控制层分析该代码。

四 控制层模块设计实现

1 登录控制层代码实现

package cn.mldn.crm.servlet.back;import java.util.Map;import javax.servlet.annotation.WebServlet;import cn.mldn.crm.factory.ServiceFactory;
import cn.mldn.crm.vo.Member;
import cn.mldn.util.MD5Code;
import cn.mldn.util.servlet.DispatcherServlet;@SuppressWarnings("serial")
@WebServlet(urlPatterns = "/LoginServletBack/*")                // 当点击登录代码,会走到这里
public class LoginServletBack extends DispatcherServlet {private Member member = new Member();public String login() {// 把输入的密码加密成功后设置给password属性this.member.setPassword(new MD5Code().getMD5ofStr(this.member.getPassword()));try {// 调用业务层获得用户相关信息Map<String,Object> map = ServiceFactory.getIMemberServiceBackInstance().login(this.member) ;boolean loginFlag = (Boolean) map.get("flag") ;if (loginFlag) {super.getSession().setAttribute("mid", this.member.getMid());super.getSession().setAttribute("flag", this.member.getFlag());super.getSession().setAttribute("groups", this.member.getRole().getGroups());super.getSession().setAttribute("allActions", map.get("allActions"));super.getSession().setAttribute("unread", map.get("unread"));// 处理权限问题;super.setMsgAndUrl("member.login.success", "index.page");} else {super.setMsgAndUrl("member.login.failure", "member.login.page");}} catch (Exception e) {e.printStackTrace();}return "forward.page" ;}......}

2 在上面这个函数中,如果密码输入正确,会跳到index.page去处理,并携带消息member.login.success

这里index.page为index.page=/pages/back/index.jsp

member.login.success为用户登录成功,欢迎光临!

3 相关属性文件定义

消息属性文件

vo.add.success={0}\u6570\u636E\u589E\u52A0\u6210\u529F\uFF01
vo.add.failure={0}\u6570\u636E\u589E\u52A0\u5931\u8D25\uFF01
vo.edit.success={0}\u6570\u636E\u4FEE\u6539\u6210\u529F\uFF01
vo.edit.failure={0}\u6570\u636E\u4FEE\u6539\u5931\u8D25\uFF01
vo.rm.success={0}\u6570\u636E\u5220\u9664\u6210\u529F\uFF01
vo.rm.failure={0}\u6570\u636E\u5220\u9664\u5931\u8D25\uFF01
member.login.success=\u7528\u6237\u767B\u5F55\u6210\u529F\uFF0C\u6B22\u8FCE\u5149\u4E34\uFF01
member.login.failure=\u767B\u5F55\u5931\u8D25\uFF0C\u9519\u8BEF\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801\uFF01
member.logout.success=\u7528\u6237\u6CE8\u9500\u6210\u529F\uFF0C\u518D\u89C1\uFF01
member.password.edit.success=\u7528\u6237\u5BC6\u7801\u4FEE\u6539\u6210\u529F\uFF0C\u4E3A\u4E86\u4FDD\u8BC1\u5B89\u5168\u8BF7\u91CD\u65B0\u767B\u5F55\uFF01
member.password.edit.failure=\u7528\u6237\u5BC6\u7801\u4FEE\u6539\u5931\u8D25\uFF0C\u4E3A\u4E86\u4FDD\u8BC1\u5B89\u5168\u8BF7\u91CD\u65B0\u767B\u5F55\uFF01
member.edit.password.admin.success=\u7528\u6237\u5BC6\u7801\u91CD\u7F6E\u6210\u529F\uFF01
member.edit.password.admin.failure=\u7528\u6237\u5BC6\u7801\u91CD\u7F6E\u5931\u8D25\uFF01
task.over.success=\u4EFB\u52A1\u5173\u95ED\u6210\u529F\uFF01
task.over.failure=\u4EFB\u52A1\u5173\u95ED\u6210\u529F\uFF01
task.finish.success=\u4EFB\u52A1\u6210\u529F\u5B8C\u6210\uFF01
task.finish.failure=\u4EFB\u52A1\u66F4\u65B0\u51FA\u9519\uFF0C\u672A\u5B8C\u6210\uFF01

页面属性文件

error.page=/pages/errors.jsp
forward.page=/pages/forward.jsp
#back.emp.add.jsp=/pages/emp/emp_add.jsp
#back.emp.list.jsp=/pages/emp/emp_list.jsp
member.login.page=/login.jsp
member.logout.servlet=/LoginServletBack/logout
index.page=/pages/back/index.jsp
default.page=/pages/back/default.jsp
member.password.edit.page=/pages/back/member/member_edit_password.jsp
client.add.page=/pages/back/client/client_add.jsp
client.add.servlet=/pages/back/client/ClientServletBack/addPre
client.list.page=/pages/back/client/client_list.jsp
client.list.servlet=/pages/back/client/ClientServletBack/listSplit
client.edit.page=/pages/back/client/client_edit.jsp
mclient.list.page=/pages/back/mclient/client_list.jsp
mclient.show.page=/pages/back/mclient/client_show.jsp
mclient.list.servlet=/pages/back/mclient/ManagerClientServletBack/listSplit
mtask.list.page=/pages/back/mtask/task_list.jsp
mtask.list.servlet=/pages/back/mtask/ManagerTaskServletBack/listSplit
mtask.show.page=/pages/back/mtask/task_show.jsp
mtask.client.list.page=/pages/back/mtask/task_client_list.jsp
task.add.page=/pages/back/task/task_add.jsp
task.add.servlet=/pages/back/task/TaskServletBack/addPre
task.client.list.page=/pages/back/task/task_client_list.jsp
task.show.page=/pages/back/task/task_show.jsp
task.list.page=/pages/back/task/task_list.jsp
task.list.servlet=/pages/back/task/TaskServletBack/listSplit
task.edit.page=/pages/back/task/task_edit.jsp
news.add.page=/pages/back/news/news_add.jsp
news.add.servlet=/pages/back/news/NewsServletBack/addPre
news.list.page=/pages/back/news/news_list.jsp
news.list.servlet=/pages/back/news/NewsServletBack/list
news.show.page=/pages/back/news/news_show.jsp
news.edit.page=/pages/back/news/news_edit.jsp
action.list.page=/pages/back/action/action_list.jsp
groups.list.page=/pages/back/groups/groups_list.jsp
groups.show.page=/pages/back/groups/groups_show.jsp
role.add.page=/pages/back/role/role_add.jsp
role.add.servlet=/pages/back/role/RoleServletBack/addPre
role.list.page=/pages/back/role/role_list.jsp
role.list.servlet=/pages/back/role/RoleServletBack/list
role.show.page=/pages/back/role/role_show.jsp
role.edit.page=/pages/back/role/role_edit.jsp
member.add.page=/pages/back/member/member_add.jsp
member.add.servlet=/pages/back/member/MemberServletBack/addPre
member.list.page=/pages/back/member/member_list.jsp
member.list.servlet=/pages/back/member/MemberServletBack/listSplit
member.edit.page=/pages/back/member/member_edit.jsp
member.edit.password.admin.servlet=/pages/back/member/MemberServletBack/editPassPre
member.edit.password.admin.page=/pages/back/member/member_edit_password_admin.jsp

4 登录后内容区显示内容,通过DefaultServletBack的show函数实现。

@SuppressWarnings("serial")
@WebServlet("/pages/back/DefaultServletBack/*")
public class DefaultServletBack extends AbstractCRMServlet {public String show() {try {Map<String, Object> map = ServiceFactory.getIDefaultServiceBackInstance().stat(super.getMid());super.request.setAttribute("allNewses",  map.get("allNewses"));super.request.setAttribute("allClients",  map.get("allClients"));super.request.setAttribute("allTasks",  map.get("allTasks"));super.request.setAttribute("clientCount",  map.get("clientCount"));super.request.setAttribute("unfinishCount",map.get("unfinishCount"));super.request.setAttribute("wfinishCount",  map.get("wfinishCount"));} catch (Exception e) {e.printStackTrace();}return "default.page";}......
}

五 业务层模块设计实现

1 业务层登录代码实现

public class MemberServiceBackImpl extends  AbstractCRMServiceBack implementsIMemberServiceBack {@Overridepublic Map<String, Object> login(Member vo) throws  Exception {Map<String, Object> result = new HashMap<String,  Object>();boolean flag = false;try {// 1、进行用户名和密码的验证,如果登录成功将返回flag、rid两个字段的数据if  (DAOFactory.getIMemberDAOInstance(this.dbc.getConnection()).findLogin(vo)) {// 2、更新member表中的最后一次登录日期时间if  (DAOFactory.getIMemberDAOInstance(this.dbc.getConnection()).doUpdateLastdate(vo.getMid()))  {result.put("unread",DAOFactory.getIMemberNewsDAOInstance(this.dbc.getConnection()).getAllCountUnread(vo.getMid()));// 3、在登录日志表中进行一条数据的保存Logs logs = new Logs();logs.getMember().setMid(vo.getMid());if (DAOFactory.getILogsDAOInstance(this.dbc.getConnection()).doCreate(logs)) {// 4、根据用户的角色编号,查询出用户对应的权限组信息List<Groups> allGroups =  DAOFactory.getIGroupsDAOInstance(this.dbc.getConnection()).findAllByRole(vo.getRole().getRid());Set<Integer> gids = new  HashSet<Integer>();// 5、根据每一个权限组的编号,查询出对应的所有权限信息Iterator<Groups> iter =  allGroups.iterator();// 6、根据每一个权限组的编号查询出所有的权限信息while (iter.hasNext()) {Groups gup = iter.next();gids.add(gup.getGid());gup.setAction(DAOFactory.getIActionDAOInstance(this.dbc.getConnection()).findAllByGroups(gup.getGid()));}// 7、将权限组的信息保存在角色里面vo.getRole().setGroups(allGroups);flag = true;result.put("allActions",DAOFactory.getIActionDAOInstance(this.dbc.getConnection()).findAllByGroups(gids));}}}} catch (Exception e) {throw e;} finally {this.dbc.close();}result.put("flag", flag);return result;}......
}

六 数据层模块设计实现

1 登录逻辑数据层实现在MemberDAOImpl寻找,还有一些实现需要在其他地方寻找。

package cn.mldn.crm.dao.impl;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;import cn.mldn.crm.dao.IMemberDAO;
import cn.mldn.crm.dao.abs.AbstractDAOImpl;
import cn.mldn.crm.vo.Member;public class MemberDAOImpl extends AbstractDAOImpl implements IMemberDAO {public MemberDAOImpl(Connection conn) {super(conn);}@Overridepublic boolean doCreate(Member vo) throws Exception {String sql = "INSERT INTO member(mid,rid,password,tel,photo,locked,flag) VALUES (?,?,?,?,?,?,?)" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setString(1, vo.getMid());super.pstmt.setInt(2, vo.getRole().getRid());super.pstmt.setString(3, vo.getPassword());super.pstmt.setString(4,vo.getTel());super.pstmt.setString(5, vo.getPhoto());super.pstmt.setInt(6, vo.getLocked());super.pstmt.setInt(7, vo.getFlag());return super.pstmt.executeUpdate() > 0 ;}@Overridepublic boolean doUpdate(Member vo) throws Exception {String sql = "UPDATE member SET rid=?,tel=?,locked=?,photo=? WHERE mid=?" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setInt(1, vo.getRole().getRid());super.pstmt.setString(2, vo.getTel());super.pstmt.setInt(3, vo.getLocked());super.pstmt.setString(4, vo.getPhoto());super.pstmt.setString(5, vo.getMid());return super.pstmt.executeUpdate() > 0 ;}@Overridepublic boolean doRemove(Set<String> ids) throws Exception {StringBuffer buf = new StringBuffer();buf.append("DELETE FROM ").append("member").append(" WHERE ").append("mid").append(" IN ( ");Iterator<String> iter = ids.iterator();while (iter.hasNext()) {buf.append("'").append(iter.next()).append("'").append(",");}buf.delete(buf.length() - 1, buf.length()).append(")");buf.append(" AND flag=0") ;    // 只能够删除普通用户this.pstmt = this.conn.prepareStatement(buf.toString());return this.pstmt.executeUpdate() == ids.size();}@Overridepublic List<Member> findAll() throws Exception {// TODO Auto-generated method stubreturn null;}@Overridepublic Member findById(String id) throws Exception {Member vo = null ;String sql = "SELECT mid,rid,tel,lastdate,photo,flag,locked FROM member WHERE mid=?" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setString(1, id);ResultSet rs = super.pstmt.executeQuery() ;if (rs.next()) {vo = new Member() ;vo.setMid(rs.getString(1));vo.getRole().setRid(rs.getInt(2));vo.setTel(rs.getString(3));vo.setLastdate(rs.getDate(4));vo.setPhoto(rs.getString(5));vo.setFlag(rs.getInt(6));vo.setLocked(rs.getInt(7));}return vo;}@Overridepublic List<Member> findAllSplit(String column, String keyWord,Integer currentPage, Integer lineSize) throws Exception {List<Member> all = new ArrayList<Member>() ;String sql = "SELECT mid,rid,tel,lastdate,photo,flag,locked FROM member WHERE " + column + " LIKE ? LIMIT ?,?" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setString(1, "%" + keyWord + "%");super.pstmt.setInt(2, (currentPage - 1) * lineSize);super.pstmt.setInt(3, lineSize);ResultSet rs = super.pstmt.executeQuery() ;while (rs.next()) {Member vo = new Member() ;vo.setMid(rs.getString(1));vo.getRole().setRid(rs.getInt(2));vo.setTel(rs.getString(3));vo.setLastdate(rs.getDate(4));vo.setPhoto(rs.getString(5));vo.setFlag(rs.getInt(6));vo.setLocked(rs.getInt(7));all.add(vo) ;}return all;}@Overridepublic Integer getAllCount(String column, String keyWord) throws Exception {return super.handleCount("member", column, keyWord);}// 查表获得用户的flag和rid,并写入到vo返回,供业务层使用@Overridepublic boolean findLogin(Member vo) throws Exception {String sql = "SELECT flag,rid FROM member WHERE mid=? AND password=? AND locked=0" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setString(1, vo.getMid());super.pstmt.setString(2, vo.getPassword());ResultSet rs = super.pstmt.executeQuery() ;if (rs.next()) {vo.setFlag(rs.getInt(1));vo.getRole().setRid(rs.getInt(2));return true ;}return false;}@Overridepublic boolean doUpdateLastdate(String id) throws Exception {String sql = "UPDATE member SET lastdate=? WHERE mid=?" ;super.pstmt = super.conn.prepareStatement(sql) ;System.out.println(new Date().getTime());super.pstmt.setTimestamp(1, new Timestamp(new Date().getTime()));super.pstmt.setString(2, id);return super.pstmt.executeUpdate() > 0;}@Overridepublic boolean doUpdatePassword(String mid, String password)throws Exception {String sql = "UPDATE member SET password=? WHERE mid=?" ;super.pstmt = super.conn.prepareStatement(sql) ;super.pstmt.setString(1, password);super.pstmt.setString(2, mid);return super.pstmt.executeUpdate() > 0 ;}}

七 参考

https://www.cnblogs.com/ylliap/p/6381478.html

客户关系管理项目——用户登录模块设计相关推荐

  1. 客户关系管理项目——客户管理模块设计

    一 模块需求细化 1 实现客户信息录入 "添加"只有具有添加客户权限的用户才可以填写,只有具备3号角色的用户才能负责客户的添加,即超链接上会出现"添加客户"超链 ...

  2. 图解客户关系管理项目权限表

    一 数据库E-R图 跟权限相关表的E-R如下: 涉及6张表:用户表,角色表,角色-群组关系表,群组表,群组权限关系表,权限表. 二 member表数据 三 role表数据 四 role_group表数 ...

  3. 客户关系管理CRM系统源码PHP开源软件源码

    客户关系管理(CRM)软件是一类软件,涵盖广泛的应用程序,旨在帮助企业管理许多关键业务流程,包括客户数据.客户交互.对业务信息的访问,销售自动化, 线索跟踪,合同,营销自动化,客户支持,客户和联系人, ...

  4. 烟草企业客户关系管理现状及解决途径

    一.烟草企业客户关系管理的科学内涵 在辞典上"关系"是指人和人之间或人和事物之间的某种联系.关系,从这个词语本身的含义上讲,具备一个 时间跨度--在一段时间里,它包含一个始发点,一 ...

  5. 【转载】Kano模型在用户调研中的应用:客户关系管理工具调研实例

    原文链接:http://www.alibuybuy.com/posts/77204.html 1.Kano模型简介 1.1 Kano模型起源:满意度的二维模式 著名市场营销学大师.美国西北大学教授菲利 ...

  6. 【微服务】矩阵式客户关系管理设计、实现方案

    这学期开始,正式开始了复旦MSE工程硕士的在读生涯,其教学计划中有一门选修课程为<客户关系管理>,一向习惯了理工科的我想换换口味,也希望从另一个角度开阔一下视野,所以毫不犹豫的选择了它,乍 ...

  7. 联系人管理-客户拜访记录| CRM客户关系管理系统项目 实战七(Struts2+Spring+Hibernate)解析+源代码

    联系人管理-客户拜访记录| CRM客户关系管理系统项目 实战七(Struts2+Spring+Hibernate)解析+源代码 客户拜访记录的列表的显示, 客户拜访记录的保存, 客户拜访记录查询(条件 ...

  8. java 用户登录模块_Java SSH框架系列:用户登录模块的设计与实现思路

    1.简介 用户登录模块,指的是根据用户输入的用户名和密码,对用户的身份进行验证等.如果用户没有登录,用户就无法访问其他的一些jsp页面,甚至是action都不能访问. 二.简单设计及实现 本程序是基于 ...

  9. C#毕业设计——基于C#+asp.net+sqlserver的客户关系管理系统设计与实现(毕业论文+程序源码)——客户关系管理系统

    基于C#+asp.net+sqlserver的客户关系管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的客户关系管理系统设计与实现,文章末尾 ...

最新文章

  1. hdu 4311 Meeting point-1
  2. 菜鸟,大牛,教主的区别
  3. lnmp、lamp、lnmpa一键安装包
  4. 第二阶段团队项目冲刺第七天
  5. git tag 功能笔记
  6. imp导入前对当前用户清库脚本
  7. LeetCode 15. 三数之和 思考分析(双指针解)
  8. SQL2005转2000
  9. 西瓜书+实战+吴恩达机器学习(十六)半监督学习(半监督SVM、半监督k-means、协同训练算法)
  10. python2和python3(导包)自定义包并导入之
  11. 深度学习-LeCun、Bengio和Hinton的联合综述
  12. 手电筒app制作实录
  13. 技术岗网上测评-智力题
  14. 统信操作系统 摄像头驱动程序
  15. angelhack_我的团队如何撼动AngelHack Seattle Hackathon
  16. Mysql 生成随机数字
  17. 计算机制图员主要学什么,制图员
  18. Excel学习笔记4||数据处理函数ROUND、INT、TRUNC、MAX、MIN、ROW、COLUMN
  19. FlinkX数据同步
  20. java -1%3_Java_SE 流程控制

热门文章

  1. 快速让网站内容可以复制
  2. 单片机与ARM嵌入式区别
  3. 万字长文:盘点2022全球10大数据泄漏事件(红蓝攻防角度)
  4. Python中常见字符串去除字符串空格的方法
  5. Xftp传输文件发生错误
  6. P1460 [USACO2.1]健康的荷斯坦奶牛 Healthy Holsteins
  7. 计算机操作实训总结,计算机操作系统安全实训心得总结.doc
  8. 计算机操作系统实训心得总结,计算机操作系统安全实训心得总结
  9. python的numpy教程_ROS与Python入门教程-使用numpy
  10. 年仅21岁,干掉6位诺贝尔奖得主,被誉为科学界最强杀手,却惨被人骂成一个笑话...