generated from dxfeng/secondev-wugang-dxfeng
入职申请 根据姓名生成公司邮箱账号
This commit is contained in:
parent
c72bbd6f4d
commit
b4835fc6a9
|
|
@ -0,0 +1,89 @@
|
|||
package com.weaver.seconddev.portal.action.entry;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.weaver.common.base.entity.result.WeaResult;
|
||||
import com.weaver.esb.api.rpc.EsbServerlessRpcRemoteInterface;
|
||||
import com.weaver.seconddev.portal.entity.param.BaseParam;
|
||||
import com.weaver.seconddev.portal.mapper.action.entry.EmailAccountGenerateMapper;
|
||||
import com.weaver.seconddev.portal.util.ChineseNameToPinyin;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author:dxfeng
|
||||
* @createTime: 2025/07/28
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("emailAccountGenerateAction")
|
||||
public class EmailAccountGenerateAction implements EsbServerlessRpcRemoteInterface {
|
||||
private static final String EMAIL_DOMAIN = "@chabaidao.com";
|
||||
|
||||
@Autowired
|
||||
EmailAccountGenerateMapper emailAccountGenerateMapper;
|
||||
|
||||
BaseParam baseParam = new BaseParam();
|
||||
|
||||
@Override
|
||||
public WeaResult<Map<String, Object>> execute(Map<String, Object> params) {
|
||||
// 获取参数
|
||||
String xm = Convert.toStr(params.get("xm"), "");
|
||||
Long requestId = Convert.toLong(params.get("requestId"));
|
||||
|
||||
if (StringUtils.isBlank(xm)) {
|
||||
return WeaResult.fail("姓名不能为空", true);
|
||||
}
|
||||
|
||||
// 生成基础邮箱账号
|
||||
String pinyinName = ChineseNameToPinyin.convertChineseNameToPinyin(xm);
|
||||
|
||||
// 检查并生成唯一邮箱账号
|
||||
String uniqueEmail = generateUniqueEmail(pinyinName, requestId);
|
||||
|
||||
Map<String, Object> dataMap = new HashMap<>();
|
||||
// 将生成的邮箱账号放入返回结果中
|
||||
dataMap.put("email", uniqueEmail);
|
||||
return WeaResult.success(dataMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一的邮箱账号
|
||||
*
|
||||
* @param pinyinName 拼音姓名
|
||||
* @return 唯一邮箱账号
|
||||
*/
|
||||
private String generateUniqueEmail(String pinyinName, Long requestId) {
|
||||
String baseEmail = pinyinName + EMAIL_DOMAIN;
|
||||
|
||||
// 首先检查基础邮箱是否已存在
|
||||
if (!isEmailExists(baseEmail,requestId)) {
|
||||
return baseEmail;
|
||||
}
|
||||
|
||||
// 如果基础邮箱已存在,则尝试添加数字后缀
|
||||
int suffix = 1;
|
||||
String emailWithSuffix;
|
||||
do {
|
||||
emailWithSuffix = pinyinName + suffix + EMAIL_DOMAIN;
|
||||
suffix++;
|
||||
} while (isEmailExists(emailWithSuffix, requestId));
|
||||
|
||||
return emailWithSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查邮箱是否已存在
|
||||
*
|
||||
* @param email 邮箱账号
|
||||
* @return 是否存在
|
||||
*/
|
||||
private boolean isEmailExists(String email, Long requestId) {
|
||||
Integer checkCount = emailAccountGenerateMapper.checkSameEmailAccount(baseParam, email, requestId);
|
||||
return checkCount != null && checkCount > 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.weaver.seconddev.portal.mapper.action.entry;
|
||||
|
||||
import com.weaver.seconddev.portal.entity.param.BaseParam;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* @author:dxfeng
|
||||
* @createTime: 2025/07/28
|
||||
* @version: 1.0
|
||||
*/
|
||||
@Mapper
|
||||
public interface EmailAccountGenerateMapper {
|
||||
|
||||
Integer checkSameEmailAccount(@Param("param") BaseParam param, @Param("email") String email, @Param("requestId") Long requestId);
|
||||
}
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
package com.weaver.seconddev.portal.util;
|
||||
|
||||
import net.sourceforge.pinyin4j.PinyinHelper;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
|
||||
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
|
||||
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 中文姓名转拼音工具类
|
||||
* 支持多音字识别、复姓处理、姓名结构分析等
|
||||
*/
|
||||
public class ChineseNameToPinyin {
|
||||
|
||||
// 拼音输出格式
|
||||
private static final HanyuPinyinOutputFormat FORMAT = new HanyuPinyinOutputFormat();
|
||||
|
||||
// 姓氏多音字映射(姓氏位置读音)
|
||||
private static final Map<String, String> SURNAME_POLYPHONE_MAP = new HashMap<>();
|
||||
|
||||
// 非姓氏多音字映射(词中/词尾读音)
|
||||
private static final Map<String, String> NON_SURNAME_POLYPHONE_MAP = new HashMap<>();
|
||||
|
||||
// 常见复姓
|
||||
private static final Set<String> COMPOUND_SURNAMES = new HashSet<>();
|
||||
|
||||
// 常见单姓
|
||||
private static final Set<String> SINGLE_SURNAMES = new HashSet<>();
|
||||
|
||||
// 常用汉字读音修正表(用于处理常见错误拼音)
|
||||
private static final Map<String, String> COMMON_CORRECTION_MAP = new HashMap<>();
|
||||
|
||||
// 缓存已处理过的姓名,提高性能
|
||||
private static final Map<String, String> NAME_CACHE = new ConcurrentHashMap<>();
|
||||
private static final int MAX_CACHE_SIZE = 10000;
|
||||
|
||||
static {
|
||||
FORMAT.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||
FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
|
||||
|
||||
// 初始化姓氏多音字映射
|
||||
initSurnamePolyphoneMap();
|
||||
|
||||
// 初始化非姓氏多音字映射
|
||||
initNonSurnamePolyphoneMap();
|
||||
|
||||
// 初始化复姓列表
|
||||
initCompoundSurnames();
|
||||
|
||||
// 初始化单姓列表
|
||||
initSingleSurnames();
|
||||
|
||||
// 初始化常用汉字读音修正表
|
||||
initCommonCorrectionMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化姓氏多音字映射
|
||||
*/
|
||||
private static void initSurnamePolyphoneMap() {
|
||||
// 姓氏中的多音字(在姓氏位置的特殊读音)
|
||||
SURNAME_POLYPHONE_MAP.put("区", "ou");
|
||||
SURNAME_POLYPHONE_MAP.put("仇", "qiu");
|
||||
SURNAME_POLYPHONE_MAP.put("单", "shan");
|
||||
SURNAME_POLYPHONE_MAP.put("解", "xie");
|
||||
SURNAME_POLYPHONE_MAP.put("华", "hua");
|
||||
SURNAME_POLYPHONE_MAP.put("朴", "piao");
|
||||
SURNAME_POLYPHONE_MAP.put("曾", "zeng");
|
||||
SURNAME_POLYPHONE_MAP.put("查", "zha");
|
||||
SURNAME_POLYPHONE_MAP.put("翟", "zhai");
|
||||
SURNAME_POLYPHONE_MAP.put("尉", "yu");
|
||||
SURNAME_POLYPHONE_MAP.put("盖", "ge");
|
||||
SURNAME_POLYPHONE_MAP.put("缪", "miao");
|
||||
SURNAME_POLYPHONE_MAP.put("覃", "qin");
|
||||
SURNAME_POLYPHONE_MAP.put("宓", "mi");
|
||||
SURNAME_POLYPHONE_MAP.put("折", "she");
|
||||
SURNAME_POLYPHONE_MAP.put("繁", "po");
|
||||
SURNAME_POLYPHONE_MAP.put("员", "yun");
|
||||
SURNAME_POLYPHONE_MAP.put("召", "shao");
|
||||
SURNAME_POLYPHONE_MAP.put("隗", "kui");
|
||||
SURNAME_POLYPHONE_MAP.put("覃", "qin");
|
||||
SURNAME_POLYPHONE_MAP.put("冼", "xian");
|
||||
SURNAME_POLYPHONE_MAP.put("覃", "tan");
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化非姓氏多音字映射
|
||||
*/
|
||||
private static void initNonSurnamePolyphoneMap() {
|
||||
// 非姓氏位置的多音字读音
|
||||
NON_SURNAME_POLYPHONE_MAP.put("区", "qu");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("仇", "chou");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("单", "dan");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("解", "jie");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("华", "hua");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("朴", "pu");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("曾", "ceng");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("查", "cha");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("翟", "di");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("尉", "wei");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("盖", "gai");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("缪", "miu");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("覃", "tan");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("宓", "fu");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("折", "zhe");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("繁", "fan");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("员", "yuan");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("召", "zhao");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("隗", "wei");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("冼", "xiǎn");
|
||||
NON_SURNAME_POLYPHONE_MAP.put("覃", "qín");
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化复姓列表
|
||||
*/
|
||||
private static void initCompoundSurnames() {
|
||||
// 常见复姓(按长度排序,长的在前)
|
||||
String[] compoundSurnames = {
|
||||
"欧阳", "太史", "端木", "上官", "司马", "东方", "独孤", "南宫", "万俟", "闻人",
|
||||
"夏侯", "诸葛", "尉迟", "公羊", "赫连", "澹台", "皇甫", "宗政", "濮阳", "公冶",
|
||||
"太叔", "申屠", "公孙", "慕容", "仲孙", "钟离", "长孙", "宇文", "司徒", "鲜于",
|
||||
"司空", "闾丘", "子车", "亓官", "司寇", "巫马", "公西", "颛孙", "壤驷", "公良",
|
||||
"漆雕", "乐正", "宰父", "谷梁", "拓跋", "夹谷", "轩辕", "令狐", "段干", "百里",
|
||||
"呼延", "东郭", "南门", "羊舌", "微生", "岳父", "缑亢", "况后", "有琴", "梁丘",
|
||||
"左丘", "东门", "西门"
|
||||
};
|
||||
COMPOUND_SURNAMES.addAll(Arrays.asList(compoundSurnames));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化单姓列表
|
||||
*/
|
||||
private static void initSingleSurnames() {
|
||||
// 常见单姓(按频率排序)
|
||||
String[] singleSurnames = {
|
||||
"王", "李", "张", "刘", "陈", "杨", "赵", "黄", "周", "吴", "徐", "孙", "胡", "朱",
|
||||
"高", "林", "何", "郭", "马", "罗", "梁", "宋", "郑", "谢", "韩", "唐", "冯", "于",
|
||||
"董", "萧", "程", "曹", "袁", "邓", "许", "傅", "沉", "曾", "彭", "吕", "苏", "卢",
|
||||
"蒋", "蔡", "贾", "丁", "魏", "薛", "叶", "阎", "余", "潘", "杜", "戴", "夏", "钟",
|
||||
"汪", "田", "任", "姜", "范", "方", "石", "姚", "谭", "廖", "邹", "熊", "金", "陆",
|
||||
"郝", "孔", "白", "崔", "康", "毛", "邱", "秦", "江", "尹", "薛", "闫", "段", "雷",
|
||||
"侯", "龙", "史", "陶", "黎", "贺", "顾", "孟", "黄", "万", "段", "雷", "钱", "汤",
|
||||
"尹", "黎", "易", "常", "武", "乔", "贺", "赖", "龚", "文"
|
||||
};
|
||||
SINGLE_SURNAMES.addAll(Arrays.asList(singleSurnames));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化常用汉字读音修正表
|
||||
*/
|
||||
private static void initCommonCorrectionMap() {
|
||||
// 常见汉字读音修正
|
||||
COMMON_CORRECTION_MAP.put("茜", "qian"); // 作为名字时通常读作qian
|
||||
COMMON_CORRECTION_MAP.put("芃", "peng"); // 人名常用字
|
||||
COMMON_CORRECTION_MAP.put("喆", "zhe"); // 人名常用字
|
||||
}
|
||||
|
||||
/**
|
||||
* 将中文姓名转换为拼音(不带声调)
|
||||
*
|
||||
* @param chineseName 中文姓名
|
||||
* @return 拼音全称
|
||||
*/
|
||||
public static String convertChineseNameToPinyin(String chineseName) {
|
||||
if (chineseName == null || chineseName.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 先从缓存中查找
|
||||
String cachedResult = NAME_CACHE.get(chineseName);
|
||||
if (cachedResult != null) {
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
String result = doConvertChineseNameToPinyin(chineseName);
|
||||
|
||||
// 缓存结果(控制缓存大小)
|
||||
if (NAME_CACHE.size() < MAX_CACHE_SIZE) {
|
||||
NAME_CACHE.put(chineseName, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实际转换逻辑
|
||||
*/
|
||||
private static String doConvertChineseNameToPinyin(String chineseName) {
|
||||
StringBuilder pinyinBuilder = new StringBuilder();
|
||||
int i = 0;
|
||||
|
||||
// 首先尝试匹配复姓
|
||||
boolean surnameProcessed = false;
|
||||
if (chineseName.length() >= 2) {
|
||||
// 优先匹配3字复姓
|
||||
if (chineseName.length() >= 3) {
|
||||
String threeCharSurname = chineseName.substring(0, 3);
|
||||
if (COMPOUND_SURNAMES.contains(threeCharSurname)) {
|
||||
processSurname(pinyinBuilder, threeCharSurname);
|
||||
i = 3;
|
||||
surnameProcessed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果不是3字复姓,再匹配2字复姓
|
||||
if (!surnameProcessed) {
|
||||
String twoCharSurname = chineseName.substring(0, 2);
|
||||
if (COMPOUND_SURNAMES.contains(twoCharSurname)) {
|
||||
processSurname(pinyinBuilder, twoCharSurname);
|
||||
i = 2;
|
||||
surnameProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果不是复姓,处理单姓
|
||||
if (!surnameProcessed && chineseName.length() >= 1) {
|
||||
String firstChar = String.valueOf(chineseName.charAt(0));
|
||||
if (SINGLE_SURNAMES.contains(firstChar) || SURNAME_POLYPHONE_MAP.containsKey(firstChar)) {
|
||||
processSurname(pinyinBuilder, firstChar);
|
||||
i = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理剩余部分(名字)
|
||||
while (i < chineseName.length()) {
|
||||
char ch = chineseName.charAt(i);
|
||||
processNonSurname(pinyinBuilder, ch, i, chineseName);
|
||||
i++;
|
||||
}
|
||||
|
||||
return pinyinBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理姓氏部分
|
||||
*/
|
||||
private static void processSurname(StringBuilder pinyinBuilder, String surname) {
|
||||
for (int j = 0; j < surname.length(); j++) {
|
||||
char ch = surname.charAt(j);
|
||||
String pinyin = getPinyinWithPolyphone(ch, true, j, surname);
|
||||
pinyinBuilder.append(pinyin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理非姓氏部分
|
||||
*/
|
||||
private static void processNonSurname(StringBuilder pinyinBuilder, char ch, int position, String fullName) {
|
||||
// 处理空格等非中文字符
|
||||
if (ch == ' ') {
|
||||
pinyinBuilder.append(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理英文字母
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
pinyinBuilder.append(Character.toLowerCase(ch));
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理数字
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
pinyinBuilder.append(ch);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理中文字符
|
||||
String pinyin = getPinyinWithPolyphone(ch, false, position, fullName);
|
||||
pinyinBuilder.append(pinyin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符的拼音(考虑多音字)
|
||||
*/
|
||||
private static String getPinyinWithPolyphone(char ch, boolean isSurname, int position, String context) {
|
||||
try {
|
||||
// 首先检查常用修正表
|
||||
String correction = COMMON_CORRECTION_MAP.get(String.valueOf(ch));
|
||||
if (correction != null) {
|
||||
return correction;
|
||||
}
|
||||
|
||||
// 检查多音字映射
|
||||
if (isSurname) {
|
||||
String surnamePinyin = SURNAME_POLYPHONE_MAP.get(String.valueOf(ch));
|
||||
if (surnamePinyin != null) {
|
||||
return surnamePinyin;
|
||||
}
|
||||
} else {
|
||||
String nonSurnamePinyin = NON_SURNAME_POLYPHONE_MAP.get(String.valueOf(ch));
|
||||
if (nonSurnamePinyin != null) {
|
||||
return nonSurnamePinyin;
|
||||
}
|
||||
}
|
||||
|
||||
// 使用pinyin4j获取拼音
|
||||
String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(ch, FORMAT);
|
||||
if (pinyinArray != null && pinyinArray.length > 0) {
|
||||
return pinyinArray[0]; // 默认返回第一个拼音
|
||||
} else {
|
||||
return String.valueOf(ch); // 非中文字符返回原字符
|
||||
}
|
||||
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||
return String.valueOf(ch); // 异常情况下返回原字符
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 带分隔符的拼音转换
|
||||
*
|
||||
* @param chineseName 中文姓名
|
||||
* @param separator 分隔符
|
||||
* @return 带分隔符的拼音
|
||||
*/
|
||||
public static String convertChineseNameToPinyinWithSeparator(String chineseName, String separator) {
|
||||
String pinyin = convertChineseNameToPinyin(chineseName);
|
||||
if (pinyin.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < pinyin.length(); i++) {
|
||||
if (i > 0) {
|
||||
result.append(separator);
|
||||
}
|
||||
result.append(pinyin.charAt(i));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
public static void clearCache() {
|
||||
NAME_CACHE.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存大小
|
||||
*/
|
||||
public static int getCacheSize() {
|
||||
return NAME_CACHE.size();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.weaver.seconddev.portal.mapper.action.entry.EmailAccountGenerateMapper">
|
||||
|
||||
<select id="checkSameEmailAccount" resultType="java.lang.Integer">
|
||||
select count(t1.id) from ${param.e10_common}.uf_jcl_rzsq t1
|
||||
where t1.tenant_key = #{param.tenantKey}
|
||||
<!-- and t1.delete_type = 0-->
|
||||
and t1.email = #{email}
|
||||
<if test="requestId != null and requestId != ''">
|
||||
and t1.form_data_id != #{requestId}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue