qingwu 5 månader sedan
förälder
incheckning
fcb0370e9b

+ 198 - 0
src/com/kingdee/eas/custom/beisen/recruitment/utils/BeisenTokenManager.java

@@ -0,0 +1,198 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import okhttp3.*;
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class BeisenTokenManager {
+    private static final Logger logger = Logger.getLogger(BeisenTokenManager.class);
+    private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");
+    private static final long EXPIRY_BUFFER = 300_000; // 5分钟缓冲时间
+
+    private final OkHttpClient httpClient;
+    private final Lock lock = new ReentrantLock();
+    private volatile TokenState tokenState;
+
+    private final String appKey;
+    private final String appSecret;
+    private final String tokenUrl;
+
+    // 添加单例实例
+    private static volatile BeisenTokenManager instance;
+
+    // 私有化构造器
+    private BeisenTokenManager() {
+        this(Config.APP_KEY, Config.APP_SECRET, Config.TOKEN_URL);
+    }
+
+
+    // 获取单例方法
+    public static BeisenTokenManager getInstance() {
+        if (instance == null) {
+            synchronized (BeisenTokenManager.class) {
+                if (instance == null) {
+                    instance = new BeisenTokenManager();
+                }
+            }
+        }
+        return instance;
+    }
+
+    public BeisenTokenManager(String appKey, String appSecret, String tokenUrl) {
+        this.appKey = appKey;
+        this.appSecret = appSecret;
+        this.tokenUrl = tokenUrl;
+        this.httpClient = buildHttpClient();
+        this.tokenState = loadInitialToken();
+    }
+
+    public String getAccessToken() throws IOException {
+        TokenState currentState = tokenState;
+        if (currentState != null && !isTokenExpired(currentState)) {
+            return currentState.getAccessToken();
+        }
+
+        if (currentState == null || isTokenExpired(currentState)) {
+            lock.lock();
+            try {
+                currentState = tokenState;
+                if (currentState == null || isTokenExpired(currentState)) {
+                    currentState = fetchNewToken();
+                    tokenState = currentState;
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+        return currentState.getAccessToken();
+    }
+
+    public void refreshToken() throws IOException {
+        TokenState currentState = tokenState;
+        if (currentState == null || currentState.getRefreshToken() == null) {
+            tokenState = fetchNewToken();
+            return;
+        }
+
+        if (isTokenExpired(currentState)) {
+            lock.lock();
+            try {
+                currentState = tokenState;
+                if (isTokenExpired(currentState)) {
+                    tokenState = refreshToken(currentState.getRefreshToken());
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
+
+    private boolean isTokenExpired(TokenState state) {
+        // 添加缓冲时间,避免在token即将过期时使用
+        return System.currentTimeMillis() > (state.getExpireTime() - EXPIRY_BUFFER);
+    }
+
+    private TokenState loadInitialToken() {
+        try {
+            return fetchNewToken();
+        } catch (Exception e) {
+            logger.error("Failed to initialize token", e);
+            throw new RuntimeException("Token initialization failed", e);
+        }
+    }
+
+    private TokenState fetchNewToken() throws IOException {
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("grant_type", "client_credentials");
+        requestBody.put("app_key", appKey);
+        requestBody.put("app_secret", appSecret);
+
+        return executeTokenRequest(requestBody);
+    }
+
+    private TokenState refreshToken(String refreshToken) throws IOException {
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("grant_type", "refresh_token");
+        requestBody.put("refresh_token", refreshToken);
+
+        return executeTokenRequest(requestBody);
+    }
+
+    private TokenState executeTokenRequest(JSONObject requestBody) throws IOException {
+        Request request = new Request.Builder()
+                .url(tokenUrl)
+                .post(RequestBody.create(JSON_MEDIA_TYPE, requestBody.toJSONString()))
+                .build();
+
+        try (Response response = httpClient.newCall(request).execute()) {
+            if (!response.isSuccessful()) {
+                String errorBody = response.body() != null ? response.body().string() : "null";
+                logger.error("Token request failed. Code: " + response.code() + ", Body: " + errorBody);
+                throw new IOException("Token request failed with code: " + response.code());
+            }
+
+            String responseBody = response.body().string();
+            JSONObject jsonResponse = JSON.parseObject(responseBody);
+
+            String accessToken = jsonResponse.getString("access_token");
+            String refreshToken = jsonResponse.getString("refresh_token");
+            Long expiresIn = jsonResponse.getLong("expires_in");
+
+            // 更健壮的空值检查
+            if (accessToken == null || expiresIn == null || expiresIn <= 0) {
+                throw new IOException("Invalid token response: " + responseBody);
+            }
+
+            return new TokenState(
+                    accessToken,
+                    System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expiresIn),
+                    refreshToken
+            );
+        }
+    }
+
+    private OkHttpClient buildHttpClient() {
+        return new OkHttpClient.Builder()
+                .connectTimeout(10, TimeUnit.SECONDS)
+                .writeTimeout(10, TimeUnit.SECONDS)
+                .readTimeout(30, TimeUnit.SECONDS)
+                .retryOnConnectionFailure(true)
+                .build();
+    }
+
+    private static class TokenState {
+        private final String accessToken;
+        private final long expireTime;
+        private final String refreshToken;
+
+        public TokenState(String accessToken, long expireTime, String refreshToken) {
+            this.accessToken = accessToken;
+            this.expireTime = expireTime;
+            this.refreshToken = refreshToken;
+        }
+
+        public String getAccessToken() {
+            return accessToken;
+        }
+
+        public long getExpireTime() {
+            return expireTime;
+        }
+
+        public String getRefreshToken() {
+            return refreshToken;
+        }
+    }
+
+    public static class Config {
+        public static String APP_KEY = "6200E9EEE80C440B8342B1F8E8F0DFFE";
+        public static String APP_SECRET = "BCDF24366FBA4851AEAE2638085548B1D780130E808842049FA7FDDD6D63B18D";
+        public static String TOKEN_URL = "https://openapi.italent.cn/token";
+    }
+}

+ 302 - 0
src/com/kingdee/eas/custom/beisen/recruitment/utils/Helper.java

@@ -0,0 +1,302 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.bos.BOSException;
+import com.kingdee.bos.Context;
+import com.kingdee.bos.util.BOSUuid;
+import com.kingdee.eas.base.attachment.AttachmentFactory;
+import com.kingdee.eas.base.attachment.AttachmentInfo;
+import com.kingdee.eas.base.attachment.BoAttchAssoFactory;
+import com.kingdee.eas.base.attachment.BoAttchAssoInfo;
+import com.kingdee.eas.common.EASBizException;
+import com.kingdee.shr.attachment.AttachmentState;
+import com.kingdee.shr.attachment.AttachmentTypeEnum;
+import com.kingdee.shr.attachment.SHRAttachmentExtFactory;
+import com.kingdee.shr.attachment.SHRAttachmentExtInfo;
+import com.kingdee.shr.preentry.PreEntryPersonInfo;
+import com.kingdee.util.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+
+public class Helper {
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURL(String url, Map<String, String> header, JSONObject requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                uriBuilder.addParameter(key, value);
+            }
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            StringEntity requestEntity = new StringEntity(requestBody.toString(), "UTF-8");
+            httpPost.setEntity(requestEntity);
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURL(String url, Map<String, String> header, JSONArray requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            List paramList = new ArrayList();
+            for (int i = 0; i < requestBody.size(); i++) {
+                paramList.add(requestBody.get(i));
+            }
+            uriBuilder.addParameters(paramList);
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            StringEntity requestEntity = new StringEntity(requestBody.toString(), "UTF-8");
+            httpPost.setEntity(requestEntity);
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURLEncoded(String url, Map<String, String> header, JSONObject requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                uriBuilder.addParameter(key, value);
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            ArrayList<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                list.add(new BasicNameValuePair(key, value));
+            }
+            httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 根据文件下载地址读取字节流
+     * @param urlStr
+     * @return
+     * @throws IOException
+     */
+    public static byte[] getBytesByNetURL(String urlStr) throws IOException {
+//		RestTemplate restTemplate = new RestTemplate();
+//		ResponseEntity<byte[]> responseEntity = restTemplate.exchange(urlStr, HttpMethod.GET, null, byte[].class);
+//		byte[] fileContent = responseEntity.getBody();
+        URL url = new URL(urlStr);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+//		//设置超时时间
+        conn.setConnectTimeout(5 * 1000);
+//		//通过输入流获取图片数据
+        InputStream in = conn.getInputStream();
+//		//得到图片的二进制数据
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = in.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, len);
+        }
+        in.close();
+        return outputStream.toByteArray();
+//		return fileContent;
+    }
+
+
+    /***
+     * 保存附件
+     * @param filename
+     * @param uipk
+     * @param data
+     * @throws BOSException
+     * @throws EASBizException
+     */
+    public static void insertAttachment(Context ctx, String filename, PreEntryPersonInfo preEntryPersonInfo, String uipk, byte[] data, String userId, String attType, String qdxswz) {
+        try {
+            if (data.length > 20971520) {
+                throw new BOSException("保存附件失败,附件大小超过20MB!");
+            }
+
+            if (StringUtils.isEmpty(filename) || null == preEntryPersonInfo.getId() || data.length <= 0) {
+                throw new BOSException("保存附件失败,参数格式不正确!");
+            }
+//			IPEAttachment iPEAttachment = PEAttachmentFactory.getLocalInstance(ctx);
+//			PEAttachmentInfo peAttachmentInfo = null;
+//			PEAttachmentCollection attachmentCollection = iPEAttachment
+//					.getPEAttachmentCollection("where talent = '" + preEntryPersonInfo.getId().toString() + "'");
+//			if (null!=attachmentCollection&&attachmentCollection.size()>0) {
+//				peAttachmentInfo = attachmentCollection.get(0);
+//			} else {
+//				peAttachmentInfo = new PEAttachmentInfo();
+//				peAttachmentInfo.setTalent(preEntryPersonInfo);
+//			}
+//			iPEAttachment.save(peAttachmentInfo);
+//			String boId = peAttachmentInfo.getId().toString();
+//			//附件
+//			IAttachment iAttachment = AttachmentFactory.getLocalInstance(ctx);
+//			//附件与业务单据关联表
+//			IBoAttchAsso iBoAttchAsso = BoAttchAssoFactory.getLocalInstance(ctx);
+//			iBoAttchAsso.delete("where boID = '"+boId+"'");
+//			ISHRAttachmentExt iSHRAttachmentExt = SHRAttachmentExtFactory.getLocalInstance(ctx);
+//			iSHRAttachmentExt.delete("where boID = '"+boId+"'");
+            String boId = preEntryPersonInfo.getId().toString();
+            SHRAttachmentExtInfo attchExt = new SHRAttachmentExtInfo();
+            AttachmentInfo ai = new AttachmentInfo();
+            ai.setName(filename.substring(0, filename.lastIndexOf('.')));
+            ai.setSimpleName(filename.substring(filename.lastIndexOf(".") + 1));
+            ai.setDescription("");
+            ai.setFile(data);
+            ai.setIsShared(false);
+            ai.setSharedDesc("否");
+            ai.setAttachID("" + System.currentTimeMillis());
+            ai.setType(getFileType(filename));
+
+            attchExt.setAttachment(ai);
+            attchExt.setName(filename);
+            attchExt.setPropertyName("null0");
+            attchExt.setType(AttachmentTypeEnum.FORM);
+            attchExt.setState(AttachmentState.UNSAVE);
+            attchExt.setBunding(userId + "#" + uipk);
+            attchExt.setBoID(boId);
+            attchExt.setState(AttachmentState.SAVE);
+            AttachmentFactory.getLocalInstance(ctx).addnew(ai);
+
+            attchExt.setState(AttachmentState.SAVE);
+            BoAttchAssoInfo boAttchAssoInfo = new BoAttchAssoInfo();
+            boAttchAssoInfo.setBoID(boId);
+            boAttchAssoInfo.setAssoBusObjType(String.valueOf(BOSUuid.getBOSObjectType(boId, true)));
+            boAttchAssoInfo.setAssoType("Added Accessories");
+            boAttchAssoInfo.setAttachment(ai);
+            BoAttchAssoFactory.getLocalInstance(ctx).addnew(boAttchAssoInfo);
+
+            SHRAttachmentExtFactory.getLocalInstance(ctx).addnew(attchExt);
+        } catch (EASBizException e) {
+            e.printStackTrace();
+        } catch (BOSException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static String getFileType(String fullname) {
+        String extname = fullname.substring(fullname.lastIndexOf(".") + 1, fullname.length());
+        if (!"doc".equalsIgnoreCase(extname) && !"docx".equalsIgnoreCase(extname)) {
+            if (!"xls".equalsIgnoreCase(extname) && !"xlsx".equalsIgnoreCase(extname) && !"xlsm".equalsIgnoreCase(extname) && !"xlsb".equalsIgnoreCase(extname)) {
+                if (!"ppt".equalsIgnoreCase(extname) && !"pptx".equalsIgnoreCase(extname) && !"pptm".equalsIgnoreCase(extname)) {
+                    return "txt".equalsIgnoreCase(extname) ? "TEXT 文本文件" : "未知文件类型(." + extname + ")";
+                } else {
+                    return "Microsoft PowerPoint 幻灯片";
+                }
+            } else {
+                return "Microsoft Excel 表格";
+            }
+        } else {
+            return "Microsoft Word 文档";
+        }
+    }
+}

+ 24 - 0
src/com/kingdee/eas/custom/beisen/recruitment/utils/ItalentConfig.java

@@ -0,0 +1,24 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+public class ItalentConfig {
+
+    /**
+     * TOKEN
+     */
+    public static final String ACCESSTOKEN_URL = "https://openapi.italent.cn/token";
+    /**
+     * 根据申请ID获取申请信息
+     */
+    public static final String GET_APPLYLIST_APPLYID = "https://openapi.italent.cn/RecruitV6/api/v1/Apply/GetApplyListByApplyId";
+    /**
+     * 根据ID获取获取数据单条
+     */
+    public static final String GET_ENTITY = "https://openapi.italent.cn/dataservice/api/Data/GetEntity";
+
+    /**
+     * 根据招聘需求ID获取招聘需求
+     */
+    public static final String GET_REQUIREMENTS = "https://openapi.italent.cn/RecruitV6/api/v1/Requirement/GetRequirements";
+
+
+}

+ 112 - 0
src/com/kingdee/eas/custom/beisen/recruitment/utils/ItalentHelper.java

@@ -0,0 +1,112 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.util.StringUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+public class ItalentHelper {
+    private static Logger logger =
+            Logger.getLogger(ItalentHelper.class);
+
+    /**
+     * 获取Tokne
+     *
+     * @return
+     * @throws IOException
+     * @throws JSONException
+     * @throws URISyntaxException
+     */
+    public static String getAccessToken() throws IOException, JSONException, URISyntaxException {
+        Properties propt = new Properties();
+        propt.load(new FileInputStream(System.getProperty("EAS_HOME") + "/server/properties/gyt/italent.properties"));
+        //propt.load(new FileInputStream("E:\\Kingdee\\eas\\server\\properties\\gyt\\italent.properties"));
+        String APP_KEY = propt.getProperty("APP_KEY");
+        String APP_SECRET = propt.getProperty("APP_SECRET");
+        BeisenTokenManager tokenManager = new BeisenTokenManager(
+                APP_KEY,
+                APP_SECRET,
+                ItalentConfig.ACCESSTOKEN_URL
+        );
+        String accessToken = tokenManager.getAccessToken();
+        logger.error("accessToken--" + accessToken);
+        return accessToken;
+    }
+
+    /**
+     * 根据申请ID获取申请信息
+     *
+     * @param parsms
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getApplyListByApplyId(JSONObject parsms) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (null != parsms && parsms.size() > 0) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            responseJson = Helper.getURL(ItalentConfig.GET_APPLYLIST_APPLYID, header, parsms, "POST");
+        }
+        return responseJson;
+    }
+
+    /**
+     * 根据ID获取获取数据单条
+     *
+     * @param
+     * @param jobId 数据Id (必填)  职位ID
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getEntity(String jobId) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (!StringUtils.isEmpty(jobId)) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            JSONObject requestBody = new JSONObject();
+            requestBody.put("metaObjectName", "Recruitment.Job");
+            requestBody.put("id", jobId);
+            responseJson = Helper.getURL(ItalentConfig.GET_ENTITY, header, requestBody, "POST");
+        }
+        return responseJson;
+    }
+
+    /**
+     * 根据招聘需求ID获取招聘需求
+     *
+     * @param
+     * @param items 招聘需求ID集合。示例:["aac5bd43-f6f4-4587-9947-f4a8182a5ab6","882ac6a3-3145-4443-8f18-9f40ef953852"]
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getRequirements(JSONArray items) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (null != items && items.size() > 0) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            responseJson = Helper.getURL(ItalentConfig.GET_REQUIREMENTS, header, items, "POST");
+        }
+        return responseJson;
+    }
+
+}

+ 198 - 0
src/com/kingdee/eas/custom/recruitment/utils/BeisenTokenManager.java

@@ -0,0 +1,198 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import okhttp3.*;
+import org.apache.log4j.Logger;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class BeisenTokenManager {
+    private static final Logger logger = Logger.getLogger(BeisenTokenManager.class);
+    private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");
+    private static final long EXPIRY_BUFFER = 300_000; // 5分钟缓冲时间
+
+    private final OkHttpClient httpClient;
+    private final Lock lock = new ReentrantLock();
+    private volatile TokenState tokenState;
+
+    private final String appKey;
+    private final String appSecret;
+    private final String tokenUrl;
+
+    // 添加单例实例
+    private static volatile BeisenTokenManager instance;
+
+    // 私有化构造器
+    private BeisenTokenManager() {
+        this(Config.APP_KEY, Config.APP_SECRET, Config.TOKEN_URL);
+    }
+
+
+    // 获取单例方法
+    public static BeisenTokenManager getInstance() {
+        if (instance == null) {
+            synchronized (BeisenTokenManager.class) {
+                if (instance == null) {
+                    instance = new BeisenTokenManager();
+                }
+            }
+        }
+        return instance;
+    }
+
+    public BeisenTokenManager(String appKey, String appSecret, String tokenUrl) {
+        this.appKey = appKey;
+        this.appSecret = appSecret;
+        this.tokenUrl = tokenUrl;
+        this.httpClient = buildHttpClient();
+        this.tokenState = loadInitialToken();
+    }
+
+    public String getAccessToken() throws IOException {
+        TokenState currentState = tokenState;
+        if (currentState != null && !isTokenExpired(currentState)) {
+            return currentState.getAccessToken();
+        }
+
+        if (currentState == null || isTokenExpired(currentState)) {
+            lock.lock();
+            try {
+                currentState = tokenState;
+                if (currentState == null || isTokenExpired(currentState)) {
+                    currentState = fetchNewToken();
+                    tokenState = currentState;
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+        return currentState.getAccessToken();
+    }
+
+    public void refreshToken() throws IOException {
+        TokenState currentState = tokenState;
+        if (currentState == null || currentState.getRefreshToken() == null) {
+            tokenState = fetchNewToken();
+            return;
+        }
+
+        if (isTokenExpired(currentState)) {
+            lock.lock();
+            try {
+                currentState = tokenState;
+                if (isTokenExpired(currentState)) {
+                    tokenState = refreshToken(currentState.getRefreshToken());
+                }
+            } finally {
+                lock.unlock();
+            }
+        }
+    }
+
+    private boolean isTokenExpired(TokenState state) {
+        // 添加缓冲时间,避免在token即将过期时使用
+        return System.currentTimeMillis() > (state.getExpireTime() - EXPIRY_BUFFER);
+    }
+
+    private TokenState loadInitialToken() {
+        try {
+            return fetchNewToken();
+        } catch (Exception e) {
+            logger.error("Failed to initialize token", e);
+            throw new RuntimeException("Token initialization failed", e);
+        }
+    }
+
+    private TokenState fetchNewToken() throws IOException {
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("grant_type", "client_credentials");
+        requestBody.put("app_key", appKey);
+        requestBody.put("app_secret", appSecret);
+
+        return executeTokenRequest(requestBody);
+    }
+
+    private TokenState refreshToken(String refreshToken) throws IOException {
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("grant_type", "refresh_token");
+        requestBody.put("refresh_token", refreshToken);
+
+        return executeTokenRequest(requestBody);
+    }
+
+    private TokenState executeTokenRequest(JSONObject requestBody) throws IOException {
+        Request request = new Request.Builder()
+                .url(tokenUrl)
+                .post(RequestBody.create(JSON_MEDIA_TYPE, requestBody.toJSONString()))
+                .build();
+
+        try (Response response = httpClient.newCall(request).execute()) {
+            if (!response.isSuccessful()) {
+                String errorBody = response.body() != null ? response.body().string() : "null";
+                logger.error("Token request failed. Code: " + response.code() + ", Body: " + errorBody);
+                throw new IOException("Token request failed with code: " + response.code());
+            }
+
+            String responseBody = response.body().string();
+            JSONObject jsonResponse = JSON.parseObject(responseBody);
+
+            String accessToken = jsonResponse.getString("access_token");
+            String refreshToken = jsonResponse.getString("refresh_token");
+            Long expiresIn = jsonResponse.getLong("expires_in");
+
+            // 更健壮的空值检查
+            if (accessToken == null || expiresIn == null || expiresIn <= 0) {
+                throw new IOException("Invalid token response: " + responseBody);
+            }
+
+            return new TokenState(
+                    accessToken,
+                    System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expiresIn),
+                    refreshToken
+            );
+        }
+    }
+
+    private OkHttpClient buildHttpClient() {
+        return new OkHttpClient.Builder()
+                .connectTimeout(10, TimeUnit.SECONDS)
+                .writeTimeout(10, TimeUnit.SECONDS)
+                .readTimeout(30, TimeUnit.SECONDS)
+                .retryOnConnectionFailure(true)
+                .build();
+    }
+
+    private static class TokenState {
+        private final String accessToken;
+        private final long expireTime;
+        private final String refreshToken;
+
+        public TokenState(String accessToken, long expireTime, String refreshToken) {
+            this.accessToken = accessToken;
+            this.expireTime = expireTime;
+            this.refreshToken = refreshToken;
+        }
+
+        public String getAccessToken() {
+            return accessToken;
+        }
+
+        public long getExpireTime() {
+            return expireTime;
+        }
+
+        public String getRefreshToken() {
+            return refreshToken;
+        }
+    }
+
+    public static class Config {
+        public static String APP_KEY = "6200E9EEE80C440B8342B1F8E8F0DFFE";
+        public static String APP_SECRET = "BCDF24366FBA4851AEAE2638085548B1D780130E808842049FA7FDDD6D63B18D";
+        public static String TOKEN_URL = "https://openapi.italent.cn/token";
+    }
+}

+ 302 - 0
src/com/kingdee/eas/custom/recruitment/utils/Helper.java

@@ -0,0 +1,302 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.bos.BOSException;
+import com.kingdee.bos.Context;
+import com.kingdee.bos.util.BOSUuid;
+import com.kingdee.eas.base.attachment.AttachmentFactory;
+import com.kingdee.eas.base.attachment.AttachmentInfo;
+import com.kingdee.eas.base.attachment.BoAttchAssoFactory;
+import com.kingdee.eas.base.attachment.BoAttchAssoInfo;
+import com.kingdee.eas.common.EASBizException;
+import com.kingdee.shr.attachment.AttachmentState;
+import com.kingdee.shr.attachment.AttachmentTypeEnum;
+import com.kingdee.shr.attachment.SHRAttachmentExtFactory;
+import com.kingdee.shr.attachment.SHRAttachmentExtInfo;
+import com.kingdee.shr.preentry.PreEntryPersonInfo;
+import com.kingdee.util.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.json.JSONException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+
+public class Helper {
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURL(String url, Map<String, String> header, JSONObject requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                uriBuilder.addParameter(key, value);
+            }
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            StringEntity requestEntity = new StringEntity(requestBody.toString(), "UTF-8");
+            httpPost.setEntity(requestEntity);
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURL(String url, Map<String, String> header, JSONArray requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            List paramList = new ArrayList();
+            for (int i = 0; i < requestBody.size(); i++) {
+                paramList.add(requestBody.get(i));
+            }
+            uriBuilder.addParameters(paramList);
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            StringEntity requestEntity = new StringEntity(requestBody.toString(), "UTF-8");
+            httpPost.setEntity(requestEntity);
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 获取请求数据
+     * @param url
+     * @param header
+     * @param requestBody
+     * @param method "GET" OR "POST"
+     * @return
+     * @throws URISyntaxException
+     * @throws JSONException
+     * @throws IOException
+     * @throws ClientProtocolException
+     */
+    public static JSONObject getURLEncoded(String url, Map<String, String> header, JSONObject requestBody, String method) throws URISyntaxException, JSONException, ClientProtocolException, IOException {
+        JSONObject responseJson = new JSONObject();
+        HttpResponse response;
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        if ("GET".equals(method)) {
+            URIBuilder uriBuilder = new URIBuilder(url);
+            HttpGet httpGet = new HttpGet(uriBuilder.build());
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpGet.addHeader(entry.getKey(), entry.getValue());
+            }
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                uriBuilder.addParameter(key, value);
+            }
+            response = httpClient.execute(httpGet);
+        } else {
+            HttpPost httpPost = new HttpPost(url);
+            for (Entry<String, String> entry : header.entrySet()) {
+                httpPost.addHeader(entry.getKey(), entry.getValue());
+            }
+            ArrayList<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
+            Iterator it = requestBody.keySet().iterator();
+            while (it.hasNext()) {
+                String key = (String) it.next();
+                String value = requestBody.getString(key);
+                list.add(new BasicNameValuePair(key, value));
+            }
+            httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
+            response = httpClient.execute(httpPost);
+        }
+        String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+        responseJson = JSONObject.parseObject(responseBody);
+        httpClient.close();
+        return responseJson;
+    }
+
+    /***
+     * 根据文件下载地址读取字节流
+     * @param urlStr
+     * @return
+     * @throws IOException
+     */
+    public static byte[] getBytesByNetURL(String urlStr) throws IOException {
+//		RestTemplate restTemplate = new RestTemplate();
+//		ResponseEntity<byte[]> responseEntity = restTemplate.exchange(urlStr, HttpMethod.GET, null, byte[].class);
+//		byte[] fileContent = responseEntity.getBody();
+        URL url = new URL(urlStr);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+//		//设置超时时间
+        conn.setConnectTimeout(5 * 1000);
+//		//通过输入流获取图片数据
+        InputStream in = conn.getInputStream();
+//		//得到图片的二进制数据
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int len;
+        while ((len = in.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, len);
+        }
+        in.close();
+        return outputStream.toByteArray();
+//		return fileContent;
+    }
+
+
+    /***
+     * 保存附件
+     * @param filename
+     * @param uipk
+     * @param data
+     * @throws BOSException
+     * @throws EASBizException
+     */
+    public static void insertAttachment(Context ctx, String filename, PreEntryPersonInfo preEntryPersonInfo, String uipk, byte[] data, String userId, String attType, String qdxswz) {
+        try {
+            if (data.length > 20971520) {
+                throw new BOSException("保存附件失败,附件大小超过20MB!");
+            }
+
+            if (StringUtils.isEmpty(filename) || null == preEntryPersonInfo.getId() || data.length <= 0) {
+                throw new BOSException("保存附件失败,参数格式不正确!");
+            }
+//			IPEAttachment iPEAttachment = PEAttachmentFactory.getLocalInstance(ctx);
+//			PEAttachmentInfo peAttachmentInfo = null;
+//			PEAttachmentCollection attachmentCollection = iPEAttachment
+//					.getPEAttachmentCollection("where talent = '" + preEntryPersonInfo.getId().toString() + "'");
+//			if (null!=attachmentCollection&&attachmentCollection.size()>0) {
+//				peAttachmentInfo = attachmentCollection.get(0);
+//			} else {
+//				peAttachmentInfo = new PEAttachmentInfo();
+//				peAttachmentInfo.setTalent(preEntryPersonInfo);
+//			}
+//			iPEAttachment.save(peAttachmentInfo);
+//			String boId = peAttachmentInfo.getId().toString();
+//			//附件
+//			IAttachment iAttachment = AttachmentFactory.getLocalInstance(ctx);
+//			//附件与业务单据关联表
+//			IBoAttchAsso iBoAttchAsso = BoAttchAssoFactory.getLocalInstance(ctx);
+//			iBoAttchAsso.delete("where boID = '"+boId+"'");
+//			ISHRAttachmentExt iSHRAttachmentExt = SHRAttachmentExtFactory.getLocalInstance(ctx);
+//			iSHRAttachmentExt.delete("where boID = '"+boId+"'");
+            String boId = preEntryPersonInfo.getId().toString();
+            SHRAttachmentExtInfo attchExt = new SHRAttachmentExtInfo();
+            AttachmentInfo ai = new AttachmentInfo();
+            ai.setName(filename.substring(0, filename.lastIndexOf('.')));
+            ai.setSimpleName(filename.substring(filename.lastIndexOf(".") + 1));
+            ai.setDescription("");
+            ai.setFile(data);
+            ai.setIsShared(false);
+            ai.setSharedDesc("否");
+            ai.setAttachID("" + System.currentTimeMillis());
+            ai.setType(getFileType(filename));
+
+            attchExt.setAttachment(ai);
+            attchExt.setName(filename);
+            attchExt.setPropertyName("null0");
+            attchExt.setType(AttachmentTypeEnum.FORM);
+            attchExt.setState(AttachmentState.UNSAVE);
+            attchExt.setBunding(userId + "#" + uipk);
+            attchExt.setBoID(boId);
+            attchExt.setState(AttachmentState.SAVE);
+            AttachmentFactory.getLocalInstance(ctx).addnew(ai);
+
+            attchExt.setState(AttachmentState.SAVE);
+            BoAttchAssoInfo boAttchAssoInfo = new BoAttchAssoInfo();
+            boAttchAssoInfo.setBoID(boId);
+            boAttchAssoInfo.setAssoBusObjType(String.valueOf(BOSUuid.getBOSObjectType(boId, true)));
+            boAttchAssoInfo.setAssoType("Added Accessories");
+            boAttchAssoInfo.setAttachment(ai);
+            BoAttchAssoFactory.getLocalInstance(ctx).addnew(boAttchAssoInfo);
+
+            SHRAttachmentExtFactory.getLocalInstance(ctx).addnew(attchExt);
+        } catch (EASBizException e) {
+            e.printStackTrace();
+        } catch (BOSException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static String getFileType(String fullname) {
+        String extname = fullname.substring(fullname.lastIndexOf(".") + 1, fullname.length());
+        if (!"doc".equalsIgnoreCase(extname) && !"docx".equalsIgnoreCase(extname)) {
+            if (!"xls".equalsIgnoreCase(extname) && !"xlsx".equalsIgnoreCase(extname) && !"xlsm".equalsIgnoreCase(extname) && !"xlsb".equalsIgnoreCase(extname)) {
+                if (!"ppt".equalsIgnoreCase(extname) && !"pptx".equalsIgnoreCase(extname) && !"pptm".equalsIgnoreCase(extname)) {
+                    return "txt".equalsIgnoreCase(extname) ? "TEXT 文本文件" : "未知文件类型(." + extname + ")";
+                } else {
+                    return "Microsoft PowerPoint 幻灯片";
+                }
+            } else {
+                return "Microsoft Excel 表格";
+            }
+        } else {
+            return "Microsoft Word 文档";
+        }
+    }
+}

+ 24 - 0
src/com/kingdee/eas/custom/recruitment/utils/ItalentConfig.java

@@ -0,0 +1,24 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+public class ItalentConfig {
+
+    /**
+     * TOKEN
+     */
+    public static final String ACCESSTOKEN_URL = "https://openapi.italent.cn/token";
+    /**
+     * 根据申请ID获取申请信息
+     */
+    public static final String GET_APPLYLIST_APPLYID = "https://openapi.italent.cn/RecruitV6/api/v1/Apply/GetApplyListByApplyId";
+    /**
+     * 根据ID获取获取数据单条
+     */
+    public static final String GET_ENTITY = "https://openapi.italent.cn/dataservice/api/Data/GetEntity";
+
+    /**
+     * 根据招聘需求ID获取招聘需求
+     */
+    public static final String GET_REQUIREMENTS = "https://openapi.italent.cn/RecruitV6/api/v1/Requirement/GetRequirements";
+
+
+}

+ 112 - 0
src/com/kingdee/eas/custom/recruitment/utils/ItalentHelper.java

@@ -0,0 +1,112 @@
+package com.kingdee.eas.custom.beisen.recruitment.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.kingdee.util.StringUtils;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+public class ItalentHelper {
+    private static Logger logger =
+            Logger.getLogger(ItalentHelper.class);
+
+    /**
+     * 获取Tokne
+     *
+     * @return
+     * @throws IOException
+     * @throws JSONException
+     * @throws URISyntaxException
+     */
+    public static String getAccessToken() throws IOException, JSONException, URISyntaxException {
+        Properties propt = new Properties();
+        propt.load(new FileInputStream(System.getProperty("EAS_HOME") + "/server/properties/gyt/italent.properties"));
+        //propt.load(new FileInputStream("E:\\Kingdee\\eas\\server\\properties\\gyt\\italent.properties"));
+        String APP_KEY = propt.getProperty("APP_KEY");
+        String APP_SECRET = propt.getProperty("APP_SECRET");
+        BeisenTokenManager tokenManager = new BeisenTokenManager(
+                APP_KEY,
+                APP_SECRET,
+                ItalentConfig.ACCESSTOKEN_URL
+        );
+        String accessToken = tokenManager.getAccessToken();
+        logger.error("accessToken--" + accessToken);
+        return accessToken;
+    }
+
+    /**
+     * 根据申请ID获取申请信息
+     *
+     * @param parsms
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getApplyListByApplyId(JSONObject parsms) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (null != parsms && parsms.size() > 0) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            responseJson = Helper.getURL(ItalentConfig.GET_APPLYLIST_APPLYID, header, parsms, "POST");
+        }
+        return responseJson;
+    }
+
+    /**
+     * 根据ID获取获取数据单条
+     *
+     * @param
+     * @param jobId 数据Id (必填)  职位ID
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getEntity(String jobId) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (!StringUtils.isEmpty(jobId)) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            JSONObject requestBody = new JSONObject();
+            requestBody.put("metaObjectName", "Recruitment.Job");
+            requestBody.put("id", jobId);
+            responseJson = Helper.getURL(ItalentConfig.GET_ENTITY, header, requestBody, "POST");
+        }
+        return responseJson;
+    }
+
+    /**
+     * 根据招聘需求ID获取招聘需求
+     *
+     * @param
+     * @param items 招聘需求ID集合。示例:["aac5bd43-f6f4-4587-9947-f4a8182a5ab6","882ac6a3-3145-4443-8f18-9f40ef953852"]
+     * @return
+     * @throws JSONException
+     * @throws IOException
+     * @throws URISyntaxException
+     */
+    public static JSONObject getRequirements(JSONArray items) throws JSONException, IOException, URISyntaxException {
+        JSONObject responseJson = null;
+        String token = getAccessToken();
+        if (null != items && items.size() > 0) {
+            Map<String, String> header = new HashMap<String, String>();
+            header.put("Content-Type", "application/json");
+            header.put("Authorization", "Bearer " + token);
+            responseJson = Helper.getURL(ItalentConfig.GET_REQUIREMENTS, header, items, "POST");
+        }
+        return responseJson;
+    }
+
+}