LAPTOP-SB56SG4Q\86185
2 years ago
24 changed files with 2024 additions and 1 deletions
Binary file not shown.
@ -1,3 +1,6 @@
|
||||
# open-JSD-9377 |
||||
|
||||
JSD-9377 IAM用户数据集插件(数据集、用户集成) |
||||
JSD-9377 IAM用户数据集插件(数据集、用户集成)\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<plugin> |
||||
<id>com.fr.plugin.icgq.sso</id> |
||||
<name><![CDATA[用户同步]]></name> |
||||
<active>yes</active> |
||||
<version>1.1.8</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2018-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[用户同步]]></description> |
||||
<change-notes><![CDATA[用户同步]]></change-notes> |
||||
<main-package>com.fr.plugin.icgq</main-package> |
||||
<prefer-packages> |
||||
<prefer-package>com.fanruan.api</prefer-package> |
||||
</prefer-packages> |
||||
<lifecycle-monitor class="com.fr.plugin.icgq.PluginMonitor"/> |
||||
<extra-core> |
||||
<LocaleFinder class="com.fr.plugin.icgq.LocaleFinder"/> |
||||
</extra-core> |
||||
<extra-decision> |
||||
<HttpHandlerProvider class="com.fr.plugin.icgq.service.RequestHandlerBridge"/> |
||||
<URLAliasProvider class="com.fr.plugin.icgq.service.URLAliasBridge"/> |
||||
</extra-decision> |
||||
<extra-designer> |
||||
<TableDataDefineProvider class="com.fr.plugin.icgq.provider.UsersTableDataDefine"/> |
||||
<ServerTableDataDefineProvider class="com.fr.plugin.icgq.provider.UsersTableDataDefine"/> |
||||
</extra-designer> |
||||
<function-recorder class="com.fr.plugin.icgq.LocaleFinder"/> |
||||
</plugin> |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright (C), 2018-2020 |
||||
* Project: starter |
||||
* FileName: LocaleFinder |
||||
* Author: Louis |
||||
* Date: 2020/8/31 22:19 |
||||
*/ |
||||
package com.fr.plugin.icgq; |
||||
|
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.fun.Authorize; |
||||
import com.fr.stable.fun.impl.AbstractLocaleFinder; |
||||
|
||||
import static com.fr.plugin.icgq.LocaleFinder.PLUGIN_ID; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <LocaleFinder> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@EnableMetrics |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class LocaleFinder extends AbstractLocaleFinder { |
||||
public static final String PLUGIN_ID = "com.fr.plugin.icgq.sso"; |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = "Plugin-icgq", source = Original.PLUGIN) |
||||
public String find() { |
||||
return "com/fr/plugin/icgq/locale/lang"; |
||||
} |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: PluginMonitor |
||||
* Author: Louis |
||||
* Date: 2021/3/30 15:10 |
||||
*/ |
||||
package com.fr.plugin.icgq; |
||||
|
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.icgq.config.IcgqConfig; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
|
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <PluginMonitor> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class PluginMonitor extends AbstractPluginLifecycleMonitor { |
||||
public PluginMonitor() { |
||||
} |
||||
|
||||
@Override |
||||
public void afterRun(PluginContext pluginContext) { |
||||
IcgqConfig.getInstance(); |
||||
} |
||||
|
||||
@Override |
||||
public void beforeStop(PluginContext pluginContext) { |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: IcgqConfig |
||||
* Author: Louis |
||||
* Date: 2021/3/30 9:38 |
||||
*/ |
||||
package com.fr.plugin.icgq.config; |
||||
|
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.config.*; |
||||
import com.fr.config.holder.Conf; |
||||
import com.fr.config.holder.factory.Holders; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <IcgqConfig> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Visualization(category = "Plugin-icgq_Group") |
||||
public class IcgqConfig extends DefaultConfiguration { |
||||
private static volatile IcgqConfig config = null; |
||||
@Identifier(value = "clientId", name = "Plugin-icgq_Config_ClientId", description = "Plugin-icgq_Config_ClientId_Description", status = Status.SHOW) |
||||
private final Conf<String> clientId = Holders.simple(StringKit.EMPTY); |
||||
@Identifier(value = "clientSecret", name = "Plugin-icgq_Config_ClientSecret", description = "Plugin-icgq_Config_ClientSecret_Description", status = Status.SHOW) |
||||
private final Conf<String> clientSecret = Holders.simple(StringKit.EMPTY); |
||||
|
||||
public static IcgqConfig getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(IcgqConfig.class); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
public String getClientId() { |
||||
return clientId.get(); |
||||
} |
||||
|
||||
public void setClientId(String clientId) { |
||||
this.clientId.set(clientId); |
||||
} |
||||
|
||||
public String getClientSecret() { |
||||
return clientSecret.get(); |
||||
} |
||||
|
||||
public void setClientSecret(String clientSecret) { |
||||
this.clientSecret.set(clientSecret); |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WechatTableData |
||||
* Author: Louis |
||||
* Date: 2021/12/8 16:55 |
||||
*/ |
||||
package com.fr.plugin.icgq.data; |
||||
|
||||
import com.fanruan.api.data.open.BaseTableData; |
||||
import com.fr.base.TableData; |
||||
import com.fr.general.data.DataModel; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.xml.XMLPrintWriter; |
||||
import com.fr.stable.xml.XMLableReader; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UsersTableData> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UsersTableData extends BaseTableData { |
||||
private static final long serialVersionUID = -7456007025209900779L; |
||||
|
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator) { |
||||
return createDataModel(calculator, TableData.RESULT_ALL); |
||||
} |
||||
|
||||
@Override |
||||
public DataModel createDataModel(Calculator calculator, int rowCount) { |
||||
return new UsersTableDataModel(Calculator.processParameters(calculator, super.getParameters(calculator))); |
||||
} |
||||
|
||||
@Override |
||||
public void readXML(XMLableReader reader) { |
||||
super.readXML(reader); |
||||
} |
||||
|
||||
@Override |
||||
public void writeXML(XMLPrintWriter writer) { |
||||
super.writeXML(writer); |
||||
} |
||||
|
||||
@Override |
||||
public Object clone() throws CloneNotSupportedException { |
||||
UsersTableData cloned = (UsersTableData) super.clone(); |
||||
return cloned; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object obj) { |
||||
return obj instanceof UsersTableData; |
||||
} |
||||
} |
@ -0,0 +1,131 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WechatTableDataModel |
||||
* Author: Louis |
||||
* Date: 2021/12/8 19:09 |
||||
*/ |
||||
package com.fr.plugin.icgq.data; |
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.json.JSONArray; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.plugin.icgq.kit.HttpKit; |
||||
import com.fr.stable.ParameterProvider; |
||||
import com.fr.third.org.apache.http.entity.StringEntity; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UsersTableDataModel> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UsersTableDataModel extends WebTableDataModel { |
||||
private static final long serialVersionUID = 8191435706966886501L; |
||||
public static final String ACCOUNT_LIST = "/esc-idm/api/v1/account/list"; |
||||
public static final String APP_ACCOUNT_ACCOUNT_UUID = "app_account__account_uuid"; |
||||
public static final String APP_ACCOUNT_ACCOUNT_NO = "app_account__account_no"; |
||||
public static final String APP_ACCOUNT_ACCOUNT_NAME = "app_account__account_name"; |
||||
public static final String REQUEST_LOG_ACTION_FLAG = "request_log__action_flag"; |
||||
public static final String REQUEST_LOG_ID = "request_log__id"; |
||||
public static final String IDT_USER_USER_NAME = "idt_user__user_name"; |
||||
public static final String IDT_USER_EMAIL = "idt_user__email"; |
||||
public static final String IDT_USER_USER_EMAIL = "idt_user__user_email"; |
||||
public static final String IDT_USER_WORK_NO = "idt_user__work_no"; |
||||
public static final String IDT_USER_MOBILE = "idt_user__mobile"; |
||||
public static final String IDT_ORG_NAME = "idt_org__name"; |
||||
public static final String IDT_JOB_NAME = "idt_job__name"; |
||||
|
||||
public UsersTableDataModel(ParameterProvider[] parameters) { |
||||
super(parameters); |
||||
this.columnNames = new String[]{APP_ACCOUNT_ACCOUNT_UUID, APP_ACCOUNT_ACCOUNT_NO, APP_ACCOUNT_ACCOUNT_NAME, REQUEST_LOG_ACTION_FLAG, REQUEST_LOG_ID, IDT_USER_USER_NAME, IDT_USER_EMAIL, IDT_USER_USER_EMAIL, IDT_USER_MOBILE, IDT_USER_WORK_NO, IDT_ORG_NAME, IDT_JOB_NAME}; |
||||
} |
||||
|
||||
@Override |
||||
protected void init() { |
||||
if (!PluginContexts.currentContext().isAvailable()) { |
||||
LogKit.error(DesignKit.i18nText("Plugin-icgq_Licence_Expired")); |
||||
return; |
||||
} |
||||
if (this.valueList != null) { |
||||
return; |
||||
} |
||||
this.valueList = new ArrayList(); |
||||
// 域名
|
||||
this.host = this.parameters[0].getValue().toString(); |
||||
// 登录名(盟拓方提供)
|
||||
String clientId = this.parameters[1].getValue().toString(); |
||||
// 密钥固定分配)
|
||||
String secret = this.parameters[2].getValue().toString(); |
||||
// 开始日期
|
||||
String startTime = this.parameters[3].getValue().toString(); |
||||
|
||||
try { |
||||
String accessToken = this.getAccessToken(clientId, secret); |
||||
JSONArray usersInfo = getUserInfo(accessToken, startTime); |
||||
addFRUserInfo2List(usersInfo); |
||||
} catch (IOException e) { |
||||
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 人员获取 |
||||
* |
||||
* @param accessToken |
||||
* @param startTime |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
private JSONArray getUserInfo(String accessToken, String startTime) throws IOException { |
||||
Map<String, String> header = new HashMap<>(); |
||||
header.put("Content-Type", "application/json;charset=UTF-8"); |
||||
header.put("Authorization", accessToken); |
||||
JSONObject params = JSONObject.create(); |
||||
params.put("size", "3000"); |
||||
params.put("page", "1"); |
||||
if (StringKit.isNotBlank(startTime)) { |
||||
params.put("startTime", startTime); |
||||
} |
||||
StringEntity stringEntity = new StringEntity(params.encode(), "UTF-8"); |
||||
String response = HttpKit.executeAndParse(com.fanruan.api.net.http.rs.HttpRequest.custom() |
||||
.url(this.host + ACCOUNT_LIST).post(stringEntity).headers(header).build()); |
||||
FineLoggerFactory.getLogger().info("icgq-UsersTableDataModel-getUserInfo-response:{}", response); |
||||
JSONObject responseJo = new JSONObject(response); |
||||
if (StringKit.equals(responseJo.getString("code"), "0")) { |
||||
return responseJo.getJSONObject("data").getJSONArray("list"); |
||||
} |
||||
return JSONArray.create(); |
||||
} |
||||
|
||||
private void addFRUserInfo2List(JSONArray usersInfo) { |
||||
ArrayList<String> frUserInfo; |
||||
for (Object o : usersInfo) { |
||||
JSONObject userInfo = (JSONObject) o; |
||||
frUserInfo = new ArrayList<>(); |
||||
frUserInfo.add(userInfo.getString(APP_ACCOUNT_ACCOUNT_UUID)); |
||||
frUserInfo.add(userInfo.getString(APP_ACCOUNT_ACCOUNT_NO)); |
||||
frUserInfo.add(userInfo.getString(APP_ACCOUNT_ACCOUNT_NAME)); |
||||
frUserInfo.add(userInfo.getString(REQUEST_LOG_ACTION_FLAG)); |
||||
frUserInfo.add(userInfo.getString(REQUEST_LOG_ID)); |
||||
frUserInfo.add(userInfo.getString(IDT_USER_USER_NAME)); |
||||
frUserInfo.add(userInfo.getString(IDT_USER_EMAIL)); |
||||
frUserInfo.add(userInfo.getString(IDT_USER_USER_EMAIL)); |
||||
frUserInfo.add(userInfo.getString(IDT_USER_WORK_NO)); |
||||
frUserInfo.add(userInfo.getString(IDT_USER_MOBILE)); |
||||
frUserInfo.add(userInfo.getString(IDT_ORG_NAME)); |
||||
frUserInfo.add(userInfo.getString(IDT_JOB_NAME)); |
||||
this.valueList.add(frUserInfo.toArray()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,75 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WebTableDataModel |
||||
* Author: Louis |
||||
* Date: 2021/12/16 8:17 |
||||
*/ |
||||
package com.fr.plugin.icgq.data; |
||||
|
||||
import com.fanruan.api.data.open.BaseDataModel; |
||||
import com.fanruan.api.err.TableDataException; |
||||
import com.fr.base.Base64; |
||||
import com.fr.stable.ParameterProvider; |
||||
|
||||
import java.util.ArrayList; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <WebTableDataModel> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public abstract class WebTableDataModel extends BaseDataModel { |
||||
private static final long serialVersionUID = 5010918328453603247L; |
||||
protected ParameterProvider[] parameters; |
||||
protected String[] columnNames; |
||||
protected ArrayList valueList = null; |
||||
protected String host; |
||||
|
||||
public WebTableDataModel(ParameterProvider[] parameters) { |
||||
this.parameters = parameters; |
||||
} |
||||
|
||||
@Override |
||||
public int getColumnCount() throws TableDataException { |
||||
return this.columnNames.length; |
||||
} |
||||
|
||||
@Override |
||||
public String getColumnName(int i) throws TableDataException { |
||||
return columnNames[i]; |
||||
} |
||||
|
||||
@Override |
||||
public int getRowCount() throws TableDataException { |
||||
init(); |
||||
return valueList.size(); |
||||
} |
||||
|
||||
@Override |
||||
public Object getValueAt(int row, int col) throws TableDataException { |
||||
init(); |
||||
return ((Object[]) valueList.get(row))[col]; |
||||
} |
||||
|
||||
@Override |
||||
public void release() throws Exception { |
||||
this.parameters = null; |
||||
} |
||||
|
||||
protected abstract void init(); |
||||
|
||||
/** |
||||
* 获取访问令牌接口Token |
||||
* |
||||
* @param clientId |
||||
* @param secret |
||||
* @return |
||||
*/ |
||||
protected String getAccessToken(String clientId, String secret) { |
||||
String auth = clientId + ":" + secret; |
||||
return "Basic " + Base64.encode(auth.getBytes()); |
||||
} |
||||
} |
@ -0,0 +1,115 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: DepartmentServiceKit |
||||
* Author: Louis |
||||
* Date: 2021/5/14 9:38 |
||||
*/ |
||||
package com.fr.plugin.icgq.kit; |
||||
|
||||
import com.fanruan.api.i18n.I18nKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.decision.authority.AuthorityContext; |
||||
import com.fr.decision.authority.base.constant.type.operation.ManualOperationType; |
||||
import com.fr.decision.authority.data.Department; |
||||
import com.fr.decision.record.OperateMessage; |
||||
import com.fr.decision.webservice.exception.general.DuplicatedNameException; |
||||
import com.fr.decision.webservice.v10.user.DepartmentService; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.intelli.record.MetricRegistry; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.stable.query.QueryFactory; |
||||
import com.fr.stable.query.condition.QueryCondition; |
||||
import com.fr.stable.query.restriction.Restriction; |
||||
import com.fr.stable.query.restriction.RestrictionFactory; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <DepartmentServiceKit> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class DepartmentServiceKit extends DepartmentService { |
||||
public static final String IDT_ORG__STATUS = "idt_org__status"; |
||||
public static final String IDT_ORG__ORG_CODE = "idt_org__org_code"; |
||||
public static final String IDT_ORG__SUP_ORG_CODE = "idt_org__sup_org_code"; |
||||
public static final String IDT_ORG__NAME = "idt_org__name"; |
||||
public static final String ROOT_DEP_ID = "10000000"; |
||||
|
||||
private static volatile DepartmentServiceKit departmentServiceKit = null; |
||||
|
||||
public DepartmentServiceKit() { |
||||
} |
||||
|
||||
public static DepartmentServiceKit getInstance() { |
||||
if (departmentServiceKit == null) { |
||||
departmentServiceKit = new DepartmentServiceKit(); |
||||
} |
||||
return departmentServiceKit; |
||||
} |
||||
|
||||
/** |
||||
* 根部门与FR根部门转换 |
||||
* |
||||
* @param parentId |
||||
* @return |
||||
*/ |
||||
public String changeRootId(String parentId) { |
||||
if (StringKit.isBlank(parentId) || StringKit.equals(parentId, ROOT_DEP_ID)) { |
||||
return DECISION_DEP_ROOT; |
||||
} |
||||
return parentId; |
||||
} |
||||
|
||||
public void addDepartment(String id, String pId, String depName) throws Exception { |
||||
if (StringKit.equals(pId, DECISION_DEP_ROOT)) { |
||||
pId = null; |
||||
} |
||||
this.checkDuplicatedDepartmentName(pId, depName); |
||||
Department department = (new Department()).id(id).name(depName).parentId(pId).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true); |
||||
AuthorityContext.getInstance().getDepartmentController().add(department); |
||||
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", this.getDepartmentFullPath(pId, depName, "/"), "Dec-Log_Add")); |
||||
} |
||||
|
||||
private void checkDuplicatedDepartmentName(String parentId, String depName) throws Exception { |
||||
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", parentId)})); |
||||
Department sameNameDep = AuthorityContext.getInstance().getDepartmentController().findOne(condition); |
||||
if (sameNameDep != null) { |
||||
throw new DuplicatedNameException(); |
||||
} |
||||
} |
||||
|
||||
private String getDepartmentFullPath(String pId, String depName, String splitter) throws Exception { |
||||
List<String> paths = new ArrayList<>(); |
||||
paths.add(depName); |
||||
while (!ComparatorUtils.equals(pId, DECISION_DEP_ROOT) && pId != null) { |
||||
Department parentDepartment = AuthorityContext.getInstance().getDepartmentController().getById(pId); |
||||
paths.add(parentDepartment.getName()); |
||||
pId = parentDepartment.getParentId(); |
||||
} |
||||
Collections.reverse(paths); |
||||
return StableUtils.join(paths.toArray(new String[0]), splitter); |
||||
} |
||||
|
||||
public void editDepartment(String departmentId, String depName, String pId) throws Exception { |
||||
if (StringKit.equals(pId, DECISION_DEP_ROOT)) { |
||||
pId = null; |
||||
} |
||||
Department department = AuthorityContext.getInstance().getDepartmentController().getById(departmentId); |
||||
String departmentFullPath = DepartmentService.getInstance().getDepartmentFullPath(departmentId); |
||||
if (!ComparatorUtils.equals(department.getName(), depName)) { |
||||
this.checkDuplicatedDepartmentName(department.getParentId(), depName); |
||||
department.setName(depName); |
||||
department.setParentId(pId); |
||||
AuthorityContext.getInstance().getDepartmentController().update(department); |
||||
} |
||||
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", DepartmentService.getInstance().getDepartmentFullPath(departmentId), "Dec-Log_Update", I18nKit.getLocText("Fine-Dec_Department") + ":" + departmentFullPath)); |
||||
} |
||||
} |
@ -0,0 +1,730 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: HttpKit |
||||
* Author: Louis |
||||
* Date: 2021/3/17 14:19 |
||||
*/ |
||||
package com.fr.plugin.icgq.kit; |
||||
|
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.macro.EncodeConstants; |
||||
import com.fanruan.api.net.http.rs.HttpRequest; |
||||
import com.fanruan.api.net.http.rs.*; |
||||
import com.fr.third.guava.collect.Maps; |
||||
import com.fr.third.org.apache.http.*; |
||||
import com.fr.third.org.apache.http.client.HttpRequestRetryHandler; |
||||
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||
import com.fr.third.org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.client.methods.HttpEntityEnclosingRequestBase; |
||||
import com.fr.third.org.apache.http.client.methods.HttpRequestBase; |
||||
import com.fr.third.org.apache.http.client.protocol.HttpClientContext; |
||||
import com.fr.third.org.apache.http.client.utils.URIBuilder; |
||||
import com.fr.third.org.apache.http.config.Registry; |
||||
import com.fr.third.org.apache.http.config.RegistryBuilder; |
||||
import com.fr.third.org.apache.http.conn.routing.HttpRoute; |
||||
import com.fr.third.org.apache.http.conn.socket.ConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.socket.LayeredConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.socket.PlainConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.ssl.SSLSocketFactory; |
||||
import com.fr.third.org.apache.http.conn.ssl.TrustStrategy; |
||||
import com.fr.third.org.apache.http.entity.FileEntity; |
||||
import com.fr.third.org.apache.http.entity.mime.HttpMultipartMode; |
||||
import com.fr.third.org.apache.http.entity.mime.MultipartEntityBuilder; |
||||
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||
import com.fr.third.org.apache.http.impl.client.HttpClients; |
||||
import com.fr.third.org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
import com.fr.third.org.apache.http.message.BasicNameValuePair; |
||||
import com.fr.third.org.apache.http.protocol.HttpContext; |
||||
import com.fr.third.org.apache.http.ssl.SSLContextBuilder; |
||||
import org.jetbrains.annotations.NotNull; |
||||
import org.jetbrains.annotations.Nullable; |
||||
|
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLException; |
||||
import javax.net.ssl.SSLHandshakeException; |
||||
import java.io.*; |
||||
import java.net.URI; |
||||
import java.net.URISyntaxException; |
||||
import java.net.URLEncoder; |
||||
import java.net.UnknownHostException; |
||||
import java.nio.charset.Charset; |
||||
import java.security.KeyManagementException; |
||||
import java.security.KeyStoreException; |
||||
import java.security.NoSuchAlgorithmException; |
||||
import java.security.cert.CertificateException; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import static com.fanruan.api.net.http.rs.HttpRequestType.POST; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-29 |
||||
* <p> |
||||
* http请求工具类,封装了用于http请求的各种方法 |
||||
* 新增https忽略证书功能 Update By louis on 2021-03-17 |
||||
* </p> |
||||
*/ |
||||
public class HttpKit { |
||||
|
||||
private static final int RETRY_TIMES = 5; |
||||
private final static Object SYNC_LOCK = new Object(); |
||||
private static CloseableHttpClient httpClient = null; |
||||
|
||||
/** |
||||
* 根据请求地址创建HttpClient对象 |
||||
* |
||||
* @param url 请求地址 |
||||
* @return HttpClient对象 |
||||
*/ |
||||
public static CloseableHttpClient getHttpClient(String url) { |
||||
String hostname = url.split("/")[2]; |
||||
int port = 80; |
||||
if (hostname.contains(":")) { |
||||
String[] arr = hostname.split(":"); |
||||
hostname = arr[0]; |
||||
port = Integer.parseInt(arr[1]); |
||||
} |
||||
if (httpClient == null) { |
||||
synchronized (SYNC_LOCK) { |
||||
if (httpClient == null) { |
||||
// httpClient = createHttpClient(hostname, port, SSLContexts.createDefault());
|
||||
try { |
||||
httpClient = createHttpClient(hostname, port, createIgnoreVerifySSL()); |
||||
} catch (NoSuchAlgorithmException e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
} catch (KeyManagementException e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return httpClient; |
||||
} |
||||
|
||||
/** |
||||
* 新增了https 请求绕过证书认证 |
||||
* |
||||
* @return |
||||
* @throws NoSuchAlgorithmException |
||||
* @throws KeyManagementException |
||||
*/ |
||||
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException { |
||||
// SSLContext sc = SSLContext.getInstance("SSLv3");
|
||||
// // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
|
||||
// X509TrustManager trustManager = new X509TrustManager() {
|
||||
// @Override
|
||||
// public void checkClientTrusted(
|
||||
// java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
|
||||
// String paramString) throws CertificateException {
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void checkServerTrusted(
|
||||
// java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
|
||||
// String paramString) throws CertificateException {
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
// sc.init(null, new TrustManager[]{trustManager}, null);
|
||||
// return sc;
|
||||
|
||||
try { |
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { |
||||
//信任所有
|
||||
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
||||
return true; |
||||
} |
||||
}).build(); |
||||
return sslContext; |
||||
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static CloseableHttpClient createHttpClient(String hostname, int port, SSLContext sslContext) { |
||||
return createHttpClient(200, 40, 100, hostname, port, sslContext); |
||||
} |
||||
|
||||
private static CloseableHttpClient createHttpClient(int maxTotal, |
||||
int maxPerRoute, |
||||
int maxRoute, |
||||
String hostname, |
||||
int port, |
||||
SSLContext sslContext) { |
||||
ConnectionSocketFactory socketFactory = PlainConnectionSocketFactory.getSocketFactory(); |
||||
LayeredConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); |
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder |
||||
.<ConnectionSocketFactory>create() |
||||
.register("http", socketFactory) |
||||
.register("https", sslConnectionSocketFactory) |
||||
.build(); |
||||
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); |
||||
// 将最大连接数增加
|
||||
cm.setMaxTotal(maxTotal); |
||||
// 将每个路由基础的连接增加
|
||||
cm.setDefaultMaxPerRoute(maxPerRoute); |
||||
HttpHost httpHost = new HttpHost(hostname, port); |
||||
// 将目标主机的最大连接数增加
|
||||
cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute); |
||||
|
||||
// 请求重试处理
|
||||
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { |
||||
@Override |
||||
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { |
||||
if (executionCount >= RETRY_TIMES) {// 如果已经重试了5次,就放弃
|
||||
return false; |
||||
} |
||||
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
|
||||
return true; |
||||
} |
||||
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
|
||||
return false; |
||||
} |
||||
if (exception instanceof InterruptedIOException) {// 超时
|
||||
return false; |
||||
} |
||||
if (exception instanceof UnknownHostException) {// 目标服务器不可达
|
||||
return false; |
||||
} |
||||
if (exception instanceof SSLException) {// SSL握手异常
|
||||
return false; |
||||
} |
||||
|
||||
HttpClientContext clientContext = HttpClientContext.adapt(context); |
||||
com.fr.third.org.apache.http.HttpRequest request = clientContext.getRequest(); |
||||
// 如果请求是幂等的,就再次尝试
|
||||
return !(request instanceof HttpEntityEnclosingRequest); |
||||
} |
||||
}; |
||||
|
||||
return HttpClients.custom() |
||||
.setConnectionManager(cm) |
||||
.setRetryHandler(httpRequestRetryHandler) |
||||
.build(); |
||||
} |
||||
|
||||
/** |
||||
* 设置 httpEntity |
||||
* |
||||
* @param requestBase 请求体 |
||||
* @param httpRequest 请求 |
||||
*/ |
||||
private static void setHttpEntity(@NotNull HttpEntityEnclosingRequestBase requestBase, @NotNull HttpRequest httpRequest) { |
||||
HttpEntity httpEntity = httpRequest.getHttpEntity(); |
||||
if (httpEntity != null) { |
||||
// 如果存在 httpEntity 直接设置
|
||||
requestBase.setEntity(httpEntity); |
||||
return; |
||||
} |
||||
Map<String, String> params = httpRequest.getParams(); |
||||
if (params == null || params.isEmpty()) { |
||||
return; |
||||
} |
||||
List<NameValuePair> pairs = new ArrayList<NameValuePair>(); |
||||
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||
pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); |
||||
} |
||||
try { |
||||
requestBase.setEntity(new UrlEncodedFormEntity(pairs, httpRequest.getEncoding())); |
||||
} catch (UnsupportedEncodingException e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
private static <V> Map<String, String> transformMap(Map<String, V> oldMap) { |
||||
if (oldMap == null) { |
||||
return null; |
||||
} |
||||
return Maps.transformEntries(oldMap, new Maps.EntryTransformer<String, V, String>() { |
||||
@Override |
||||
public String transformEntry(@Nullable String key, @Nullable V value) { |
||||
return value == null ? null : value.toString(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static <V> String post(String url, Map<String, V> params) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseType 返回类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <T, V> T post(String url, Map<String, V> params, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build()); |
||||
return responseType.result(response, null); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param headers 请求头 |
||||
* @param responseType 返回类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
@Deprecated |
||||
public static <T, V> T post(String url, Map<String, V> params, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build()); |
||||
return responseType.result(response, null); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
@Deprecated |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param paramsEncoding 参数编码 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static <V> String post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.encoding(paramsEncoding) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起POST请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params POST请求的参数 |
||||
* @param responseEncoding 响应的文本的编码 |
||||
* @param paramsEncoding 参数编码 |
||||
* @param headers 请求头 |
||||
* @param responseType 返回值类型 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#execute(HttpRequest) |
||||
*/ |
||||
public static <T, V> T post(String url, Map<String, V> params, String responseEncoding, String paramsEncoding, Map<String, String> headers, HttpResponseType<T> responseType) throws IOException { |
||||
CloseableHttpResponse response = execute(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.post(transformMap(params)) |
||||
.encoding(paramsEncoding) |
||||
.headers(headers) |
||||
.build()); |
||||
return responseType.result(response, responseEncoding); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static String get(String url) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @return 服务器返回的文本内容 |
||||
*/ |
||||
public static String get(String url, Map<String, String> params) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).params(params).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param headers 请求头 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).params(params).headers(headers).build()); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param responseEncoding 返回的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, String responseEncoding) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 发起GET请求并获取返回的文本 |
||||
* |
||||
* @param url 响应请求的的服务器地址 |
||||
* @param params 参数 |
||||
* @param responseEncoding 返回的文本的编码 |
||||
* @return 服务器返回的文本内容 |
||||
* @see com.fanruan.api.net.http.HttpKit#executeAndParse(HttpRequest, BaseHttpResponseHandle) |
||||
*/ |
||||
public static String get(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.headers(headers) |
||||
.build(), |
||||
new TextResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 从指定的地址下载文件 |
||||
* |
||||
* @param url 文件下载地址 |
||||
* @return 文件的字节流 |
||||
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||
*/ |
||||
public static ByteArrayInputStream download(String url) throws IOException { |
||||
return executeAndParse(HttpRequest.custom().url(url).build(), StreamResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 从指定的地址下载文件 |
||||
* |
||||
* @param url 文件下载地址 |
||||
* @param params 参数对 |
||||
* @param responseEncoding 响应的文件编码 |
||||
* @param headers 请求头 |
||||
* @return 文件的字节流 |
||||
* @throws IOException 下载过程中出现错误则抛出此异常 |
||||
*/ |
||||
public static ByteArrayInputStream download(String url, Map<String, String> params, String responseEncoding, Map<String, String> headers) throws IOException { |
||||
return executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.params(params) |
||||
.headers(headers) |
||||
.build(), |
||||
new StreamResponseHandle(responseEncoding)); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param file 要上传的文件,默认的文件编码为utf-8 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, File file) throws IOException { |
||||
upload(url, file, Charset.forName("utf-8")); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param file 要上传的文件 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, File file, Charset charset) throws IOException { |
||||
upload(url, new FileEntity(file), charset); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param builder 附件构造器 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, MultipartEntityBuilder builder, Charset charset) throws IOException { |
||||
upload(url, builder, charset, Collections.<String, String>emptyMap(), POST); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param fileEntity 文件实体 |
||||
* @param charset 文件的编码 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, FileEntity fileEntity, Charset charset) throws IOException { |
||||
upload(url, fileEntity, charset, Collections.<String, String>emptyMap(), POST); |
||||
} |
||||
|
||||
/** |
||||
* 上传多文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param builder 附件构造器 |
||||
* @param charset 文件的编码 |
||||
* @param headers 请求头 |
||||
* @param httpRequestType 请求类型 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, MultipartEntityBuilder builder, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||
// richie:采用浏览器模式,防止出现乱码
|
||||
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); |
||||
HttpEntity reqEntity = builder.setCharset(charset).build(); |
||||
upload(url, reqEntity, charset, headers, httpRequestType); |
||||
} |
||||
|
||||
/** |
||||
* 上传文件到指定的服务器 |
||||
* |
||||
* @param url 接收文件的服务器地址 |
||||
* @param reqEntity 请求实体 |
||||
* @param charset 文件的编码 |
||||
* @param headers 请求头 |
||||
* @param httpRequestType 请求类型 |
||||
* @throws IOException 上传中出现错误则抛出此异常 |
||||
*/ |
||||
public static void upload(String url, HttpEntity reqEntity, Charset charset, Map<String, String> headers, HttpRequestType httpRequestType) throws IOException { |
||||
executeAndParse(HttpRequest |
||||
.custom() |
||||
.url(url) |
||||
.headers(headers) |
||||
.method(httpRequestType) |
||||
.httpEntity(reqEntity) |
||||
.encoding(charset.toString()) |
||||
.build(), |
||||
UploadResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,使用默认文本http解析器,UTF-8编码 |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static String executeAndParse(HttpRequest httpRequest) throws IOException { |
||||
return executeAndParse(httpRequest, TextResponseHandle.DEFAULT); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,自请求参数,并指定 http 响应处理器 |
||||
* 例: |
||||
* <pre> |
||||
* String res = HttpToolbox.executeAndParse(HttpRequest |
||||
* .custom() |
||||
* .url("") |
||||
* .build(), |
||||
* TextResponseHandle.DEFAULT); |
||||
* </pre> |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @param handle http 解析器 |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static <T> T executeAndParse(HttpRequest httpRequest, BaseHttpResponseHandle<T> handle) throws IOException { |
||||
return handle.parse(execute(httpRequest)); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,传入请求参数 |
||||
* |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static CloseableHttpResponse execute(HttpRequest httpRequest) throws IOException { |
||||
return execute(getHttpClient(httpRequest.getUrl()), httpRequest); |
||||
} |
||||
|
||||
/** |
||||
* 请求资源或服务,自定义client对象,传入请求参数 |
||||
* |
||||
* @param httpClient http客户端 |
||||
* @param httpRequest httpRequest |
||||
* @return 返回处理结果 |
||||
*/ |
||||
public static CloseableHttpResponse execute(CloseableHttpClient httpClient, HttpRequest httpRequest) throws IOException { |
||||
String url = httpRequest.getUrl(); |
||||
|
||||
// 创建请求对象
|
||||
HttpRequestBase httpRequestBase = httpRequest.getMethod().createHttpRequest(url); |
||||
|
||||
// 设置header信息
|
||||
httpRequestBase.setHeader("User-Agent", "Mozilla/5.0"); |
||||
Map<String, String> headers = httpRequest.getHeaders(); |
||||
if (headers != null && !headers.isEmpty()) { |
||||
for (Map.Entry<String, String> entry : headers.entrySet()) { |
||||
httpRequestBase.setHeader(entry.getKey(), entry.getValue()); |
||||
} |
||||
} |
||||
|
||||
// 配置请求的设置
|
||||
RequestConfig requestConfig = httpRequest.getConfig(); |
||||
if (requestConfig != null) { |
||||
httpRequestBase.setConfig(requestConfig); |
||||
} |
||||
|
||||
// 判断是否支持设置entity(仅HttpPost、HttpPut、HttpPatch支持)
|
||||
if (HttpEntityEnclosingRequestBase.class.isAssignableFrom(httpRequestBase.getClass())) { |
||||
setHttpEntity((HttpEntityEnclosingRequestBase) httpRequestBase, httpRequest); |
||||
} else { |
||||
Map<String, String> params = httpRequest.getParams(); |
||||
if (params != null && !params.isEmpty()) { |
||||
// 注意get等不支持设置entity需要更新拼接之后的URL,但是url变量没有更新
|
||||
httpRequestBase.setURI(URI.create(buildUrl(url, params, httpRequest.getEncoding()))); |
||||
} |
||||
} |
||||
|
||||
return httpClient.execute(httpRequestBase); |
||||
} |
||||
|
||||
/** |
||||
* 构建 Url |
||||
* |
||||
* @param url 请求地址 |
||||
* @param params 参数 |
||||
* @return 拼接之后的地址 |
||||
*/ |
||||
public static String buildUrl(String url, Map<String, String> params) { |
||||
try { |
||||
return buildUrl(url, params, EncodeConstants.ENCODING_UTF_8); |
||||
} catch (UnsupportedEncodingException ignore) { |
||||
} |
||||
return url; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 构建 Url |
||||
* |
||||
* @param url 请求地址 |
||||
* @param params 参数 |
||||
* @return 拼接之后的地址 |
||||
* @throws UnsupportedEncodingException 不支持的编码 |
||||
*/ |
||||
private static String buildUrl(String url, Map<String, String> params, String paramsEncoding) throws UnsupportedEncodingException { |
||||
if (params == null || params.isEmpty()) { |
||||
return url; |
||||
} |
||||
URIBuilder builder; |
||||
try { |
||||
builder = new URIBuilder(url); |
||||
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||
String key = URLEncoder.encode(entry.getKey(), paramsEncoding); |
||||
String value = URLEncoder.encode(entry.getValue(), paramsEncoding); |
||||
builder.setParameter(key, value); |
||||
} |
||||
return builder.build().toString(); |
||||
} catch (URISyntaxException e) { |
||||
LogKit.debug("Error to build url, please check the arguments."); |
||||
} |
||||
return url; |
||||
} |
||||
} |
@ -0,0 +1,173 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: UserServiceKit |
||||
* Author: Louis |
||||
* Date: 2021/5/14 8:28 |
||||
*/ |
||||
package com.fr.plugin.icgq.kit; |
||||
|
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.decision.authority.AuthorityContext; |
||||
import com.fr.decision.authority.data.Department; |
||||
import com.fr.decision.authority.data.Post; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.privilege.TransmissionTool; |
||||
import com.fr.decision.webservice.bean.user.DepartmentPostBean; |
||||
import com.fr.decision.webservice.bean.user.UserBean; |
||||
import com.fr.decision.webservice.v10.user.PositionService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.stable.query.QueryFactory; |
||||
import com.fr.stable.query.condition.QueryCondition; |
||||
import com.fr.stable.query.restriction.RestrictionFactory; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import static com.fr.plugin.icgq.kit.DepartmentServiceKit.IDT_ORG__NAME; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UserServiceKit> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UserServiceKit extends UserService { |
||||
public static final String USER_NAME = "app_account__account_no"; |
||||
public static final String ACCOUNT_NAME = "app_account__account_name"; |
||||
public static final String ACCOUNT_NO = "app_account__account_no"; |
||||
public static final String ENABLE = "app_account__status"; |
||||
public static final String EMAIL = "idt_user__email"; |
||||
public static final String MOBILE = "idt_user__mobile"; |
||||
public static final String POSITION = "idt_job__name"; |
||||
public static final String PASSWORD = "idt_user__pwd"; |
||||
private static volatile UserServiceKit userServiceKit = null; |
||||
|
||||
public UserServiceKit() { |
||||
} |
||||
|
||||
public static UserServiceKit getInstance() { |
||||
if (userServiceKit == null) { |
||||
userServiceKit = new UserServiceKit(); |
||||
} |
||||
return userServiceKit; |
||||
} |
||||
|
||||
public UserBean createUserBean(JSONObject account) throws Exception { |
||||
UserBean userBean = new UserBean(); |
||||
userBean.setUsername(account.getString(USER_NAME)); |
||||
userBean.setRealName(account.getString(ACCOUNT_NAME)); |
||||
userBean.setEnable(true); |
||||
userBean.setEmail(account.getString(EMAIL)); |
||||
userBean.setMobile(account.getString(MOBILE)); |
||||
userBean.setPassword(TransmissionTool.defaultEncrypt(account.getString(USER_NAME) + "123456")); |
||||
String departmentId; |
||||
String position = StringKit.EMPTY; |
||||
try { |
||||
String depName = account.getJSONArray("orgs").getJSONObject(0).getString(IDT_ORG__NAME); |
||||
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", null))); |
||||
Department department = AuthorityContext.getInstance().getDepartmentController().findOne(condition); |
||||
departmentId = department.getId(); |
||||
} catch (Exception e) { |
||||
departmentId = StringKit.EMPTY; |
||||
} |
||||
if (StringKit.isNotBlank(departmentId)) { |
||||
List<String> departmentPostIds = UserServiceKit.getInstance().createDepartmentPostIds(departmentId, position); |
||||
userBean.setDepartmentPostIds(departmentPostIds); |
||||
} |
||||
return userBean; |
||||
} |
||||
|
||||
/** |
||||
* 部门id转为部门职务组合list |
||||
* |
||||
* @param departmentPostId |
||||
* @param title |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
public List<String> createDepartmentPostIds(String departmentPostId, String title) throws Exception { |
||||
List<String> departmentPostIds = new ArrayList<>(); |
||||
// 职务处理
|
||||
// String positionId = positionSynOperation(title, departmentPostId);
|
||||
// if (StringKit.isNotBlank(positionId)) {
|
||||
// departmentPostId = departmentPostId + "@@@" + positionId;
|
||||
// }
|
||||
departmentPostIds.add(departmentPostId); |
||||
return departmentPostIds; |
||||
} |
||||
|
||||
/** |
||||
* 职务同步操作 |
||||
* |
||||
* @param title |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private String positionSynOperation(String title, String departmentId) throws Exception { |
||||
String position = StringKit.isNotBlank(title) ? title : "职员"; |
||||
Post post = AuthorityContext.getInstance().getPostController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("name", position))); |
||||
String positionId; |
||||
if (post == null) { |
||||
positionId = PositionService.getInstance().addPosition(position, position); |
||||
} else { |
||||
positionId = post.getId(); |
||||
} |
||||
List<DepartmentPostBean> departmentPostBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(getAdminUserId(), departmentId, position); |
||||
if (departmentPostBeanList == null || departmentPostBeanList.isEmpty()) { |
||||
try { |
||||
AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, departmentId); |
||||
} catch (Exception e) { |
||||
LogKit.info("icgq-UserServiceKit-positionSynOperation-addPostToDepartmentFailed-position:{}, departmentId:{}", positionId + position, departmentId); |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
return positionId; |
||||
} |
||||
|
||||
/** |
||||
* 获取管理员id |
||||
* |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
public String getAdminUserId() throws Exception { |
||||
List<String> adminUserIdList = UserService.getInstance().getAdminUserIdList(); |
||||
if (adminUserIdList.isEmpty()) { |
||||
return "admin"; |
||||
} |
||||
return StringKit.isNotBlank(adminUserIdList.get(0)) ? adminUserIdList.get(0) : "admin"; |
||||
} |
||||
|
||||
public UserBean updateUserBean(JSONObject account) throws Exception { |
||||
User user = UserService.getInstance().getUserByUserName(account.getString(USER_NAME)); |
||||
if (user == null) { |
||||
return null; |
||||
} |
||||
UserBean userBean = new UserBean(); |
||||
userBean.setId(user.getId()); |
||||
userBean.setUsername(user.getUserName()); |
||||
userBean.setRealName(account.getString(ACCOUNT_NAME)); |
||||
userBean.setEnable(true); |
||||
userBean.setEmail(account.getString(EMAIL)); |
||||
userBean.setMobile(account.getString(MOBILE)); |
||||
String departmentId; |
||||
String position = StringKit.EMPTY; |
||||
try { |
||||
String depName = account.getJSONArray("orgs").getJSONObject(0).getString(IDT_ORG__NAME); |
||||
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", null))); |
||||
Department department = AuthorityContext.getInstance().getDepartmentController().findOne(condition); |
||||
departmentId = department.getId(); |
||||
} catch (Exception e) { |
||||
departmentId = StringKit.EMPTY; |
||||
} |
||||
if (StringKit.isNotBlank(departmentId)) { |
||||
List<String> departmentPostIds = UserServiceKit.getInstance().createDepartmentPostIds(departmentId, position); |
||||
userBean.setDepartmentPostIds(departmentPostIds); |
||||
} |
||||
return userBean; |
||||
} |
||||
} |
@ -0,0 +1,57 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WechatTableDataDefine |
||||
* Author: Louis |
||||
* Date: 2021/12/8 16:41 |
||||
*/ |
||||
package com.fr.plugin.icgq.provider; |
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fr.base.TableData; |
||||
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; |
||||
import com.fr.design.fun.ServerTableDataDefineProvider; |
||||
import com.fr.design.fun.impl.AbstractTableDataDefineProvider; |
||||
import com.fr.plugin.icgq.data.UsersTableData; |
||||
import com.fr.plugin.icgq.ui.UsersTableDataPane; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <WechatTableDataDefine> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UsersTableDataDefine extends AbstractTableDataDefineProvider implements ServerTableDataDefineProvider { |
||||
public static final String ICON_PATH = "/com/fr/plugin/icgq/images/logo16.png"; |
||||
|
||||
@Override |
||||
public Class<? extends TableData> classForTableData() { |
||||
return UsersTableData.class; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends TableData> classForInitTableData() { |
||||
return UsersTableData.class; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends AbstractTableDataPane> appearanceForTableData() { |
||||
return UsersTableDataPane.class; |
||||
} |
||||
|
||||
@Override |
||||
public String nameForTableData() { |
||||
return DesignKit.i18nText("Plugin-icgq_Users_Table_Data"); |
||||
} |
||||
|
||||
@Override |
||||
public String prefixForTableData() { |
||||
return DesignKit.i18nText("Plugin-icgq_Users_Table_Data"); |
||||
} |
||||
|
||||
@Override |
||||
public String iconPathForTableData() { |
||||
return ICON_PATH; |
||||
} |
||||
} |
@ -0,0 +1,181 @@
|
||||
/* |
||||
* Copyright (C), 2015-2019 |
||||
* FileName: ReportDataHandler |
||||
* Author: Louis |
||||
* Date: 2019/8/22 8:34 |
||||
* Description: ReportDataHandler |
||||
* History: |
||||
* <author> <time> <version> <desc> |
||||
*/ |
||||
package com.fr.plugin.icgq.service; |
||||
|
||||
import com.fanruan.api.i18n.I18nKit; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.base.Base64; |
||||
import com.fr.data.NetworkHelper; |
||||
import com.fr.decision.authority.AuthorityContext; |
||||
import com.fr.decision.authority.data.Department; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.decision.webservice.bean.user.UserBean; |
||||
import com.fr.decision.webservice.bean.user.UserUpdateBean; |
||||
import com.fr.decision.webservice.v10.user.DepartmentService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.intelli.record.Focus; |
||||
import com.fr.intelli.record.Original; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.plugin.context.PluginContexts; |
||||
import com.fr.plugin.icgq.config.IcgqConfig; |
||||
import com.fr.plugin.icgq.kit.UserServiceKit; |
||||
import com.fr.record.analyzer.EnableMetrics; |
||||
import com.fr.stable.query.QueryFactory; |
||||
import com.fr.stable.query.condition.QueryCondition; |
||||
import com.fr.stable.query.restriction.RestrictionFactory; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.web.utils.WebUtils; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.BufferedReader; |
||||
import java.io.IOException; |
||||
import java.io.InputStreamReader; |
||||
import java.nio.charset.StandardCharsets; |
||||
|
||||
import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; |
||||
import static com.fr.plugin.icgq.LocaleFinder.PLUGIN_ID; |
||||
import static com.fr.plugin.icgq.data.UsersTableDataModel.REQUEST_LOG_ACTION_FLAG; |
||||
import static com.fr.plugin.icgq.kit.DepartmentServiceKit.IDT_ORG__NAME; |
||||
import static com.fr.plugin.icgq.kit.DepartmentServiceKit.IDT_ORG__ORG_CODE; |
||||
import static com.fr.plugin.icgq.kit.UserServiceKit.USER_NAME; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈ReportDataHandler〉 |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@EnableMetrics |
||||
public class ReportDataHandler extends BaseHttpHandler { |
||||
public static final String IAM_USERS = "/iam/data"; |
||||
public static final String BASIC_AUTH = "Basic "; |
||||
|
||||
@Override |
||||
public RequestMethod getMethod() { |
||||
return RequestMethod.POST; |
||||
} |
||||
|
||||
@Override |
||||
public String getPath() { |
||||
return IAM_USERS; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isPublic() { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = "Plugin-icgq", source = Original.PLUGIN) |
||||
public void handle(HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
if (!PluginContexts.currentContext().isAvailable()) { |
||||
LogKit.error(I18nKit.getLocText("Plugin-icgq_Licence_Expired")); |
||||
printErrorJSON(response, I18nKit.getLocText("Plugin-icgq_Licence_Expired")); |
||||
return; |
||||
} |
||||
String authorization = request.getHeader("Authorization"); |
||||
LogKit.info("icgq-ReportDataHandler-authorization:{}", authorization); |
||||
if (StringKit.isEmpty(authorization) || !authorization.startsWith(BASIC_AUTH) || !StringKit.equals(authorization, getAuth())) { |
||||
printErrorJSON(response, "认证错误"); |
||||
return; |
||||
} |
||||
try { |
||||
JSONObject userInfo = this.getParams(request); |
||||
if (userInfo.getJSONArray("orgs") != null && !userInfo.getJSONArray("orgs").isEmpty()) { |
||||
departmentSynOperation(userInfo.getJSONArray("orgs").getJSONObject(0)); |
||||
} |
||||
userSynOperation(userInfo); |
||||
printResultJSON(response, userInfo.getString("request_log__id")); |
||||
} catch (Exception e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
printErrorJSON(response, e.getMessage()); |
||||
} |
||||
} |
||||
|
||||
private String getAuth() { |
||||
String auth = IcgqConfig.getInstance().getClientId() + ":" + IcgqConfig.getInstance().getClientSecret(); |
||||
return "Basic " + Base64.encode(auth.getBytes()); |
||||
} |
||||
|
||||
/** |
||||
* 部门组织的新增更新操作 |
||||
* |
||||
* @param departmentJo |
||||
* @throws Exception |
||||
*/ |
||||
private void departmentSynOperation(JSONObject departmentJo) throws Exception { |
||||
LogKit.info("icgq-ReportDataHandler-departmentSynOperation-departmentJo:{}", departmentJo.encode()); |
||||
String departmentId = departmentJo.getString(IDT_ORG__ORG_CODE); |
||||
// String parentId = departmentJo.getString(IDT_ORG__SUP_ORG_CODE);
|
||||
// parentId = DepartmentServiceKit.getInstance().changeRootId(parentId);
|
||||
String parentId = DECISION_DEP_ROOT; |
||||
String depName = departmentJo.getString(IDT_ORG__NAME); |
||||
QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", null))); |
||||
Department sameNameDep = AuthorityContext.getInstance().getDepartmentController().findOne(condition); |
||||
if (sameNameDep == null) { |
||||
DepartmentService.getInstance().addDepartment(parentId, depName); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 用户新增和更新操作 |
||||
* |
||||
* @param userJo |
||||
*/ |
||||
private void userSynOperation(JSONObject userJo) throws Exception { |
||||
LogKit.info("icgq-ReportDataHandler-userSynOperation-userJo:{}", userJo.encode()); |
||||
UserBean userBean; |
||||
if (ComparatorUtils.equals(userJo.getInt(REQUEST_LOG_ACTION_FLAG), 0)) { |
||||
userBean = UserServiceKit.getInstance().createUserBean(userJo); |
||||
UserService.getInstance().addUser(userBean); |
||||
} else if (ComparatorUtils.equals(userJo.getInt(REQUEST_LOG_ACTION_FLAG), 1)) { |
||||
userBean = UserServiceKit.getInstance().updateUserBean(userJo); |
||||
if (userBean == null) { |
||||
return; |
||||
} |
||||
UserServiceKit.getInstance().editUser(userBean, UserServiceKit.getInstance().getAdminUserId()); |
||||
} else if (ComparatorUtils.equals(userJo.getInt(REQUEST_LOG_ACTION_FLAG), 2)) { |
||||
User user = UserService.getInstance().getUserByUserName(userJo.getString(USER_NAME)); |
||||
String[] removeUserIds = new String[]{user.getId()}; |
||||
UserUpdateBean userUpdateBean = new UserUpdateBean(); |
||||
userUpdateBean.setRemoveUserIds(removeUserIds); |
||||
UserService.getInstance().deleteUsers(userUpdateBean); |
||||
} |
||||
} |
||||
|
||||
private JSONObject getParams(HttpServletRequest req) throws IOException { |
||||
BufferedReader br = new BufferedReader(new InputStreamReader(NetworkHelper.getRequestInputStream(req), StandardCharsets.UTF_8)); |
||||
StringBuilder sb = new StringBuilder(); |
||||
String temp; |
||||
while ((temp = br.readLine()) != null) { |
||||
sb.append(temp); |
||||
} |
||||
br.close(); |
||||
return new JSONObject(sb.toString()); |
||||
} |
||||
|
||||
private void printResultJSON(HttpServletResponse res, String data) throws Exception { |
||||
JSONObject result = JSONObject.create(); |
||||
result.put("code", "0").put("timestamp", String.valueOf(System.currentTimeMillis())) |
||||
.put("data", data).put("msg", "操作成功"); |
||||
WebUtils.printAsJSON(res, result); |
||||
} |
||||
|
||||
private void printErrorJSON(HttpServletResponse res, String msg) throws Exception { |
||||
JSONObject errorJSON = JSONObject.create(); |
||||
errorJSON.put("code", "1").put("msg", msg); |
||||
WebUtils.printAsJSON(res, errorJSON); |
||||
} |
||||
} |
@ -0,0 +1,33 @@
|
||||
/* |
||||
* Copyright (C), 2015-2019 |
||||
* FileName: RequestHandlerBridge |
||||
* Author: Louis |
||||
* Date: 2019/8/17 22:20 |
||||
* Description: RequestHandlerBridge |
||||
* History: |
||||
* <author> <time> <version> <desc> |
||||
*/ |
||||
package com.fr.plugin.icgq.service; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; |
||||
import com.fr.decision.fun.impl.BaseHttpHandler; |
||||
import com.fr.stable.fun.Authorize; |
||||
|
||||
import static com.fr.plugin.icgq.LocaleFinder.PLUGIN_ID; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈RequestHandlerBridge〉 |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class RequestHandlerBridge extends AbstractHttpHandlerProvider { |
||||
@Override |
||||
public BaseHttpHandler[] registerHandlers() { |
||||
return new BaseHttpHandler[]{ |
||||
new ReportDataHandler() |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,35 @@
|
||||
/* |
||||
* Copyright (C), 2015-2019 |
||||
* FileName: URLAliasBridge |
||||
* Author: Louis |
||||
* Date: 2019/8/17 22:21 |
||||
* Description: URLAliasBridge |
||||
* History: |
||||
* <author> <time> <version> <desc> |
||||
*/ |
||||
package com.fr.plugin.icgq.service; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractURLAliasProvider; |
||||
import com.fr.decision.webservice.url.alias.URLAlias; |
||||
import com.fr.decision.webservice.url.alias.URLAliasFactory; |
||||
import com.fr.stable.fun.Authorize; |
||||
|
||||
import static com.fr.plugin.icgq.LocaleFinder.PLUGIN_ID; |
||||
import static com.fr.plugin.icgq.service.ReportDataHandler.IAM_USERS; |
||||
|
||||
/** |
||||
* 〈Function Description〉<br> |
||||
* 〈URLAliasBridge〉 |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Authorize(callSignKey = PLUGIN_ID) |
||||
public class URLAliasBridge extends AbstractURLAliasProvider { |
||||
@Override |
||||
public URLAlias[] registerAlias() { |
||||
return new URLAlias[]{ |
||||
URLAliasFactory.createPluginAlias(IAM_USERS, IAM_USERS, true), |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WechatTableDataPane |
||||
* Author: Louis |
||||
* Date: 2021/12/8 19:19 |
||||
*/ |
||||
package com.fr.plugin.icgq.ui; |
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fr.plugin.icgq.data.UsersTableData; |
||||
import com.fr.script.Calculator; |
||||
import com.fr.stable.ParameterProvider; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UsersTableDataPane> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UsersTableDataPane extends WebBaseTableDataPane<UsersTableData> { |
||||
|
||||
public UsersTableDataPane() { |
||||
super(); |
||||
} |
||||
|
||||
@Override |
||||
public void populateBean(UsersTableData data) { |
||||
if (data == null) { |
||||
return; |
||||
} |
||||
Calculator c = Calculator.createCalculator(); |
||||
this.editorPane.populate(data.getParameters(c)); |
||||
} |
||||
|
||||
@Override |
||||
public UsersTableData updateBean() { |
||||
UsersTableData data = new UsersTableData(); |
||||
List<ParameterProvider> parameterProviderList = this.editorPane.update(); |
||||
ParameterProvider[] parameters = parameterProviderList.toArray(new ParameterProvider[0]); |
||||
data.setParameters(parameters); |
||||
return data; |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return DesignKit.i18nText("Plugin-icgq_Query"); |
||||
} |
||||
} |
@ -0,0 +1,136 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WebBaseTableDatapane |
||||
* Author: Louis |
||||
* Date: 2021/12/10 8:49 |
||||
*/ |
||||
package com.fr.plugin.icgq.ui; |
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fanruan.api.design.ui.action.UpdateAction; |
||||
import com.fanruan.api.design.ui.component.UIToolbar; |
||||
import com.fanruan.api.design.ui.component.table.UITableEditorPane; |
||||
import com.fanruan.api.design.ui.component.table.action.UITableEditAction; |
||||
import com.fanruan.api.design.ui.component.table.model.ParameterTableModel; |
||||
import com.fanruan.api.design.ui.component.table.model.UITableModelAdapter; |
||||
import com.fanruan.api.design.ui.toolbar.ToolBarDef; |
||||
import com.fanruan.api.design.work.BaseTableDataPane; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.util.IOKit; |
||||
import com.fr.base.TableData; |
||||
import com.fr.stable.ParameterProvider; |
||||
|
||||
import javax.swing.*; |
||||
import java.awt.*; |
||||
import java.awt.event.ActionEvent; |
||||
import java.io.IOException; |
||||
import java.net.URI; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <WebBaseTableDatapane> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public abstract class WebBaseTableDataPane<T extends TableData> extends BaseTableDataPane<T> { |
||||
public static final String ICON_HELP = "/com/fr/plugin/icgq/images/help.png"; |
||||
public static final String ICON_PREVIEW = "/com/fr/design/images/m_file/preview.png"; |
||||
public static final String ICON_REFRESH = "/com/fr/design/images/control/refresh.png"; |
||||
public static final String HELP_URL = "https://help.finereport.com/index.php"; |
||||
private static final String PREVIEW_BUTTON = DesignKit.i18nText("Plugin-icgq_Preview"); |
||||
private static final String REFRESH_BUTTON = DesignKit.i18nText("Plugin-icgq_Refresh"); |
||||
private static final String HELP_BUTTON = DesignKit.i18nText("Plugin-icgq_Help"); |
||||
|
||||
protected UITableEditorPane<ParameterProvider> editorPane; |
||||
|
||||
public WebBaseTableDataPane() { |
||||
this.setLayout(new BorderLayout(4, 4)); |
||||
Box box = new Box(BoxLayout.Y_AXIS); |
||||
JPanel northPane = new JPanel(new BorderLayout(4, 4)); |
||||
JToolBar editToolBar = createToolBar(); |
||||
northPane.add(editToolBar, BorderLayout.CENTER); |
||||
JToolBar editHelpBar = createHelpBar(); |
||||
northPane.add(editHelpBar, BorderLayout.EAST); |
||||
northPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 6, 0)); |
||||
|
||||
UITableModelAdapter<ParameterProvider> model = new ParameterTableModel(); |
||||
editorPane = new UITableEditorPane<ParameterProvider>(model); |
||||
box.add(northPane); |
||||
box.add(editorPane); |
||||
JPanel sqlSplitPane = new JPanel(new BorderLayout(4, 4)); |
||||
sqlSplitPane.add(box, BorderLayout.CENTER); |
||||
this.add(sqlSplitPane, BorderLayout.CENTER); |
||||
} |
||||
|
||||
private JToolBar createToolBar() { |
||||
ToolBarDef toolBarDef = new ToolBarDef(); |
||||
toolBarDef.addShortCut(new PreviewAction()); |
||||
UIToolbar editToolBar = ToolBarDef.createJToolBar(); |
||||
toolBarDef.updateToolBar(editToolBar); |
||||
return editToolBar; |
||||
} |
||||
|
||||
private JToolBar createHelpBar() { |
||||
ToolBarDef helpBarDef = new ToolBarDef(); |
||||
helpBarDef.addShortCut(new HelpAction()); |
||||
UIToolbar editHelpBar = ToolBarDef.createJToolBar(); |
||||
helpBarDef.updateToolBar(editHelpBar); |
||||
return editHelpBar; |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return DesignKit.i18nText("Plugin-icgq_Query"); |
||||
} |
||||
|
||||
private void refresh() { |
||||
java.util.List<ParameterProvider> existParameterList = editorPane.update(); |
||||
ParameterProvider[] ps = existParameterList == null ? new ParameterProvider[0] : existParameterList.toArray(new ParameterProvider[0]); |
||||
editorPane.populate(ps); |
||||
} |
||||
|
||||
private class PreviewAction extends UpdateAction { |
||||
public PreviewAction() { |
||||
this.setName(PREVIEW_BUTTON); |
||||
this.setMnemonic('P'); |
||||
this.setSmallIcon(IOKit.readIcon(ICON_PREVIEW)); |
||||
} |
||||
|
||||
public void actionPerformed(ActionEvent evt) { |
||||
DesignKit.previewTableData(WebBaseTableDataPane.this.updateBean()); |
||||
} |
||||
} |
||||
|
||||
private class HelpAction extends UpdateAction { |
||||
public HelpAction() { |
||||
this.setName(HELP_BUTTON); |
||||
this.setMnemonic('P'); |
||||
this.setSmallIcon(IOKit.readIcon(ICON_HELP)); |
||||
} |
||||
|
||||
public void actionPerformed(ActionEvent evt) { |
||||
try { |
||||
Desktop.getDesktop().browse(URI.create(HELP_URL)); |
||||
} catch (IOException e1) { |
||||
LogKit.error(e1.getMessage(), e1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected class RefreshAction extends UITableEditAction { |
||||
public RefreshAction() { |
||||
this.setName(REFRESH_BUTTON); |
||||
this.setSmallIcon(IOKit.readIcon(ICON_REFRESH)); |
||||
} |
||||
|
||||
public void actionPerformed(ActionEvent e) { |
||||
refresh(); |
||||
} |
||||
|
||||
@Override |
||||
public void checkEnabled() { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,60 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: WechatQueryPane |
||||
* Author: Louis |
||||
* Date: 2021/12/14 15:32 |
||||
*/ |
||||
package com.fr.plugin.icgq.ui; |
||||
|
||||
import com.fanruan.api.design.DesignKit; |
||||
import com.fanruan.api.design.ui.component.UIButtonGroup; |
||||
import com.fanruan.api.design.ui.component.UILabel; |
||||
import com.fanruan.api.design.ui.container.BasicPane; |
||||
import com.fanruan.api.design.ui.layout.TableLayoutKit; |
||||
|
||||
import java.awt.*; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <WebQueryPane> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class WebQueryPane extends BasicPane { |
||||
public static final String[] SEARCH_OPTIONS = new String[]{ |
||||
DesignKit.i18nText("Plugin-icgq_Search_User"), |
||||
DesignKit.i18nText("Plugin-icgq_Search_Department") |
||||
}; |
||||
private UIButtonGroup searchType; |
||||
|
||||
public WebQueryPane() { |
||||
setLayout(new BorderLayout()); |
||||
searchType = new UIButtonGroup<String[]>(SEARCH_OPTIONS); |
||||
searchType.setSelectedIndex(0); |
||||
Component[][] coms = new Component[][]{ |
||||
{new UILabel(DesignKit.i18nText("Plugin-icgq_Search_Type") + ":"), searchType} |
||||
}; |
||||
|
||||
double p = TableLayoutKit.PREFERRED; |
||||
double f = TableLayoutKit.FILL; |
||||
double[] rowSize = {p}; |
||||
double[] columnSize = {p, f}; |
||||
|
||||
add(TableLayoutKit.createTableLayoutPane(coms, rowSize, columnSize)); |
||||
} |
||||
|
||||
@Override |
||||
protected String title4PopupWindow() { |
||||
return DesignKit.i18nText("Plugin-icgq_Query"); |
||||
} |
||||
|
||||
public int getSearchType() { |
||||
return searchType.getSelectedIndex(); |
||||
} |
||||
|
||||
public void setSearchType(int searchType) { |
||||
this.searchType.setSelectedIndex(searchType); |
||||
} |
||||
} |
After Width: | Height: | Size: 817 B |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,15 @@
|
||||
Plugin-icgq=Sso Plugin |
||||
Plugin-icgq_Group=Sso Plugin |
||||
Plugin-icgq_Config_ClientId=Client Id |
||||
Plugin-icgq_Config_ClientId_Description=Client Id |
||||
Plugin-icgq_Config_ClientSecret=Client Secret |
||||
Plugin-icgq_Config_ClientSecret_Description=Client Secret |
||||
Plugin-icgq_Licence_Expired=Sso Plugin Licence Expired |
||||
Plugin-icgq_Users_Table_Data=Users Table Data |
||||
Plugin-icgq_Query=Query |
||||
Plugin-icgq_Help=Help |
||||
Plugin-icgq_Preview=Preview |
||||
Plugin-icgq_Refresh=Refresh |
||||
Plugin-icgq_Search_Type=Search Type |
||||
Plugin-icgq_Search_User=User |
||||
Plugin-icgq_Search_Department=Department |
@ -0,0 +1,15 @@
|
||||
Plugin-icgq=\u7528\u6237\u540C\u6B65\u63D2\u4EF6 |
||||
Plugin-icgq_Group=\u7528\u6237\u540C\u6B65\u63D2\u4EF6 |
||||
Plugin-icgq_Config_ClientId=\u5E94\u7528ID |
||||
Plugin-icgq_Config_ClientId_Description=\u5E94\u7528ID |
||||
Plugin-icgq_Config_ClientSecret=\u5E94\u7528\u79D8\u94A5 |
||||
Plugin-icgq_Config_ClientSecret_Description=\u5E94\u7528\u79D8\u94A5 |
||||
Plugin-icgq_Licence_Expired=\u7528\u6237\u540C\u6B65\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F |
||||
Plugin-icgq_Users_Table_Data=\u7528\u6237\u6570\u636E\u96C6 |
||||
Plugin-icgq_Query=\u67E5\u8BE2 |
||||
Plugin-icgq_Help=\u5E2E\u52A9\u6587\u6863 |
||||
Plugin-icgq_Preview=\u9884\u89C8 |
||||
Plugin-icgq_Refresh=\u5237\u65B0 |
||||
Plugin-icgq_Search_Type=\u64CD\u4F5C\u79CD\u7C7B |
||||
Plugin-icgq_Search_User=\u7528\u6237 |
||||
Plugin-icgq_Search_Department=\u90E8\u95E8 |
Loading…
Reference in new issue