zoukankan      html  css  js  c++  java
  • 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创建表

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

    1.2.2创建实体和映射

    实体:

    package com.albertyy.crm.entity;
    
    
    
    import java.sql.Date;
    
    import java.sql.Timestamp;
    
    
    
    /**
    
     *        项目名称:CRM   类名称:SaleVisit   类描述: 客户拜访实体类  创建人:yangyangyang  
    
     * 创建时间:2019年1月1日 下午4:32:53   修改人:yangyangyang   修改时间:2019年1月1日 下午4:32:53  
    
     * 修改备注:   @version       
    
     */
    
    
    
    public class SaleVisit {
    
         private String visit_id;
    
         private Timestamp visit_time;
    
         private String visit_addr;
    
         private String visit_detail;
    
         private Date visit_nexttime;
    
         // 拜访记录关联的客户对象
    
         private Customer customer;
    
         // 拜访记录关联的用户对象
    
         private User user;
    
    
    
         public String getVisit_id() {
    
             return visit_id;
    
         }
    
    
    
         public void setVisit_id(String visit_id) {
    
             this.visit_id = visit_id;
    
         }
    
    
    
         public Timestamp getVisit_time() {
    
             return visit_time;
    
         }
    
    
    
         public void setVisit_time(Timestamp visit_time) {
    
             this.visit_time = visit_time;
    
         }
    
    
    
         public String getVisit_addr() {
    
             return visit_addr;
    
         }
    
    
    
         public void setVisit_addr(String visit_addr) {
    
             this.visit_addr = visit_addr;
    
         }
    
    
    
         public String getVisit_detail() {
    
             return visit_detail;
    
         }
    
    
    
         public void setVisit_detail(String visit_detail) {
    
             this.visit_detail = visit_detail;
    
         }
    
    
    
         public Date getVisit_nexttime() {
    
             return visit_nexttime;
    
         }
    
    
    
         public void setVisit_nexttime(Date visit_nexttime) {
    
             this.visit_nexttime = visit_nexttime;
    
         }
    
    
    
         public Customer getCustomer() {
    
             return customer;
    
         }
    
    
    
         public void setCustomer(Customer customer) {
    
             this.customer = customer;
    
         }
    
    
    
         public User getUser() {
    
             return user;
    
         }
    
    
    
         public void setUser(User user) {
    
             this.user = user;
    
         }
    
    
    
    }
    
    

    映射:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE hibernate-mapping PUBLIC
    
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping>
    
         <class name="com.albertyy.crm.entity.SaleVisit" table="sale_visit">
    
             <id name="visit_id" column="visit_id">
    
                  <generator class="uuid"/>
    
             </id>
    
            
    
             <property name="visit_time" column="visit_time"/>
    
             <property name="visit_addr" column="visit_addr"/>
    
             <property name="visit_detail" column="visit_detail"/>
    
             <property name="visit_nexttime" column="visit_nexttime"/>
    
        
    
         <!-- 配置与客户的关联关系 -->
    
         <many-to-one name="customer" class="com.albertyy.crm.entity.Customer" column="visit_cust_id" />
    
         <!-- 配置与用户的关联关系 -->
    
         <many-to-one name="user" class="com.albertyy.crm.entity.User" column="visit_user_id" />
    
        
    
         </class>
    
    </hibernate-mapping>

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

     

    <!-- ======配置客户拜访的相关类======= -->
    
         <!-- 配置Action -->
    
         <bean id="saleVisitAction" class="com.albertyy.crm.web.action.SaleVisitAction" scope="prototype">
    
             <property name="saleVisitService" ref="saleVisitService"/>
    
             <property name="customerService" ref="customerService"/>
    
             <property name="userService" ref="userService"/>
    
         </bean>
    
         <!-- 配置Service -->
    
         <bean id="saleVisitService" class="com.albertyy.crm.serviceImpl.SaleVisitServiceImpl">
    
             <property name="saleVisitDao" ref="saleVisitDao"/>
    
         </bean>
    
         <!-- 配置DAO -->
    
         <bean id="saleVisitDao" class="com.albertyy.crm.daoImpl.SaleVisitDaoImpl">
    
             <property name="sessionFactory" ref="sessionFactory"/>
    
         </bean>

    1.3客户拜访记录列表显示

    1.3.1修改left.jsp的提交路径

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

    1.3.2编写action

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

    1.3.3编写service

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

     

    1.3.4编写显示页面

    <div class="main" style="overflow-y: auto">
    
    
    
             <div class="container">
    
    
    
                  <form name="customerForm"
    
                       action="${pageContext.request.contextPath }/saleVisit_findAll.action"
    
                       method="post">
    
    
    
                       <div id="search_bar" class="mt10">
    
                           <div class="box">
    
                                <div class="box_border">
    
                                     <div class="box_top">
    
                                         <b class="pl15">搜索</b>
    
                                     </div>
    
                                     <div class="box_center pt10 pb10">
    
                                         <table class="form_table" cellspacing="0" cellpadding="0"
    
                                              border="0">
    
                                              <tbody>
    
                                                   <tr>
    
                                                       <td>拜访时间从:</td>
    
                                                       <td><input type="date" name="visit_time"
    
                                                            value="<s:date name="visit_time" format="yyyy-MM-dd"/>"
    
                                                            class="input-text lh25" size="10"></td>
    
                                                       <td>到:</td>
    
                                                       <td><input type="date" name="visit_endtime"
    
                                                            value="<s:date name="visit_endtime" format="yyyy-MM-dd"/>"
    
                                                            class="input-text lh25" size="10"></td>
    
    
    
    
    
    
    
                                                       <td><input type="submit" name="button"
    
                                                            class="btn btn82 btn_search" value="查询"></td>
    
                                                   </tr>
    
    
    
                                              </tbody>
    
                                         </table>
    
                                     </div>
    
    
    
                                </div>
    
                           </div>
    
                       </div>
    
    
    
                       <div id="table" class="mt10">
    
                           <div class="box span10 oh">
    
                                <table width="100%" border="0" cellpadding="0" cellspacing="0"
    
                                     class="list_table">
    
                                     <tr>
    
                                         <th width="100">客户名称</th>
    
                                         <th width="100">负责人名称</th>
    
                                         <th width="100">拜访时间</th>
    
                                         <th width="100">拜访地点</th>
    
                                         <th width="100">拜访详情</th>
    
                                         <th width="100">下次拜访时间</th>
    
                                         <th width="150">操作</th>
    
                                     </tr>
    
                                     <s:iterator value="list">
    
    
    
                                         <tr class="tr">
    
                                              <td><s:property value="customer.cust_name" /></td>
    
                                              <td><s:property value="user.user_name" /></td>
    
                                              <td><s:date name="visit_time" format="yyyy-MM-dd"/></td>
    
                                              <td><s:property value="visit_addr" /></td>
    
                                              <td><div style="height: 30px; overflow-y: auto;">
    
                                                       <s:property value="visit_detail" />
    
                                                   </div></td>
    
                                              <td><s:date name="visit_nexttime" format="yyyy-MM-dd"/></td>
    
                                              <td><input type="button" name="button"
    
                                                   class="btn btn82 btn_add" id="modifyBtn"
    
                                                   onclick="toUpdate('<s:property value="lkm_id"/>')" value="修改">
    
                                                   <input type="button" name="button" class="btn btn82 btn_del"
    
                                                   onclick="toDelete('<s:property value="lkm_id"/>')" value="删除"></td>
    
    
    
                                         </tr>
    
                                     </s:iterator>
    
    
    
                                </table>
    
                                <div class="page mt10">
    
    
    
                                     <div class="pagination">
    
                                         <ul>
    
                                              <li class="disabled"><span> 共<s:property
    
                                                            value="totalCount" />条记录, 共 <s:property value="totalPage" />页
    
                                              </span></li>
    
                                              <li><span> 每页显示记录数: <select name="pageSize"
    
                                                       onchange="to_page()">
    
                                                            <option value="5" <s:if test="pageSize==5">selected</s:if>>5条</option>
    
                                                            <option value="10" <s:if test="pageSize==10">selected</s:if>>10条</option>
    
                                                            <option value="20" <s:if test="pageSize==20">selected</s:if>>20条</option>
    
                                                   </select>
    
    
    
                                              </span></li>
    
    
    
    
    
                                              <s:if test="page!=1">
    
                                                   <li><a href="javascript:to_page(1)">首页</a></li>
    
                                                   <li><a
    
                                                       href="javascript:to_page(<s:property value="page-1" />)">上一页</a></li>
    
                                              </s:if>
    
    
    
                                              <s:iterator var="i" begin="1" end="totalPage">
    
                                                   <s:if test="#i==page">
    
                                                       <li class="active"><span><s:property value="#i" />
    
                                                       </span></li>
    
                                                   </s:if>
    
                                                   <s:else>
    
                                                       <li><a
    
                                                            href="javascript:to_page(<s:property value="#i" />)"><s:property
    
                                                                     value="#i" /></a></li>
    
                                                   </s:else>
    
                                              </s:iterator>
    
    
    
                                              <s:if test="page!=totalPage">
    
                                                   <li><a
    
                                                       href="javascript:to_page(<s:property value="page+1" />)">下一页</a></li>
    
                                                   <li><a
    
                                                       href="javascript:to_page(<s:property value="totalPage" />)">末页</a></li>
    
                                              </s:if>
    
                                              <li>到第 <input class="input-text lh25" type="text"
    
                                                   id="page" name="page" size="2" height="10px" />页 <input
    
                                                   class="ext_btn" type="button" value="GO" onclick="to_page()" />
    
    
    
                                              </li>
    
                                         </ul>
    
                                     </div>
    
                                </div>
    
                  </form>
    
    
    
    
    
             </div>
    
         </div>

    1.4客户拜访记录列表显示

    1.4.1编写action

     

    // 跳转到添加页面的方法
    
         public String saveUI() {
    
             // 查询客户和负责人
    
             List<Customer> customerlist = customerService.findAll();
    
             List<User> userlist = userService.findAll();
    
             ActionContext.getContext().getValueStack().set("customerlist", customerlist);
    
             ActionContext.getContext().getValueStack().set("userlist", userlist);
    
             return "saveUI";
    
         }
    
    
    
         // 保存拜访记录
    
         public String save() {
    
             saleVisitService.save(saleVisit);
    
    
    
             // 跳转到列表页面
    
             findAll();
    
             return "saveSuccess";
    
         }
    
    
    
    配置action:
    
    <!-- 客户拜访Action -->
    
             <action name="saleVisit_*" class="saleVisitAction" method="{1}">
    
                  <result name="findAll">/salevisit/list.jsp</result>
    
                  <result name="saveUI">/salevisit/add.jsp</result>
    
                  <result name="saveSuccess">/salevisit/list.jsp</result>
    
                 
    
             </action>

    1.4.2编写service

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

    1.4.3编写保存页面

     

    <div class="main" style="overflow-y: auto">
    
             <div class="container">
    
                  <div class="main_top">
    
                       <div id="forms" class="mt10">
    
                           <div class="box">
    
                                <div class="box_border">
    
                                     <div class="box_top">
    
                                         <b class="pl15">新增客户拜访</b>
    
                                     </div>
    
                                     <div class="box_center">
    
                                         <form
    
                                              action="${pageContext.request.contextPath }/saleVisit_save.action"
    
                                              method="post" class="jqtransform">
    
                                              <table class="form_table pt15 pb15" width="100%" border="0"
    
                                                   cellpadding="0" cellspacing="0">
    
                                                   <tr>
    
                                                       <td class="td_right">客户名称:</td>
    
                                                       <td class=""><span class="fl">
    
                                                                 <div class="select_border">
    
                                                                     <div class="select_containers ">
    
                                                                          <select name="customer.cust_id" id="cust_source"
    
                                                                               class="select">
    
                                                                               <option value="">-请选择-</option>
    
                                                                               <s:iterator value="customerlist">
    
                                                                                   <option value='<s:property value="cust_id"/>'><s:property
    
                                                                                             value="cust_name" /></option>
    
                                                                               </s:iterator>
    
                                                                          </select>
    
                                                                     </div>
    
                                                                 </div>
    
                                                       </span></td>
    
                                                   </tr>
    
                                                  
    
                                                   <tr>
    
                                                       <td class="td_right">负责人名称:</td>
    
                                                       <td class=""><span class="fl">
    
                                                                 <div class="select_border">
    
                                                                     <div class="select_containers ">
    
                                                                          <select name="user.user_id" id="cust_source"
    
                                                                               class="select">
    
                                                                               <option value="">-请选择-</option>
    
                                                                               <s:iterator value="userlist">
    
                                                                                   <option value='<s:property value="user_id"/>'><s:property
    
                                                                                             value="user_name" /></option>
    
                                                                               </s:iterator>
    
                                                                          </select>
    
                                                                     </div>
    
                                                                 </div>
    
                                                       </span></td>
    
                                                   </tr>
    
                                                  
    
                                                   <tr>
    
                                                       <td class="td_right">拜访时间:</td>
    
                                                       <td class=""><input type="date" name="visit_time"
    
                                                            class="input-text lh30" ></td>
    
    
    
                                                   </tr>
    
                                                   <tr>
    
                                                       <td class="td_right">拜访地点:</td>
    
                                                       <td class=""><input type="text" name="visit_addr"
    
                                                            class="input-text lh30" ></td>
    
    
    
                                                   </tr>
    
                                                   <tr>
    
                                                       <td class="td_right">拜访详情:</td>
    
                                                       <td class=""><textarea name="visit_detail" id="" cols="30" rows="10"
    
                                                                 class="textarea" style=" 362px; height: 93px;"></textarea>
    
                                                       </td>
    
                                                   </tr>
    
    <tr>
    
                                                       <td class="td_right">下次拜访时间:</td>
    
                                                       <td class=""><input type="date" name="visit_nexttime"
    
                                                            class="input-text lh30" ></td>
    
    
    
                                                   </tr>
    
    
    
    
    
    
    
                                                   <tr>
    
                                                       <td class="td_right">&nbsp;</td>
    
                                                       <td class=""><input type="submit" name="button"
    
                                                            class="btn btn82 btn_save2" value="保存"> <input
    
                                                            type="reset" name="button" class="btn btn82 btn_res"
    
                                                            value="重置"></td>
    
                                                   </tr>
    
                                              </table>
    
                                         </form>
    
                                     </div>
    
                                </div>
    
                           </div>
    
                       </div>
    
                  </div>
    
    
    
             </div>
    
         </div>

     

    2.权限管理

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

     

    package com.albertyy.crm.web.intercept;
    
    
    
    import org.apache.struts2.ServletActionContext;
    
    
    
    import com.albertyy.crm.entity.User;
    
    import com.opensymphony.xwork2.ActionInvocation;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
    
    /*
    
     * 拦截器类
    
     */
    
    public class PrivilegeInterceptor extends MethodFilterInterceptor {
    
    
    
         /**
    
          *
    
          */
    
         private static final long serialVersionUID = 1L;
    
    
    
         @Override
    
         protected String doIntercept(ActionInvocation invocation) throws Exception {
    
             //判断session中是否有登陆用户
    
             User loginUser=(User) ServletActionContext.getRequest().getSession().getAttribute("loginuser");
    
             if(loginUser==null){
    
                  //跳转到登陆页面
    
                  ActionSupport actionSupport=(ActionSupport) invocation.getAction();
    
                  actionSupport.addActionError("您还没有登陆,请登陆!");
    
                  return actionSupport.LOGIN;
    
             }else{
    
                  //已经登陆
    
                  return invocation.invoke();
    
             }
    
            
    
         }
    
    
    
    }
    
    
    
    

    2.2配置拦截器

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE struts PUBLIC
    
         "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    
         "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <struts>
    
    
    
         <!-- 配置Struts2的常量 -->
    
         <constant name="struts.action.extension" value="action" />
    
         <!-- 配置Struts2中一个表单中上传文件总大小10M -->
    
         <constant name="struts.multipart.maxSize" value="10485760"></constant>
    
    
    
    
    
    
    
         <!-- 配置Action -->
    
         <package name="crm" extends="struts-default" namespace="/">
    
             <!-- 定义拦截器 -->
    
             <interceptors>
    
                  <interceptor name="privilegeInterceptor"
    
                       class="com.albertyy.crm.web.intercept.PrivilegeInterceptor"></interceptor>
    
             </interceptors>
    
             <!-- 全局结果 -->
    
             <global-results>
    
                  <result name="login">/login.jsp</result>
    
             </global-results>
    
             <!-- 用户 -->
    
             <action name="user_*" class="userAction" method="{1}">
    
                  <result name="exitSuccess">/login.jsp</result>
    
                  <result name="success" type="redirect">/index.jsp</result>
    
                  <result name="register" >/register.jsp</result>
    
             </action>
    
    
    
             <!-- 客户管理Action -->
    
             <action name="customer_*" class="customerAction" method="{1}">
    
                  <result name="saveUI">/customer/add.jsp</result>
    
                  <result name="findAll">/customer/list.jsp</result>
    
                  <result name="deleteSuccess" type="redirect">/customer_findAll.action
    
                  </result>
    
                  <result name="updateSuccess" type="redirect">/customer_findAll.action
    
                  </result>
    
                  <result name="input">/customer/add.jsp</result>
    
    
    
                  <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
    
                  <!-- 配置文件上传拦截器 -->
    
                  <interceptor-ref name="defaultStack">
    
                       <param name="fileUpload.maximumSize">5242880</param>
    
                       <param name="fileUpload.allowedExtensions">.jpg,.bmp,.png,.txt,.gif</param>
    
                  </interceptor-ref>
    
             </action>
    
    
    
             <!-- 字典管理Action -->
    
             <action name="baseDict_*" class="baseDictAction" method="{1}">
    
    
    
                  <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
    
                  <interceptor-ref name="defaultStack"></interceptor-ref>
    
             </action>
    
    
    
             <!-- 联系人管理Action -->
    
             <action name="linkMan_*" class="linkManAction" method="{1}">
    
                  <result name="findAll">/linkman/list.jsp</result>
    
                  <result name="saveUI">/linkman/add.jsp</result>
    
                  <result name="saveSuccess">/linkman/list.jsp</result>
    
                  <result name="deleteSuccess">/linkman/list.jsp</result>
    
                  <result name="updateSuccess" type="redirect">/linkMan_findAll.action
    
                  </result>
    
    
    
                  <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
    
                  <interceptor-ref name="defaultStack"></interceptor-ref>
    
             </action>
    
    
    
             <!-- 客户拜访Action -->
    
             <action name="saleVisit_*" class="saleVisitAction" method="{1}">
    
                  <result name="findAll">/salevisit/list.jsp</result>
    
                  <result name="saveUI">/salevisit/add.jsp</result>
    
                  <result name="saveSuccess">/salevisit/list.jsp</result>
    
                  <interceptor-ref name="privilegeInterceptor"></interceptor-ref>
    
                  <interceptor-ref name="defaultStack"></interceptor-ref>
    
             </action>
    
    
    
         </package>
    
    </struts>

     

    3验证码

    3.1编写工具类

    编写工具类SecurityCode

    package com.albertyy.crm.utils;
    
    
    
    import java.util.Arrays;
    
    
    
    /**  
    
    *   
    
    * 项目名称:CRM  
    
    * 类名称:SecurityCode  
    
    * 类描述:  生成验证码字符串
    
    * 创建人:yangyangyang  
    
    * 创建时间:2019年1月4日 下午5:07:27  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2019年1月4日 下午5:07:27  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    public class SecurityCode {
    
       
    
        /**
    
         * 验证码难度级别,Simple只包含数字,Medium包含数字和小写英文,Hard包含数字和大小写英文
    
         */
    
        public enum SecurityCodeLevel {Simple,Medium,Hard};
    
       
    
        /**
    
         * 产生默认验证码,4位中等难度
    
         * @return  String 验证码
    
         */
    
        public static String getSecurityCode(){
    
            return getSecurityCode(4,SecurityCodeLevel.Medium,false);
    
        }
    
       
    
        /**
    
         * 产生长度和难度任意的验证码
    
         * @param length  长度
    
         * @param level   难度级别
    
         * @param isCanRepeat  是否能够出现重复的字符,如果为true,则可能出现 5578这样包含两个5,如果为false,则不可能出现这种情况
    
         * @return  String 验证码
    
         */
    
        public static String getSecurityCode(int length,SecurityCodeLevel level,boolean isCanRepeat){
    
           
    
            //随机抽取len个字符
    
            int len=length;
    
           
    
            //字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O)
    
            char[] codes={'1','2','3','4','5','6','7','8','9',
    
                          'a','b','c','d','e','f','g','h','i',
    
                          'j','k','m','n','p','q','r','s','t',
    
                          'u','v','w','x','y','z','A','B','C',
    
                          'D','E','F','G','H','I','J','K','L',
    
                          'M','N','P','Q','R','S','T','U','V',
    
                          'W','X','Y','Z'};
    
           
    
            //根据不同的难度截取字符数组
    
            if(level==SecurityCodeLevel.Simple){
    
                codes=Arrays.copyOfRange(codes, 0,9);
    
            }else if(level==SecurityCodeLevel.Medium){
    
                codes=Arrays.copyOfRange(codes, 0,33);
    
            }
    
           
    
            //字符集合长度
    
            int n=codes.length;
    
           
    
            //抛出运行时异常
    
            if(len>n&&isCanRepeat==false){
    
                throw new RuntimeException(
    
                        String.format("调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常," +
    
                                       "当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s",
    
                                       len,level,isCanRepeat,n));
    
            }
    
           
    
            //存放抽取出来的字符
    
            char[] result=new char[len];
    
           
    
            //判断能否出现重复的字符
    
            if(isCanRepeat){
    
                for(int i=0;i<result.length;i++){
    
                    //索引 0 and n-1
    
                    int r=(int)(Math.random()*n);
    
               
    
                    //将result中的第i个元素设置为codes[r]存放的数值
    
                    result[i]=codes[r];
    
                }
    
            }else{
    
                for(int i=0;i<result.length;i++){
    
                    //索引 0 and n-1
    
                    int r=(int)(Math.random()*n);
    
                   
    
                    //将result中的第i个元素设置为codes[r]存放的数值
    
                    result[i]=codes[r];
    
                   
    
                    //必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。
    
                    //因此,这里用数组中的最后一个字符改写codes[r],并将n减1
    
                    codes[r]=codes[n-1];
    
                    n--;
    
                }
    
            }
    
           
    
            return String.valueOf(result);
    
        }
    
    }
    
    

    编写工具类SecurityImage

    
    package com.albertyy.crm.utils;
    
    
    
    /**  
    
    *   
    
    * 项目名称:CRM  
    
    * 类名称:SecurityImage  
    
    * 类描述: 生成验证码图片 
    
    * 创建人:yangyangyang  
    
    * 创建时间:2019年1月4日 下午5:09:18  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2019年1月4日 下午5:09:18  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    import java.awt.Color;
    
    import java.awt.Font;
    
    import java.awt.Graphics;
    
    import java.awt.image.BufferedImage;
    
    import java.io.ByteArrayInputStream;
    
    import java.io.ByteArrayOutputStream;
    
    import java.io.IOException;
    
    import java.util.Random;
    
    import com.sun.image.codec.jpeg.ImageFormatException;
    
    import com.sun.image.codec.jpeg.JPEGCodec;
    
    import com.sun.image.codec.jpeg.JPEGImageEncoder;
    
    
    
    /**
    
     * 工具类,生成验证码图片
    
     * @version 1.0 2012/08/21
    
     * @author dongliyang
    
     *
    
     */
    
    public class SecurityImage {
    
       
    
        /**
    
         * 生成验证码图片
    
         * @param securityCode   验证码字符
    
         * @return  BufferedImage  图片
    
         */
    
        public static BufferedImage createImage(String securityCode){
    
           
    
            //验证码长度
    
            int codeLength=securityCode.length();
    
            //字体大小
    
            int fSize = 15;
    
            int fWidth = fSize + 1;
    
            //图片宽度
    
            int width = codeLength * fWidth + 6 ;
    
            //图片高度
    
            int height = fSize * 2 + 1;
    
           
    
            //图片
    
            BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    
            Graphics g=image.createGraphics();
    
           
    
            //设置背景色
    
            g.setColor(Color.WHITE);
    
            //填充背景
    
            g.fillRect(0, 0, width, height);
    
           
    
            //设置边框颜色
    
            g.setColor(Color.LIGHT_GRAY);
    
            //边框字体样式
    
            g.setFont(new Font("Arial", Font.BOLD, height - 2));
    
            //绘制边框
    
            g.drawRect(0, 0, width - 1, height -1);
    
           
    
           
    
            //绘制噪点
    
            Random rand = new Random();
    
            //设置噪点颜色
    
            g.setColor(Color.LIGHT_GRAY);
    
            for(int i = 0;i < codeLength * 6;i++){
    
                int x = rand.nextInt(width);
    
                int y = rand.nextInt(height);
    
                //绘制1*1大小的矩形
    
                g.drawRect(x, y, 1, 1);
    
            }
    
           
    
            //绘制验证码
    
            int codeY = height - 10; 
    
            //设置字体颜色和样式
    
            g.setColor(new Color(19,148,246));
    
            g.setFont(new Font("Georgia", Font.BOLD, fSize));
    
            for(int i = 0; i < codeLength;i++){
    
                g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5, codeY);
    
            }
    
            //关闭资源
    
            g.dispose();
    
           
    
            return image;
    
        }
    
       
    
        /**
    
         * 返回验证码图片的流格式
    
         * @param securityCode  验证码
    
         * @return ByteArrayInputStream 图片流
    
         */
    
        public static ByteArrayInputStream getImageAsInputStream(String securityCode){
    
           
    
            BufferedImage image = createImage(securityCode);
    
            return convertImageToStream(image);
    
        }
    
       
    
        /**
    
         * 将BufferedImage转换成ByteArrayInputStream
    
         * @param image  图片
    
         * @return ByteArrayInputStream 流
    
         */
    
        private static ByteArrayInputStream convertImageToStream(BufferedImage image){
    
           
    
            ByteArrayInputStream inputStream = null;
    
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
            JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos);
    
            try {
    
                jpeg.encode(image);
    
                byte[] bts = bos.toByteArray();
    
                inputStream = new ByteArrayInputStream(bts);
    
            } catch (ImageFormatException e) {
    
                e.printStackTrace();
    
            } catch (IOException e) {
    
                e.printStackTrace();
    
            }
    
            return inputStream;
    
        }
    
    }
    
    

    3.2编写action

    
    package com.albertyy.crm.web.action;
    
    
    
    import java.io.ByteArrayInputStream;
    
    import java.util.Map;
    
    
    
    import org.apache.struts2.interceptor.SessionAware;
    
    
    
    import com.albertyy.crm.utils.SecurityCode;
    
    import com.albertyy.crm.utils.SecurityCode.SecurityCodeLevel;
    
    import com.albertyy.crm.utils.SecurityImage;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    
    
    /**  
    
    *   
    
    * 项目名称:CRM  
    
    * 类名称:SecurityCodeImageAction  
    
    * 类描述:  验证码
    
    * 创建人:yangyangyang  
    
    * 创建时间:2019年1月4日 下午5:35:21  
    
    * 修改人:yangyangyang  
    
    * 修改时间:2019年1月4日 下午5:35:21  
    
    * 修改备注:  
    
    * @version   
    
    *   
    
    */
    
    
    
    @SuppressWarnings("serial")
    
    public class SecurityCodeImageAction extends ActionSupport implements SessionAware{
    
       
    
        //Struts2中Map类型的session
    
        private Map<String, Object> session;
    
       
    
        //图片流
    
        private ByteArrayInputStream imageStream;
    
    
    
        public ByteArrayInputStream getImageStream() {
    
            return imageStream;
    
        }
    
    
    
        public void setImageStream(ByteArrayInputStream imageStream) {
    
            this.imageStream = imageStream;
    
        }
    
    
    
       
    
        public String execute() throws Exception {
    
            //如果开启Hard模式,可以不区分大小写
    
            String securityCode = SecurityCode.getSecurityCode(4,SecurityCodeLevel.Hard, false).toLowerCase();
    
           
    
            //获取默认难度和长度的验证码
    
            //String securityCode = SecurityCode.getSecurityCode();
    
            imageStream = SecurityImage.getImageAsInputStream(securityCode);
    
            //放入session中
    
            session.put("SESSION_SECURITY_CODE", securityCode);
    
            return SUCCESS;
    
        }
    
    
    
        public void setSession(Map<String, Object> session) {
    
            this.session = session;
    
        }
    
    
    
    }

    配置文件:

    <!-- 验证码action -->
    
             <action name="SecurityCodeImageAction" class="com.albertyy.crm.web.action.SecurityCodeImageAction">
    
                  <result name="success" type="stream">
    
                       <param name="contentType">image/jpeg</param>
    
                       <param name="inputName">imageStream</param>
    
                       <param name="bufferSize">2048</param>
    
                  </result>
    
             </action>

     

    3.3编写页面

    Html

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

    Js:

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

     

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

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

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

     

     

     

  • 相关阅读:
    0603 学术诚信与道德
    0601 新的冲刺
    0525 Scrum 项目7.0
    0523 Scrum 项目6.0
    0518 Scrum项目5.0
    0512 Scrum 4.0
    0512 操作系统之进程调度
    0511 backlog
    0506 Scrum 项目1.0
    复利计算再升级
  • 原文地址:https://www.cnblogs.com/yangxianyang/p/13675629.html
Copyright © 2011-2022 走看看