Commit 53e5fba1 authored by 任海峰's avatar 任海峰 Committed by 雍欢

组织管理,初始化人员密码的显示优化(提供发送密码修改后邮件的接口)

parent 41a0ba86
package com.huigou.uasp.bmp.opm.application;
import com.huigou.uasp.bmp.opm.domain.model.org.Person;
/**
* @author haifeng
* @date 2020-05-19 12:03
* @description 初始化密码执行方法接口
*/
public interface InitPasswordListener {
/**
* 初始化密码提示邮件模板
*/
public static final String INIT_PSW_MAIL_OBJECT = "初始化密码";
/**
* 执行初始化密码发送邮件
* @param person 人员信息
* @param newPassword 新密码
*/
void onInitPassword(Person person,String newPassword);
}
......@@ -483,6 +483,15 @@ public interface OrgApplication {
*/
void initPassword(String personId);
/**
* 初始化密码
* @param personId
* 人员ID
* @param newPassword
* 新密码
*/
void initPassword(String personId,String newPassword);
/**
* 分页查询人员
*
......
......@@ -17,6 +17,7 @@ import com.huigou.exception.ApplicationException;
import com.huigou.uasp.bmp.opm.LicenseChecker;
import com.huigou.uasp.bmp.opm.OpmUtil;
import com.huigou.uasp.bmp.opm.SelectOrgScope;
import com.huigou.uasp.bmp.opm.application.InitPasswordListener;
import com.huigou.uasp.bmp.opm.application.OrgApplication;
import com.huigou.uasp.bmp.opm.application.PermissionBuilder;
import com.huigou.uasp.bmp.opm.domain.model.access.Role;
......@@ -56,6 +57,8 @@ public class OrgApplicationImpl extends BaseApplication implements OrgApplicatio
private RoleRepository roleRepository;
private InitPasswordListener initPasswordListener;
public void setOrgPropertyDefinitionRepository(OrgPropertyDefinitionRepository orgPropertyDefinitionRepository) {
this.orgPropertyDefinitionRepository = orgPropertyDefinitionRepository;
}
......@@ -88,6 +91,10 @@ public class OrgApplicationImpl extends BaseApplication implements OrgApplicatio
this.roleRepository = roleRepository;
}
public void setInitPasswordListener(InitPasswordListener initPasswordListener) {
this.initPasswordListener = initPasswordListener;
}
private String getQuerySqlByName(String name) {
QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "org");
return queryDescriptor.getSqlByName(name);
......@@ -1410,6 +1417,20 @@ public class OrgApplicationImpl extends BaseApplication implements OrgApplicatio
this.personRepository.save(person);
}
@Override
public void initPassword(String personId, String newPassword) {
Assert.hasText(personId, String.format(CommonDomainConstants.PARAMETER_NOT_NULL_FORMAT, "personId"));
Person person = this.loadPerson(personId);
Util.check(person != null, "没有找到ID“%s”对应的人员。", new Object[] { personId });
String decodedPassword = new String(Base64.decodeBase64(newPassword));
person.setPassword(Md5Builder.getMd5(decodedPassword));
this.personRepository.save(person);
if(initPasswordListener!=null){
//发送邮件
initPasswordListener.onInitPassword(person,decodedPassword);
}
}
private void internalUpdatePassword(String personId, String oldPassword, String newPassword) {
Assert.hasText(personId, String.format(CommonDomainConstants.PARAMETER_NOT_NULL_FORMAT, "personId"));
Assert.isTrue(!StringUtil.isBlank(newPassword) && !StringUtil.isBlank(oldPassword), "密码不能为空。");
......
......@@ -5,6 +5,7 @@ import com.huigou.data.domain.service.CommonDomainService;
import com.huigou.data.query.executor.SQLExecutorDao;
import com.huigou.data.repository.GeneralRepository;
import com.huigou.domain.ValidStatus;
import com.huigou.uasp.bmp.opm.application.InitPasswordListener;
import com.huigou.uasp.bmp.opm.application.OrgApplication;
import com.huigou.uasp.bmp.opm.domain.model.org.Org;
import com.huigou.uasp.bmp.opm.domain.model.org.OrgPropertyDefinition;
......@@ -64,6 +65,9 @@ public class OrgApplicationProxy {
@Autowired
private ManagementApplicationProxy managementApplicationProxy;
@Autowired
private InitPasswordListener initPasswordListener;
void initProperties(OrgApplicationImpl orgApplicationImpl) {
orgApplicationImpl.setCommonDomainService(commonDomainService);
orgApplicationImpl.setSqlExecutorDao(sqlExecutorDao);
......@@ -76,6 +80,7 @@ public class OrgApplicationProxy {
orgApplicationImpl.setPersonRepository(personRepository);
orgApplicationImpl.setSecurityPolicyApplication(this.securityPolicyApplication);
orgApplicationImpl.setRoleRepository(roleRepository);
orgApplicationImpl.setInitPasswordListener(initPasswordListener);
}
public OrgApplication getOrgApplication() {
......@@ -314,6 +319,11 @@ public class OrgApplicationProxy {
getOrgApplication().initPassword(personId);
}
@Transactional
public void initPassword(String personId,String newPassword) {
getOrgApplication().initPassword(personId,newPassword);
}
public Map<String, Object> slicedQueryPerson(String parentIdOrFullId, boolean showDisabled, boolean showAllChildren, CodeAndNameQueryRequest queryRequest) {
return getOrgApplication().slicedQueryPerson(parentIdOrFullId, showDisabled, showAllChildren, queryRequest);
}
......
package com.huigou.uasp.bmp.opm.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.huigou.data.domain.model.CommonDomainConstants;
import com.huigou.data.domain.query.CodeAndNameQueryRequest;
import com.huigou.domain.ValidStatus;
......@@ -19,12 +7,7 @@ import com.huigou.exception.ApplicationException;
import com.huigou.uasp.annotation.ControllerMapping;
import com.huigou.uasp.bmp.doc.attachment.application.AttachmentApplication;
import com.huigou.uasp.bmp.doc.attachment.domain.model.Attachment;
import com.huigou.uasp.bmp.opm.domain.model.org.Org;
import com.huigou.uasp.bmp.opm.domain.model.org.OrgNodeKind;
import com.huigou.uasp.bmp.opm.domain.model.org.OrgProperty;
import com.huigou.uasp.bmp.opm.domain.model.org.OrgPropertyDefinition;
import com.huigou.uasp.bmp.opm.domain.model.org.OrgType;
import com.huigou.uasp.bmp.opm.domain.model.org.Person;
import com.huigou.uasp.bmp.opm.domain.model.org.*;
import com.huigou.uasp.bmp.opm.domain.query.OrgPropertyDefinitionQueryRequest;
import com.huigou.uasp.bmp.opm.domain.query.OrgQueryModel;
import com.huigou.uasp.bmp.opm.proxy.OrgApplicationProxy;
......@@ -34,10 +17,18 @@ import com.huigou.uasp.client.CommonController;
import com.huigou.uasp.log.annotation.LogInfo;
import com.huigou.uasp.log.domain.model.LogType;
import com.huigou.uasp.log.domain.model.OperationType;
import com.huigou.util.ClassHelper;
import com.huigou.util.Constants;
import com.huigou.util.SDO;
import com.huigou.util.StringUtil;
import com.huigou.util.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
......@@ -513,10 +504,23 @@ public class OrgController extends CommonController {
public String initPassword() {
SDO sdo = this.getSDO();
String personId = sdo.getString("personId");
this.application.initPassword(personId);
String newPassword = sdo.getString("newPsw");
this.application.initPassword(personId,newPassword);
return success("初始化密码成功。");
}
public String initPasswordDetail(){
SDO sdo = this.getSDO();
String personId = sdo.getString("personId");
this.putAttribute("personId",personId);
return this.forward("OrgInitPasswordDetail");
}
public String generateRandomPassword(){
String randomPassword = RandomString.getInstance().getRandomString(6, "ilu");
return success(randomPassword);
}
private void clearSessionSecurityPolicyAttributes(){
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
......
package com.huigou.uasp.client;
import com.huigou.uasp.bmp.opm.application.InitPasswordListener;
import com.huigou.uasp.bmp.opm.domain.model.org.Person;
import com.huigou.uasp.tool.mail.EmailSender;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author haifeng
* @date 2020-05-19 12:12
* @description 初始化密码时,实现发送邮件
*/
public class InitPasswordEmailNotifier implements InitPasswordListener {
@Autowired
private EmailSender mailSender;
/**
* 模板
*/
private String initPswMail;
public void setInitPswMail(String initPswMail) {
this.initPswMail = initPswMail;
}
@Override
public void onInitPassword(Person person, String newPassword) {
Map<String,Object> map = new LinkedHashMap<>(2);
map.put("person",person);
map.put("newPsw",newPassword);
try{
mailSender.doSend(person.getEmail(),INIT_PSW_MAIL_OBJECT,initPswMail,map);
}catch (Exception e){
e.printStackTrace();
}
}
}
......@@ -2,35 +2,62 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="messageSenderManager" class="com.huigou.uasp.bpm.engine.MessageSenderManagerImpl">
<property name="messageSenders">
<list>
</list>
</property>
</bean>
<bean id="processEventSupport" class="com.huigou.uasp.bpm.event.ProcessEventSupport">
<property name="listeners">
<list>
</list>
</property>
</bean>
<bean id="tmspmConifg" class="com.huigou.context.TmspmConifg">
<property name="useTspm" value="false" />
<property name="enableTspm" value="false" />
<property name="doHideSuperAdministrator" value="false" />
</bean>
<bean id="loadExpressClasses" class="com.huigou.express.LoadExpressClasses">
<!-- 多个包"package.a,package.b"并对每个包都会递归搜索 -->
<constructor-arg value="com.huigou" />
<!-- 指定扫描包中含有特定注解标记的bean,支持多个注解 -->
<constructor-arg>
<list>
<value>com.huigou.uasp.annotation.Expression</value>
</list>
</constructor-arg>
</bean>
<bean id="messageSenderManager" class="com.huigou.uasp.bpm.engine.MessageSenderManagerImpl">
<property name="messageSenders">
<list>
</list>
</property>
</bean>
<bean id="processEventSupport" class="com.huigou.uasp.bpm.event.ProcessEventSupport">
<property name="listeners">
<list>
</list>
</property>
</bean>
<bean id="tmspmConifg" class="com.huigou.context.TmspmConifg">
<property name="useTspm" value="false"/>
<property name="enableTspm" value="false"/>
<property name="doHideSuperAdministrator" value="false"/>
</bean>
<bean id="loadExpressClasses" class="com.huigou.express.LoadExpressClasses">
<!-- 多个包"package.a,package.b"并对每个包都会递归搜索 -->
<constructor-arg value="com.huigou"/>
<!-- 指定扫描包中含有特定注解标记的bean,支持多个注解 -->
<constructor-arg>
<list>
<value>com.huigou.uasp.annotation.Expression</value>
</list>
</constructor-arg>
</bean>
<!-- JavaMail相关配置 任务中心邮件通知发送 -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${email.host}"/>
<property name="username" value="${email.username}"/>
<property name="password" value="${email.password}"/>
<property name="defaultEncoding" value="utf-8"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
<prop key="mail.smtp.timeout">25000</prop>
</props>
</property>
</bean>
<!-- 普通任务邮件 -->
<bean id="simpleEmailSender" class="com.huigou.uasp.tool.mail.impl.EmailSenderImpl">
<property name="mailSender" ref="mailSender" />
<property name="fromEmail" value="${email.username}"/>
<property name="emailTemplate" value="taskNotice"/>
</bean>
<!-- 初始化密码后发送邮件通知用户 -->
<bean id="initPasswordEmail" class="com.huigou.uasp.client.InitPasswordEmailNotifier">
<property name="initPswMail" value="initPasswordMail"/>
</bean>
</beans>
\ No newline at end of file
......@@ -435,13 +435,64 @@ function initPassword(){
Public.errorTip("请选择人员。");
return ;
}
UICtrl.showAjaxDialog({
title:"初始化密码",
width:406,
url:web_app.name + '/org/initPasswordDetail.load',
param:{personId: row.personId},
init:function(div){
$("#newInitPassword",div).parent().addClass("input-group");
$("<span class='input-group-addon btn btn-default' id='randomPsw'>获取随机密码</span>").insertAfter("#newInitPassword");
$('#randomPsw').on("click",function(){
Public.ajax(
web_app.name + '/org/generateRandomPassword.ajax',
{},
function(data){
$('#newInitPassword').val(data);
pswStrength(data)
},
function(){
}
)
});
},
ok:doInitPasswordWord,
close:true
})
}
var action = "/org/initPassword.ajax";
var params = {};
params.personId = row.personId;
Public.ajax(web_app.name + action, params, function () { });
function doInitPasswordWord(){
var _this = this;
var _form=$('#submitInitPasswordForm');
var chPattern = /^[A-Za-z0-9\~\!\@\#\$\%\^\&\*\(\)\_\+\`\-\=\[\]\{\}\\\;\'\:\"\,\.\/\<\>\?]*$/;
var newPassword = $.trim($('input[name="newInitPassword"]',_form).val());
if (newPassword == "") {
Public.tip('初始化密码不能空。');
return;
}
if(!chPattern.test(newPassword)){
Public.tip('输入的密码不合法。');
return;
}
if (newPassword.length < 6) {
Public.tip('密码长度应大于等于6位。');
return;
}
if (newPassword.length > 16) {
Public.tip('密码长度应小于16位。');
return;
}
_form.ajaxSubmit({
url: web_app.name + "/org/initPassword.ajax",
param: {newPsw: $.base64.btoa(newPassword)},
success: function () {
_this.close();
}
});
}
function showInsertPersonDialog() {
......
$(function(){
initPasswordEvent();
});
function initPasswordEvent(){
var input=$('input[name="newInitPassword"]',$('#submitInitPasswordForm'));
input.bind('blur',function(){
pswStrength($(this).val());
}).bind('keyup',function(){
pswStrength($(this).val());
});
}
//测试某个字符是属于哪一类.
function charMode(iN) {
if (iN >= 48 && iN <= 57) //数字
return 1;
if (iN >= 65 && iN <= 90) //大写字母
return 2;
if (iN >= 97 && iN <= 122) //小写
return 4;
else return 8; //特殊字符
}
//计算出当前密码当中一共有多少种模式
function bitTotal(num) {
var modes = 0;
for (var i = 0; i < 4; i++) {
if (num & 1) modes++;
num >>>= 1;
}
return modes;
}
//返回密码的强度级别
function checkStrong(psw) {
if (psw.length <= 3) return 0; //密码太短
var modes = 0;
for (var i = 0; i < psw.length; i++) {
//测试每一个字符的类别并统计一共有多少种模式.
modes |= charMode(psw.charCodeAt(i));
}
return bitTotal(modes);
}
//当用户放开键盘或密码输入框失去焦点时,根据不同的级别显示不同的颜色
function pswStrength(pwd) {
var o_color = "#e0f0ff",l_color = "#FF0000",m_color = "#FF9900",h_color = "#33CC00";
if (Public.isBlank(pwd)) {
$.each([1,2,3],function(i,o){
$('#passwordStrength'+o).css({backgroundColor:o_color});
});
return;
} else {
var level = checkStrong(pwd);
switch (level) {
case 0:
case 1:
$('#passwordStrength1').css({backgroundColor:l_color});
$('#passwordStrength2').css({backgroundColor:o_color});
$('#passwordStrength3').css({backgroundColor:o_color});
break;
case 2:
$('#passwordStrength1').css({backgroundColor:o_color});
$('#passwordStrength2').css({backgroundColor:m_color});
$('#passwordStrength3').css({backgroundColor:o_color});
break;
default:
$('#passwordStrength1').css({backgroundColor:o_color});
$('#passwordStrength2').css({backgroundColor:o_color});
$('#passwordStrength3').css({backgroundColor:h_color});
}
}
return;
}
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@taglib uri="/WEB-INF/taglib.tld" prefix="x"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<x:script src='/lib/jquery/jquery.base64.js'/>
<x:script src='/system/opm/organization/OrgInitPasswordDetail.js'/>
<form class='hg-form' method="post" action="" id="submitInitPasswordForm">
<x:hidden name="id" />
<x:hidden name="personId" />
<x:inputC name="newInitPassword" required="true" label="密码" labelCol="2" fieldCol="10" maxLength="16"/>
<div class="col-xs-12 col-md-12" style="text-align: center;">
<span class='password-strength' id='passwordStrength1'><x:message key="user.password.weak"/></span>&nbsp;
<span class='password-strength' id='passwordStrength2'><x:message key="user.password.middling"/></span>&nbsp;
<span class='password-strength' id='passwordStrength3'><x:message key="user.password.strong"/></span>&nbsp;
</div>
</form>
<div style="width:700px;margin:0 auto;">
<p>亲爱的${person.name},您好</p>
<p>&emsp;&emsp;管理员已将您的密码重置为新的密码:<span style="font-size: 20px;color: red">${newPsw}</span></p>
<p>&emsp;&emsp;在您下次登录后,为了方便个人账号的管理,还请修改成自己的密码。</p>
<div style="padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;">
<p>此为系统邮件,请勿回复。<br>
请保管好您的邮箱,避免账号被他人盗用。
</p>
<p style="font-size: 8px">© 腾燊嘉诚(上海)信息科技股份有限公司</p>
</div>
</div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment