|
@@ -1,8 +1,16 @@
|
|
|
-package com.citu.module.menduner.system.util;
|
|
|
+package com.citu.module.menduner.system.service.resume;
|
|
|
|
|
|
import cn.hutool.core.codec.Base64;
|
|
|
+import cn.hutool.http.HttpRequest;
|
|
|
+import cn.hutool.http.HttpResponse;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.citu.framework.common.pojo.CommonResult;
|
|
|
+import com.citu.module.menduner.system.controller.base.resume.resumesdk.TemResumeResVo;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
|
import javax.crypto.Mac;
|
|
|
import javax.crypto.spec.SecretKeySpec;
|
|
@@ -19,144 +27,118 @@ import java.security.NoSuchAlgorithmException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
|
|
|
-public class TenUtil {
|
|
|
+@Service
|
|
|
+public class TenResumeServiceImpl implements TenResumeService {
|
|
|
|
|
|
- private static final Logger log = LoggerFactory.getLogger(TenUtil.class);
|
|
|
- // url参数拼接
|
|
|
- private static String url = "https://service-9wsy8usn-1302482110.bj.apigw.tencentcs.com/release/ResumeParser";
|
|
|
+ private final Logger log = LoggerFactory.getLogger(TenResumeServiceImpl.class);
|
|
|
|
|
|
- public static String calcAuthorization(String source, String secretId, String secretKey, String datetime)
|
|
|
- throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
|
|
|
- String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
|
|
|
- Mac mac = Mac.getInstance("HmacSHA1");
|
|
|
- Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
|
|
|
- mac.init(sKey);
|
|
|
- byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
|
|
|
- String sig = new Base64().encode(hash);
|
|
|
+ @Value("${ten.resume.secretid:AKID9zQ0cC08nOPi3R8iWSXHPn4n01HZoawovA0}")
|
|
|
+ private String tenResumeSecretId;
|
|
|
|
|
|
- String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
|
|
|
- return auth;
|
|
|
- }
|
|
|
|
|
|
- public static String urlencode(Map<?, ?> map) throws UnsupportedEncodingException {
|
|
|
- StringBuilder sb = new StringBuilder();
|
|
|
- for (Map.Entry<?, ?> entry : map.entrySet()) {
|
|
|
- if (sb.length() > 0) {
|
|
|
- sb.append("&");
|
|
|
- }
|
|
|
- sb.append(String.format("%s=%s",
|
|
|
- URLEncoder.encode(entry.getKey().toString(), "UTF-8"),
|
|
|
- URLEncoder.encode(entry.getValue().toString(), "UTF-8")
|
|
|
- ));
|
|
|
+ @Value("${ten.resume.secretkey:HlKf8e7sDtBbm1Am05r0628y2SUYC5LxEz57odxY}")
|
|
|
+ private String tenResumeSecretKey;
|
|
|
+
|
|
|
+ @Value("${ten.resume.url:https://service-9wsy8usn-1302482110.bj.apigw.tencentcs.com/release/ResumeParser}")
|
|
|
+ private String resumeReqUrl;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public CommonResult<TemResumeResVo> tenResumeService(String fileName, String fileContent) {
|
|
|
+ try {
|
|
|
+ TemResumeResVo resume = resume(fileName, fileContent, 1, 1, 1);
|
|
|
+ return CommonResult.success(resume);
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("tenResumeService error:{}",e.getMessage());
|
|
|
+ throw new RuntimeException("简历解析异常!");
|
|
|
}
|
|
|
- return sb.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param secretId 云市场分配的密钥Id
|
|
|
- * @param secretKey 云市场分配的密钥Key
|
|
|
- * @param fileName 简历文件名。请务必带上正确的文件后缀名,否则部分简历可能解析失败。
|
|
|
- * @param fileCount 简历文件内容(以base64编码),其中:
|
|
|
- * 1)图片简历:based64编码后大小不超过8M,最短边至少100px,支持jpg/jpeg/png/bmp/tif/gif格式。
|
|
|
- * 图片越大OCR超时风险越高,建议大小不超过4M、长宽比小于4、分辨率600*800以上;
|
|
|
- * 2)非图片简历:based64编码后大小不超过10M(注:阿里云接口是不超过8M);
|
|
|
- * @param needAvatar 是否需要解析头像,0为不需要,1为需要,默认为0。(注:解析头像会增加1倍左右耗时,如不需头像建议不开启)
|
|
|
+ *
|
|
|
+ * @param fileName 简历文件名。请务必带上正确的文件后缀名,否则部分简历可能解析失败。
|
|
|
+ * @param fileCount 简历文件内容(以base64编码),其中:
|
|
|
+ * 1)图片简历:based64编码后大小不超过8M,最短边至少100px,支持jpg/jpeg/png/bmp/tif/gif格式。
|
|
|
+ * 图片越大OCR超时风险越高,建议大小不超过4M、长宽比小于4、分辨率600*800以上;
|
|
|
+ * 2)非图片简历:based64编码后大小不超过10M(注:阿里云接口是不超过8M);
|
|
|
+ * @param needAvatar 是否需要解析头像,0为不需要,1为需要,默认为0。(注:解析头像会增加1倍左右耗时,如不需头像建议不开启)
|
|
|
* @param needSocialExp 是否需要解析实践经历,0为不需要,1为需要,默认为0:
|
|
|
* 1)若需要解析,则对“社会实践”及“在校活动”文本进行解析,解析结果放置在social_exp_objs字段中
|
|
|
- * @param version 接口版本,当前取值为0和1,默认为0:
|
|
|
- * 1)version=0:仅当字段在简历中有出现,才会在json结果中返回;
|
|
|
- * 2)version=1:不管字段在简历中有无出现,均在json结果中返回,若无出现则该字段取值为空;
|
|
|
+ * @param version 接口版本,当前取值为0和1,默认为0:
|
|
|
+ * 1)version=0:仅当字段在简历中有出现,才会在json结果中返回;
|
|
|
+ * 2)version=1:不管字段在简历中有无出现,均在json结果中返回,若无出现则该字段取值为空;
|
|
|
* @return
|
|
|
* @throws NoSuchAlgorithmException
|
|
|
* @throws UnsupportedEncodingException
|
|
|
* @throws InvalidKeyException
|
|
|
*/
|
|
|
- public static String resume(String secretId, String secretKey, String fileName, String fileCount, Integer needAvatar
|
|
|
- , Integer needSocialExp, Integer version) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
|
|
|
+ public TemResumeResVo resume(String fileName,String fileCount,Integer needAvatar
|
|
|
+ ,Integer needSocialExp,Integer version) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
|
|
|
|
|
|
+ String url = resumeReqUrl;
|
|
|
String source = "market";
|
|
|
Calendar cd = Calendar.getInstance();
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
|
|
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
String datetime = sdf.format(cd.getTime());
|
|
|
|
|
|
- // 请求方法
|
|
|
- String method = "POST";
|
|
|
- // 请求头
|
|
|
- Map<String, String> headers = new HashMap<String, String>();
|
|
|
- headers.put("X-Source", source);
|
|
|
- headers.put("X-Date", datetime);
|
|
|
- // 签名
|
|
|
- headers.put("Authorization", calcAuthorization(source, secretId, secretKey, datetime));
|
|
|
- headers.put("Content-Type", "application/json");
|
|
|
- // 查询参数
|
|
|
- Map<String, String> queryParams = new HashMap<String, String>();
|
|
|
-
|
|
|
// body参数
|
|
|
Map<String, String> bodyParams = new HashMap<String, String>();
|
|
|
- bodyParams.put("body", "");
|
|
|
- bodyParams.put("file_name", fileName);
|
|
|
- bodyParams.put("file_count", fileCount);
|
|
|
- bodyParams.put("need_avatar", needAvatar.toString());
|
|
|
- bodyParams.put("need_social_exp", needSocialExp.toString());
|
|
|
- bodyParams.put("version", version.toString());
|
|
|
+ bodyParams.put("body","");
|
|
|
+ bodyParams.put("file_name",fileName);
|
|
|
+ bodyParams.put("file_cont",fileCount);
|
|
|
+ bodyParams.put("need_avatar",needAvatar.toString());
|
|
|
+ bodyParams.put("need_social_exp",needSocialExp.toString());
|
|
|
+ bodyParams.put("version",version.toString());
|
|
|
+
|
|
|
+ HttpRequest post = HttpUtil.createPost(url);
|
|
|
+ post.header("X-Source", source);
|
|
|
+ post.header("X-Date", datetime);
|
|
|
+ // 签名
|
|
|
+ post.header("Authorization", calcAuthorization(source, this.tenResumeSecretId, this.tenResumeSecretKey, datetime));
|
|
|
+ post.header("Content-Type","application/json");
|
|
|
+ post.body(JSON.toJSONString(bodyParams));
|
|
|
+ HttpResponse execute = post.execute();
|
|
|
+ String body = execute.body();
|
|
|
+ log.info("parse resume res->{}",body);
|
|
|
+ System.out.println(body);
|
|
|
+ TemResumeResVo temResumeResVo = JSON.parseObject(body, TemResumeResVo.class);
|
|
|
+ if(temResumeResVo.getStatus().getCode()!=200){
|
|
|
+ throw new RuntimeException("简历解析失败");
|
|
|
+ }
|
|
|
+ return temResumeResVo;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- if (!queryParams.isEmpty()) {
|
|
|
- url += "?" + urlencode(queryParams);
|
|
|
- }
|
|
|
|
|
|
- BufferedReader in = null;
|
|
|
- try {
|
|
|
- URL realUrl = new URL(url);
|
|
|
- HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
|
|
|
- conn.setConnectTimeout(5000);
|
|
|
- conn.setReadTimeout(5000);
|
|
|
- conn.setRequestMethod(method);
|
|
|
-
|
|
|
- // request headers
|
|
|
- for (Map.Entry<String, String> entry : headers.entrySet()) {
|
|
|
- conn.setRequestProperty(entry.getKey(), entry.getValue());
|
|
|
- }
|
|
|
|
|
|
- // request body
|
|
|
- Map<String, Boolean> methods = new HashMap<>();
|
|
|
- methods.put("POST", true);
|
|
|
- methods.put("PUT", true);
|
|
|
- methods.put("PATCH", true);
|
|
|
- Boolean hasBody = methods.get(method);
|
|
|
- if (hasBody != null) {
|
|
|
- conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
|
|
- conn.setDoOutput(true);
|
|
|
- DataOutputStream out = new DataOutputStream(conn.getOutputStream());
|
|
|
- out.writeBytes(urlencode(bodyParams));
|
|
|
- out.flush();
|
|
|
- out.close();
|
|
|
- }
|
|
|
+ private String calcAuthorization(String source, String secretId, String secretKey, String datetime)
|
|
|
+ throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
|
|
|
+ String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
|
|
|
+ Mac mac = Mac.getInstance("HmacSHA1");
|
|
|
+ Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
|
|
|
+ mac.init(sKey);
|
|
|
+ byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
|
|
|
+ String sig = new Base64().encode(hash);
|
|
|
|
|
|
- // 定义 BufferedReader输入流来读取URL的响应
|
|
|
- in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
|
- String line;
|
|
|
- String result = "";
|
|
|
- while ((line = in.readLine()) != null) {
|
|
|
- result += line;
|
|
|
- }
|
|
|
+ String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
|
|
|
+ return auth;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
- } catch (Exception e) {
|
|
|
- log.error(String.valueOf(e));
|
|
|
- e.printStackTrace();
|
|
|
- return null;
|
|
|
- } finally {
|
|
|
- try {
|
|
|
- if (in != null) {
|
|
|
- in.close();
|
|
|
- }
|
|
|
- } catch (Exception e2) {
|
|
|
- e2.printStackTrace();
|
|
|
+ private String urlencode(Map<?, ?> map) throws UnsupportedEncodingException {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
|
|
|
+ if (sb.length() > 0) {
|
|
|
+ sb.append("&");
|
|
|
}
|
|
|
+ sb.append(String.format("%s=%s",
|
|
|
+ URLEncoder.encode(entry.getKey().toString(), "UTF-8"),
|
|
|
+ URLEncoder.encode(entry.getValue().toString(), "UTF-8")
|
|
|
+ ));
|
|
|
}
|
|
|
+ return sb.toString();
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
}
|