CRM第六天:客户拜访管理,权限配置,验证码实现

目录

1.CRM客户关系管理系统:客户拜访记录

1.1需求概述

1.2准备工作

1.2.1创建表

1.2.2创建实体和映射

1.2.3创建相关类,并交给Spring管理

1.3客户拜访记录列表显示

1.3.1修改left.jsp的提交路径

1.3.2编写action

1.3.3编写service

1.3.4编写显示页面

1.4客户拜访记录列表显示

1.4.1编写action

1.4.2编写service

1.4.3编写保存页面

2.权限管理

2.1编写一个类继承拦截器类

2.2配置拦截器

3验证码

3.1编写工具类

3.2编写action

3.3编写页面


 

1.CRM客户关系管理系统:客户拜访记录

1.1需求概述

一个系统的用户(公司业务员),业务员需要对客户进行拜访,对拜访的过程进行记录。业务员(用户)和客户(客户)之间关系(需要具体业务具体分析:一对多公司产品比较单一,只允许一个业务员对应多个客户。多对多大公司有不同的产品,不同产品下有不同业务员都可以接触到同一个客户,一个客户可以对应多个业务员)。大部分情况创建成多对多。

  1. 多对多建表原则:
    1. 创建中间表,中间表中至少两个字段分别作为外键指向多对多双方的主键。

1.2准备工作

