weaver-hrm-recruit/src/com/engine/recruit/service/impl/ResumeRecognitionServiceImp...

421 lines
16 KiB
Java
Raw Normal View History

2023-12-13 17:09:46 +08:00
package com.engine.recruit.service.impl;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.core.exception.ECException;
import com.engine.core.impl.Service;
import com.engine.recruit.exception.CustomizeRunTimeException;
import com.engine.recruit.service.ResumeRecognitionService;
import com.engine.resumestorage.util.HttpUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import weaver.file.ImageFileManager;
import weaver.formmode.recruit.modeexpand.util.RecruitModeUtil;
import weaver.general.BaseBean;
import weaver.general.Util;
import java.io.File;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* @author:dxfeng
* @createTime: 2023/12/12
* @version: 1.0
*/
public class ResumeRecognitionServiceImpl extends Service implements ResumeRecognitionService {
/**
* 简历识别类型
*/
private static final String OCR_TYPE = RecruitModeUtil.getRecruitPropValue("OCR_TYPE");
@Override
public Map<String, Object> resumeUpload(Map<String, Object> param) {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("isOcr", true);
if (StringUtils.isBlank(OCR_TYPE)) {
returnMap.put("isOcr", false);
return returnMap;
}
String resumeId = Util.null2String(param.get("resumeId"));
if (StringUtils.isBlank(resumeId)) {
throw new CustomizeRunTimeException("原始简历文件获取失败");
}
// 调用千里聆服务
if ("1".equals(OCR_TYPE)) {
qllResumeUpload(Integer.parseInt(resumeId), returnMap);
}
// 调用阿里云服务
if ("2".equals(OCR_TYPE)) {
alyResumeUpload(Integer.parseInt(resumeId), returnMap);
}
return returnMap;
}
/**
* @param resumeId 简历ID
* @param returnMap 响应集合
*/
private void qllResumeUpload(int resumeId, Map<String, Object> returnMap) {
String response = doQllPost(resumeId);
if (StringUtils.isBlank(response)) {
throw new CustomizeRunTimeException("千里聆接口调用失败,响应结果为空");
}
JSONObject all = JSONObject.parseObject(response);
if (!all.getBoolean("isSuccess")) {
throw new CustomizeRunTimeException("千里聆接口调用失败,接口不通");
}
JSONObject resultall = all.getJSONObject("data");
String status = resultall.getString("state");
if ("fail".equals(status)) {
throw new CustomizeRunTimeException("调用千里聆接口失败,失败原因:" + resultall.getString("info"));
}
JSONObject result = resultall.getJSONObject("result");
Map<String, Object> dataMap = parseQllJsonToMap(result);
returnMap.put("data", dataMap);
}
/**
* @param resumeId 简历ID
* @param returnMap 响应集合
*/
private void alyResumeUpload(int resumeId, Map<String, Object> returnMap) {
String response = doAlyPost(resumeId);
JSONObject all = JSONObject.parseObject(response);
String error_msg = all.getString("error_msg");
if (!"成功".equals(error_msg)) {
throw new CustomizeRunTimeException("阿里云简历识别失败");
}
Map<String, String> saveResume = new HashMap<>();
JSONObject cv_parse = all.getJSONObject("data").getJSONObject("cv_parse");
saveResume.putAll(buildBasicInfo(cv_parse.getJSONObject("basic_info")));
saveResume.putAll(buildEducations(this.getJsonArrayFirstIfPresent(cv_parse.getJSONArray("educations"))));
saveResume.putAll(buildContact(cv_parse.getJSONObject("contact")));
saveResume.putAll(buildJobObjective(cv_parse.getJSONObject("job_objective")));
saveResume.putAll(buildOccupations(this.getJsonArrayFirstIfPresent(cv_parse.getJSONArray("occupations"))));
returnMap.put("data", saveResume);
}
private Map<String, Object> parseQllJsonToMap(JSONObject obj) {
Map<String, Object> dataMap = new HashMap<>();
// 姓名
String xm = parseArray(obj.getJSONArray("姓名"));
dataMap.put("xm", parseInputObject(xm));
// 电子邮箱
String dzyx = parseArray(obj.getJSONArray("电子邮箱"));
dataMap.put("dzyx", parseInputObject(dzyx));
// 手机号码
String sjhm = parseArray(obj.getJSONArray("手机号"));
dataMap.put("sjhm", parseInputObject(sjhm));
// 年龄
String nl = parseArray(obj.getJSONArray("年龄"));
dataMap.put("nl", parseInputObject(nl));
// 出生日期
String csrq = parseArray(obj.getJSONArray("出生日期"));
dataMap.put("csrq", parseDateObject(csrq));
// 民族
// 性别
String xb = "".equals(parseArray(obj.getJSONArray("性别"))) ? "0" : "1";
dataMap.put("xb", parseValueObject(xb));
// 体重KG
// 身高CM
// 籍贯
dataMap.put("jg", parseArray(obj.getJSONArray("籍贯")));
// 婚姻状况
// 当前所在地
dataMap.put("jzd", parseArray(obj.getJSONArray("现居住地")));
// 政治面貌
// 在职状态
// 工作经验
dataMap.put("gzjy", parseArray(obj.getJSONArray("工作经验")));
// 最高学位
dataMap.put("zgxw", parseArray(obj.getJSONArray("最高学位")));
// 最高学历
dataMap.put("zgxlwb", parseArray(obj.getJSONArray("最高学历")));
// 专业
String zy = parseArray(obj.getJSONArray("专业"));
dataMap.put("zy", parseInputObject(zy));
// 毕业院校
String byyx = parseArray(obj.getJSONArray("毕业院校"));
dataMap.put("byyx", parseInputObject(byyx));
// 期望税前月薪K
String qwxz = parseArray(obj.getJSONArray("期望薪资"));
dataMap.put("qwxz", parseInputObject(qwxz));
// 现税前月薪K
// 自我评价
String zwpj = parseArray(obj.getJSONArray("个人评价"));
dataMap.put("zwpj", parseInputObject(zwpj));
// 明细表数据
// 教育经历
// 工作经历
// 项目经验
// 语言能力
// TODO
// 当前所在地
// TODO
dataMap.put("mz", parseArray(obj.getJSONArray("民族")));
dataMap.put("wx", parseArray(obj.getJSONArray("微信")));
dataMap.put("qq", parseArray(obj.getJSONArray("QQ")));
dataMap.put("ah", parseArray(obj.getJSONArray("爱好")));
dataMap.put("bysj", parseArray(obj.getJSONArray("毕业时间")));
dataMap.put("zyjn", parseArray(obj.getJSONArray("专业技能")));
dataMap.put("sxjl", parseArray(obj.getJSONArray("实习经历")));
dataMap.put("yysp", parseArray(obj.getJSONArray("英语水平")));
dataMap.put("jnzs", parseArray(obj.getJSONArray("技能证书")));
dataMap.put("xyjl", parseArray(obj.getJSONArray("校园经历")));
dataMap.put("gzxg", parseArray(obj.getJSONArray("工作信息")));
dataMap.put("qwcsgw", parseArray(obj.getJSONArray("期望从事岗位")));
dataMap.put("qwgzdd", parseArray(obj.getJSONArray("期望工作地点")));
dataMap.put("xmjl", parseArray(obj.getJSONArray("项目经历")));
dataMap.put("xyxg", parseArray(obj.getJSONArray("学业信息")));
return dataMap;
}
private Map<String, String> buildBasicInfo(JSONObject basicInfo) {
Map<String, String> basic = new HashMap();
if (basicInfo.containsKey("name")) {
String jzd;
basic.put("xm", Util.null2String(basicInfo.getString("name")));
basic.put("nl", Util.null2String(basicInfo.getInteger("age")));
if ("".equals(Util.null2String(basicInfo.getString("gender")))) {
basic.put("xb", "0");
} else if ("".equals(Util.null2String(basicInfo.getString("gender")))) {
basic.put("xb", "1");
}
jzd = basicInfo.getJSONObject("location").getString("province") + basicInfo.getJSONObject("location").getString("city");
basic.put("jzd", Util.null2String(jzd));
}
return basic;
}
private Map<String, String> buildEducations(JSONObject educations) {
Map<String, String> major = new HashMap<>();
if (educations != null) {
if (educations.containsKey("major")) {
major.put("sxzy", Util.null2String(educations.getString("major")));
}
}
return major;
}
private Map<String, String> buildContact(JSONObject contact) {
Map<String, String> mobile = new HashMap();
if (contact.containsKey("mobile")) {
mobile.put("wx", Util.null2String(contact.getString("mobile")));
mobile.put("sjhm", Util.null2String(contact.getString("mobile")));
mobile.put("qq", Util.null2String(contact.getString("qq")));
mobile.put("email", Util.null2String(contact.getString("email")));
}
return mobile;
}
private Map<String, String> buildJobObjective(JSONObject job_objective) {
Map<String, String> expect_salary = new HashMap();
if (job_objective != null) {
if (job_objective.containsKey("expect_salary")) {
expect_salary.put("qwxz", Util.null2String(job_objective.getString("expect_salary")));
}
}
return expect_salary;
}
private Map<String, String> buildOccupations(JSONObject occupations) {
Map<String, String> company = new HashMap();
if (occupations != null) {
if (occupations.containsKey("company")) {
company.put("gs", Util.null2String(occupations.getString("expect_salary")));
}
}
return company;
}
private JSONObject getJsonArrayFirstIfPresent(JSONArray jsonArray) {
return jsonArray.size() > 0 ? jsonArray.getJSONObject(0) : null;
}
/**
* @param resumeId
* @return
*/
private String doQllPost(int resumeId) {
BaseBean bean = new BaseBean();
String url = bean.getPropValue("resume_qianliling", "qianlilingurl");
String appId = bean.getPropValue("resume_qianliling", "appId");
String appSecret = bean.getPropValue("resume_qianliling", "appSecret");
long currentTime = System.currentTimeMillis();
ImageFileManager manager = new ImageFileManager();
manager.getImageFileInfoById(resumeId);
HttpPost postRequest = new HttpPost(url);
postRequest.addHeader("sign", getSign(appId, appSecret, currentTime));
postRequest.addHeader("appId", appId);
postRequest.addHeader("timestamp", String.valueOf(currentTime));
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// TODO
builder.addTextBody("type", "pdf");
builder.addBinaryBody("resume", manager.getInputStream(), ContentType.APPLICATION_OCTET_STREAM, manager.getImageFileName());
HttpEntity entity = builder.build();
postRequest.setEntity(entity);
try {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(postRequest);
HttpEntity responseEntity = response.getEntity();
return EntityUtils.toString(responseEntity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @param resumeId
* @return
*/
private String doAlyPost(int resumeId) {
try {
BaseBean bean = new BaseBean();
String PARSE_HOST = bean.getPropValue("youyun", "host");
String PATH = bean.getPropValue("youyun", "path");
String METHOD = bean.getPropValue("youyun", "method");
String APPCODE = bean.getPropValue("youyun", "appcode");
ImageFileManager manager = new ImageFileManager();
manager.getImageFileInfoById(resumeId);
String filePath = manager.getFileRealPath();
File file = new File(filePath);
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "APPCODE " + APPCODE);
headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
Map<String, String> queryMap = new HashMap<>();
Map<String, String> bodyMap = new HashMap<>();
byte[] bytes = FileUtils.readFileToByteArray(file);
String base64 = Base64.encodeBase64String(bytes);
bodyMap.put("content", base64);
bodyMap.put("ext", "doc");
HttpResponse response = HttpUtils.doPost(PARSE_HOST, PATH, METHOD, headers, queryMap, bodyMap);
return EntityUtils.toString(response.getEntity());
} catch (Exception var10) {
throw new ECException("简历解析失败!详情:" + var10.getMessage());
}
}
/**
* 千里聆签名
*
* @param appId 开发者AppId
* @param appSecret 开发者appSecret
* @param timestamp 当前时间戳(毫秒数)
* @return
*/
private static String getSign(String appId, String appSecret, long timestamp) {
if (appId != null && appId.length() != 0) {
if (appSecret != null && appSecret.length() != 0) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(appId.getBytes());
md5.update((timestamp + "").getBytes());
md5.update(appSecret.getBytes());
byte[] bytes = md5.digest();
return (new BigInteger(1, bytes)).toString(16);
} catch (NoSuchAlgorithmException var8) {
throw new CustomizeRunTimeException("不支持的加密算法", var8);
}
} else {
throw new CustomizeRunTimeException("appSecret不能为空");
}
} else {
throw new CustomizeRunTimeException("appId不能为空");
}
}
/**
* 文本转换
*
* @param ar
* @return
*/
private String parseArray(JSONArray ar) {
StringBuilder rs = new StringBuilder();
if (ar != null && ar.size() > 0) {
for (int i = 0; i < ar.size(); ++i) {
if (i == ar.size() - 1) {
rs.append(ar.get(i));
} else {
rs.append(ar.get(i)).append(",");
}
}
}
return rs.toString();
}
/**
* 转换文本对象
*
* @param value
* @return
*/
private String parseInputObject(String value) {
return value;
// return "{value: \"" + value + "\",showhtml: \"" + value + "\"}";
}
private String parseValueObject(String value) {
return value;
// return "{value: \"" + value + "\"}";
}
/**
* 转换日期对象
*
* @param value
* @return
*/
private String parseDateObject(String value) {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
try {
sdf.parse(value);
} catch (ParseException e) {
value = "";
}
return parseInputObject(value);
}
}