1.2.1创建表


  
  1. CREATE TABLE `sale_visit` (
  2.   `visit_id` varchar(32) NOT NULL,
  3.   `visit_cust_id` bigint(32) DEFAULT NULL COMMENT '客户id',
  4.   `visit_user_id` bigint(32) DEFAULT NULL COMMENT '负责人id',
  5.   `visit_time` datetime DEFAULT NULL COMMENT '拜访时间',
  6.   `visit_addr` varchar(128) DEFAULT NULL COMMENT '拜访地点',
  7.   `visit_detail` varchar(256) DEFAULT NULL COMMENT '拜访详情',
  8.   `visit_nexttime` date DEFAULT NULL COMMENT '下次拜访时间',
  9.   PRIMARY KEY (`visit_id`),
  10.   KEY `FK_sale_visit_cust_id` (`visit_cust_id`),
  11.   KEY `FK_sale_visit_user_id` (`visit_user_id`),
  12.   CONSTRAINT `FK_sale_visit_cust_id` FOREIGN KEY (`visit_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  13.   CONSTRAINT `FK_sale_visit_user_id` FOREIGN KEY (`visit_user_id`) REFERENCES `sys_user` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  14. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.2.2创建实体和映射

实体:


  
  1. package com.albertyy.crm.entity;
  2. import java.sql.Date;
  3. import java.sql.Timestamp;
  4. /**
  5.  *        项目名称:CRM   类名称:SaleVisit   类描述: 客户拜访实体类  创建人:yangyangyang  
  6.  * 创建时间:2019年1月1日 下午4:32:53   修改人:yangyangyang   修改时间:2019年1月1日 下午4:32:53  
  7.  * 修改备注:   @version       
  8.  */
  9. public class SaleVisit {
  10.      private String visit_id;
  11.      private Timestamp visit_time;
  12.      private String visit_addr;
  13.      private String visit_detail;
  14.      private Date visit_nexttime;
  15.      // 拜访记录关联的客户对象
  16.      private Customer customer;
  17.      // 拜访记录关联的用户对象
  18.      private User user;
  19.      public String getVisit_id() {
  20.          return visit_id;
  21.      }
  22.      public void setVisit_id(String visit_id) {
  23.          this.visit_id = visit_id;
  24.      }
  25.      public Timestamp getVisit_time() {
  26.          return visit_time;
  27.      }
  28.      public void setVisit_time(Timestamp visit_time) {
  29.          this.visit_time = visit_time;
  30.      }
  31.      public String getVisit_addr() {
  32.          return visit_addr;
  33.      }
  34.      public void setVisit_addr(String visit_addr) {
  35.          this.visit_addr = visit_addr;
  36.      }
  37.      public String getVisit_detail() {
  38.          return visit_detail;
  39.      }
  40.      public void setVisit_detail(String visit_detail) {
  41.          this.visit_detail = visit_detail;
  42.      }
  43.      public Date getVisit_nexttime() {
  44.          return visit_nexttime;
  45.      }
  46.      public void setVisit_nexttime(Date visit_nexttime) {
  47.          this.visit_nexttime = visit_nexttime;
  48.      }
  49.      public Customer getCustomer() {
  50.          return customer;
  51.      }
  52.      public void setCustomer(Customer customer) {
  53.          this.customer = customer;
  54.      }
  55.      public User getUser() {
  56.          return user;
  57.      }
  58.      public void setUser(User user) {
  59.          this.user = user;
  60.      }
  61. }

映射:


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3.     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4.     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6.      <class name="com.albertyy.crm.entity.SaleVisit" table="sale_visit">
  7.          <id name="visit_id" column="visit_id">
  8.               <generator class="uuid"/>
  9.          </id>
  10.         
  11.          <property name="visit_time" column="visit_time"/>
  12.          <property name="visit_addr" column="visit_addr"/>
  13.          <property name="visit_detail" column="visit_detail"/>
  14.          <property name="visit_nexttime" column="visit_nexttime"/>
  15.     
  16.      <!-- 配置与客户的关联关系 -->
  17.      <many-to-one name="customer" class="com.albertyy.crm.entity.Customer" column="visit_cust_id" />
  18.      <!-- 配置与用户的关联关系 -->
  19.      <many-to-one name="user" class="com.albertyy.crm.entity.User" column="visit_user_id" />
  20.     
  21.      </class>
  22. </hibernate-mapping>

1.2.3创建相关类,并交给Spring管理

 


  
  1. <!-- ======配置客户拜访的相关类======= -->
  2.      <!-- 配置Action -->
  3.      <bean id="saleVisitAction" class="com.albertyy.crm.web.action.SaleVisitAction" scope="prototype">
  4.          <property name="saleVisitService" ref="saleVisitService"/>
  5.          <property name="customerService" ref="customerService"/>
  6.          <property name="userService" ref="userService"/>
  7.      </bean>
  8.      <!-- 配置Service -->
  9.      <bean id="saleVisitService" class="com.albertyy.crm.serviceImpl.SaleVisitServiceImpl">
  10.          <property name="saleVisitDao" ref="saleVisitDao"/>
  11.      </bean>
  12.      <!-- 配置DAO -->
  13.      <bean id="saleVisitDao" class="com.albertyy.crm.daoImpl.SaleVisitDaoImpl">
  14.          <property name="sessionFactory" ref="sessionFactory"/>
  15.      </bean>

1.3客户拜访记录列表显示

1.3.1修改left.jsp的提交路径


  
  1. <h3>客户拜访管理</h3>
  2.          <ul>
  3.               <li><a
  4.                    href="${pageContext.request.contextPath }/saleVisit_saveUI.action">新增客户拜访</a></li>
  5.               <li><a
  6.                    href="${pageContext.request.contextPath }/saleVisit_findAll.action">客户拜访列表</a></li>
  7.          </ul>

1.3.2编写action


  
  1. // 分页查询客户拜访记录的方法
  2.      public String findAll() {
  3.          // 创建离线条件查询对象
  4.          DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SaleVisit.class);
  5.          // 设置条件
  6.         
  7.          PageBean<SaleVisit> pageBean = saleVisitService.findByPage(detachedCriteria, page, pageSize);
  8.          ActionContext.getContext().getValueStack().push(pageBean);
  9.          return "findAll";
  10.      }

1.3.3编写service


  
  1. //客户拜访分页查询业务层方法
  2.      @Override
  3.      public PageBean<SaleVisit> findByPage(DetachedCriteria detachedCriteria, Integer page, Integer pageSize) {
  4.          PageBean<SaleVisit> pageBean=new PageBean<SaleVisit>();
  5.          pageBean.setPage(page);
  6.          pageBean.setPageSize(pageSize);
  7.          int totalCount=saleVisitDao.findCount(detachedCriteria);
  8.          pageBean.setTotalCount(totalCount);
  9.          double tc=totalCount;
  10.          Double num=Math.ceil(tc/pageSize);
  11.          pageBean.setTotalPage(num.intValue());
  12.          Integer begin=(page-1)*pageSize;
  13.          List<SaleVisit> list=saleVisitDao.findByPage(detachedCriteria, begin, pageSize);
  14.          pageBean.setList(list);
  15.          return pageBean;
  16.      }

 

1.3.4编写显示页面


  
  1. <div class="main" style="overflow-y: auto">
  2.          <div class="container">
  3.               <form name="customerForm"
  4.                    action="${pageContext.request.contextPath }/saleVisit_findAll.action"
  5.                    method="post">
  6.                    <div id="search_bar" class="mt10">
  7.                        <div class="box">
  8.                             <div class="box_border">
  9.                                  <div class="box_top">
  10.                                      <b class="pl15">搜索</b>
  11.                                  </div>
  12.                                  <div class="box_center pt10 pb10">
  13.                                      <table class="form_table" cellspacing="0" cellpadding="0"
  14.                                           border="0">
  15.                                           <tbody>
  16.                                                <tr>
  17.                                                    <td>拜访时间从:</td>
  18.                                                    <td><input type="date" name="visit_time"
  19.                                                         value="<s:date name="visit_time" format="yyyy-MM-dd"/>"
  20.                                                         class="input-text lh25" size="10"></td>
  21.                                                    <td>到:</td>
  22.                                                    <td><input type="date" name="visit_endtime"
  23.                                                         value="<s:date name="visit_endtime" format="yyyy-MM-dd"/>"
  24.                                                         class="input-text lh25" size="10"></td>
  25.                                                    <td><input type="submit" name="button"
  26.                                                         class="btn btn82 btn_search" value="查询"></td>
  27.                                                </tr>
  28.                                           </tbody>
  29.                                      </table>
  30.                                  </div>
  31.                             </div>
  32.                        </div>
  33.                    </div>
  34.                    <div id="table" class="mt10">
  35.                        <div class="box span10 oh">
  36.                             <table width="100%" border="0" cellpadding="0" cellspacing="0"
  37.                                  class="list_table">
  38.                                  <tr>
  39.                                      <th width="100">客户名称</th>
  40.                                      <th width="100">负责人名称</th>
  41.                                      <th width="100">拜访时间</th>
  42.                                      <th width="100">拜访地点</th>
  43.                                      <th width="100">拜访详情</th>
  44.                                      <th width="100">下次拜访时间</th>
  45.                                      <th width="150">操作</th>
  46.                                  </tr>
  47.                                  <s:iterator value="list">
  48.                                      <tr class="tr">
  49.                                           <td><s:property value="customer.cust_name" /></td>
  50.                                           <td><s:property value="user.user_name" /></td>
  51.                                           <td><s:date name="visit_time" format="yyyy-MM-dd"/></td>
  52.                                           <td><s:property value="visit_addr" /></td>
  53.                                           <td><div style="height: 30px; overflow-y: auto;">
  54.                                                    <s:property value="visit_detail" />
  55.                                                </div></td>
  56.                                           <td><s:date name="visit_nexttime" format="yyyy-MM-dd"/></td>
  57.                                           <td><input type="button" name="button"
  58.                                                class="btn btn82 btn_add" id="modifyBtn"
  59.                                                onclick="toUpdate('<s:property value="lkm_id"/>')" value="修改">
  60.                                                <input type="button" name="button" class="btn btn82 btn_del"
  61.                                                onclick="toDelete('<s:property value="lkm_id"/>')" value="删除"></td>
  62.                                      </tr>
  63.                                  </s:iterator>
  64.                             </table>
  65.                             <div class="page mt10">
  66.                                  <div class="pagination">
  67.                                      <ul>
  68.                                           <li class="disabled"><span><s:property
  69.                                                         value="totalCount" />条记录, 共 <s:property value="totalPage" />
  70.                                           </span></li>
  71.                                           <li><span> 每页显示记录数: <select name="pageSize"
  72.                                                    onchange="to_page()">
  73.                                                         <option value="5" <s:if test="pageSize==5">selected</s:if>>5条</option>
  74.                                                         <option value="10" <s:if test="pageSize==10">selected</s:if>>10条</option>
  75.                                                         <option value="20" <s:if test="pageSize==20">selected</s:if>>20条</option>
  76.                                                </select>
  77.                                           </span></li>
  78.                                           <s:if test="page!=1">
  79.                                                <li><a href="javascript:to_page(1)">首页</a></li>
  80.                                                <li><a
  81.                                                    href="javascript:to_page(<s:property value="page-1" />)">上一页</a></li>
  82.                                           </s:if>
  83.                                           <s:iterator var="i" begin="1" end="totalPage">
  84.                                                <s:if test="#i==page">
  85.                                                    <li class="active"><span><s:property value="#i" />
  86.                                                    </span></li>
  87.                                                </s:if>
  88.                                                <s:else>
  89.                                                    <li><a
  90.                                                         href="javascript:to_page(<s:property value="#i" />)"><s:property
  91.                                                                  value="#i" /></a></li>
  92.                                                </s:else>
  93.                                           </s:iterator>
  94.                                           <s:if test="page!=totalPage">
  95.                                                <li><a
  96.                                                    href="javascript:to_page(<s:property value="page+1" />)">下一页</a></li>
  97.                                                <li><a
  98.                                                    href="javascript:to_page(<s:property value="totalPage" />)">末页</a></li>
  99.                                           </s:if>
  100.                                           <li>到第 <input class="input-text lh25" type="text"
  101.                                                id="page" name="page" size="2" height="10px" />页 <input
  102.                                                class="ext_btn" type="button" value="GO" onclick="to_page()" />
  103.                                           </li>
  104.                                      </ul>
  105.                                  </div>
  106.                             </div>
  107.               </form>
  108.          </div>
  109.      </div>

1.4客户拜访记录列表显示

1.4.1编写action

 


  
  1. // 跳转到添加页面的方法
  2.      public String saveUI() {
  3.          // 查询客户和负责人
  4.          List<Customer> customerlist = customerService.findAll();
  5.          List<User> userlist = userService.findAll();
  6.          ActionContext.getContext().getValueStack().set("customerlist", customerlist);
  7.          ActionContext.getContext().getValueStack().set("userlist", userlist);
  8.          return "saveUI";
  9.      }
  10.      // 保存拜访记录
  11.      public String save() {
  12.          saleVisitService.save(saleVisit);
  13.          // 跳转到列表页面
  14.          findAll();
  15.          return "saveSuccess";
  16.      }
  17. 配置action:
  18. <!-- 客户拜访Action -->
  19.          <action name="saleVisit_*" class="saleVisitAction" method="{1}">
  20.               <result name="findAll">/salevisit/list.jsp</result>
  21.               <result name="saveUI">/salevisit/add.jsp</result>
  22.               <result name="saveSuccess">/salevisit/list.jsp</result>
  23.              
  24.          </action>

1.4.2编写service


  
  1. //保存客户拜访记录
  2.      @Override
  3.      public void save(SaleVisit saleVisit) {
  4.          saleVisitDao.save(saleVisit);
  5.      }

1.4.3编写保存页面

 


  
  1. <div class="main" style="overflow-y: auto">
  2.          <div class="container">
  3.               <div class="main_top">
  4.                    <div id="forms" class="mt10">
  5.                        <div class="box">
  6.                             <div class="box_border">
  7.                                  <div class="box_top">
  8.                                      <b class="pl15">新增客户拜访</b>
  9.                                  </div>
  10.                                  <div class="box_center">
  11.                                      <form
  12.                                           action="${pageContext.request.contextPath }/saleVisit_save.action"
  13.                                           method="post" class="jqtransform">
  14.                                           <table class="form_table pt15 pb15" width="100%" border="0"
  15.                                                cellpadding="0" cellspacing="0">
  16.                                                <tr>
  17.                                                    <td class="td_right">客户名称:</td>
  18.                                                    <td class=""><span class="fl">
  19.                                                              <div class="select_border">
  20.                                                                  <div class="select_containers ">
  21.                                                                       <select name="customer.cust_id" id="cust_source"
  22.                                                                            class="select">
  23.                                                                            <option value="">-请选择-</option>
  24.                                                                            <s:iterator value="customerlist">
  25.                                                                                <option value='<s:property value="cust_id"/>'><s:property
  26.                                                                                          value="cust_name" /></option>
  27.                                                                            </s:iterator>
  28.                                                                       </select>
  29.                                                                  </div>
  30.                                                              </div>
  31.                                                    </span></td>
  32.                                                </tr>
  33.                                               
  34.                                                <tr>
  35.                                                    <td class="td_right">负责人名称:</td>
  36.                                                    <td class=""><span class="fl">
  37.                                                              <div class="select_border">
  38.                                                                  <div class="select_containers ">
  39.                                                                       <select name="user.user_id" id="cust_source"
  40.                                                                            class="select">
  41.                                                                            <option value="">-请选择-</option>
  42.                                                                            <s:iterator value="userlist">
  43.                                                                                <option value='<s:property value="user_id"/>'><s:property
  44.                                                                                          value="user_name" /></option>
  45.                                                                            </s:iterator>
  46.                                                                       </select>
  47.                                                                  </div>
  48.                                                              </div>
  49.                                                    </span></td>
  50.                                                </tr>
  51.                                               
  52.                                                <tr>
  53.                                                    <td class="td_right">拜访时间:</td>
  54.                                                    <td class=""><input type="date" name="visit_time"
  55.                                                         class="input-text lh30" ></td>
  56.                                                </tr>
  57.                                                <tr>
  58.                                                    <td class="td_right">拜访地点:</td>
  59.                                                    <td class=""><input type="text" name="visit_addr"
  60.                                                         class="input-text lh30" ></td>
  61.                                                </tr>
  62.                                                <tr>
  63.                                                    <td class="td_right">拜访详情:</td>
  64.                                                    <td class=""><textarea name="visit_detail" id="" cols="30" rows="10"
  65.                                                              class="textarea" style="width: 362px; height: 93px;"></textarea>
  66.                                                    </td>
  67.                                                </tr>
  68. <tr>
  69.                                                    <td class="td_right">下次拜访时间:</td>
  70.                                                    <td class=""><input type="date" name="visit_nexttime"
  71.                                                         class="input-text lh30" ></td>
  72.                                                </tr>
  73.                                                <tr>
  74.                                                    <td class="td_right">&nbsp;</td>
  75.                                                    <td class=""><input type="submit" name="button"
  76.                                                         class="btn btn82 btn_save2" value="保存"> <input
  77.                                                         type="reset" name="button" class="btn btn82 btn_res"
  78.                                                         value="重置"></td>
  79.                                                </tr>
  80.                                           </table>
  81.                                      </form>
  82.                                  </div>
  83.                             </div>
  84.                        </div>
  85.                    </div>
  86.               </div>
  87.          </div>
  88.      </div>

 

2.权限管理

2.1编写一个类继承拦截器类

 


  
  1. package com.albertyy.crm.web.intercept;
  2. import org.apache.struts2.ServletActionContext;
  3. import com.albertyy.crm.entity.User;
  4. import com.opensymphony.xwork2.ActionInvocation;
  5. import com.opensymphony.xwork2.ActionSupport;
  6. import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
  7. /*
  8.  * 拦截器类
  9.  */
  10. public class PrivilegeInterceptor extends MethodFilterInterceptor {
  11.      /**
  12.       *
  13.       */
  14.      private static final long serialVersionUID = 1L;
  15.      @Override
  16.      protected String doIntercept(ActionInvocation invocation) throws Exception {
  17.          //判断session中是否有登陆用户
  18.          User loginUser=(User) ServletActionContext.getRequest().getSession().getAttribute("loginuser");
  19.          if(loginUser==null){
  20.               //跳转到登陆页面
  21.               ActionSupport actionSupport=(ActionSupport) invocation.getAction();
  22.               actionSupport.addActionError("您还没有登陆,请登陆!");
  23.               return actionSupport.LOGIN;
  24.          }else{
  25.               //已经登陆
  26.               return invocation.invoke();
  27.          }
  28.         
  29.      }
  30. }

2.2配置拦截器


  
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE struts PUBLIC
  3.      "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  4.      "http://struts.apache.org/dtds/struts-2.3.dtd">
  5. <struts>
  6.      <!-- 配置Struts2的常量 -->
  7.      <constant name="struts.action.extension" value="action" />
  8.      <!-- 配置Struts2中一个表单中上传文件总大小10M -->
  9.      <constant name="struts.multipart.maxSize" value="10485760"></constant>
  10.      <!-- 配置Action -->
  11.      <package name="crm" extends="struts-default" namespace="/">
  12.          <!-- 定义拦截器 -->
  13.          <interceptors>
  14.               <interceptor name="privilegeInterceptor"
  15.                    class="com.albertyy.crm.web.intercept.PrivilegeInterceptor"></interceptor>
  16.          </interceptors>
  17.          <!-- 全局结果 -->
  18.          <global-results>
  19.               <result name="login">/login.jsp</result>
  20.          </global-results>
  21.          <!-- 用户 -->
  22.          <action name="user_*" class="userAction" method="{1}">
  23.               <result name="exitSuccess">/login.jsp</result>
  24.               <result name="success" type="redirect">/index.jsp</result>
  25.               <result name="register" >/register.jsp</result>
  26.          </action>
  27.          <!-- 客户管理Action -->
  28.          <action name="customer_*" class="customerAction" method="{1}">
  29.               <result name="saveUI">/customer/add.jsp</result>
  30.               <result name="findAll">/customer/list.jsp</result>
  31.               <result name="deleteSuccess" type="redirect">/customer_findAll.action
  32.               </result>
  33.               <result name="updateSuccess" type="redirect">/customer_findAll.action
  34.               </result>
  35.               <result name="input">/customer/add.jsp</result>
  36.               <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
  37.               <!-- 配置文件上传拦截器 -->
  38.               <interceptor-ref name="defaultStack">
  39.                    <param name="fileUpload.maximumSize">5242880</param>
  40.                    <param name="fileUpload.allowedExtensions">.jpg,.bmp,.png,.txt,.gif</param>
  41.               </interceptor-ref>
  42.          </action>
  43.          <!-- 字典管理Action -->
  44.          <action name="baseDict_*" class="baseDictAction" method="{1}">
  45.               <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
  46.               <interceptor-ref name="defaultStack"></interceptor-ref>
  47.          </action>
  48.          <!-- 联系人管理Action -->
  49.          <action name="linkMan_*" class="linkManAction" method="{1}">
  50.               <result name="findAll">/linkman/list.jsp</result>
  51.               <result name="saveUI">/linkman/add.jsp</result>
  52.               <result name="saveSuccess">/linkman/list.jsp</result>
  53.               <result name="deleteSuccess">/linkman/list.jsp</result>
  54.               <result name="updateSuccess" type="redirect">/linkMan_findAll.action
  55.               </result>
  56.               <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
  57.               <interceptor-ref name="defaultStack"></interceptor-ref>
  58.          </action>
  59.          <!-- 客户拜访Action -->
  60.          <action name="saleVisit_*" class="saleVisitAction" method="{1}">
  61.               <result name="findAll">/salevisit/list.jsp</result>
  62.               <result name="saveUI">/salevisit/add.jsp</result>
  63.               <result name="saveSuccess">/salevisit/list.jsp</result>
  64.               <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
  65.               <interceptor-ref name="defaultStack"></interceptor-ref>
  66.          </action>
  67.      </package>
  68. </struts>

 

3验证码

3.1编写工具类

编写工具类SecurityCode


  
  1. package com.albertyy.crm.utils;
  2. import java.util.Arrays;
  3. /**  
  4. *   
  5. * 项目名称:CRM  
  6. * 类名称:SecurityCode  
  7. * 类描述:  生成验证码字符串
  8. * 创建人:yangyangyang  
  9. * 创建时间:2019年1月4日 下午5:07:27  
  10. * 修改人:yangyangyang  
  11. * 修改时间:2019年1月4日 下午5:07:27  
  12. * 修改备注:  
  13. * @version   
  14. *   
  15. */
  16. public class SecurityCode {
  17.    
  18.     /**
  19.      * 验证码难度级别,Simple只包含数字,Medium包含数字和小写英文,Hard包含数字和大小写英文
  20.      */
  21.     public enum SecurityCodeLevel {Simple,Medium,Hard};
  22.    
  23.     /**
  24.      * 产生默认验证码,4位中等难度
  25.      * @return  String 验证码
  26.      */
  27.     public static String getSecurityCode(){
  28.         return getSecurityCode(4,SecurityCodeLevel.Medium,false);
  29.     }
  30.    
  31.     /**
  32.      * 产生长度和难度任意的验证码
  33.      * @param length  长度
  34.      * @param level   难度级别
  35.      * @param isCanRepeat  是否能够出现重复的字符,如果为true,则可能出现 5578这样包含两个5,如果为false,则不可能出现这种情况
  36.      * @return  String 验证码
  37.      */
  38.     public static String getSecurityCode(int length,SecurityCodeLevel level,boolean isCanRepeat){
  39.        
  40.         //随机抽取len个字符
  41.         int len=length;
  42.        
  43.         //字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O)
  44.         char[] codes={'1','2','3','4','5','6','7','8','9',
  45.                       'a','b','c','d','e','f','g','h','i',
  46.                       'j','k','m','n','p','q','r','s','t',
  47.                       'u','v','w','x','y','z','A','B','C',
  48.                       'D','E','F','G','H','I','J','K','L',
  49.                       'M','N','P','Q','R','S','T','U','V',
  50.                       'W','X','Y','Z'};
  51.        
  52.         //根据不同的难度截取字符数组
  53.         if(level==SecurityCodeLevel.Simple){
  54.             codes=Arrays.copyOfRange(codes, 0,9);
  55.         }else if(level==SecurityCodeLevel.Medium){
  56.             codes=Arrays.copyOfRange(codes, 0,33);
  57.         }
  58.        
  59.         //字符集合长度
  60.         int n=codes.length;
  61.        
  62.         //抛出运行时异常
  63.         if(len>n&&isCanRepeat==false){
  64.             throw new RuntimeException(
  65.                     String.format("调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常," +
  66.                                    "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s",
  67.                                    len,level,isCanRepeat,n));
  68.         }
  69.        
  70.         //存放抽取出来的字符
  71.         char[] result=new char[len];
  72.        
  73.         //判断能否出现重复的字符
  74.         if(isCanRepeat){
  75.             for(int i=0;i<result.length;i++){
  76.                 //索引 0 and n-1
  77.                 int r=(int)(Math.random()*n);
  78.            
  79.                 //将result中的第i个元素设置为codes[r]存放的数值
  80.                 result[i]=codes[r];
  81.             }
  82.         }else{
  83.             for(int i=0;i<result.length;i++){
  84.                 //索引 0 and n-1
  85.                 int r=(int)(Math.random()*n);
  86.                
  87.                 //将result中的第i个元素设置为codes[r]存放的数值
  88.                 result[i]=codes[r];
  89.                
  90.                 //必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。
  91.                 //因此,这里用数组中的最后一个字符改写codes[r],并将n减1
  92.                 codes[r]=codes[n-1];
  93.                 n--;
  94.             }
  95.         }
  96.        
  97.         return String.valueOf(result);
  98.     }
  99. }

编写工具类SecurityImage


  
  1. package com.albertyy.crm.utils;
  2. /**  
  3. *   
  4. * 项目名称:CRM  
  5. * 类名称:SecurityImage  
  6. * 类描述: 生成验证码图片 
  7. * 创建人:yangyangyang  
  8. * 创建时间:2019年1月4日 下午5:09:18  
  9. * 修改人:yangyangyang  
  10. * 修改时间:2019年1月4日 下午5:09:18  
  11. * 修改备注:  
  12. * @version   
  13. *   
  14. */
  15. import java.awt.Color;
  16. import java.awt.Font;
  17. import java.awt.Graphics;
  18. import java.awt.image.BufferedImage;
  19. import java.io.ByteArrayInputStream;
  20. import java.io.ByteArrayOutputStream;
  21. import java.io.IOException;
  22. import java.util.Random;
  23. import com.sun.image.codec.jpeg.ImageFormatException;
  24. import com.sun.image.codec.jpeg.JPEGCodec;
  25. import com.sun.image.codec.jpeg.JPEGImageEncoder;
  26. /**
  27.  * 工具类,生成验证码图片
  28.  * @version 1.0 2012/08/21
  29.  * @author dongliyang
  30.  *
  31.  */
  32. public class SecurityImage {
  33.    
  34.     /**
  35.      * 生成验证码图片
  36.      * @param securityCode   验证码字符
  37.      * @return  BufferedImage  图片
  38.      */
  39.     public static BufferedImage createImage(String securityCode){
  40.        
  41.         //验证码长度
  42.         int codeLength=securityCode.length();
  43.         //字体大小
  44.         int fSize = 15;
  45.         int fWidth = fSize + 1;
  46.         //图片宽度
  47.         int width = codeLength * fWidth + 6 ;
  48.         //图片高度
  49.         int height = fSize * 2 + 1;
  50.        
  51.         //图片
  52.         BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  53.         Graphics g=image.createGraphics();
  54.        
  55.         //设置背景色
  56.         g.setColor(Color.WHITE);
  57.         //填充背景
  58.         g.fillRect(0, 0, width, height);
  59.        
  60.         //设置边框颜色
  61.         g.setColor(Color.LIGHT_GRAY);
  62.         //边框字体样式
  63.         g.setFont(new Font("Arial", Font.BOLD, height - 2));
  64.         //绘制边框
  65.         g.drawRect(0, 0, width - 1, height -1);
  66.        
  67.        
  68.         //绘制噪点
  69.         Random rand = new Random();
  70.         //设置噪点颜色
  71.         g.setColor(Color.LIGHT_GRAY);
  72.         for(int i = 0;i < codeLength * 6;i++){
  73.             int x = rand.nextInt(width);
  74.             int y = rand.nextInt(height);
  75.             //绘制1*1大小的矩形
  76.             g.drawRect(x, y, 1, 1);
  77.         }
  78.        
  79.         //绘制验证码
  80.         int codeY = height - 10
  81.         //设置字体颜色和样式
  82.         g.setColor(new Color(19,148,246));
  83.         g.setFont(new Font("Georgia", Font.BOLD, fSize));
  84.         for(int i = 0; i < codeLength;i++){
  85.             g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5, codeY);
  86.         }
  87.         //关闭资源
  88.         g.dispose();
  89.        
  90.         return image;
  91.     }
  92.    
  93.     /**
  94.      * 返回验证码图片的流格式
  95.      * @param securityCode  验证码
  96.      * @return ByteArrayInputStream 图片流
  97.      */
  98.     public static ByteArrayInputStream getImageAsInputStream(String securityCode){
  99.        
  100.         BufferedImage image = createImage(securityCode);
  101.         return convertImageToStream(image);
  102.     }
  103.    
  104.     /**
  105.      * 将BufferedImage转换成ByteArrayInputStream
  106.      * @param image  图片
  107.      * @return ByteArrayInputStream 流
  108.      */
  109.     private static ByteArrayInputStream convertImageToStream(BufferedImage image){
  110.        
  111.         ByteArrayInputStream inputStream = null;
  112.         ByteArrayOutputStream bos = new ByteArrayOutputStream();
  113.         JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);
  114.         try {
  115.             jpeg.encode(image);
  116.             byte[] bts = bos.toByteArray();
  117.             inputStream = new ByteArrayInputStream(bts);
  118.         } catch (ImageFormatException e) {
  119.             e.printStackTrace();
  120.         } catch (IOException e) {
  121.             e.printStackTrace();
  122.         }
  123.         return inputStream;
  124.     }
  125. }

3.2编写action


  
  1. package com.albertyy.crm.web.action;
  2. import java.io.ByteArrayInputStream;
  3. import java.util.Map;
  4. import org.apache.struts2.interceptor.SessionAware;
  5. import com.albertyy.crm.utils.SecurityCode;
  6. import com.albertyy.crm.utils.SecurityCode.SecurityCodeLevel;
  7. import com.albertyy.crm.utils.SecurityImage;
  8. import com.opensymphony.xwork2.ActionSupport;
  9. /**  
  10. *   
  11. * 项目名称:CRM  
  12. * 类名称:SecurityCodeImageAction  
  13. * 类描述:  验证码
  14. * 创建人:yangyangyang  
  15. * 创建时间:2019年1月4日 下午5:35:21  
  16. * 修改人:yangyangyang  
  17. * 修改时间:2019年1月4日 下午5:35:21  
  18. * 修改备注:  
  19. * @version   
  20. *   
  21. */
  22. @SuppressWarnings("serial")
  23. public class SecurityCodeImageAction extends ActionSupport implements SessionAware{
  24.    
  25.     //Struts2中Map类型的session
  26.     private Map<String, Object> session;
  27.    
  28.     //图片流
  29.     private ByteArrayInputStream imageStream;
  30.     public ByteArrayInputStream getImageStream() {
  31.         return imageStream;
  32.     }
  33.     public void setImageStream(ByteArrayInputStream imageStream) {
  34.         this.imageStream = imageStream;
  35.     }
  36.    
  37.     public String execute() throws Exception {
  38.         //如果开启Hard模式,可以不区分大小写
  39.         String securityCode = SecurityCode.getSecurityCode(4,SecurityCodeLevel.Hard, false).toLowerCase();
  40.        
  41.         //获取默认难度和长度的验证码
  42.         //String securityCode = SecurityCode.getSecurityCode();
  43.         imageStream = SecurityImage.getImageAsInputStream(securityCode);
  44.         //放入session中
  45.         session.put("SESSION_SECURITY_CODE", securityCode);
  46.         return SUCCESS;
  47.     }
  48.     public void setSession(Map<String, Object> session) {
  49.         this.session = session;
  50.     }
  51. }

配置文件:


  
  1. <!-- 验证码action -->
  2.          <action name="SecurityCodeImageAction" class="com.albertyy.crm.web.action.SecurityCodeImageAction">
  3.               <result name="success" type="stream">
  4.                    <param name="contentType">image/jpeg</param>
  5.                    <param name="inputName">imageStream</param>
  6.                    <param name="bufferSize">2048</param>
  7.               </result>
  8.          </action>

 

3.3编写页面

Html

<a href="###"><img id="Verify" src="${pageContext.request.contextPath}/SecurityCodeImageAction.action"  alt="看不清换一张" width="80" height="40"></a>
 

Js:


  
  1. <script type="text/javascript">
  2.      window.onload=function(){
  3.               var verifyObj = document.getElementById("Verify");
  4.               verifyObj.onclick=function(){
  5.                   this.src="SecurityCodeImageAction.action?timestamp="+new Date().getTime();
  6.               };
  7.       }
  8.      </script>

 

本项目基本的功能已经实现,由于只是练手,后边的小功能不在实现,如有需要可以自己实现。

源码已经上传,地址为:https://github.com/AlbertYang666/CRM

演示地址:http://www.albertyy.com/CRM/

 

 

 

文章来源: albertyang.blog.csdn.net,作者:Albert Yang,版权归原作者所有,如需转载,请联系作者。

原文链接:albertyang.blog.csdn.net/article/details/85798058

(完)