From 7772b404dc2e4db87e9dfaaa51ebc5bf3884503f Mon Sep 17 00:00:00 2001 From: "youhong.ai" Date: Wed, 10 May 2023 14:15:05 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E9=9B=85=E8=AF=97=E5=85=B0=E9=BB=9B?= =?UTF-8?q?=E6=8B=86=E5=8D=95=E6=8A=A5=E8=A1=A8=E3=80=81=E6=B4=B2=E9=99=85?= =?UTF-8?q?=E9=85=92=E5=BA=97=E4=BB=BB=E5=8A=A1=E5=85=83=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/common/Utils.js | 31 +- javascript/common/dev.js | 7 + .../youhong.ai/pcn/workflow_code_block.js | 60 +- src/main/java/aiyh/utils/ScriptUtil.java | 25 + src/main/java/aiyh/utils/Util.java | 26 + .../aiyh/utils/recordset/ResultMapper.java | 8 +- .../tool/cn/hutool/http/ContentType.java | 161 ++ .../tool/cn/hutool/http/GlobalHeaders.java | 229 +++ .../cn/hutool/http/GlobalInterceptor.java | 94 + .../utils/tool/cn/hutool/http/HTMLFilter.java | 539 ++++++ .../utils/tool/cn/hutool/http/Header.java | 153 ++ .../utils/tool/cn/hutool/http/HtmlUtil.java | 212 +++ .../utils/tool/cn/hutool/http/HttpBase.java | 357 ++++ .../utils/tool/cn/hutool/http/HttpConfig.java | 300 +++ .../tool/cn/hutool/http/HttpConnection.java | 568 ++++++ .../tool/cn/hutool/http/HttpDownloader.java | 122 ++ .../tool/cn/hutool/http/HttpException.java | 36 + .../tool/cn/hutool/http/HttpGlobalConfig.java | 214 +++ .../tool/cn/hutool/http/HttpInputStream.java | 108 ++ .../tool/cn/hutool/http/HttpInterceptor.java | 56 + .../tool/cn/hutool/http/HttpRequest.java | 1393 ++++++++++++++ .../tool/cn/hutool/http/HttpResource.java | 56 + .../tool/cn/hutool/http/HttpResponse.java | 644 +++++++ .../utils/tool/cn/hutool/http/HttpStatus.java | 222 +++ .../utils/tool/cn/hutool/http/HttpUtil.java | 893 +++++++++ .../utils/tool/cn/hutool/http/Method.java | 10 + .../cn/hutool/http/MultipartOutputStream.java | 185 ++ .../utils/tool/cn/hutool/http/Status.java | 189 ++ .../tool/cn/hutool/http/body/BytesBody.java | 40 + .../hutool/http/body/FormUrlEncodedBody.java | 38 + .../cn/hutool/http/body/MultipartBody.java | 89 + .../tool/cn/hutool/http/body/RequestBody.java | 32 + .../cn/hutool/http/body/package-info.java | 6 + .../http/cookie/GlobalCookieManager.java | 109 ++ .../http/cookie/ThreadLocalCookieStore.java | 75 + .../cn/hutool/http/cookie/package-info.java | 6 + .../tool/cn/hutool/http/package-info.java | 6 + .../cn/hutool/http/server/HttpServerBase.java | 57 + .../hutool/http/server/HttpServerRequest.java | 442 +++++ .../http/server/HttpServerResponse.java | 429 +++++ .../cn/hutool/http/server/SimpleServer.java | 226 +++ .../cn/hutool/http/server/action/Action.java | 26 + .../hutool/http/server/action/RootAction.java | 86 + .../http/server/action/package-info.java | 6 + .../hutool/http/server/filter/HttpFilter.java | 27 + .../http/server/filter/SimpleFilter.java | 17 + .../http/server/filter/package-info.java | 4 + .../http/server/handler/ActionHandler.java | 38 + .../http/server/handler/package-info.java | 4 + .../cn/hutool/http/server/package-info.java | 6 + .../http/ssl/AndroidSupportSSLFactory.java | 25 + .../http/ssl/CustomProtocolsSSLFactory.java | 97 + .../cn/hutool/http/ssl/DefaultSSLFactory.java | 14 + .../cn/hutool/http/ssl/DefaultSSLInfo.java | 32 + .../http/ssl/SSLSocketFactoryBuilder.java | 95 + .../http/ssl/TrustAnyHostnameVerifier.java | 17 + .../tool/cn/hutool/http/ssl/package-info.java | 6 + .../cn/hutool/http/useragent/Browser.java | 140 ++ .../tool/cn/hutool/http/useragent/Engine.java | 62 + .../tool/cn/hutool/http/useragent/OS.java | 107 ++ .../cn/hutool/http/useragent/Platform.java | 147 ++ .../cn/hutool/http/useragent/UserAgent.java | 196 ++ .../hutool/http/useragent/UserAgentInfo.java | 114 ++ .../http/useragent/UserAgentParser.java | 108 ++ .../hutool/http/useragent/UserAgentUtil.java | 20 + .../hutool/http/useragent/package-info.java | 6 + .../cn/hutool/http/webservice/SoapClient.java | 654 +++++++ .../hutool/http/webservice/SoapProtocol.java | 35 + .../http/webservice/SoapRuntimeException.java | 32 + .../cn/hutool/http/webservice/SoapUtil.java | 91 + .../hutool/http/webservice/package-info.java | 6 + .../contoller/TaskElementController.java | 61 + .../entity/IhgTaskElementConfigItem.java | 43 + .../taskele/mapper/TaskElementMapper.java | 97 + .../mapstruct/TaskElementMapstruct.java | 30 + .../service/TaskElementGetValueInterface.java | 20 + .../taskele/service/TaskElementService.java | 160 ++ .../taskele/vo/IhgTaskElementVo.java | 41 + .../controller/OpenTheBillController.java | 73 + .../controller/OpenThenBillController.java | 38 - .../openbill/mapper/OpenTheBillMapper.java | 69 + .../openbill/mapper/OpenThenBillMapper.java | 26 - .../openbill/pojo/ConditionDetail.java | 23 + .../openbill/pojo/ConditionEntity.java | 26 + .../openbill/service/OpenTheBillService.java | 572 ++++++ .../openbill/service/OpenThenBillService.java | 30 - .../yashilandai/openbill/util/ExcelBody.java | 18 + .../yashilandai/openbill/util/ExcelCell.java | 23 + .../yashilandai/openbill/util/ExcelHead.java | 20 + .../yashilandai/openbill/util/ExcelPort.java | 135 ++ .../yashilandai/openbill/util/ExcelRow.java | 23 + .../yashilandai/openbill/util/ExcelSheet.java | 22 + .../openbill/util/IExcelCellStyleCreator.java | 28 + .../config/service/DealWithMapping.java | 2 +- .../sapdocking/VoucherPayableNewAction.java | 7 +- .../service/VoucherPayableService.java | 14 +- .../action/CaElectronicSignatureAction.java | 4 +- .../cusgetvalue/FileToBase64CusGetValue.java | 12 +- .../esteeLauderExcelExport.properties | 112 ++ .../CommonFaCallbackController.java | 45 +- .../service/CommonFaService.java | 431 ++--- .../controller/MobileController.java | 85 + .../controller/SupportAction.java | 258 +++ .../com/api/supportCenter/pojo/ChartBean.java | 71 + .../api/supportCenter/pojo/MobileEvents.java | 247 +++ .../service/Impl/SupportServiceImpl.java | 1671 +++++++++++++++++ .../supportCenter/service/SupportService.java | 75 + .../common_fadada/mapper/ActionMapper.java | 161 +- .../wang/shyl/dataasync/AsyncTest.java | 663 ++++--- .../java/youhong/ai/utiltest/GenericTest.java | 22 +- .../youhong/ai/yashilandai/GroupByTime.java | 8 - .../java/youhong/ai/yashilandai/MyTest.java | 21 +- .../java/youhong/ai/yihong/YiHongTest.java | 12 + view-sql-server.sql | 60 +- 常用信息.md | 12 +- 115 files changed, 15431 insertions(+), 811 deletions(-) create mode 100644 src/main/java/aiyh/utils/ScriptUtil.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ContentType.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalHeaders.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalInterceptor.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HTMLFilter.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/Header.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HtmlUtil.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpBase.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConfig.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConnection.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpDownloader.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpException.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpGlobalConfig.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInputStream.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInterceptor.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpRequest.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResource.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResponse.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpStatus.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/HttpUtil.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/Method.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/MultipartOutputStream.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/Status.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/body/BytesBody.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/body/FormUrlEncodedBody.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/body/MultipartBody.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/body/RequestBody.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/body/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/GlobalCookieManager.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/ThreadLocalCookieStore.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerBase.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerRequest.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerResponse.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/SimpleServer.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/Action.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/RootAction.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/HttpFilter.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/SimpleFilter.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/ActionHandler.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/server/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/AndroidSupportSSLFactory.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLFactory.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLInfo.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/TrustAnyHostnameVerifier.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/package-info.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Browser.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Engine.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/OS.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Platform.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgent.java create mode 100755 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentInfo.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentParser.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentUtil.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/package-info.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapClient.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapProtocol.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapRuntimeException.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapUtil.java create mode 100644 src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/package-info.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapstruct/TaskElementMapstruct.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementGetValueInterface.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java create mode 100644 src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenTheBillController.java delete mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenThenBillController.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenTheBillMapper.java delete mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenThenBillMapper.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionDetail.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionEntity.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenTheBillService.java delete mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenThenBillService.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelBody.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelCell.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelHead.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelPort.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelRow.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelSheet.java create mode 100644 src/main/java/com/api/youhong/ai/yashilandai/openbill/util/IExcelCellStyleCreator.java create mode 100644 src/main/resources/WEB-INF/prop/prop2map/esteeLauderExcelExport.properties create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/controller/MobileController.java create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/controller/SupportAction.java create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/pojo/ChartBean.java create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/pojo/MobileEvents.java create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/service/Impl/SupportServiceImpl.java create mode 100644 src/main/youhong_ai_old_src/com/api/supportCenter/service/SupportService.java diff --git a/javascript/common/Utils.js b/javascript/common/Utils.js index 6c960d1..5b7d700 100644 --- a/javascript/common/Utils.js +++ b/javascript/common/Utils.js @@ -1,9 +1,9 @@ -window.Utils = { +class CusUtils { /** * @author youhong.ai * @desc 发起请求 */ - request: function (url, type = "GET", data, isAsync = true, success = () => { + request(url, type = "GET", data, isAsync = true, success = () => { }, error = () => { }, complete = () => { }, contentType = 'application/json', beforeSend = () => { @@ -24,13 +24,13 @@ window.Utils = { options.data = JSON.stringify(data) } return $.ajax(options) - }, + } /** * @author youhong.ai * @desc 发起请求 */ - api: function (requestOptions = { + api(requestOptions = { url: "", type: "GET", data: "", @@ -61,13 +61,13 @@ window.Utils = { } }, requestOptions) return $.ajax(options) - }, + } /** * @author youhong.ai * @desc 获取react组件实例 */ - findReact: function (dom, traverseUp = 0) { + findReact(dom, traverseUp = 0) { const key = Object.keys(dom).find(key => { return key.startsWith("__reactFiber$") // react 17+ || key.startsWith("__reactInternalInstance$") @@ -96,7 +96,7 @@ window.Utils = { compFiber = GetCompFiber(compFiber); } return compFiber.stateNode; - }, + } /** @@ -104,7 +104,7 @@ window.Utils = { * @param fieldName 字段名称 * @returns {*|string} */ - convertNameToIdUtil: function (fieldName) { + convertNameToIdUtil(fieldName) { let fieldIds = []; if (fieldName instanceof Array) { fieldName.forEach(item => { @@ -113,19 +113,19 @@ window.Utils = { return fieldIds.join(',') } return Utils.convertNameObjToId(fieldName) - }, + } /** * 将字段名称转为字段id * @param fieldObj 字段名称对象 {string|object} * @returns {*} */ - convertNameObjToId: function (fieldObj = {fieldName: '', table: 'main'}) { + convertNameObjToId(fieldObj = {fieldName: '', table: 'main'}) { if (typeof fieldObj === 'object') { return WfForm.convertFieldNameToId(fieldObj.fieldName, fieldObj.table) } return WfForm.convertFieldNameToId(fieldObj) - }, + } /** * 根据字段名称查询字段值 @@ -133,17 +133,18 @@ window.Utils = { * @param rowIndex 明细行下表(明细获取才传递) * @returns {*} 字段值 */ - getFiledValueByName: function (fieldName, rowIndex) { + getFiledValueByName(fieldName, rowIndex) { return WfForm.getFieldValue(Utils.convertNameObjToId(fieldName) + (rowIndex ? '_' + rowIndex : '')) - }, + } /** * 通过字段名称修改字段值 * @param fieldName 字段名称 * @param value 值 */ - changeFieldValueByName: function (fieldName, value) { + changeFieldValueByName(fieldName, value) { WfForm.changeFieldValue(Utils.convertNameObjToId(fieldName), {value}) } - } + +window.Utils = new CusUtils() diff --git a/javascript/common/dev.js b/javascript/common/dev.js index cb46f64..331fa30 100644 --- a/javascript/common/dev.js +++ b/javascript/common/dev.js @@ -1,3 +1,10 @@ +const ecodeSDK = {} +ecodeSDK.setCom = (id, name, Com) => { +} +ecodeSDK.imp = (obj) => { +} +ecodeSDK.exp = (obj) => { +} const WfForm = { isMobile: () => { // true表示是eMobile、微信、钉钉等移动终端,false代表PC端 diff --git a/javascript/youhong.ai/pcn/workflow_code_block.js b/javascript/youhong.ai/pcn/workflow_code_block.js index ff52a8a..f99dbcc 100644 --- a/javascript/youhong.ai/pcn/workflow_code_block.js +++ b/javascript/youhong.ai/pcn/workflow_code_block.js @@ -680,4 +680,62 @@ $(() => { }) -/* ******************* 明细数据数量统计添加 end ******************* */ \ No newline at end of file +/* ******************* 明细数据数量统计添加 end ******************* */ + + +/* ******************* 计算年月日 start ******************* */ + +$(() => { + const config = [{ + // 源字段 + sourceField: '', + // 目标字段 + targetField: '', + // 日期加月份字段 + numberField: '' + }, { + sourceField: '', + targetField: '', + numberField: '' + }] + + runJs(); + + function runJs() { + config.forEach(item => { + bindAction(item) + }) + } + + function bindAction(configItem) { + let fieldId = WfForm.convertFieldNameToId(configItem.numberField) + WfForm.bindFieldChangeEvent(fieldId, (obj, id, value) => { + if ("" == value) { + WfForm.changeFieldValue(WfForm.convertFieldNameToId(configItem.targetField, {value: ""})) + return + } + let sourceValue = WfForm.getFieldValue(WfForm.convertFieldNameToId(configItem.sourceField)); + let date = new Date(sourceValue) + date.setMonth(date.getMonth() + +value) + let objectDate = new Date(); + + + let day = objectDate.getDate(); + let month = objectDate.getMonth() + 1; + let year = objectDate.getFullYear(); + WfForm.changeFieldValue(WfForm.convertFieldNameToId(configItem.targetField, { + value: `${year}-${fullNum(month)}-${fullNum(day)}` + })) + }) + } + + function fullNum(i) { + if (i <= 9) { + return '0' + i + } else { + return i + } + } + +}) +/* ******************* 计算年月日 end ******************* */ \ No newline at end of file diff --git a/src/main/java/aiyh/utils/ScriptUtil.java b/src/main/java/aiyh/utils/ScriptUtil.java new file mode 100644 index 0000000..7f6cbd1 --- /dev/null +++ b/src/main/java/aiyh/utils/ScriptUtil.java @@ -0,0 +1,25 @@ +package aiyh.utils; + +import aiyh.utils.tool.org.apache.commons.jexl3.*; + +import java.util.Map; + +/** + *

脚本工具

+ * + *

create: 2023/3/3 23:03

+ * + * @author youHong.ai + */ +public class ScriptUtil { + private static final JexlEngine jexl = new JexlBuilder().create(); + + public static Object invokeScript(String script, Map params) { + JexlContext jc = new MapContext(); + for (Map.Entry entry : params.entrySet()) { + jc.set(entry.getKey(), entry.getValue()); + } + JexlExpression expression = jexl.createExpression(script); + return expression.evaluate(jc); + } +} diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index 61f38fc..fd7046e 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -3751,6 +3751,32 @@ public class Util extends weaver.general.Util { return pathParamMap; } + public static T getClassInstance(String classPath, Class t) { + Class aClass; + try { + aClass = Class.forName(classPath); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("未能找到自定义接口:" + classPath); + } + if (!t.isAssignableFrom(aClass)) { + throw new IllegalArgumentException("自定义接口:" + classPath + " 不是" + + t.getName() + "的子类或实现类!"); + } + Constructor constructor; + try { + constructor = aClass.getConstructor(); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(classPath + "没有空参构造方法,无法获取构造方法对象!"); + } + T o; + try { + o = (T) constructor.newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("无法构造" + classPath + "对象!"); + } + return o; + } + public static Object executeActionProcess(String process, RequestInfo requestInfo) { if (StringUtils.isNullOrEmpty(process)) { return null; diff --git a/src/main/java/aiyh/utils/recordset/ResultMapper.java b/src/main/java/aiyh/utils/recordset/ResultMapper.java index 0e3b2f3..cd3a2d7 100644 --- a/src/main/java/aiyh/utils/recordset/ResultMapper.java +++ b/src/main/java/aiyh/utils/recordset/ResultMapper.java @@ -569,7 +569,9 @@ public class ResultMapper { cassociationValue = paramType.get(declaredField.getType()).apply(String.valueOf(cassociationValue)); } try { - propertyDescriptor.getWriteMethod().invoke(o, cassociationValue); + if (Objects.nonNull(value)) { + propertyDescriptor.getWriteMethod().invoke(o, cassociationValue); + } } catch (Exception e) { Util.getLogger().error("实体数据写入报错:" + fieldName + " => " + value); if (value != null) { @@ -584,7 +586,9 @@ public class ResultMapper { if (collectionMapping != null) { Object collection = collection(rs, collectionMapping, method); try { - propertyDescriptor.getWriteMethod().invoke(o, collection); + if (Objects.nonNull(value)) { + propertyDescriptor.getWriteMethod().invoke(o, collection); + } } catch (Exception e) { Util.getLogger().error("实体数据写入报错:" + fieldName + " => " + value); if (value != null) { diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ContentType.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ContentType.java new file mode 100644 index 0000000..c4b4665 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ContentType.java @@ -0,0 +1,161 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.nio.charset.Charset; + +/** + * 常用Content-Type类型枚举 + * + * @author looly + * @since 4.0.11 + */ +public enum ContentType { + + /** + * 标准表单编码,当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…) + */ + FORM_URLENCODED("application/x-www-form-urlencoded"), + /** + * 文件上传编码,浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition,并加上分割符(boundary) + */ + MULTIPART("multipart/form-data"), + /** + * Rest请求JSON编码 + */ + JSON("application/json"), + /** + * Rest请求XML编码 + */ + XML("application/xml"), + /** + * text/plain编码 + */ + TEXT_PLAIN("text/plain"), + /** + * Rest请求text/xml编码 + */ + TEXT_XML("text/xml"), + /** + * text/html编码 + */ + TEXT_HTML("text/html"), + /** + * application/octet-stream编码 + */ + OCTET_STREAM("application/octet-stream"); + + private final String value; + + /** + * 构造 + * + * @param value ContentType值 + */ + ContentType(String value) { + this.value = value; + } + + /** + * 获取value值 + * + * @return value值 + * @since 5.2.6 + */ + public String getValue() { + return value; + } + + @Override + public String toString() { + return getValue(); + } + + /** + * 输出Content-Type字符串,附带编码信息 + * + * @param charset 编码 + * @return Content-Type字符串 + */ + public String toString(Charset charset) { + return build(this.value, charset); + } + + /** + * 是否为默认Content-Type,默认包括{@code null}和application/x-www-form-urlencoded + * + * @param contentType 内容类型 + * @return 是否为默认Content-Type + * @since 4.1.5 + */ + public static boolean isDefault(String contentType) { + return null == contentType || isFormUrlEncode(contentType); + } + + /** + * 是否为application/x-www-form-urlencoded + * + * @param contentType 内容类型 + * @return 是否为application/x-www-form-urlencoded + */ + public static boolean isFormUrlEncode(String contentType) { + return StrUtil.startWithIgnoreCase(contentType, FORM_URLENCODED.toString()); + } + + /** + * 从请求参数的body中判断请求的Content-Type类型,支持的类型有: + * + *
+	 * 1. application/json
+	 * 1. application/xml
+	 * 
+ * + * @param body 请求参数体 + * @return Content-Type类型,如果无法判断返回null + */ + public static ContentType get(String body) { + ContentType contentType = null; + if (StrUtil.isNotBlank(body)) { + char firstChar = body.charAt(0); + switch (firstChar) { + case '{': + case '[': + // JSON请求体 + contentType = JSON; + break; + case '<': + // XML请求体 + contentType = XML; + break; + + default: + break; + } + } + return contentType; + } + + /** + * 输出Content-Type字符串,附带编码信息 + * + * @param contentType Content-Type类型 + * @param charset 编码 + * @return Content-Type字符串 + * @since 4.5.4 + */ + public static String build(String contentType, Charset charset) { + return StrUtil.format("{};charset={}", contentType, charset.name()); + } + + /** + * 输出Content-Type字符串,附带编码信息 + * + * @param contentType Content-Type 枚举类型 + * @param charset 编码 + * @return Content-Type字符串 + * @since 5.7.15 + */ + public static String build(ContentType contentType, Charset charset) { + return build(contentType.getValue(), charset); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalHeaders.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalHeaders.java new file mode 100644 index 0000000..49de06c --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalHeaders.java @@ -0,0 +1,229 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.util.*; +import java.util.Map.Entry; + +/** + * 全局头部信息
+ * 所有Http请求将共用此全局头部信息,除非在{@link HttpRequest}中自定义头部信息覆盖之 + * + * @author looly + */ +public enum GlobalHeaders { + INSTANCE; + + /** + * 存储头信息 + */ + final Map> headers = new HashMap<>(); + + /** + * 构造 + */ + GlobalHeaders() { + putDefault(false); + } + + /** + * 加入默认的头部信息 + * + * @param isReset 是否重置所有头部信息(删除自定义保留默认) + * @return this + */ + public GlobalHeaders putDefault(boolean isReset) { + // 解决HttpURLConnection中无法自定义Host等头信息的问题 + // https://stackoverflow.com/questions/9096987/how-to-overwrite-http-header-host-in-a-httpurlconnection/9098440 + System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); + + // 解决server certificate change is restricted during renegotiation问题 + System.setProperty("jdk.tls.allowUnsafeServerCertChange", "true"); + System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true"); + + if (isReset) { + this.headers.clear(); + } + + header(aiyh.utils.tool.cn.hutool.http.Header.ACCEPT, "text/html,application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", true); + header(aiyh.utils.tool.cn.hutool.http.Header.ACCEPT_ENCODING, "gzip, deflate", true); + header(aiyh.utils.tool.cn.hutool.http.Header.ACCEPT_LANGUAGE, "zh-CN,zh;q=0.8", true); + // 此Header只有在post请求中有用,因此在HttpRequest的method方法中设置此头信息,此处去掉 + // header(Header.CONTENT_TYPE, ContentType.FORM_URLENCODED.toString(CharsetUtil.CHARSET_UTF_8), true); + header(aiyh.utils.tool.cn.hutool.http.Header.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool", true); + return this; + } + + // ---------------------------------------------------------------- Headers start + + /** + * 根据name获取头信息 + * + * @param name Header名 + * @return Header值 + */ + public String header(String name) { + final List values = headerList(name); + if (CollectionUtil.isEmpty(values)) { + return null; + } + return values.get(0); + } + + /** + * 根据name获取头信息列表 + * + * @param name Header名 + * @return Header值 + * @since 3.1.1 + */ + public List headerList(String name) { + if (StrUtil.isBlank(name)) { + return null; + } + + return headers.get(name.trim()); + } + + /** + * 根据name获取头信息 + * + * @param name Header名 + * @return Header值 + */ + public String header(aiyh.utils.tool.cn.hutool.http.Header name) { + if (null == name) { + return null; + } + return header(name.toString()); + } + + /** + * 设置一个header
+ * 如果覆盖模式,则替换之前的值,否则加入到值列表中 + * + * @param name Header名 + * @param value Header值 + * @param isOverride 是否覆盖已有值 + * @return this + */ + synchronized public GlobalHeaders header(String name, String value, boolean isOverride) { + if (null != name && null != value) { + final List values = headers.get(name.trim()); + if (isOverride || CollectionUtil.isEmpty(values)) { + final ArrayList valueList = new ArrayList<>(); + valueList.add(value); + headers.put(name.trim(), valueList); + } else { + values.add(value.trim()); + } + } + return this; + } + + /** + * 设置一个header
+ * 如果覆盖模式,则替换之前的值,否则加入到值列表中 + * + * @param name Header名 + * @param value Header值 + * @param isOverride 是否覆盖已有值 + * @return this + */ + public GlobalHeaders header(aiyh.utils.tool.cn.hutool.http.Header name, String value, boolean isOverride) { + return header(name.toString(), value, isOverride); + } + + /** + * 设置一个header
+ * 覆盖模式,则替换之前的值 + * + * @param name Header名 + * @param value Header值 + * @return this + */ + public GlobalHeaders header(aiyh.utils.tool.cn.hutool.http.Header name, String value) { + return header(name.toString(), value, true); + } + + /** + * 设置一个header
+ * 覆盖模式,则替换之前的值 + * + * @param name Header名 + * @param value Header值 + * @return this + */ + public GlobalHeaders header(String name, String value) { + return header(name, value, true); + } + + /** + * 设置请求头
+ * 不覆盖原有请求头 + * + * @param headers 请求头 + * @return this + */ + public GlobalHeaders header(Map> headers) { + if (MapUtil.isEmpty(headers)) { + return this; + } + + String name; + for (Entry> entry : headers.entrySet()) { + name = entry.getKey(); + for (String value : entry.getValue()) { + this.header(name, StrUtil.nullToEmpty(value), false); + } + } + return this; + } + + /** + * 移除一个头信息 + * + * @param name Header名 + * @return this + */ + synchronized public GlobalHeaders removeHeader(String name) { + if (name != null) { + headers.remove(name.trim()); + } + return this; + } + + /** + * 移除一个头信息 + * + * @param name Header名 + * @return this + */ + public GlobalHeaders removeHeader(Header name) { + return removeHeader(name.toString()); + } + + /** + * 获取headers + * + * @return Headers Map + */ + public Map> headers() { + return Collections.unmodifiableMap(headers); + } + + /** + * 清除所有头信息,包括全局头信息 + * + * @return this + * @since 5.7.13 + */ + synchronized public GlobalHeaders clearHeaders() { + this.headers.clear(); + return this; + } + // ---------------------------------------------------------------- Headers end + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalInterceptor.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalInterceptor.java new file mode 100755 index 0000000..8c740fb --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/GlobalInterceptor.java @@ -0,0 +1,94 @@ +package aiyh.utils.tool.cn.hutool.http; + +/** + * 全局的拦截器
+ * 包括请求拦截器和响应拦截器 + * + * @author looly + * @since 5.8.0 + */ +public enum GlobalInterceptor { + INSTANCE; + + private final HttpInterceptor.Chain requestInterceptors = new HttpInterceptor.Chain<>(); + private final HttpInterceptor.Chain responseInterceptors = new HttpInterceptor.Chain<>(); + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + */ + synchronized public GlobalInterceptor addRequestInterceptor(HttpInterceptor interceptor) { + this.requestInterceptors.addChain(interceptor); + return this; + } + + /** + * 设置拦截器,用于在响应读取后完成编辑或读取 + * + * @param interceptor 拦截器实现 + * @return this + */ + synchronized public GlobalInterceptor addResponseInterceptor(HttpInterceptor interceptor) { + this.responseInterceptors.addChain(interceptor); + return this; + } + + /** + * 清空请求和响应拦截器 + * + * @return this + */ + public GlobalInterceptor clear() { + clearRequest(); + clearResponse(); + return this; + } + + /** + * 清空请求拦截器 + * + * @return this + */ + synchronized public GlobalInterceptor clearRequest() { + requestInterceptors.clear(); + return this; + } + + /** + * 清空响应拦截器 + * + * @return this + */ + synchronized public GlobalInterceptor clearResponse() { + responseInterceptors.clear(); + return this; + } + + /** + * 复制请求过滤器列表 + * + * @return {@link HttpInterceptor.Chain} + */ + HttpInterceptor.Chain getCopiedRequestInterceptor() { + final HttpInterceptor.Chain copied = new HttpInterceptor.Chain<>(); + for (HttpInterceptor interceptor : this.requestInterceptors) { + copied.addChain(interceptor); + } + return copied; + } + + /** + * 复制响应过滤器列表 + * + * @return {@link HttpInterceptor.Chain} + */ + HttpInterceptor.Chain getCopiedResponseInterceptor() { + final HttpInterceptor.Chain copied = new HttpInterceptor.Chain<>(); + for (HttpInterceptor interceptor : this.responseInterceptors) { + copied.addChain(interceptor); + } + return copied; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HTMLFilter.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HTMLFilter.java new file mode 100644 index 0000000..fcea8de --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HTMLFilter.java @@ -0,0 +1,539 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.lang.Console; +import aiyh.utils.tool.cn.hutool.core.map.SafeConcurrentHashMap; +import aiyh.utils.tool.cn.hutool.core.util.CharUtil; + +import java.util.*; +import java.util.concurrent.ConcurrentMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * HTML过滤器,用于去除XSS(Cross Site Scripting) 漏洞隐患。 + * + *

+ * 此类中的方法非线程安全 + *

+ * + *
+ *     String clean = new HTMLFilter().filter(input);
+ * 
+ *

+ * 此类来自:http://xss-html-filter.sf.net + * + * @author Joseph O'Connell + * @author Cal Hendersen + * @author Michael Semb Wever + */ +public final class HTMLFilter { + + /** + * regex flag union representing /si modifiers in php + **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("\""); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new SafeConcurrentHashMap<>(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new SafeConcurrentHashMap<>(); + + /** + * set of allowed html elements, along with allowed attributes for each element + **/ + private final Map> vAllowed; + /** + * counts of open tags for each (allowable) html element + **/ + private final Map vTagCounts = new HashMap<>(); + + /** + * html elements which must always be self-closing (e.g. "<img />") + **/ + private final String[] vSelfClosingTags; + /** + * html elements which must always have separate opening and closing tags (e.g. "<b></b>") + **/ + private final String[] vNeedClosingTags; + /** + * set of disallowed html elements + **/ + private final String[] vDisallowed; + /** + * attributes which should be checked for valid protocols + **/ + private final String[] vProtocolAtts; + /** + * allowed protocols + **/ + private final String[] vAllowedProtocols; + /** + * tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") + **/ + private final String[] vRemoveBlanks; + /** + * entities allowed within html markup + **/ + private final String[] vAllowedEntities; + /** + * flag determining whether comments are allowed in input String. + */ + private final boolean stripComment; + private final boolean encodeQuotes; + private boolean vDebug = false; + /** + * flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>" becomes "<b> text </g>"). + * If set to false, unbalanced angle brackets will be + * html escaped. + */ + private final boolean alwaysMakeTags; + + /** + * Default constructor. + */ + public HTMLFilter() { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList<>(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList<>(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList<>(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[]{"img"}; + vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"}; + vDisallowed = new String[]{}; + vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp. + vProtocolAtts = new String[]{"src", "href"}; + vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"}; + vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"}; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = true; + } + + /** + * Set debug flag to true. Otherwise use default settings. See the default constructor. + * + * @param debug turn debug on with a true argument + */ + public HTMLFilter(final boolean debug) { + this(); + vDebug = debug; + + } + + /** + * Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + @SuppressWarnings("unchecked") + public HTMLFilter(final Map conf) { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() { + vTagCounts.clear(); + } + + private void debug(final String msg) { + if (vDebug) { + Console.log(msg); + } + } + + // --------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + // --------------------------------------------------------------- + + /** + * given a user submitted input String, filter out any invalid or restricted html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) { + reset(); + String s = input; + + debug("************************************************"); + debug(" INPUT: " + input); + + s = escapeComments(s); + debug(" escapeComments: " + s); + + s = balanceHTML(s); + debug(" balanceHTML: " + s); + + s = checkTags(s); + debug(" checkTags: " + s); + + s = processRemoveBlanks(s); + debug("processRemoveBlanks: " + s); + + s = validateEntities(s); + debug(" validateEntites: " + s); + + debug("************************************************\n\n"); + return s; + } + + public boolean isAlwaysMakeTags() { + return alwaysMakeTags; + } + + public boolean isStripComments() { + return stripComment; + } + + private String escapeComments(final String s) { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) { + final String match = m.group(1); // (.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) { + if (alwaysMakeTags) { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } else { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + final StringBuilder sBuilder = new StringBuilder(buf.toString()); + for (String key : vTagCounts.keySet()) { + for (int ii = 0; ii < vTagCounts.get(key); ii++) { + sBuilder.append(""); + } + } + s = sBuilder.toString(); + + return s; + } + + private String processRemoveBlanks(final String s) { + String result = s; + for (String tag : vRemoveBlanks) { + if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) { + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) { + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) { + if (!inArray(name, vSelfClosingTags)) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + // debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) { + final StringBuilder params = new StringBuilder(); + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList<>(); + final List paramValues = new ArrayList<>(); + while (m2.find()) { + paramNames.add(m2.group(1)); // ([a-z0-9]+) + paramValues.add(m2.group(3)); // (.*?) + } + while (m3.find()) { + paramNames.add(m3.group(1)); // ([a-z0-9]+) + paramValues.add(m3.group(3)); // ([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + + // debug( "paramName='" + paramName + "'" ); + // debug( "paramValue='" + paramValue + "'" ); + // debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) { + if (inArray(paramName, vProtocolAtts)) { + paramValue = processParamProtocol(paramValue); + } + params.append(CharUtil.SPACE).append(paramName).append("=\"").append(paramValue).append("\""); + } + } + + if (inArray(name, vSelfClosingTags)) { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) { + ending = ""; + } + + if (ending == null || ending.length() < 1) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } else { + vTagCounts.put(name, 1); + } + } else { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } else { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1); + if (s.startsWith("#//")) { + s = "#" + s.substring(3); + } + } + } + + return s; + } + + private String decodeEntities(String s) { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.decode(match); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.parseInt(match, 16); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.parseInt(match, 16); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) { + final String one = m.group(1); // ([^&;]*) + final String two = m.group(2); // (?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s) { + if (encodeQuotes) { + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) { + final String one = m.group(1); // (>|^) + final String two = m.group(2); // ([^<]+?) + final String three = m.group(3); // (<|$) + m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three)); + } + m.appendTail(buf); + return buf.toString(); + } else { + return s; + } + } + + private String checkEntity(final String preamble, final String term) { + + return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble; + } + + private boolean isValidEntity(final String entity) { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) { + for (String item : array) { + if (item != null && item.equals(s)) { + return true; + } + } + return false; + } + + private boolean allowed(final String name) { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/Header.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/Header.java new file mode 100644 index 0000000..3723c1f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/Header.java @@ -0,0 +1,153 @@ +package aiyh.utils.tool.cn.hutool.http; + +/** + * Http 头域 + * + * @author Looly + */ +public enum Header { + + //------------------------------------------------------------- 通用头域 + /** + * 提供验证头,例如: + *

+	 * Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
+	 * 
+ */ + AUTHORIZATION("Authorization"), + /** + * 提供给代理服务器的用于身份验证的凭证,例如: + *
+	 * Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
+	 * 
+ */ + PROXY_AUTHORIZATION("Proxy-Authorization"), + /** + * 提供日期和时间标志,说明报文是什么时间创建的 + */ + DATE("Date"), + /** + * 允许客户端和服务器指定与请求/响应连接有关的选项 + */ + CONNECTION("Connection"), + /** + * 给出发送端使用的MIME版本 + */ + MIME_VERSION("MIME-Version"), + /** + * 如果报文采用了分块传输编码(chunked transfer encoding) 方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合 + */ + TRAILER("Trailer"), + /** + * 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 + */ + TRANSFER_ENCODING("Transfer-Encoding"), + /** + * 给出了发送端可能想要"升级"使用的新版本和协议 + */ + UPGRADE("Upgrade"), + /** + * 显示了报文经过的中间节点 + */ + VIA("Via"), + /** + * 指定请求和响应遵循的缓存机制 + */ + CACHE_CONTROL("Cache-Control"), + /** + * 用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同 + */ + PRAGMA("Pragma"), + /** + * 请求表示提交内容类型或返回返回内容的MIME类型 + */ + CONTENT_TYPE("Content-Type"), + + //------------------------------------------------------------- 请求头域 + /** + * 指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回 + */ + HOST("Host"), + /** + * 允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被 追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址 + */ + REFERER("Referer"), + /** + * 指定请求的域 + */ + ORIGIN("Origin"), + /** + * HTTP客户端运行的浏览器类型的详细信息。通过该头部信息,web服务器可以判断到当前HTTP请求的客户端浏览器类别 + */ + USER_AGENT("User-Agent"), + /** + * 指定客户端能够接收的内容类型,内容类型中的先后次序表示客户端接收的先后次序 + */ + ACCEPT("Accept"), + /** + * 指定HTTP客户端浏览器用来展示返回信息所优先选择的语言 + */ + ACCEPT_LANGUAGE("Accept-Language"), + /** + * 指定客户端浏览器可以支持的web服务器返回内容压缩编码类型 + */ + ACCEPT_ENCODING("Accept-Encoding"), + /** + * 浏览器可以接受的字符编码集 + */ + ACCEPT_CHARSET("Accept-Charset"), + /** + * HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器 + */ + COOKIE("Cookie"), + /** + * 请求的内容长度 + */ + CONTENT_LENGTH("Content-Length"), + + //------------------------------------------------------------- 响应头域 + /** + * 提供WWW验证响应头 + */ + WWW_AUTHENTICATE("WWW-Authenticate"), + /** + * Cookie + */ + SET_COOKIE("Set-Cookie"), + /** + * Content-Encoding + */ + CONTENT_ENCODING("Content-Encoding"), + /** + * Content-Disposition + */ + CONTENT_DISPOSITION("Content-Disposition"), + /** + * ETag + */ + ETAG("ETag"), + /** + * 重定向指示到的URL + */ + LOCATION("Location"); + + private final String value; + + Header(String value) { + this.value = value; + } + + /** + * 获取值 + * + * @return 值 + */ + public String getValue() { + return this.value; + } + + @Override + public String toString() { + return getValue(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HtmlUtil.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HtmlUtil.java new file mode 100755 index 0000000..7b9f040 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HtmlUtil.java @@ -0,0 +1,212 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.util.EscapeUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +/** + * HTML工具类 + * + *

+ * 比如我们在使用爬虫爬取HTML页面后,需要对返回页面的HTML内容做一定处理,
+ * 比如去掉指定标签(例如广告栏等)、去除JS、去掉样式等等,这些操作都可以使用此工具类完成。 + * + * @author xiaoleilu + */ +public class HtmlUtil { + + public static final String NBSP = StrUtil.HTML_NBSP; + public static final String AMP = StrUtil.HTML_AMP; + public static final String QUOTE = StrUtil.HTML_QUOTE; + public static final String APOS = StrUtil.HTML_APOS; + public static final String LT = StrUtil.HTML_LT; + public static final String GT = StrUtil.HTML_GT; + + public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; + public static final String RE_SCRIPT = "<[\\s]*?script[^>]*?>.*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; + + private static final char[][] TEXT = new char[256][]; + + static { + // ascii码值最大的是【0x7f=127】,扩展ascii码值最大的是【0xFF=255】,因为ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符,标准ASCII码也叫基础ASCII码。 + for (int i = 0; i < 256; i++) { + TEXT[i] = new char[]{(char) i}; + } + + // special HTML characters + TEXT['\''] = "'".toCharArray(); // 单引号 (''' doesn't work - it is not by the w3 specs) + TEXT['"'] = QUOTE.toCharArray(); // 双引号 + TEXT['&'] = AMP.toCharArray(); // &符 + TEXT['<'] = LT.toCharArray(); // 小于号 + TEXT['>'] = GT.toCharArray(); // 大于号 + TEXT[' '] = NBSP.toCharArray(); // 不断开空格(non-breaking space,缩写nbsp。ASCII值是32:是用键盘输入的空格;ASCII值是160:不间断空格,即  ,所产生的空格,作用是在页面换行时不被打断) + } + + /** + * 转义文本中的HTML字符为安全的字符,以下字符被转义: + *

    + *
  • ' 替换为 &#039; (&apos; doesn't work in HTML4)
  • + *
  • " 替换为 &quot;
  • + *
  • & 替换为 &amp;
  • + *
  • < 替换为 &lt;
  • + *
  • > 替换为 &gt;
  • + *
+ * + * @param text 被转义的文本 + * @return 转义后的文本 + */ + public static String escape(String text) { + return encode(text); + } + + /** + * 还原被转义的HTML特殊字符 + * + * @param htmlStr 包含转义符的HTML内容 + * @return 转换后的字符串 + */ + public static String unescape(String htmlStr) { + if (StrUtil.isBlank(htmlStr)) { + return htmlStr; + } + + return EscapeUtil.unescapeHtml4(htmlStr); + } + + // ---------------------------------------------------------------- encode text + + /** + * 清除所有HTML标签,但是不删除标签内的内容 + * + * @param content 文本 + * @return 清除标签后的文本 + */ + public static String cleanHtmlTag(String content) { + return content.replaceAll(RE_HTML_MARK, ""); + } + + /** + * 清除指定HTML标签和被标签包围的内容
+ * 不区分大小写 + * + * @param content 文本 + * @param tagNames 要清除的标签 + * @return 去除标签后的文本 + */ + public static String removeHtmlTag(String content, String... tagNames) { + return removeHtmlTag(content, true, tagNames); + } + + /** + * 清除指定HTML标签,不包括内容
+ * 不区分大小写 + * + * @param content 文本 + * @param tagNames 要清除的标签 + * @return 去除标签后的文本 + */ + public static String unwrapHtmlTag(String content, String... tagNames) { + return removeHtmlTag(content, false, tagNames); + } + + /** + * 清除指定HTML标签
+ * 不区分大小写 + * + * @param content 文本 + * @param withTagContent 是否去掉被包含在标签中的内容 + * @param tagNames 要清除的标签 + * @return 去除标签后的文本 + */ + public static String removeHtmlTag(String content, boolean withTagContent, String... tagNames) { + String regex; + for (String tagName : tagNames) { + if (StrUtil.isBlank(tagName)) { + continue; + } + tagName = tagName.trim(); + // (?i)表示其后面的表达式忽略大小写 + if (withTagContent) { + // 标签及其包含内容 + regex = StrUtil.format("(?i)<{}(\\s+[^>]*?)?/?>(.*?)?", tagName, tagName); + } else { + // 标签不包含内容 + regex = StrUtil.format("(?i)<{}(\\s+[^>]*?)?/?>|", tagName, tagName); + } + + content = ReUtil.delAll(regex, content); // 非自闭标签小写 + } + return content; + } + + /** + * 去除HTML标签中的属性,如果多个标签有相同属性,都去除 + * + * @param content 文本 + * @param attrs 属性名(不区分大小写) + * @return 处理后的文本 + */ + public static String removeHtmlAttr(String content, String... attrs) { + String regex; + for (String attr : attrs) { + // (?i) 表示忽略大小写 + // \s* 属性名前后的空白符去除 + // [^>]+? 属性值,至少有一个非>的字符,>表示标签结束 + // \s+(?=>) 表示属性值后跟空格加>,即末尾的属性,此时去掉空格 + // (?=\s|>) 表示属性值后跟空格(属性后还有别的属性)或者跟>(最后一个属性) + regex = StrUtil.format("(?i)(\\s*{}\\s*=[^>]+?\\s+(?=>))|(\\s*{}\\s*=[^>]+?(?=\\s|>))", attr, attr); + content = content.replaceAll(regex, StrUtil.EMPTY); + } + return content; + } + + /** + * 去除指定标签的所有属性 + * + * @param content 内容 + * @param tagNames 指定标签 + * @return 处理后的文本 + */ + public static String removeAllHtmlAttr(String content, String... tagNames) { + String regex; + for (String tagName : tagNames) { + regex = StrUtil.format("(?i)<{}[^>]*?>", tagName); + content = content.replaceAll(regex, StrUtil.format("<{}>", tagName)); + } + return content; + } + + /** + * Encoder + * + * @param text 被编码的文本 + * @return 编码后的字符 + */ + private static String encode(String text) { + int len; + if ((text == null) || ((len = text.length()) == 0)) { + return StrUtil.EMPTY; + } + StringBuilder buffer = new StringBuilder(len + (len >> 2)); + char c; + for (int i = 0; i < len; i++) { + c = text.charAt(i); + if (c < 256) { + buffer.append(TEXT[c]); + } else { + buffer.append(c); + } + } + return buffer.toString(); + } + + /** + * 过滤HTML文本,防止XSS攻击 + * + * @param htmlContent HTML内容 + * @return 过滤后的内容 + */ + public static String filter(String htmlContent) { + return new HTMLFilter().filter(htmlContent); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpBase.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpBase.java new file mode 100644 index 0000000..38042ca --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpBase.java @@ -0,0 +1,357 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.map.CaseInsensitiveMap; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.util.CharsetUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.nio.charset.Charset; +import java.util.*; +import java.util.Map.Entry; + +/** + * http基类 + * + * @param 子类类型,方便链式编程 + * @author Looly + */ +@SuppressWarnings("unchecked") +public abstract class HttpBase { + + /** + * 默认的请求编码、URL的encode、decode编码 + */ + protected static final Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8; + + /** + * HTTP/1.0 + */ + public static final String HTTP_1_0 = "HTTP/1.0"; + /** + * HTTP/1.1 + */ + public static final String HTTP_1_1 = "HTTP/1.1"; + + /** + * 存储头信息 + */ + protected Map> headers = new HashMap<>(); + /** + * 编码 + */ + protected Charset charset = DEFAULT_CHARSET; + /** + * http版本 + */ + protected String httpVersion = HTTP_1_1; + /** + * 存储主体 + */ + protected byte[] bodyBytes; + + // ---------------------------------------------------------------- Headers start + + /** + * 根据name获取头信息
+ * 根据RFC2616规范,header的name不区分大小写 + * + * @param name Header名 + * @return Header值 + */ + public String header(String name) { + final List values = headerList(name); + if (CollectionUtil.isEmpty(values)) { + return null; + } + return values.get(0); + } + + /** + * 根据name获取头信息列表 + * + * @param name Header名 + * @return Header值 + * @since 3.1.1 + */ + public List headerList(String name) { + if (StrUtil.isBlank(name)) { + return null; + } + + final CaseInsensitiveMap> headersIgnoreCase = new CaseInsensitiveMap<>(this.headers); + return headersIgnoreCase.get(name.trim()); + } + + /** + * 根据name获取头信息 + * + * @param name Header名 + * @return Header值 + */ + public String header(Header name) { + if (null == name) { + return null; + } + return header(name.toString()); + } + + /** + * 设置一个header
+ * 如果覆盖模式,则替换之前的值,否则加入到值列表中 + * + * @param name Header名 + * @param value Header值 + * @param isOverride 是否覆盖已有值 + * @return T 本身 + */ + public T header(String name, String value, boolean isOverride) { + if (null != name && null != value) { + final List values = headers.get(name.trim()); + if (isOverride || CollectionUtil.isEmpty(values)) { + final ArrayList valueList = new ArrayList<>(); + valueList.add(value); + headers.put(name.trim(), valueList); + } else { + values.add(value.trim()); + } + } + return (T) this; + } + + /** + * 设置一个header
+ * 如果覆盖模式,则替换之前的值,否则加入到值列表中 + * + * @param name Header名 + * @param value Header值 + * @param isOverride 是否覆盖已有值 + * @return T 本身 + */ + public T header(Header name, String value, boolean isOverride) { + return header(name.toString(), value, isOverride); + } + + /** + * 设置一个header
+ * 覆盖模式,则替换之前的值 + * + * @param name Header名 + * @param value Header值 + * @return T 本身 + */ + public T header(Header name, String value) { + return header(name.toString(), value, true); + } + + /** + * 设置一个header
+ * 覆盖模式,则替换之前的值 + * + * @param name Header名 + * @param value Header值 + * @return T 本身 + */ + public T header(String name, String value) { + return header(name, value, true); + } + + /** + * 设置请求头 + * + * @param headers 请求头 + * @param isOverride 是否覆盖已有头信息 + * @return this + * @since 4.6.3 + */ + public T headerMap(Map headers, boolean isOverride) { + if (MapUtil.isEmpty(headers)) { + return (T) this; + } + + for (Entry entry : headers.entrySet()) { + this.header(entry.getKey(), StrUtil.nullToEmpty(entry.getValue()), isOverride); + } + return (T) this; + } + + /** + * 设置请求头
+ * 不覆盖原有请求头 + * + * @param headers 请求头 + * @return this + */ + public T header(Map> headers) { + return header(headers, false); + } + + /** + * 设置请求头 + * + * @param headers 请求头 + * @param isOverride 是否覆盖已有头信息 + * @return this + * @since 4.0.8 + */ + public T header(Map> headers, boolean isOverride) { + if (MapUtil.isEmpty(headers)) { + return (T) this; + } + + String name; + for (Entry> entry : headers.entrySet()) { + name = entry.getKey(); + for (String value : entry.getValue()) { + this.header(name, StrUtil.nullToEmpty(value), isOverride); + } + } + return (T) this; + } + + /** + * 新增请求头
+ * 不覆盖原有请求头 + * + * @param headers 请求头 + * @return this + * @since 4.0.3 + */ + public T addHeaders(Map headers) { + if (MapUtil.isEmpty(headers)) { + return (T) this; + } + + for (Entry entry : headers.entrySet()) { + this.header(entry.getKey(), StrUtil.nullToEmpty(entry.getValue()), false); + } + return (T) this; + } + + /** + * 移除一个头信息 + * + * @param name Header名 + * @return this + */ + public T removeHeader(String name) { + if (name != null) { + headers.remove(name.trim()); + } + return (T) this; + } + + /** + * 移除一个头信息 + * + * @param name Header名 + * @return this + */ + public T removeHeader(Header name) { + return removeHeader(name.toString()); + } + + /** + * 获取headers + * + * @return Headers Map + */ + public Map> headers() { + return Collections.unmodifiableMap(headers); + } + + /** + * 清除所有头信息,包括全局头信息 + * + * @return this + * @since 5.7.13 + */ + public T clearHeaders() { + this.headers.clear(); + return (T) this; + } + // ---------------------------------------------------------------- Headers end + + /** + * 返回http版本 + * + * @return String + */ + public String httpVersion() { + return httpVersion; + } + + /** + * 设置http版本,此方法不会影响到实际请求的HTTP版本,只用于帮助判断是否connect:Keep-Alive + * + * @param httpVersion Http版本,{@link HttpBase#HTTP_1_0},{@link HttpBase#HTTP_1_1} + * @return this + */ + public T httpVersion(String httpVersion) { + this.httpVersion = httpVersion; + return (T) this; + } + + /** + * 获取bodyBytes存储字节码 + * + * @return byte[] + */ + public byte[] bodyBytes() { + return this.bodyBytes; + } + + /** + * 返回字符集 + * + * @return 字符集 + */ + public String charset() { + return charset.name(); + } + + /** + * 设置字符集 + * + * @param charset 字符集 + * @return T 自己 + * @see CharsetUtil + */ + public T charset(String charset) { + if (StrUtil.isNotBlank(charset)) { + charset(Charset.forName(charset)); + } + return (T) this; + } + + /** + * 设置字符集 + * + * @param charset 字符集 + * @return T 自己 + * @see CharsetUtil + */ + public T charset(Charset charset) { + if (null != charset) { + this.charset = charset; + } + return (T) this; + } + + @Override + public String toString() { + StringBuilder sb = StrUtil.builder(); + sb.append("Request Headers: ").append(StrUtil.CRLF); + for (Entry> entry : this.headers.entrySet()) { + sb.append(" ").append( + entry.getKey()).append(": ").append(CollUtil.join(entry.getValue(), ",")) + .append(StrUtil.CRLF); + } + + sb.append("Request Body: ").append(StrUtil.CRLF); + sb.append(" ").append(StrUtil.str(this.bodyBytes, this.charset)).append(StrUtil.CRLF); + + return sb.toString(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConfig.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConfig.java new file mode 100755 index 0000000..ac885fb --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConfig.java @@ -0,0 +1,300 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.lang.Assert; +import aiyh.utils.tool.cn.hutool.core.net.SSLUtil; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import java.net.InetSocketAddress; +import java.net.Proxy; + +/** + * Http配置项 + * + * @author looly + * @since 5.8.0 + */ +public class HttpConfig { + + /** + * 创建默认Http配置信息 + * + * @return HttpConfig + */ + public static HttpConfig create() { + return new HttpConfig(); + } + + /** + * 默认连接超时 + */ + int connectionTimeout = HttpGlobalConfig.getTimeout(); + /** + * 默认读取超时 + */ + int readTimeout = HttpGlobalConfig.getTimeout(); + + /** + * 是否禁用缓存 + */ + boolean isDisableCache; + + /** + * 最大重定向次数 + */ + int maxRedirectCount = HttpGlobalConfig.getMaxRedirectCount(); + + /** + * 代理 + */ + Proxy proxy; + + /** + * HostnameVerifier,用于HTTPS安全连接 + */ + HostnameVerifier hostnameVerifier; + /** + * SSLSocketFactory,用于HTTPS安全连接 + */ + SSLSocketFactory ssf; + + /** + * Chuncked块大小,0或小于0表示不设置Chuncked模式 + */ + int blockSize; + + /** + * 获取是否忽略响应读取时可能的EOF异常。
+ * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
+ * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 + */ + boolean ignoreEOFError = HttpGlobalConfig.isIgnoreEOFError(); + /** + * 获取是否忽略解码URL,包括URL中的Path部分和Param部分。
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + */ + boolean decodeUrl = HttpGlobalConfig.isDecodeUrl(); + + /** + * 请求前的拦截器,用于在请求前重新编辑请求 + */ + final HttpInterceptor.Chain requestInterceptors = GlobalInterceptor.INSTANCE.getCopiedRequestInterceptor(); + /** + * 响应后的拦截器,用于在响应后处理逻辑 + */ + final HttpInterceptor.Chain responseInterceptors = GlobalInterceptor.INSTANCE.getCopiedResponseInterceptor(); + + /** + * 重定向时是否使用拦截器 + */ + boolean interceptorOnRedirect; + + /** + * 设置超时,单位:毫秒
+ * 超时包括: + * + *
+	 * 1. 连接超时
+	 * 2. 读取响应超时
+	 * 
+ * + * @param milliseconds 超时毫秒数 + * @return this + * @see #setConnectionTimeout(int) + * @see #setReadTimeout(int) + */ + public HttpConfig timeout(int milliseconds) { + setConnectionTimeout(milliseconds); + setReadTimeout(milliseconds); + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + */ + public HttpConfig setConnectionTimeout(int milliseconds) { + this.connectionTimeout = milliseconds; + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + */ + public HttpConfig setReadTimeout(int milliseconds) { + this.readTimeout = milliseconds; + return this; + } + + /** + * 禁用缓存 + * + * @return this + */ + public HttpConfig disableCache() { + this.isDisableCache = true; + return this; + } + + /** + * 设置最大重定向次数
+ * 如果次数小于1则表示不重定向,大于等于1表示打开重定向 + * + * @param maxRedirectCount 最大重定向次数 + * @return this + */ + public HttpConfig setMaxRedirectCount(int maxRedirectCount) { + this.maxRedirectCount = Math.max(maxRedirectCount, 0); + return this; + } + + /** + * 设置域名验证器
+ * 只针对HTTPS请求,如果不设置,不做验证,所有域名被信任 + * + * @param hostnameVerifier HostnameVerifier + * @return this + */ + public HttpConfig setHostnameVerifier(HostnameVerifier hostnameVerifier) { + // 验证域 + this.hostnameVerifier = hostnameVerifier; + return this; + } + + /** + * 设置Http代理 + * + * @param host 代理 主机 + * @param port 代理 端口 + * @return this + */ + public HttpConfig setHttpProxy(String host, int port) { + final Proxy proxy = new Proxy(Proxy.Type.HTTP, + new InetSocketAddress(host, port)); + return setProxy(proxy); + } + + /** + * 设置代理 + * + * @param proxy 代理 {@link Proxy} + * @return this + */ + public HttpConfig setProxy(Proxy proxy) { + this.proxy = proxy; + return this; + } + + /** + * 设置SSLSocketFactory
+ * 只针对HTTPS请求,如果不设置,使用默认的SSLSocketFactory
+ * 默认SSLSocketFactory为:SSLSocketFactoryBuilder.create().build(); + * + * @param ssf SSLScketFactory + * @return this + */ + public HttpConfig setSSLSocketFactory(SSLSocketFactory ssf) { + this.ssf = ssf; + return this; + } + + /** + * 设置HTTPS安全连接协议,只针对HTTPS请求,可以使用的协议包括:
+ * 此方法调用后{@link #setSSLSocketFactory(SSLSocketFactory)} 将被覆盖。 + * + *
+	 * 1. TLSv1.2
+	 * 2. TLSv1.1
+	 * 3. SSLv3
+	 * ...
+	 * 
+ * + * @param protocol 协议 + * @return this + * @see SSLUtil#createSSLContext(String) + * @see #setSSLSocketFactory(SSLSocketFactory) + */ + public HttpConfig setSSLProtocol(String protocol) { + Assert.notBlank(protocol, "protocol must be not blank!"); + setSSLSocketFactory(SSLUtil.createSSLContext(protocol).getSocketFactory()); + return this; + } + + /** + * 采用流方式上传数据,无需本地缓存数据。
+ * HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。 + * + * @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式 + * @return this + */ + public HttpConfig setBlockSize(int blockSize) { + this.blockSize = blockSize; + return this; + } + + /** + * 设置是否忽略响应读取时可能的EOF异常。
+ * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
+ * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 + * + * @param ignoreEOFError 是否忽略响应读取时可能的EOF异常。 + * @return this + * @since 5.7.20 + */ + public HttpConfig setIgnoreEOFError(boolean ignoreEOFError) { + this.ignoreEOFError = ignoreEOFError; + return this; + } + + /** + * 设置是否忽略解码URL,包括URL中的Path部分和Param部分。
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + * + * @param decodeUrl 是否忽略解码URL + * @return this + */ + public HttpConfig setDecodeUrl(boolean decodeUrl) { + this.decodeUrl = decodeUrl; + return this; + } + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + */ + public HttpConfig addRequestInterceptor(HttpInterceptor interceptor) { + this.requestInterceptors.addChain(interceptor); + return this; + } + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + */ + public HttpConfig addResponseInterceptor(HttpInterceptor interceptor) { + this.responseInterceptors.addChain(interceptor); + return this; + } + + /** + * 重定向时是否使用拦截器 + * + * @param interceptorOnRedirect 重定向时是否使用拦截器 + * @return this + */ + public HttpConfig setInterceptorOnRedirect(boolean interceptorOnRedirect) { + this.interceptorOnRedirect = interceptorOnRedirect; + return this; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConnection.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConnection.java new file mode 100644 index 0000000..571c8d2 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpConnection.java @@ -0,0 +1,568 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.util.ObjectUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReflectUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.core.util.URLUtil; +import aiyh.utils.tool.cn.hutool.http.ssl.DefaultSSLInfo; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * http连接对象,对HttpURLConnection的包装 + * + * @author Looly + */ +public class HttpConnection { + + private final URL url; + private final Proxy proxy; + private HttpURLConnection conn; + + /** + * 创建HttpConnection + * + * @param urlStr URL + * @param proxy 代理,无代理传{@code null} + * @return HttpConnection + */ + public static HttpConnection create(String urlStr, Proxy proxy) { + return create(URLUtil.toUrlForHttp(urlStr), proxy); + } + + /** + * 创建HttpConnection + * + * @param url URL + * @param proxy 代理,无代理传{@code null} + * @return HttpConnection + */ + public static HttpConnection create(URL url, Proxy proxy) { + return new HttpConnection(url, proxy); + } + + // --------------------------------------------------------------- Constructor start + + /** + * 构造HttpConnection + * + * @param url URL + * @param proxy 代理 + */ + public HttpConnection(URL url, Proxy proxy) { + this.url = url; + this.proxy = proxy; + + // 初始化Http连接 + initConn(); + } + + // --------------------------------------------------------------- Constructor end + + /** + * 初始化连接相关信息 + * + * @return HttpConnection + * @since 4.4.1 + */ + public HttpConnection initConn() { + try { + this.conn = openHttp(); + } catch (IOException e) { + throw new HttpException(e); + } + + // 默认读取响应内容 + this.conn.setDoInput(true); + + return this; + } + + // --------------------------------------------------------------- Getters And Setters start + + /** + * 获取请求方法,GET/POST + * + * @return 请求方法, GET/POST + */ + public aiyh.utils.tool.cn.hutool.http.Method getMethod() { + return aiyh.utils.tool.cn.hutool.http.Method.valueOf(this.conn.getRequestMethod()); + } + + /** + * 设置请求方法 + * + * @param method 请求方法 + * @return 自己 + */ + public HttpConnection setMethod(aiyh.utils.tool.cn.hutool.http.Method method) { + if (aiyh.utils.tool.cn.hutool.http.Method.POST.equals(method) // + || aiyh.utils.tool.cn.hutool.http.Method.PUT.equals(method)// + || aiyh.utils.tool.cn.hutool.http.Method.PATCH.equals(method)// + || aiyh.utils.tool.cn.hutool.http.Method.DELETE.equals(method)) { + this.conn.setUseCaches(false); + + // 增加PATCH方法支持 + if (aiyh.utils.tool.cn.hutool.http.Method.PATCH.equals(method)) { + try { + HttpGlobalConfig.allowPatch(); + } catch (Exception ignore) { + // ignore + // https://github.com/dromara/hutool/issues/2832 + } + } + } + + // method + try { + this.conn.setRequestMethod(method.toString()); + } catch (ProtocolException e) { + if (aiyh.utils.tool.cn.hutool.http.Method.PATCH.equals(method)) { + // 如果全局设置失效,此处针对单独链接重新设置 + reflectSetMethod(method); + } else { + throw new HttpException(e); + } + } + return this; + } + + /** + * 获取请求URL + * + * @return 请求URL + */ + public URL getUrl() { + return url; + } + + /** + * 获得代理 + * + * @return {@link Proxy} + */ + public Proxy getProxy() { + return proxy; + } + + /** + * 获取HttpURLConnection对象 + * + * @return HttpURLConnection + */ + public HttpURLConnection getHttpURLConnection() { + return conn; + } + + // --------------------------------------------------------------- Getters And Setters end + + // ---------------------------------------------------------------- Headers start + + /** + * 设置请求头
+ * 当请求头存在时,覆盖之 + * + * @param header 头名 + * @param value 头值 + * @param isOverride 是否覆盖旧值 + * @return HttpConnection + */ + public HttpConnection header(String header, String value, boolean isOverride) { + if (null != this.conn) { + if (isOverride) { + this.conn.setRequestProperty(header, value); + } else { + this.conn.addRequestProperty(header, value); + } + } + + return this; + } + + /** + * 设置请求头
+ * 当请求头存在时,覆盖之 + * + * @param header 头名 + * @param value 头值 + * @param isOverride 是否覆盖旧值 + * @return HttpConnection + */ + public HttpConnection header(aiyh.utils.tool.cn.hutool.http.Header header, String value, boolean isOverride) { + return header(header.toString(), value, isOverride); + } + + /** + * 设置请求头
+ * 不覆盖原有请求头 + * + * @param headerMap 请求头 + * @param isOverride 是否覆盖 + * @return this + */ + public HttpConnection header(Map> headerMap, boolean isOverride) { + if (MapUtil.isNotEmpty(headerMap)) { + String name; + for (Entry> entry : headerMap.entrySet()) { + name = entry.getKey(); + for (String value : entry.getValue()) { + this.header(name, StrUtil.nullToEmpty(value), isOverride); + } + } + } + return this; + } + + /** + * 获取Http请求头 + * + * @param name Header名 + * @return Http请求头值 + */ + public String header(String name) { + return this.conn.getHeaderField(name); + } + + /** + * 获取Http请求头 + * + * @param name Header名 + * @return Http请求头值 + */ + public String header(aiyh.utils.tool.cn.hutool.http.Header name) { + return header(name.toString()); + } + + /** + * 获取所有Http请求头 + * + * @return Http请求头Map + */ + public Map> headers() { + return this.conn.getHeaderFields(); + } + + // ---------------------------------------------------------------- Headers end + + /** + * 设置https请求参数
+ * 有些时候htts请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现,此为sun内部api,按照普通http请求处理 + * + * @param hostnameVerifier 域名验证器,非https传入null + * @param ssf SSLSocketFactory,非https传入null + * @return this + * @throws HttpException KeyManagementException和NoSuchAlgorithmException异常包装 + */ + public HttpConnection setHttpsInfo(HostnameVerifier hostnameVerifier, SSLSocketFactory ssf) throws HttpException { + final HttpURLConnection conn = this.conn; + + if (conn instanceof HttpsURLConnection) { + // Https请求 + final HttpsURLConnection httpsConn = (HttpsURLConnection) conn; + // 验证域 + httpsConn.setHostnameVerifier(ObjectUtil.defaultIfNull(hostnameVerifier, DefaultSSLInfo.TRUST_ANY_HOSTNAME_VERIFIER)); + httpsConn.setSSLSocketFactory(ObjectUtil.defaultIfNull(ssf, DefaultSSLInfo.DEFAULT_SSF)); + } + + return this; + } + + /** + * 关闭缓存 + * + * @return this + * @see HttpURLConnection#setUseCaches(boolean) + */ + public HttpConnection disableCache() { + this.conn.setUseCaches(false); + return this; + } + + /** + * 设置连接超时 + * + * @param timeout 超时 + * @return this + */ + public HttpConnection setConnectTimeout(int timeout) { + if (timeout > 0 && null != this.conn) { + this.conn.setConnectTimeout(timeout); + } + + return this; + } + + /** + * 设置读取超时 + * + * @param timeout 超时 + * @return this + */ + public HttpConnection setReadTimeout(int timeout) { + if (timeout > 0 && null != this.conn) { + this.conn.setReadTimeout(timeout); + } + + return this; + } + + /** + * 设置连接和读取的超时时间 + * + * @param timeout 超时时间 + * @return this + */ + public HttpConnection setConnectionAndReadTimeout(int timeout) { + setConnectTimeout(timeout); + setReadTimeout(timeout); + + return this; + } + + /** + * 设置Cookie + * + * @param cookie Cookie + * @return this + */ + public HttpConnection setCookie(String cookie) { + if (cookie != null) { + header(Header.COOKIE, cookie, true); + } + return this; + } + + /** + * 采用流方式上传数据,无需本地缓存数据。
+ * HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。 + * + * @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式 + * @return this + */ + public HttpConnection setChunkedStreamingMode(int blockSize) { + if (blockSize > 0) { + conn.setChunkedStreamingMode(blockSize); + } + return this; + } + + /** + * 设置自动HTTP 30X跳转 + * + * @param isInstanceFollowRedirects 是否自定跳转 + * @return this + */ + public HttpConnection setInstanceFollowRedirects(boolean isInstanceFollowRedirects) { + conn.setInstanceFollowRedirects(isInstanceFollowRedirects); + return this; + } + + /** + * 连接 + * + * @return this + * @throws IOException IO异常 + */ + public HttpConnection connect() throws IOException { + if (null != this.conn) { + this.conn.connect(); + } + return this; + } + + /** + * 静默断开连接。不抛出异常 + * + * @return this + * @since 4.6.0 + */ + public HttpConnection disconnectQuietly() { + try { + disconnect(); + } catch (Throwable e) { + // ignore + } + + return this; + } + + /** + * 断开连接 + * + * @return this + */ + public HttpConnection disconnect() { + if (null != this.conn) { + this.conn.disconnect(); + } + return this; + } + + /** + * 获得输入流对象
+ * 输入流对象用于读取数据 + * + * @return 输入流对象 + * @throws IOException IO异常 + */ + public InputStream getInputStream() throws IOException { + if (null != this.conn) { + return this.conn.getInputStream(); + } + return null; + } + + /** + * 当返回错误代码时,获得错误内容流 + * + * @return 错误内容 + */ + public InputStream getErrorStream() { + if (null != this.conn) { + return this.conn.getErrorStream(); + } + return null; + } + + /** + * 获取输出流对象 输出流对象用于发送数据 + * + * @return OutputStream + * @throws IOException IO异常 + */ + public OutputStream getOutputStream() throws IOException { + if (null == this.conn) { + throw new IOException("HttpURLConnection has not been initialized."); + } + + final aiyh.utils.tool.cn.hutool.http.Method method = getMethod(); + + // 当有写出需求时,自动打开之 + this.conn.setDoOutput(true); + final OutputStream out = this.conn.getOutputStream(); + + // 解决在Rest请求中,GET请求附带body导致GET请求被强制转换为POST + // 在sun.net.www.protocol.http.HttpURLConnection.getOutputStream0方法中,会把GET方法 + // 修改为POST,而且无法调用setRequestMethod方法修改,因此此处使用反射强制修改字段属性值 + // https://stackoverflow.com/questions/978061/http-get-with-request-body/983458 + if (method == aiyh.utils.tool.cn.hutool.http.Method.GET && method != getMethod()) { + reflectSetMethod(method); + } + + return out; + } + + /** + * 获取响应码 + * + * @return 响应码 + * @throws IOException IO异常 + */ + public int responseCode() throws IOException { + if (null != this.conn) { + return this.conn.getResponseCode(); + } + return 0; + } + + /** + * 获得字符集编码
+ * 从Http连接的头信息中获得字符集
+ * 从ContentType中获取 + * + * @return 字符集编码 + */ + public String getCharsetName() { + return HttpUtil.getCharset(conn); + } + + /** + * 获取字符集编码
+ * 从Http连接的头信息中获得字符集
+ * 从ContentType中获取 + * + * @return {@link Charset}编码 + * @since 3.0.9 + */ + public Charset getCharset() { + Charset charset = null; + final String charsetName = getCharsetName(); + if (StrUtil.isNotBlank(charsetName)) { + try { + charset = Charset.forName(charsetName); + } catch (UnsupportedCharsetException e) { + // ignore + } + } + return charset; + } + + @Override + public String toString() { + StringBuilder sb = StrUtil.builder(); + sb.append("Request URL: ").append(this.url).append(StrUtil.CRLF); + sb.append("Request Method: ").append(this.getMethod()).append(StrUtil.CRLF); + // sb.append("Request Headers: ").append(StrUtil.CRLF); + // for (Entry> entry : this.conn.getHeaderFields().entrySet()) { + // sb.append(" ").append(entry).append(StrUtil.CRLF); + // } + + return sb.toString(); + } + + // --------------------------------------------------------------- Private Method start + + /** + * 初始化http或https请求参数
+ * 有些时候https请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现,此为sun内部api,按照普通http请求处理 + * + * @return {@link HttpURLConnection},https返回{@link HttpsURLConnection} + */ + private HttpURLConnection openHttp() throws IOException { + final URLConnection conn = openConnection(); + if (!(conn instanceof HttpURLConnection)) { + // 防止其它协议造成的转换异常 + throw new HttpException("'{}' of URL [{}] is not a http connection, make sure URL is format for http.", conn.getClass().getName(), this.url); + } + + return (HttpURLConnection) conn; + } + + /** + * 建立连接 + * + * @return {@link URLConnection} + * @throws IOException IO异常 + */ + private URLConnection openConnection() throws IOException { + return (null == this.proxy) ? url.openConnection() : url.openConnection(this.proxy); + } + + /** + * 通过反射设置方法名,首先设置HttpURLConnection本身的方法名,再检查是否为代理类,如果是,设置带路对象的方法名。 + * + * @param method 方法名 + */ + private void reflectSetMethod(Method method) { + ReflectUtil.setFieldValue(this.conn, "method", method.name()); + + // HttpsURLConnectionImpl实现中,使用了代理类,需要修改被代理类的method方法 + final Object delegate = ReflectUtil.getFieldValue(this.conn, "delegate"); + if (null != delegate) { + ReflectUtil.setFieldValue(delegate, "method", method.name()); + } + } + // --------------------------------------------------------------- Private Method end +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpDownloader.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpDownloader.java new file mode 100644 index 0000000..d330a70 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpDownloader.java @@ -0,0 +1,122 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.io.FastByteArrayOutputStream; +import aiyh.utils.tool.cn.hutool.core.io.StreamProgress; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; + +import java.io.File; +import java.io.OutputStream; +import java.nio.charset.Charset; + +/** + * 下载封装,下载统一使用{@code GET}请求,默认支持30x跳转 + * + * @author looly + * @since 5.6.4 + */ +public class HttpDownloader { + + /** + * 下载远程文本 + * + * @param url 请求的url + * @param customCharset 自定义的字符集,可以使用{@code CharsetUtil#charset} 方法转换 + * @param streamPress 进度条 {@link StreamProgress} + * @return 文本 + */ + public static String downloadString(String url, Charset customCharset, StreamProgress streamPress) { + final FastByteArrayOutputStream out = new FastByteArrayOutputStream(); + download(url, out, true, streamPress); + return null == customCharset ? out.toString() : out.toString(customCharset); + } + + /** + * 下载远程文件数据,支持30x跳转 + * + * @param url 请求的url + * @return 文件数据 + */ + public static byte[] downloadBytes(String url) { + return requestDownload(url, -1).bodyBytes(); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param targetFileOrDir 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @param streamProgress 进度条 + * @return 文件大小 + */ + public static long downloadFile(String url, File targetFileOrDir, int timeout, StreamProgress streamProgress) { + return requestDownload(url, timeout).writeBody(targetFileOrDir, streamProgress); + } + + /** + * 下载文件-避免未完成的文件
+ * 来自:https://gitee.com/dromara/hutool/pulls/407
+ * 此方法原理是先在目标文件同级目录下创建临时文件,下载之,等下载完毕后重命名,避免因下载错误导致的文件不完整。 + * + * @param url 请求的url + * @param targetFileOrDir 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param tempFileSuffix 临时文件后缀,默认".temp" + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @param streamProgress 进度条 + * @return 下载大小 + * @since 5.7.12 + */ + public long downloadFile(String url, File targetFileOrDir, String tempFileSuffix, int timeout, StreamProgress streamProgress) { + return requestDownload(url, timeout).writeBody(targetFileOrDir, tempFileSuffix, streamProgress); + } + + /** + * 下载远程文件,返回文件 + * + * @param url 请求的url + * @param targetFileOrDir 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @param streamProgress 进度条 + * @return 文件 + */ + public static File downloadForFile(String url, File targetFileOrDir, int timeout, StreamProgress streamProgress) { + return requestDownload(url, timeout).writeBodyForFile(targetFileOrDir, streamProgress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param out 将下载内容写到输出流中 {@link OutputStream} + * @param isCloseOut 是否关闭输出流 + * @param streamProgress 进度条 + * @return 文件大小 + */ + public static long download(String url, OutputStream out, boolean isCloseOut, StreamProgress streamProgress) { + Assert.notNull(out, "[out] is null !"); + + return requestDownload(url, -1).writeBody(out, isCloseOut, streamProgress); + } + + /** + * 请求下载文件 + * + * @param url 请求下载文件地址 + * @param timeout 超时时间 + * @return HttpResponse + * @since 5.4.1 + */ + private static aiyh.utils.tool.cn.hutool.http.HttpResponse requestDownload(String url, int timeout) { + Assert.notBlank(url, "[url] is blank !"); + + final HttpResponse response = HttpUtil.createGet(url, true) + .timeout(timeout) + .executeAsync(); + + if (response.isOk()) { + return response; + } + + throw new HttpException("Server response error with status code: [{}]", response.getStatus()); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpException.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpException.java new file mode 100644 index 0000000..11153cb --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpException.java @@ -0,0 +1,36 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +/** + * HTTP异常 + * + * @author xiaoleilu + */ +public class HttpException extends RuntimeException { + private static final long serialVersionUID = 8247610319171014183L; + + public HttpException(Throwable e) { + super(e.getMessage(), e); + } + + public HttpException(String message) { + super(message); + } + + public HttpException(String messageTemplate, Object... params) { + super(StrUtil.format(messageTemplate, params)); + } + + public HttpException(String message, Throwable throwable) { + super(message, throwable); + } + + public HttpException(String message, Throwable throwable, boolean enableSuppression, boolean writableStackTrace) { + super(message, throwable, enableSuppression, writableStackTrace); + } + + public HttpException(Throwable throwable, String messageTemplate, Object... params) { + super(StrUtil.format(messageTemplate, params), throwable); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpGlobalConfig.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpGlobalConfig.java new file mode 100755 index 0000000..5e8e524 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpGlobalConfig.java @@ -0,0 +1,214 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.util.ArrayUtil; +import aiyh.utils.tool.cn.hutool.core.util.RandomUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReflectUtil; +import aiyh.utils.tool.cn.hutool.http.cookie.GlobalCookieManager; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.net.CookieManager; +import java.net.HttpURLConnection; + +/** + * HTTP 全局参数配置 + * + * @author Looly + * @since 4.6.2 + */ +public class HttpGlobalConfig implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * -1: 含义,永不超时。 + * 如果:设置timeout = 3s(3000 ms), 那一次请求最大超时:就是:6s + * 官方含义:timeout of zero is interpreted as an infinite timeout. (0的超时被解释为无限超时。) + * 这里实际项目一定要进行修改,防止把系统拖死. + * 底层调用:{@link HttpURLConnection#setReadTimeout(int)} 同时设置: 读取超时 + * 底层调用:{@link HttpURLConnection#setConnectTimeout(int)} 同时设置: 连接超时 + */ + private static int timeout = -1; + private static boolean isAllowPatch = false; + private static String boundary = "--------------------Hutool_" + RandomUtil.randomString(16); + private static int maxRedirectCount = 0; + private static boolean ignoreEOFError = true; + private static boolean decodeUrl = false; + + /** + * 获取全局默认的超时时长 + * + * @return 全局默认的超时时长 + */ + public static int getTimeout() { + return timeout; + } + + /** + * 设置默认的连接和读取超时时长
+ * -1: 含义,永不超时。
+ * 如果:设置timeout = 3s(3000 ms), 那一次请求最大超时:就是:6s
+ * 官方含义:timeout of zero is interpreted as an infinite timeout. (0的超时被解释为无限超时。)
+ * 这里实际项目一定要进行修改,防止把系统拖死.
+ * 底层调用:{@link HttpURLConnection#setReadTimeout(int)} 同时设置: 读取超时
+ * 底层调用:{@link HttpURLConnection#setConnectTimeout(int)} 同时设置: 连接超时 + * + * @param customTimeout 超时时长 + */ + synchronized public static void setTimeout(int customTimeout) { + timeout = customTimeout; + } + + /** + * 获取全局默认的Multipart边界 + * + * @return 全局默认的Multipart边界 + * @since 5.7.17 + */ + public static String getBoundary() { + return boundary; + } + + /** + * 设置默认的Multipart边界 + * + * @param customBoundary 自定义Multipart边界 + * @since 5.7.17 + */ + synchronized public static void setBoundary(String customBoundary) { + boundary = customBoundary; + } + + /** + * 获取全局默认的最大重定向次数,如设置0表示不重定向
+ * 如果设置为1,表示重定向一次,即请求两次 + * + * @return 全局默认的最大重定向次数 + * @since 5.7.19 + */ + public static int getMaxRedirectCount() { + return maxRedirectCount; + } + + /** + * 设置默认全局默认的最大重定向次数,如设置0表示不重定向
+ * 如果设置为1,表示重定向一次,即请求两次 + * + * @param customMaxRedirectCount 全局默认的最大重定向次数 + * @since 5.7.19 + */ + synchronized public static void setMaxRedirectCount(int customMaxRedirectCount) { + maxRedirectCount = customMaxRedirectCount; + } + + /** + * 获取是否忽略响应读取时可能的EOF异常。
+ * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
+ * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 + * + * @return 是否忽略响应读取时可能的EOF异常 + * @since 5.7.20 + */ + public static boolean isIgnoreEOFError() { + return ignoreEOFError; + } + + /** + * 设置是否忽略响应读取时可能的EOF异常。
+ * 在Http协议中,对于Transfer-Encoding: Chunked在正常情况下末尾会写入一个Length为0的的chunk标识完整结束。
+ * 如果服务端未遵循这个规范或响应没有正常结束,会报EOF异常,此选项用于是否忽略这个异常。 + * + * @param customIgnoreEOFError 是否忽略响应读取时可能的EOF异常。 + * @since 5.7.20 + */ + synchronized public static void setIgnoreEOFError(boolean customIgnoreEOFError) { + ignoreEOFError = customIgnoreEOFError; + } + + /** + * 获取是否忽略解码URL,包括URL中的Path部分和Param部分。
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + * + * @return 是否忽略解码URL + * @since 5.7.22 + */ + public static boolean isDecodeUrl() { + return decodeUrl; + } + + /** + * 设置是否忽略解码URL,包括URL中的Path部分和Param部分。
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果此参数为{@code true},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + * + * @param customDecodeUrl 是否忽略解码URL + * @since 5.7.22 + */ + synchronized public static void setDecodeUrl(boolean customDecodeUrl) { + decodeUrl = customDecodeUrl; + } + + /** + * 获取Cookie管理器,用于自定义Cookie管理 + * + * @return {@link CookieManager} + * @see GlobalCookieManager#getCookieManager() + * @since 4.1.0 + */ + public static CookieManager getCookieManager() { + return GlobalCookieManager.getCookieManager(); + } + + /** + * 自定义{@link CookieManager} + * + * @param customCookieManager 自定义的{@link CookieManager} + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 4.5.14 + */ + synchronized public static void setCookieManager(CookieManager customCookieManager) { + GlobalCookieManager.setCookieManager(customCookieManager); + } + + /** + * 关闭Cookie + * + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 4.1.9 + */ + synchronized public static void closeCookie() { + GlobalCookieManager.setCookieManager(null); + } + + /** + * 增加支持的METHOD方法
+ * 此方法通过注入方式修改{@link HttpURLConnection}中的methods静态属性,增加PATCH方法
+ * see: https://stackoverflow.com/questions/25163131/httpurlconnection-invalid-http-method-patch + * + * @since 5.7.4 + */ + synchronized public static void allowPatch() { + if (isAllowPatch) { + return; + } + final Field methodsField = ReflectUtil.getField(HttpURLConnection.class, "methods"); + if (null == methodsField) { + throw new HttpException("None static field [methods] with Java version: [{}]", System.getProperty("java.version")); + } + + // 去除final修饰 + ReflectUtil.removeFinalModify(methodsField); + final String[] methods = { + "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE", "PATCH" + }; + ReflectUtil.setFieldValue(null, methodsField, methods); + + // 检查注入是否成功 + final Object staticFieldValue = ReflectUtil.getStaticFieldValue(methodsField); + if (!ArrayUtil.equals(methods, staticFieldValue)) { + throw new HttpException("Inject value to field [methods] failed!"); + } + + isAllowPatch = true; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInputStream.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInputStream.java new file mode 100644 index 0000000..d1c2dce --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInputStream.java @@ -0,0 +1,108 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +/** + * HTTP输入流,此流用于包装Http请求响应内容的流,用于解析各种压缩、分段的响应流内容 + * + * @author Looly + * + */ +public class HttpInputStream extends InputStream { + + /** 原始流 */ + private InputStream in; + + /** + * 构造 + * + * @param response 响应对象 + */ + public HttpInputStream(aiyh.utils.tool.cn.hutool.http.HttpResponse response) { + init(response); + } + + @Override + public int read() throws IOException { + return this.in.read(); + } + + @SuppressWarnings("NullableProblems") + @Override + public int read(byte[] b, int off, int len) throws IOException { + return this.in.read(b, off, len); + } + + @Override + public long skip(long n) throws IOException { + return this.in.skip(n); + } + + @Override + public int available() throws IOException { + return this.in.available(); + } + + @Override + public void close() throws IOException { + this.in.close(); + } + + @Override + public synchronized void mark(int readlimit) { + this.in.mark(readlimit); + } + + @Override + public synchronized void reset() throws IOException { + this.in.reset(); + } + + @Override + public boolean markSupported() { + return this.in.markSupported(); + } + + /** + * 初始化流 + * + * @param response 响应对象 + */ + private void init(HttpResponse response) { + try { + this.in = (response.status < HttpStatus.HTTP_BAD_REQUEST) ? response.httpConnection.getInputStream() : response.httpConnection.getErrorStream(); + } catch (IOException e) { + if (false == (e instanceof FileNotFoundException)) { + throw new HttpException(e); + } + // 服务器无返回内容,忽略之 + } + + // 在一些情况下,返回的流为null,此时提供状态码说明 + if (null == this.in) { + this.in = new ByteArrayInputStream(StrUtil.format("Error request, response status: {}", response.status).getBytes()); + return; + } + + if (response.isGzip() && false == (response.in instanceof GZIPInputStream)) { + // Accept-Encoding: gzip + try { + this.in = new GZIPInputStream(this.in); + } catch (IOException e) { + // 在类似于Head等方法中无body返回,此时GZIPInputStream构造会出现错误,在此忽略此错误读取普通数据 + // ignore + } + } else if (response.isDeflate() && false == (this.in instanceof InflaterInputStream)) { + // Accept-Encoding: defalte + this.in = new InflaterInputStream(this.in, new Inflater(true)); + } + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInterceptor.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInterceptor.java new file mode 100644 index 0000000..4b4507c --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpInterceptor.java @@ -0,0 +1,56 @@ +package aiyh.utils.tool.cn.hutool.http; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Http拦截器接口,通过实现此接口,完成请求发起前或结束后对请求的编辑工作 + * + * @param 过滤参数类型,HttpRequest或者HttpResponse + * @author looly + * @since 5.7.16 + */ +@FunctionalInterface +public interface HttpInterceptor> { + + /** + * 处理请求 + * + * @param httpObj 请求或响应对象 + */ + void process(T httpObj); + + /** + * 拦截器链 + * + * @param 过滤参数类型,HttpRequest或者HttpResponse + * @author looly + * @since 5.7.16 + */ + class Chain> implements aiyh.utils.tool.cn.hutool.core.lang.Chain, Chain> { + private final List> interceptors = new LinkedList<>(); + + @Override + public Chain addChain(HttpInterceptor element) { + interceptors.add(element); + return this; + } + + @Override + public Iterator> iterator() { + return interceptors.iterator(); + } + + /** + * 清空 + * + * @return this + * @since 5.8.0 + */ + public Chain clear() { + interceptors.clear(); + return this; + } + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpRequest.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpRequest.java new file mode 100755 index 0000000..61f77c8 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpRequest.java @@ -0,0 +1,1393 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.convert.Convert; +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.io.resource.BytesResource; +import aiyh.utils.tool.cn.hutool.core.io.resource.FileResource; +import aiyh.utils.tool.cn.hutool.core.io.resource.MultiFileResource; +import aiyh.utils.tool.cn.hutool.core.io.resource.Resource; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.map.TableMap; +import aiyh.utils.tool.cn.hutool.core.net.SSLUtil; +import aiyh.utils.tool.cn.hutool.core.net.url.UrlBuilder; +import aiyh.utils.tool.cn.hutool.core.net.url.UrlQuery; +import aiyh.utils.tool.cn.hutool.core.util.ArrayUtil; +import aiyh.utils.tool.cn.hutool.core.util.ObjectUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.http.body.BytesBody; +import aiyh.utils.tool.cn.hutool.http.body.FormUrlEncodedBody; +import aiyh.utils.tool.cn.hutool.http.body.MultipartBody; +import aiyh.utils.tool.cn.hutool.http.body.RequestBody; +import aiyh.utils.tool.cn.hutool.http.cookie.GlobalCookieManager; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; +import java.io.File; +import java.io.IOException; +import java.net.*; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * http请求类
+ * Http请求类用于构建Http请求并同步获取结果,此类通过CookieManager持有域名对应的Cookie值,再次请求时会自动附带Cookie信息 + * + * @author Looly + */ +public class HttpRequest extends HttpBase { + + // ---------------------------------------------------------------- static Http Method start + + /** + * POST请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest post(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.POST); + } + + /** + * GET请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest get(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.GET); + } + + /** + * HEAD请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest head(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.HEAD); + } + + /** + * OPTIONS请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest options(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.OPTIONS); + } + + /** + * PUT请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest put(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.PUT); + } + + /** + * PATCH请求 + * + * @param url URL + * @return HttpRequest + * @since 3.0.9 + */ + public static HttpRequest patch(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.PATCH); + } + + /** + * DELETE请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest delete(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.DELETE); + } + + /** + * TRACE请求 + * + * @param url URL + * @return HttpRequest + */ + public static HttpRequest trace(String url) { + return of(url).method(aiyh.utils.tool.cn.hutool.http.Method.TRACE); + } + + /** + * 构建一个HTTP请求
+ * 对于传入的URL,可以自定义是否解码已经编码的内容,设置见{@link HttpGlobalConfig#setDecodeUrl(boolean)}
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果{@link HttpGlobalConfig#isDecodeUrl()}为{@code true},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + * + * @param url URL链接,默认自动编码URL中的参数等信息 + * @return HttpRequest + * @since 5.7.18 + */ + public static HttpRequest of(String url) { + return of(url, HttpGlobalConfig.isDecodeUrl() ? DEFAULT_CHARSET : null); + } + + /** + * 构建一个HTTP请求
+ * 对于传入的URL,可以自定义是否解码已经编码的内容。
+ * 在构建Http请求时,用户传入的URL可能有编码后和未编码的内容混合在一起,如果charset参数不为{@code null},则会统一解码编码后的参数,
+ * 按照RFC3986规范,在发送请求时,全部编码之。如果为{@code false},则不会解码已经编码的内容,在请求时只编码需要编码的部分。 + * + * @param url URL链接 + * @param charset 编码,如果为{@code null}不自动解码编码URL + * @return HttpRequest + * @since 5.7.18 + */ + public static HttpRequest of(String url, Charset charset) { + return of(UrlBuilder.ofHttp(url, charset)); + } + + /** + * 构建一个HTTP请求
+ * + * @param url {@link UrlBuilder} + * @return HttpRequest + * @since 5.8.0 + */ + public static HttpRequest of(UrlBuilder url) { + return new HttpRequest(url); + } + + /** + * 设置全局默认的连接和读取超时时长 + * + * @param customTimeout 超时时长 + * @see HttpGlobalConfig#setTimeout(int) + * @since 4.6.2 + */ + public static void setGlobalTimeout(int customTimeout) { + HttpGlobalConfig.setTimeout(customTimeout); + } + + /** + * 获取Cookie管理器,用于自定义Cookie管理 + * + * @return {@link CookieManager} + * @see GlobalCookieManager#getCookieManager() + * @since 4.1.0 + */ + public static CookieManager getCookieManager() { + return GlobalCookieManager.getCookieManager(); + } + + /** + * 自定义{@link CookieManager} + * + * @param customCookieManager 自定义的{@link CookieManager} + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 4.5.14 + */ + public static void setCookieManager(CookieManager customCookieManager) { + GlobalCookieManager.setCookieManager(customCookieManager); + } + + /** + * 关闭Cookie + * + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 4.1.9 + */ + public static void closeCookie() { + GlobalCookieManager.setCookieManager(null); + } + // ---------------------------------------------------------------- static Http Method end + + private HttpConfig config = HttpConfig.create(); + private UrlBuilder url; + private URLStreamHandler urlHandler; + private aiyh.utils.tool.cn.hutool.http.Method method = aiyh.utils.tool.cn.hutool.http.Method.GET; + /** + * 连接对象 + */ + private HttpConnection httpConnection; + + /** + * 存储表单数据 + */ + private Map form; + /** + * Cookie + */ + private String cookie; + /** + * 是否为Multipart表单 + */ + private boolean isMultiPart; + /** + * 是否是REST请求模式 + */ + private boolean isRest; + /** + * 重定向次数计数器,内部使用 + */ + private int redirectCount; + + /** + * 构造,URL编码默认使用UTF-8 + * + * @param url URL + * @deprecated 请使用 {@link #of(String)} + */ + @Deprecated + public HttpRequest(String url) { + this(UrlBuilder.ofHttp(url)); + } + + /** + * 构造 + * + * @param url {@link UrlBuilder} + */ + public HttpRequest(UrlBuilder url) { + this.url = Assert.notNull(url, "URL must be not null!"); + // 给定默认URL编码 + final Charset charset = url.getCharset(); + if (null != charset) { + this.charset(charset); + } + // 给定一个默认头信息 + this.header(GlobalHeaders.INSTANCE.headers); + } + + /** + * 获取请求URL + * + * @return URL字符串 + * @since 4.1.8 + */ + public String getUrl() { + return url.toString(); + } + + /** + * 设置URL + * + * @param url url字符串 + * @return this + * @since 4.1.8 + */ + public HttpRequest setUrl(String url) { + return setUrl(UrlBuilder.ofHttp(url, this.charset)); + } + + /** + * 设置URL + * + * @param urlBuilder url字符串 + * @return this + * @since 5.3.1 + */ + public HttpRequest setUrl(UrlBuilder urlBuilder) { + this.url = urlBuilder; + return this; + } + + /** + * 设置{@link URLStreamHandler} + *

+ * 部分环境下需要单独设置此项,例如当 WebLogic Server 实例充当 SSL 客户端角色(它会尝试通过 SSL 连接到其他服务器或应用程序)时,
+ * 它会验证 SSL 服务器在数字证书中返回的主机名是否与用于连接 SSL 服务器的 URL 主机名相匹配。如果主机名不匹配,则删除此连接。
+ * 因此weblogic不支持https的sni协议的主机名验证,此时需要将此值设置为sun.net.www.protocol.https.Handler对象。 + *

+ * 相关issue见:https://gitee.com/dromara/hutool/issues/IMD1X + * + * @param urlHandler {@link URLStreamHandler} + * @return this + * @since 4.1.9 + */ + public HttpRequest setUrlHandler(URLStreamHandler urlHandler) { + this.urlHandler = urlHandler; + return this; + } + + /** + * 获取Http请求方法 + * + * @return {@link aiyh.utils.tool.cn.hutool.http.Method} + * @since 4.1.8 + */ + public aiyh.utils.tool.cn.hutool.http.Method getMethod() { + return this.method; + } + + /** + * 设置请求方法 + * + * @param method HTTP方法 + * @return HttpRequest + * @see #method(aiyh.utils.tool.cn.hutool.http.Method) + * @since 4.1.8 + */ + public HttpRequest setMethod(aiyh.utils.tool.cn.hutool.http.Method method) { + return method(method); + } + + /** + * 获取{@link HttpConnection}
+ * 在{@link #execute()} 执行前此对象为null + * + * @return {@link HttpConnection} + * @since 4.2.2 + */ + public HttpConnection getConnection() { + return this.httpConnection; + } + + /** + * 设置请求方法 + * + * @param method HTTP方法 + * @return HttpRequest + */ + public HttpRequest method(aiyh.utils.tool.cn.hutool.http.Method method) { + this.method = method; + return this; + } + + // ---------------------------------------------------------------- Http Request Header start + + /** + * 设置contentType + * + * @param contentType contentType + * @return HttpRequest + */ + public HttpRequest contentType(String contentType) { + header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE, contentType); + return this; + } + + /** + * 设置是否为长连接 + * + * @param isKeepAlive 是否长连接 + * @return HttpRequest + */ + public HttpRequest keepAlive(boolean isKeepAlive) { + header(aiyh.utils.tool.cn.hutool.http.Header.CONNECTION, isKeepAlive ? "Keep-Alive" : "Close"); + return this; + } + + /** + * @return 获取是否为长连接 + */ + public boolean isKeepAlive() { + String connection = header(aiyh.utils.tool.cn.hutool.http.Header.CONNECTION); + if (connection == null) { + return !HTTP_1_0.equalsIgnoreCase(httpVersion); + } + + return !"close".equalsIgnoreCase(connection); + } + + /** + * 获取内容长度 + * + * @return String + */ + public String contentLength() { + return header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_LENGTH); + } + + /** + * 设置内容长度 + * + * @param value 长度 + * @return HttpRequest + */ + public HttpRequest contentLength(int value) { + header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_LENGTH, String.valueOf(value)); + return this; + } + + /** + * 设置Cookie
+ * 自定义Cookie后会覆盖Hutool的默认Cookie行为 + * + * @param cookies Cookie值数组,如果为{@code null}则设置无效,使用默认Cookie行为 + * @return this + * @since 5.4.1 + */ + public HttpRequest cookie(Collection cookies) { + return cookie(CollUtil.isEmpty(cookies) ? null : cookies.toArray(new HttpCookie[0])); + } + + /** + * 设置Cookie
+ * 自定义Cookie后会覆盖Hutool的默认Cookie行为 + * + * @param cookies Cookie值数组,如果为{@code null}则设置无效,使用默认Cookie行为 + * @return this + * @since 3.1.1 + */ + public HttpRequest cookie(HttpCookie... cookies) { + if (ArrayUtil.isEmpty(cookies)) { + return disableCookie(); + } + // 名称/值对之间用分号和空格 ('; ') + // https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cookie + return cookie(ArrayUtil.join(cookies, "; ")); + } + + /** + * 设置Cookie
+ * 自定义Cookie后会覆盖Hutool的默认Cookie行为 + * + * @param cookie Cookie值,如果为{@code null}则设置无效,使用默认Cookie行为 + * @return this + * @since 3.0.7 + */ + public HttpRequest cookie(String cookie) { + this.cookie = cookie; + return this; + } + + /** + * 禁用默认Cookie行为,此方法调用后会将Cookie置为空。
+ * 如果想重新启用Cookie,请调用:{@link #cookie(String)}方法自定义Cookie。
+ * 如果想启动默认的Cookie行为(自动回填服务器传回的Cookie),则调用{@link #enableDefaultCookie()} + * + * @return this + * @since 3.0.7 + */ + public HttpRequest disableCookie() { + return cookie(StrUtil.EMPTY); + } + + /** + * 打开默认的Cookie行为(自动回填服务器传回的Cookie) + * + * @return this + */ + public HttpRequest enableDefaultCookie() { + return cookie((String) null); + } + // ---------------------------------------------------------------- Http Request Header end + + // ---------------------------------------------------------------- Form start + + /** + * 设置表单数据
+ * + * @param name 名 + * @param value 值 + * @return this + */ + public HttpRequest form(String name, Object value) { + if (StrUtil.isBlank(name) || ObjectUtil.isNull(value)) { + return this; // 忽略非法的form表单项内容; + } + + // 停用body + this.bodyBytes = null; + + if (value instanceof File) { + // 文件上传 + return this.form(name, (File) value); + } + + if (value instanceof Resource) { + return form(name, (Resource) value); + } + + // 普通值 + String strValue; + if (value instanceof Iterable) { + // 列表对象 + strValue = CollUtil.join((Iterable) value, ","); + } else if (ArrayUtil.isArray(value)) { + if (File.class == ArrayUtil.getComponentType(value)) { + // 多文件 + return this.form(name, (File[]) value); + } + // 数组对象 + strValue = ArrayUtil.join((Object[]) value, ","); + } else { + // 其他对象一律转换为字符串 + strValue = Convert.toStr(value, null); + } + + return putToForm(name, strValue); + } + + /** + * 设置表单数据 + * + * @param name 名 + * @param value 值 + * @param parameters 参数对,奇数为名,偶数为值 + * @return this + */ + public HttpRequest form(String name, Object value, Object... parameters) { + form(name, value); + + for (int i = 0; i < parameters.length; i += 2) { + form(parameters[i].toString(), parameters[i + 1]); + } + return this; + } + + /** + * 设置map类型表单数据 + * + * @param formMap 表单内容 + * @return this + */ + public HttpRequest form(Map formMap) { + if (MapUtil.isNotEmpty(formMap)) { + formMap.forEach(this::form); + } + return this; + } + + /** + * 设置map<String, String>类型表单数据 + * + * @param formMapStr 表单内容 + * @return this + * @since 5.6.7 + */ + public HttpRequest formStr(Map formMapStr) { + if (MapUtil.isNotEmpty(formMapStr)) { + formMapStr.forEach(this::form); + } + return this; + } + + /** + * 文件表单项
+ * 一旦有文件加入,表单变为multipart/form-data + * + * @param name 名 + * @param files 需要上传的文件,为空跳过 + * @return this + */ + public HttpRequest form(String name, File... files) { + if (ArrayUtil.isEmpty(files)) { + return this; + } + if (1 == files.length) { + final File file = files[0]; + return form(name, file, file.getName()); + } + return form(name, new MultiFileResource(files)); + } + + /** + * 文件表单项
+ * 一旦有文件加入,表单变为multipart/form-data + * + * @param name 名 + * @param file 需要上传的文件 + * @return this + */ + public HttpRequest form(String name, File file) { + return form(name, file, file.getName()); + } + + /** + * 文件表单项
+ * 一旦有文件加入,表单变为multipart/form-data + * + * @param name 名 + * @param file 需要上传的文件 + * @param fileName 文件名,为空使用文件默认的文件名 + * @return this + */ + public HttpRequest form(String name, File file, String fileName) { + if (null != file) { + form(name, new FileResource(file, fileName)); + } + return this; + } + + /** + * 文件byte[]表单项
+ * 一旦有文件加入,表单变为multipart/form-data + * + * @param name 名 + * @param fileBytes 需要上传的文件 + * @param fileName 文件名 + * @return this + * @since 4.1.0 + */ + public HttpRequest form(String name, byte[] fileBytes, String fileName) { + if (null != fileBytes) { + form(name, new BytesResource(fileBytes, fileName)); + } + return this; + } + + /** + * 文件表单项
+ * 一旦有文件加入,表单变为multipart/form-data + * + * @param name 名 + * @param resource 数据源,文件可以使用{@link FileResource}包装使用 + * @return this + * @since 4.0.9 + */ + public HttpRequest form(String name, Resource resource) { + if (null != resource) { + if (!isKeepAlive()) { + keepAlive(true); + } + + this.isMultiPart = true; + return putToForm(name, resource); + } + return this; + } + + /** + * 获取表单数据 + * + * @return 表单Map + */ + public Map form() { + return this.form; + } + + /** + * 获取文件表单数据 + * + * @return 文件表单Map + * @since 3.3.0 + */ + public Map fileForm() { + final Map result = MapUtil.newHashMap(); + this.form.forEach((key, value) -> { + if (value instanceof Resource) { + result.put(key, (Resource) value); + } + }); + return result; + } + // ---------------------------------------------------------------- Form end + + // ---------------------------------------------------------------- Body start + + /** + * 设置内容主体
+ * 请求体body参数支持两种类型: + * + *

+	 * 1. 标准参数,例如 a=1&b=2 这种格式
+	 * 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
+	 * 
+ * + * @param body 请求体 + * @return this + */ + public HttpRequest body(String body) { + return this.body(body, null); + } + + /** + * 设置内容主体
+ * 请求体body参数支持两种类型: + * + *
+	 * 1. 标准参数,例如 a=1&b=2 这种格式
+	 * 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
+	 * 
+ * + * @param body 请求体 + * @param contentType 请求体类型,{@code null}表示自动判断类型 + * @return this + */ + public HttpRequest body(String body, String contentType) { + byte[] bytes = StrUtil.bytes(body, this.charset); + body(bytes); + this.form = null; // 当使用body时,停止form的使用 + + if (null != contentType) { + // Content-Type自定义设置 + this.contentType(contentType); + } else { + // 在用户未自定义的情况下自动根据内容判断 + contentType = HttpUtil.getContentTypeByRequestBody(body); + if (null != contentType && ContentType.isDefault(this.header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE))) { + if (null != this.charset) { + // 附加编码信息 + contentType = ContentType.build(contentType, this.charset); + } + this.contentType(contentType); + } + } + + // 判断是否为rest请求 + if (StrUtil.containsAnyIgnoreCase(contentType, "json", "xml")) { + this.isRest = true; + contentLength(bytes.length); + } + return this; + } + + /** + * 设置主体字节码
+ * 需在此方法调用前使用charset方法设置编码,否则使用默认编码UTF-8 + * + * @param bodyBytes 主体 + * @return this + */ + public HttpRequest body(byte[] bodyBytes) { + if (null != bodyBytes) { + this.bodyBytes = bodyBytes; + } + return this; + } + // ---------------------------------------------------------------- Body end + + /** + * 将新的配置加入
+ * 注意加入的配置可能被修改 + * + * @param config 配置 + * @return this + */ + public HttpRequest setConfig(HttpConfig config) { + this.config = config; + return this; + } + + /** + * 设置超时,单位:毫秒
+ * 超时包括: + * + *
+	 * 1. 连接超时
+	 * 2. 读取响应超时
+	 * 
+ * + * @param milliseconds 超时毫秒数 + * @return this + * @see #setConnectionTimeout(int) + * @see #setReadTimeout(int) + */ + public HttpRequest timeout(int milliseconds) { + config.timeout(milliseconds); + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + * @since 4.5.6 + */ + public HttpRequest setConnectionTimeout(int milliseconds) { + config.setConnectionTimeout(milliseconds); + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + * @since 4.5.6 + */ + public HttpRequest setReadTimeout(int milliseconds) { + config.setReadTimeout(milliseconds); + return this; + } + + /** + * 禁用缓存 + * + * @return this + */ + public HttpRequest disableCache() { + config.disableCache(); + return this; + } + + /** + * 设置是否打开重定向,如果打开默认重定向次数为2
+ * 此方法效果与{@link #setMaxRedirectCount(int)} 一致 + * + *

+ * 需要注意的是,当设置为{@code true}时,如果全局重定向次数非0,直接复用,否则设置默认2次。
+ * 当设置为{@code false}时,无论全局是否设置次数,都设置为0。
+ * 不调用此方法的情况下,使用全局默认的次数。 + *

+ * + * @param isFollowRedirects 是否打开重定向 + * @return this + */ + public HttpRequest setFollowRedirects(boolean isFollowRedirects) { + if (isFollowRedirects) { + if (config.maxRedirectCount <= 0) { + // 默认两次跳转 + return setMaxRedirectCount(2); + } + } else { + // 手动强制关闭重定向,此时不受全局重定向设置影响 + if (config.maxRedirectCount < 0) { + return setMaxRedirectCount(0); + } + } + return this; + } + + /** + * 设置最大重定向次数
+ * 如果次数小于1则表示不重定向,大于等于1表示打开重定向 + * + * @param maxRedirectCount 最大重定向次数 + * @return this + * @since 3.3.0 + */ + public HttpRequest setMaxRedirectCount(int maxRedirectCount) { + config.setMaxRedirectCount(maxRedirectCount); + return this; + } + + /** + * 设置域名验证器
+ * 只针对HTTPS请求,如果不设置,不做验证,所有域名被信任 + * + * @param hostnameVerifier HostnameVerifier + * @return this + */ + public HttpRequest setHostnameVerifier(HostnameVerifier hostnameVerifier) { + config.setHostnameVerifier(hostnameVerifier); + return this; + } + + /** + * 设置Http代理 + * + * @param host 代理 主机 + * @param port 代理 端口 + * @return this + * @since 5.4.5 + */ + public HttpRequest setHttpProxy(String host, int port) { + config.setHttpProxy(host, port); + return this; + } + + /** + * 设置代理 + * + * @param proxy 代理 {@link Proxy} + * @return this + */ + public HttpRequest setProxy(Proxy proxy) { + config.setProxy(proxy); + return this; + } + + /** + * 设置SSLSocketFactory
+ * 只针对HTTPS请求,如果不设置,使用默认的SSLSocketFactory
+ * 默认SSLSocketFactory为:SSLSocketFactoryBuilder.create().build(); + * + * @param ssf SSLScketFactory + * @return this + */ + public HttpRequest setSSLSocketFactory(SSLSocketFactory ssf) { + config.setSSLSocketFactory(ssf); + return this; + } + + /** + * 设置HTTPS安全连接协议,只针对HTTPS请求,可以使用的协议包括:
+ * 此方法调用后{@link #setSSLSocketFactory(SSLSocketFactory)} 将被覆盖。 + * + *
+	 * 1. TLSv1.2
+	 * 2. TLSv1.1
+	 * 3. SSLv3
+	 * ...
+	 * 
+ * + * @param protocol 协议 + * @return this + * @see SSLUtil#createSSLContext(String) + * @see #setSSLSocketFactory(SSLSocketFactory) + */ + public HttpRequest setSSLProtocol(String protocol) { + config.setSSLProtocol(protocol); + return this; + } + + /** + * 设置是否rest模式
+ * rest模式下get请求不会把参数附加到URL之后 + * + * @param isRest 是否rest模式 + * @return this + * @since 4.5.0 + */ + public HttpRequest setRest(boolean isRest) { + this.isRest = isRest; + return this; + } + + /** + * 采用流方式上传数据,无需本地缓存数据。
+ * HttpUrlConnection默认是将所有数据读到本地缓存,然后再发送给服务器,这样上传大文件时就会导致内存溢出。 + * + * @param blockSize 块大小(bytes数),0或小于0表示不设置Chuncked模式 + * @return this + * @since 4.6.5 + */ + public HttpRequest setChunkedStreamingMode(int blockSize) { + config.setBlockSize(blockSize); + return this; + } + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + * @see #addRequestInterceptor(HttpInterceptor) + * @since 5.7.16 + */ + public HttpRequest addInterceptor(HttpInterceptor interceptor) { + return addRequestInterceptor(interceptor); + } + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + * @since 5.8.0 + */ + public HttpRequest addRequestInterceptor(HttpInterceptor interceptor) { + config.addRequestInterceptor(interceptor); + return this; + } + + /** + * 设置拦截器,用于在请求前重新编辑请求 + * + * @param interceptor 拦截器实现 + * @return this + * @since 5.8.0 + */ + public HttpRequest addResponseInterceptor(HttpInterceptor interceptor) { + config.addResponseInterceptor(interceptor); + return this; + } + + /** + * 执行Reuqest请求 + * + * @return this + */ + public aiyh.utils.tool.cn.hutool.http.HttpResponse execute() { + return this.execute(false); + } + + /** + * 异步请求
+ * 异步请求后获取的{@link aiyh.utils.tool.cn.hutool.http.HttpResponse} 为异步模式,执行完此方法后发送请求到服务器,但是并不立即读取响应内容。
+ * 此时保持Http连接不关闭,直调用获取内容方法为止。 + * + *

+ * 一般执行完execute之后会把响应内容全部读出来放在一个 byte数组里,如果你响应的内容太多内存就爆了,此法是发送完请求不直接读响应内容,等有需要的时候读。 + * + * @return 异步对象,使用get方法获取HttpResponse对象 + */ + public aiyh.utils.tool.cn.hutool.http.HttpResponse executeAsync() { + return this.execute(true); + } + + /** + * 执行Reuqest请求 + * + * @param isAsync 是否异步 + * @return this + */ + public aiyh.utils.tool.cn.hutool.http.HttpResponse execute(boolean isAsync) { + return doExecute(isAsync, config.requestInterceptors, config.responseInterceptors); + } + + /** + * 执行Request请求后,对响应内容后续处理
+ * 处理结束后关闭连接 + * + * @param consumer 响应内容处理函数 + * @since 5.7.8 + */ + public void then(Consumer consumer) { + try (final aiyh.utils.tool.cn.hutool.http.HttpResponse response = execute(true)) { + consumer.accept(response); + } + } + + /** + * 执行Request请求后,对响应内容后续处理
+ * 处理结束后关闭连接 + * + * @param 处理结果类型 + * @param function 响应内容处理函数 + * @return 处理结果 + * @since 5.8.5 + */ + public T thenFunction(Function function) { + try (final aiyh.utils.tool.cn.hutool.http.HttpResponse response = execute(true)) { + return function.apply(response); + } + } + + /** + * 简单验证,生成的头信息类似于: + *

+	 * Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
+	 * 
+ * + * @param username 用户名 + * @param password 密码 + * @return this + */ + public HttpRequest basicAuth(String username, String password) { + return auth(HttpUtil.buildBasicAuth(username, password, charset)); + } + + /** + * 简单代理验证,生成的头信息类似于: + *
+	 * Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
+	 * 
+ * + * @param username 用户名 + * @param password 密码 + * @return this + * @since 5.4.6 + */ + public HttpRequest basicProxyAuth(String username, String password) { + return proxyAuth(HttpUtil.buildBasicAuth(username, password, charset)); + } + + /** + * 令牌验证,生成的头类似于:"Authorization: Bearer XXXXX",一般用于JWT + * + * @param token 令牌内容 + * @return HttpRequest + * @since 5.5.3 + */ + public HttpRequest bearerAuth(String token) { + return auth("Bearer " + token); + } + + /** + * 验证,简单插入Authorization头 + * + * @param content 验证内容 + * @return HttpRequest + * @since 5.2.4 + */ + public HttpRequest auth(String content) { + header(aiyh.utils.tool.cn.hutool.http.Header.AUTHORIZATION, content, true); + return this; + } + + /** + * 验证,简单插入Authorization头 + * + * @param content 验证内容 + * @return HttpRequest + * @since 5.4.6 + */ + public HttpRequest proxyAuth(String content) { + header(aiyh.utils.tool.cn.hutool.http.Header.PROXY_AUTHORIZATION, content, true); + return this; + } + + @Override + public String toString() { + StringBuilder sb = StrUtil.builder(); + sb.append("Request Url: ").append(this.url.setCharset(this.charset)).append(StrUtil.CRLF); + sb.append(super.toString()); + return sb.toString(); + } + + // ---------------------------------------------------------------- Private method start + + /** + * 执行Reuqest请求 + * + * @param isAsync 是否异步 + * @param requestInterceptors 请求拦截器列表 + * @param responseInterceptors 响应拦截器列表 + * @return this + */ + private aiyh.utils.tool.cn.hutool.http.HttpResponse doExecute(boolean isAsync, HttpInterceptor.Chain requestInterceptors, + HttpInterceptor.Chain responseInterceptors) { + if (null != requestInterceptors) { + for (HttpInterceptor interceptor : requestInterceptors) { + interceptor.process(this); + } + } + + // 初始化URL + urlWithParamIfGet(); + // 初始化 connection + initConnection(); + // 发送请求 + send(); + + // 手动实现重定向 + aiyh.utils.tool.cn.hutool.http.HttpResponse httpResponse = sendRedirectIfPossible(isAsync); + + // 获取响应 + if (null == httpResponse) { + httpResponse = new aiyh.utils.tool.cn.hutool.http.HttpResponse(this.httpConnection, this.config, this.charset, isAsync, isIgnoreResponseBody()); + } + + // 拦截响应 + if (null != responseInterceptors) { + for (HttpInterceptor interceptor : responseInterceptors) { + interceptor.process(httpResponse); + } + } + + return httpResponse; + } + + /** + * 初始化网络连接 + */ + private void initConnection() { + if (null != this.httpConnection) { + // 执行下次请求时自动关闭上次请求(常用于转发) + this.httpConnection.disconnectQuietly(); + } + + this.httpConnection = HttpConnection + // issue#I50NHQ + // 在生成正式URL前,设置自定义编码 + .create(this.url.setCharset(this.charset).toURL(this.urlHandler), config.proxy)// + .setConnectTimeout(config.connectionTimeout)// + .setReadTimeout(config.readTimeout)// + .setMethod(this.method)// + .setHttpsInfo(config.hostnameVerifier, config.ssf)// + // 关闭JDK自动转发,采用手动转发方式 + .setInstanceFollowRedirects(false) + // 流方式上传数据 + .setChunkedStreamingMode(config.blockSize) + // 覆盖默认Header + .header(this.headers, true); + + if (null != this.cookie) { + // 当用户自定义Cookie时,全局Cookie自动失效 + this.httpConnection.setCookie(this.cookie); + } else { + // 读取全局Cookie信息并附带到请求中 + GlobalCookieManager.add(this.httpConnection); + } + + // 是否禁用缓存 + if (config.isDisableCache) { + this.httpConnection.disableCache(); + } + } + + /** + * 对于GET请求将参数加到URL中
+ * 此处不对URL中的特殊字符做单独编码
+ * 对于非rest的GET请求,且处于重定向时,参数丢弃 + */ + private void urlWithParamIfGet() { + if (aiyh.utils.tool.cn.hutool.http.Method.GET.equals(method) && !this.isRest && this.redirectCount <= 0) { + UrlQuery query = this.url.getQuery(); + if (null == query) { + query = new UrlQuery(); + this.url.setQuery(query); + } + + // 优先使用body形式的参数,不存在使用form + if (ArrayUtil.isNotEmpty(this.bodyBytes)) { + query.parse(StrUtil.str(this.bodyBytes, this.charset), this.charset); + } else { + query.addAll(this.form); + } + } + } + + /** + * 调用转发,如果需要转发返回转发结果,否则返回{@code null} + * + * @param isAsync 是否异步 + * @return {@link aiyh.utils.tool.cn.hutool.http.HttpResponse},无转发返回 {@code null} + */ + private HttpResponse sendRedirectIfPossible(boolean isAsync) { + // 手动实现重定向 + if (config.maxRedirectCount > 0) { + int responseCode; + try { + responseCode = httpConnection.responseCode(); + } catch (IOException e) { + // 错误时静默关闭连接 + this.httpConnection.disconnectQuietly(); + throw new HttpException(e); + } + + if (responseCode != HttpURLConnection.HTTP_OK) { + if (HttpStatus.isRedirected(responseCode)) { + final UrlBuilder redirectUrl; + String location = httpConnection.header(aiyh.utils.tool.cn.hutool.http.Header.LOCATION); + if (!HttpUtil.isHttp(location) && !HttpUtil.isHttps(location)) { + // issue#I5TPSY + // location可能为相对路径 + if (!location.startsWith("/")) { + location = StrUtil.addSuffixIfNot(this.url.getPathStr(), "/") + location; + } + redirectUrl = UrlBuilder.of(this.url.getScheme(), this.url.getHost(), this.url.getPort() + , location, null, null, this.charset); + } else { + redirectUrl = UrlBuilder.ofHttpWithoutEncode(location); + } + setUrl(redirectUrl); + if (redirectCount < config.maxRedirectCount) { + redirectCount++; + // 重定向不再走过滤器 + return doExecute(isAsync, config.interceptorOnRedirect ? config.requestInterceptors : null, + config.interceptorOnRedirect ? config.responseInterceptors : null); + } + } + } + } + return null; + } + + /** + * 发送数据流 + * + * @throws IORuntimeException IO异常 + */ + private void send() throws IORuntimeException { + try { + if (aiyh.utils.tool.cn.hutool.http.Method.POST.equals(this.method) // + || aiyh.utils.tool.cn.hutool.http.Method.PUT.equals(this.method) // + || aiyh.utils.tool.cn.hutool.http.Method.DELETE.equals(this.method) // + || this.isRest) { + if (isMultipart()) { + sendMultipart(); // 文件上传表单 + } else { + sendFormUrlEncoded();// 普通表单 + } + } else { + this.httpConnection.connect(); + } + } catch (IOException e) { + // 异常时关闭连接 + this.httpConnection.disconnectQuietly(); + throw new IORuntimeException(e); + } + } + + /** + * 发送普通表单
+ * 发送数据后自动关闭输出流 + * + * @throws IOException IO异常 + */ + private void sendFormUrlEncoded() throws IOException { + if (StrUtil.isBlank(this.header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE))) { + // 如果未自定义Content-Type,使用默认的application/x-www-form-urlencoded + this.httpConnection.header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE, ContentType.FORM_URLENCODED.toString(this.charset), true); + } + + // Write的时候会优先使用body中的内容,write时自动关闭OutputStream + RequestBody body; + if (ArrayUtil.isNotEmpty(this.bodyBytes)) { + body = BytesBody.create(this.bodyBytes); + } else { + body = FormUrlEncodedBody.create(this.form, this.charset); + } + body.writeClose(this.httpConnection.getOutputStream()); + } + + /** + * 发送多组件请求(例如包含文件的表单)
+ * 发送数据后自动关闭输出流 + * + * @throws IOException IO异常 + */ + private void sendMultipart() throws IOException { + final MultipartBody multipartBody = MultipartBody.create(this.form, this.charset); + // 设置表单类型为Multipart(文件上传) + this.httpConnection.header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE, multipartBody.getContentType(), true); + multipartBody.writeClose(this.httpConnection.getOutputStream()); + } + + /** + * 是否忽略读取响应body部分
+ * HEAD、CONNECT、OPTIONS、TRACE方法将不读取响应体 + * + * @return 是否需要忽略响应body部分 + * @since 3.1.2 + */ + private boolean isIgnoreResponseBody() { + return aiyh.utils.tool.cn.hutool.http.Method.HEAD == this.method // + || aiyh.utils.tool.cn.hutool.http.Method.CONNECT == this.method // + || aiyh.utils.tool.cn.hutool.http.Method.OPTIONS == this.method // + || Method.TRACE == this.method; + } + + /** + * 判断是否为multipart/form-data表单,条件如下: + * + *
+	 *     1. 存在资源对象(fileForm非空)
+	 *     2. 用户自定义头为multipart/form-data开头
+	 * 
+ * + * @return 是否为multipart/form-data表单 + * @since 5.3.5 + */ + private boolean isMultipart() { + if (this.isMultiPart) { + return true; + } + + final String contentType = header(Header.CONTENT_TYPE); + return StrUtil.isNotEmpty(contentType) && + contentType.startsWith(ContentType.MULTIPART.getValue()); + } + + /** + * 将参数加入到form中,如果form为空,新建之。 + * + * @param name 表单属性名 + * @param value 属性值 + * @return this + */ + private HttpRequest putToForm(String name, Object value) { + if (null == name || null == value) { + return this; + } + if (null == this.form) { + this.form = new TableMap<>(16); + } + this.form.put(name, value); + return this; + } + // ---------------------------------------------------------------- Private method end + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResource.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResource.java new file mode 100644 index 0000000..1b345f9 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResource.java @@ -0,0 +1,56 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.io.resource.Resource; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; + +import java.io.InputStream; +import java.io.Serializable; +import java.net.URL; + +/** + * HTTP资源,可自定义Content-Type + * + * @author looly + * @since 5.7.17 + */ +public class HttpResource implements Resource, Serializable { + private static final long serialVersionUID = 1L; + + private final Resource resource; + private final String contentType; + + /** + * 构造 + * + * @param resource 资源,非空 + * @param contentType Content-Type类型,{@code null}表示不设置 + */ + public HttpResource(Resource resource, String contentType) { + this.resource = Assert.notNull(resource, "Resource must be not null !"); + this.contentType = contentType; + } + + @Override + public String getName() { + return resource.getName(); + } + + @Override + public URL getUrl() { + return resource.getUrl(); + } + + @Override + public InputStream getStream() { + return resource.getStream(); + } + + /** + * 获取自定义Content-Type类型 + * + * @return Content-Type类型 + */ + public String getContentType() { + return this.contentType; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResponse.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResponse.java new file mode 100755 index 0000000..379f947 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpResponse.java @@ -0,0 +1,644 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.convert.Convert; +import aiyh.utils.tool.cn.hutool.core.io.FastByteArrayOutputStream; +import aiyh.utils.tool.cn.hutool.core.io.FileUtil; +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.io.StreamProgress; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; +import aiyh.utils.tool.cn.hutool.core.util.ObjUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.core.util.URLUtil; +import aiyh.utils.tool.cn.hutool.http.cookie.GlobalCookieManager; + +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.EOFException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpCookie; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map.Entry; + +/** + * Http响应类
+ * 非线程安全对象 + * + * @author Looly + */ +public class HttpResponse extends HttpBase implements Closeable { + + /** + * Http配置 + */ + protected HttpConfig config; + /** + * 持有连接对象 + */ + protected HttpConnection httpConnection; + /** + * Http请求原始流 + */ + protected InputStream in; + /** + * 是否异步,异步下只持有流,否则将在初始化时直接读取body内容 + */ + private volatile boolean isAsync; + /** + * 响应状态码 + */ + protected int status; + /** + * 是否忽略读取Http响应体 + */ + private final boolean ignoreBody; + /** + * 从响应中获取的编码 + */ + private Charset charsetFromResponse; + + /** + * 构造 + * + * @param httpConnection {@link HttpConnection} + * @param config Http配置 + * @param charset 编码,从请求编码中获取默认编码 + * @param isAsync 是否异步 + * @param isIgnoreBody 是否忽略读取响应体 + * @since 3.1.2 + */ + protected HttpResponse(HttpConnection httpConnection, HttpConfig config, Charset charset, boolean isAsync, boolean isIgnoreBody) { + this.httpConnection = httpConnection; + this.config = config; + this.charset = charset; + this.isAsync = isAsync; + this.ignoreBody = isIgnoreBody; + initWithDisconnect(); + } + + /** + * 获取状态码 + * + * @return 状态码 + */ + public int getStatus() { + return this.status; + } + + /** + * 请求是否成功,判断依据为:状态码范围在200~299内。 + * + * @return 是否成功请求 + * @since 4.1.9 + */ + public boolean isOk() { + return this.status >= 200 && this.status < 300; + } + + /** + * 同步
+ * 如果为异步状态,则暂时不读取服务器中响应的内容,而是持有Http链接的{@link InputStream}。
+ * 当调用此方法时,异步状态转为同步状态,此时从Http链接流中读取body内容并暂存在内容中。如果已经是同步状态,则不进行任何操作。 + * + * @return this + */ + public HttpResponse sync() { + return this.isAsync ? forceSync() : this; + } + + // ---------------------------------------------------------------- Http Response Header start + + /** + * 获取内容编码 + * + * @return String + */ + public String contentEncoding() { + return header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_ENCODING); + } + + /** + * 获取内容长度,以下情况长度无效: + *
    + *
  • Transfer-Encoding: Chunked
  • + *
  • Content-Encoding: XXX
  • + *
+ * 参考:https://blog.csdn.net/jiang7701037/article/details/86304302 + * + * @return 长度,-1表示服务端未返回或长度无效 + * @since 5.7.9 + */ + public long contentLength() { + long contentLength = Convert.toLong(header(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_LENGTH), -1L); + if (contentLength > 0 && (isChunked() || StrUtil.isNotBlank(contentEncoding()))) { + //按照HTTP协议规范,在 Transfer-Encoding和Content-Encoding设置后 Content-Length 无效。 + contentLength = -1; + } + return contentLength; + } + + /** + * 是否为gzip压缩过的内容 + * + * @return 是否为gzip压缩过的内容 + */ + public boolean isGzip() { + final String contentEncoding = contentEncoding(); + return "gzip".equalsIgnoreCase(contentEncoding); + } + + /** + * 是否为zlib(Deflate)压缩过的内容 + * + * @return 是否为zlib(Deflate)压缩过的内容 + * @since 4.5.7 + */ + public boolean isDeflate() { + final String contentEncoding = contentEncoding(); + return "deflate".equalsIgnoreCase(contentEncoding); + } + + /** + * 是否为Transfer-Encoding:Chunked的内容 + * + * @return 是否为Transfer-Encoding:Chunked的内容 + * @since 4.6.2 + */ + public boolean isChunked() { + final String transferEncoding = header(aiyh.utils.tool.cn.hutool.http.Header.TRANSFER_ENCODING); + return "Chunked".equalsIgnoreCase(transferEncoding); + } + + /** + * 获取本次请求服务器返回的Cookie信息 + * + * @return Cookie字符串 + * @since 3.1.1 + */ + public String getCookieStr() { + return header(aiyh.utils.tool.cn.hutool.http.Header.SET_COOKIE); + } + + /** + * 获取Cookie + * + * @return Cookie列表 + * @since 3.1.1 + */ + public List getCookies() { + return GlobalCookieManager.getCookies(this.httpConnection); + } + + /** + * 获取Cookie + * + * @param name Cookie名 + * @return {@link HttpCookie} + * @since 4.1.4 + */ + public HttpCookie getCookie(String name) { + List cookie = getCookies(); + if (null != cookie) { + for (HttpCookie httpCookie : cookie) { + if (httpCookie.getName().equals(name)) { + return httpCookie; + } + } + } + return null; + } + + /** + * 获取Cookie值 + * + * @param name Cookie名 + * @return Cookie值 + * @since 4.1.4 + */ + public String getCookieValue(String name) { + HttpCookie cookie = getCookie(name); + return (null == cookie) ? null : cookie.getValue(); + } + // ---------------------------------------------------------------- Http Response Header end + + // ---------------------------------------------------------------- Body start + + /** + * 获得服务区响应流
+ * 异步模式下获取Http原生流,同步模式下获取获取到的在内存中的副本
+ * 如果想在同步模式下获取流,请先调用{@link #sync()}方法强制同步
+ * 流获取后处理完毕需关闭此类 + * + * @return 响应流 + */ + public InputStream bodyStream() { + if (isAsync) { + return this.in; + } + return new ByteArrayInputStream(this.bodyBytes); + } + + /** + * 获取响应流字节码
+ * 此方法会转为同步模式 + * + * @return byte[] + */ + @Override + public byte[] bodyBytes() { + sync(); + return this.bodyBytes; + } + + /** + * 设置主体字节码
+ * 需在此方法调用前使用charset方法设置编码,否则使用默认编码UTF-8 + * + * @param bodyBytes 主体 + * @return this + */ + public HttpResponse body(byte[] bodyBytes) { + sync(); + if (null != bodyBytes) { + this.bodyBytes = bodyBytes; + } + return this; + } + + /** + * 获取响应主体 + * + * @return String + * @throws HttpException 包装IO异常 + */ + public String body() throws HttpException { + return HttpUtil.getString(bodyBytes(), this.charset, null == this.charsetFromResponse); + } + + /** + * 将响应内容写出到{@link OutputStream}
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param out 写出的流 + * @param isCloseOut 是否关闭输出流 + * @param streamProgress 进度显示接口,通过实现此接口显示下载进度 + * @return 写出bytes数 + * @since 3.3.2 + */ + public long writeBody(OutputStream out, boolean isCloseOut, StreamProgress streamProgress) { + Assert.notNull(out, "[out] must be not null!"); + final long contentLength = contentLength(); + try { + return copyBody(bodyStream(), out, contentLength, streamProgress, this.config.ignoreEOFError); + } finally { + IoUtil.close(this); + if (isCloseOut) { + IoUtil.close(out); + } + } + } + + /** + * 将响应内容写出到文件
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param targetFileOrDir 写出到的文件或目录 + * @param streamProgress 进度显示接口,通过实现此接口显示下载进度 + * @return 写出bytes数 + * @since 3.3.2 + */ + public long writeBody(File targetFileOrDir, StreamProgress streamProgress) { + Assert.notNull(targetFileOrDir, "[targetFileOrDir] must be not null!"); + + final File outFile = completeFileNameFromHeader(targetFileOrDir); + return writeBody(FileUtil.getOutputStream(outFile), true, streamProgress); + } + + /** + * 将响应内容写出到文件-避免未完成的文件
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式)
+ * 来自:https://gitee.com/dromara/hutool/pulls/407
+ * 此方法原理是先在目标文件同级目录下创建临时文件,下载之,等下载完毕后重命名,避免因下载错误导致的文件不完整。 + * + * @param targetFileOrDir 写出到的文件或目录 + * @param tempFileSuffix 临时文件后缀,默认".temp" + * @param streamProgress 进度显示接口,通过实现此接口显示下载进度 + * @return 写出bytes数 + * @since 5.7.12 + */ + public long writeBody(File targetFileOrDir, String tempFileSuffix, StreamProgress streamProgress) { + Assert.notNull(targetFileOrDir, "[targetFileOrDir] must be not null!"); + + File outFile = completeFileNameFromHeader(targetFileOrDir); + + if (StrUtil.isBlank(tempFileSuffix)) { + tempFileSuffix = ".temp"; + } else { + tempFileSuffix = StrUtil.addPrefixIfNot(tempFileSuffix, StrUtil.DOT); + } + + // 目标文件真实名称 + final String fileName = outFile.getName(); + // 临时文件名称 + final String tempFileName = fileName + tempFileSuffix; + + // 临时文件 + outFile = new File(outFile.getParentFile(), tempFileName); + + long length; + try { + length = writeBody(outFile, streamProgress); + // 重命名下载好的临时文件 + FileUtil.rename(outFile, fileName, true); + } catch (Throwable e) { + // 异常则删除临时文件 + FileUtil.del(outFile); + throw new HttpException(e); + } + return length; + } + + /** + * 将响应内容写出到文件
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param targetFileOrDir 写出到的文件 + * @param streamProgress 进度显示接口,通过实现此接口显示下载进度 + * @return 写出的文件 + * @since 5.6.4 + */ + public File writeBodyForFile(File targetFileOrDir, StreamProgress streamProgress) { + Assert.notNull(targetFileOrDir, "[targetFileOrDir] must be not null!"); + + final File outFile = completeFileNameFromHeader(targetFileOrDir); + writeBody(FileUtil.getOutputStream(outFile), true, streamProgress); + + return outFile; + } + + /** + * 将响应内容写出到文件
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param targetFileOrDir 写出到的文件或目录 + * @return 写出bytes数 + * @since 3.3.2 + */ + public long writeBody(File targetFileOrDir) { + return writeBody(targetFileOrDir, null); + } + + /** + * 将响应内容写出到文件
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param targetFileOrDir 写出到的文件或目录的路径 + * @return 写出bytes数 + * @since 3.3.2 + */ + public long writeBody(String targetFileOrDir) { + return writeBody(FileUtil.file(targetFileOrDir)); + } + // ---------------------------------------------------------------- Body end + + @Override + public void close() { + IoUtil.close(this.in); + this.in = null; + // 关闭连接 + this.httpConnection.disconnectQuietly(); + } + + @Override + public String toString() { + StringBuilder sb = StrUtil.builder(); + sb.append("Response Headers: ").append(StrUtil.CRLF); + for (Entry> entry : this.headers.entrySet()) { + sb.append(" ").append(entry).append(StrUtil.CRLF); + } + + sb.append("Response Body: ").append(StrUtil.CRLF); + sb.append(" ").append(this.body()).append(StrUtil.CRLF); + + return sb.toString(); + } + + /** + * 从响应头补全下载文件名 + * + * @param targetFileOrDir 目标文件夹或者目标文件 + * @return File 保存的文件 + * @since 5.4.1 + */ + public File completeFileNameFromHeader(File targetFileOrDir) { + if (false == targetFileOrDir.isDirectory()) { + // 非目录直接返回 + return targetFileOrDir; + } + + // 从头信息中获取文件名 + String fileName = getFileNameFromDisposition(null); + if (StrUtil.isBlank(fileName)) { + final String path = httpConnection.getUrl().getPath(); + // 从路径中获取文件名 + fileName = StrUtil.subSuf(path, path.lastIndexOf('/') + 1); + if (StrUtil.isBlank(fileName)) { + // 编码后的路径做为文件名 + fileName = URLUtil.encodeQuery(path, charset); + } else { + // issue#I4K0FS@Gitee + fileName = URLUtil.decode(fileName, charset); + } + } + return FileUtil.file(targetFileOrDir, fileName); + } + + /** + * 从Content-Disposition头中获取文件名 + * @param paramName 文件参数名 + * + * @return 文件名,empty表示无 + */ + public String getFileNameFromDisposition(String paramName) { + paramName = ObjUtil.defaultIfNull(paramName, "filename"); + String fileName = null; + final String disposition = header(Header.CONTENT_DISPOSITION); + if (StrUtil.isNotBlank(disposition)) { + fileName = ReUtil.get(paramName+"=\"(.*?)\"", disposition, 1); + if (StrUtil.isBlank(fileName)) { + fileName = StrUtil.subAfter(disposition, paramName + "=", true); + } + } + return fileName; + } + + // ---------------------------------------------------------------- Private method start + + /** + * 初始化Http响应,并在报错时关闭连接。
+ * 初始化包括: + * + *
+	 * 1、读取Http状态
+	 * 2、读取头信息
+	 * 3、持有Http流,并不关闭流
+	 * 
+ * + * @return this + * @throws HttpException IO异常 + */ + private HttpResponse initWithDisconnect() throws HttpException { + try { + init(); + } catch (HttpException e) { + this.httpConnection.disconnectQuietly(); + throw e; + } + return this; + } + + /** + * 初始化Http响应
+ * 初始化包括: + * + *
+	 * 1、读取Http状态
+	 * 2、读取头信息
+	 * 3、持有Http流,并不关闭流
+	 * 
+ * + * @return this + * @throws HttpException IO异常 + */ + private HttpResponse init() throws HttpException { + // 获取响应状态码 + try { + this.status = httpConnection.responseCode(); + } catch (IOException e) { + if (false == (e instanceof FileNotFoundException)) { + throw new HttpException(e); + } + // 服务器无返回内容,忽略之 + } + + + // 读取响应头信息 + try { + this.headers = httpConnection.headers(); + } catch (IllegalArgumentException e) { + // ignore + // StaticLog.warn(e, e.getMessage()); + } + + // 存储服务端设置的Cookie信息 + GlobalCookieManager.store(httpConnection); + + // 获取响应编码 + final Charset charset = httpConnection.getCharset(); + this.charsetFromResponse = charset; + if (null != charset) { + this.charset = charset; + } + + // 获取响应内容流 + this.in = new HttpInputStream(this); + + // 同步情况下强制同步 + return this.isAsync ? this : forceSync(); + } + + /** + * 强制同步,用于初始化
+ * 强制同步后变化如下: + * + *
+	 * 1、读取body内容到内存
+	 * 2、异步状态设为false(变为同步状态)
+	 * 3、关闭Http流
+	 * 4、断开与服务器连接
+	 * 
+ * + * @return this + */ + private HttpResponse forceSync() { + // 非同步状态转为同步状态 + try { + this.readBody(this.in); + } catch (IORuntimeException e) { + //noinspection StatementWithEmptyBody + if (e.getCause() instanceof FileNotFoundException) { + // 服务器无返回内容,忽略之 + } else { + throw new HttpException(e); + } + } finally { + if (this.isAsync) { + this.isAsync = false; + } + this.close(); + } + return this; + } + + /** + * 读取主体,忽略EOFException异常 + * + * @param in 输入流 + * @throws IORuntimeException IO异常 + */ + private void readBody(InputStream in) throws IORuntimeException { + if (ignoreBody) { + return; + } + + final long contentLength = contentLength(); + final FastByteArrayOutputStream out = new FastByteArrayOutputStream((int) contentLength); + copyBody(in, out, contentLength, null, this.config.ignoreEOFError); + this.bodyBytes = out.toByteArray(); + } + + /** + * 将响应内容写出到{@link OutputStream}
+ * 异步模式下直接读取Http流写出,同步模式下将存储在内存中的响应内容写出
+ * 写出后会关闭Http流(异步模式) + * + * @param in 输入流 + * @param out 写出的流 + * @param contentLength 总长度,-1表示未知 + * @param streamProgress 进度显示接口,通过实现此接口显示下载进度 + * @param isIgnoreEOFError 是否忽略响应读取时可能的EOF异常 + * @return 拷贝长度 + */ + private static long copyBody(InputStream in, OutputStream out, long contentLength, StreamProgress streamProgress, boolean isIgnoreEOFError) { + if (null == out) { + throw new NullPointerException("[out] is null!"); + } + + long copyLength = -1; + try { + copyLength = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE, contentLength, streamProgress); + } catch (IORuntimeException e) { + //noinspection StatementWithEmptyBody + if (isIgnoreEOFError + && (e.getCause() instanceof EOFException || StrUtil.containsIgnoreCase(e.getMessage(), "Premature EOF"))) { + // 忽略读取HTTP流中的EOF错误 + } else { + throw e; + } + } + return copyLength; + } + // ---------------------------------------------------------------- Private method end +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpStatus.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpStatus.java new file mode 100644 index 0000000..90c856c --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpStatus.java @@ -0,0 +1,222 @@ +package aiyh.utils.tool.cn.hutool.http; + +/** + * HTTP状态码 + * + * @author Looly + * @see java.net.HttpURLConnection + * + */ +public class HttpStatus { + + /* 2XX: generally "OK" */ + + /** + * HTTP Status-Code 200: OK. + */ + public static final int HTTP_OK = 200; + + /** + * HTTP Status-Code 201: Created. + */ + public static final int HTTP_CREATED = 201; + + /** + * HTTP Status-Code 202: Accepted. + */ + public static final int HTTP_ACCEPTED = 202; + + /** + * HTTP Status-Code 203: Non-Authoritative Information. + */ + public static final int HTTP_NOT_AUTHORITATIVE = 203; + + /** + * HTTP Status-Code 204: No Content. + */ + public static final int HTTP_NO_CONTENT = 204; + + /** + * HTTP Status-Code 205: Reset Content. + */ + public static final int HTTP_RESET = 205; + + /** + * HTTP Status-Code 206: Partial Content. + */ + public static final int HTTP_PARTIAL = 206; + + /* 3XX: relocation/redirect */ + + /** + * HTTP Status-Code 300: Multiple Choices. + */ + public static final int HTTP_MULT_CHOICE = 300; + + /** + * HTTP Status-Code 301: Moved Permanently. + */ + public static final int HTTP_MOVED_PERM = 301; + + /** + * HTTP Status-Code 302: Temporary Redirect. + */ + public static final int HTTP_MOVED_TEMP = 302; + + /** + * HTTP Status-Code 303: See Other. + */ + public static final int HTTP_SEE_OTHER = 303; + + /** + * HTTP Status-Code 304: Not Modified. + */ + public static final int HTTP_NOT_MODIFIED = 304; + + /** + * HTTP Status-Code 305: Use Proxy. + */ + public static final int HTTP_USE_PROXY = 305; + + /** + * HTTP 1.1 Status-Code 307: Temporary Redirect.
+ * 见:RFC-7231 + */ + public static final int HTTP_TEMP_REDIRECT = 307; + + /** + * HTTP 1.1 Status-Code 308: Permanent Redirect 永久重定向
+ * 见:RFC-7231 + */ + public static final int HTTP_PERMANENT_REDIRECT = 308; + + /* 4XX: client error */ + + /** + * HTTP Status-Code 400: Bad Request. + */ + public static final int HTTP_BAD_REQUEST = 400; + + /** + * HTTP Status-Code 401: Unauthorized. + */ + public static final int HTTP_UNAUTHORIZED = 401; + + /** + * HTTP Status-Code 402: Payment Required. + */ + public static final int HTTP_PAYMENT_REQUIRED = 402; + + /** + * HTTP Status-Code 403: Forbidden. + */ + public static final int HTTP_FORBIDDEN = 403; + + /** + * HTTP Status-Code 404: Not Found. + */ + public static final int HTTP_NOT_FOUND = 404; + + /** + * HTTP Status-Code 405: Method Not Allowed. + */ + public static final int HTTP_BAD_METHOD = 405; + + /** + * HTTP Status-Code 406: Not Acceptable. + */ + public static final int HTTP_NOT_ACCEPTABLE = 406; + + /** + * HTTP Status-Code 407: Proxy Authentication Required. + */ + public static final int HTTP_PROXY_AUTH = 407; + + /** + * HTTP Status-Code 408: Request Time-Out. + */ + public static final int HTTP_CLIENT_TIMEOUT = 408; + + /** + * HTTP Status-Code 409: Conflict. + */ + public static final int HTTP_CONFLICT = 409; + + /** + * HTTP Status-Code 410: Gone. + */ + public static final int HTTP_GONE = 410; + + /** + * HTTP Status-Code 411: Length Required. + */ + public static final int HTTP_LENGTH_REQUIRED = 411; + + /** + * HTTP Status-Code 412: Precondition Failed. + */ + public static final int HTTP_PRECON_FAILED = 412; + + /** + * HTTP Status-Code 413: Request Entity Too Large. + */ + public static final int HTTP_ENTITY_TOO_LARGE = 413; + + /** + * HTTP Status-Code 414: Request-URI Too Large. + */ + public static final int HTTP_REQ_TOO_LONG = 414; + + /** + * HTTP Status-Code 415: Unsupported Media Type. + */ + public static final int HTTP_UNSUPPORTED_TYPE = 415; + + /* 5XX: server error */ + + /** + * HTTP Status-Code 500: Internal Server Error. + */ + public static final int HTTP_INTERNAL_ERROR = 500; + + /** + * HTTP Status-Code 501: Not Implemented. + */ + public static final int HTTP_NOT_IMPLEMENTED = 501; + + /** + * HTTP Status-Code 502: Bad Gateway. + */ + public static final int HTTP_BAD_GATEWAY = 502; + + /** + * HTTP Status-Code 503: Service Unavailable. + */ + public static final int HTTP_UNAVAILABLE = 503; + + /** + * HTTP Status-Code 504: Gateway Timeout. + */ + public static final int HTTP_GATEWAY_TIMEOUT = 504; + + /** + * HTTP Status-Code 505: HTTP Version Not Supported. + */ + public static final int HTTP_VERSION = 505; + + /** + * 是否为重定向状态码 + * @param responseCode 被检查的状态码 + * @return 是否为重定向状态码 + * @since 5.6.3 + */ + public static boolean isRedirected(int responseCode){ + return responseCode == HTTP_MOVED_PERM + || responseCode == HTTP_MOVED_TEMP + || responseCode == HTTP_SEE_OTHER + // issue#1504@Github,307和308是RFC 7538中http 1.1定义的规范 + || responseCode == HTTP_TEMP_REDIRECT + || responseCode == HTTP_PERMANENT_REDIRECT; + + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpUtil.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpUtil.java new file mode 100755 index 0000000..51393c9 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/HttpUtil.java @@ -0,0 +1,893 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.codec.Base64; +import aiyh.utils.tool.cn.hutool.core.convert.Convert; +import aiyh.utils.tool.cn.hutool.core.io.FileUtil; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.io.StreamProgress; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.net.RFC3986; +import aiyh.utils.tool.cn.hutool.core.net.url.UrlQuery; +import aiyh.utils.tool.cn.hutool.core.text.StrBuilder; +import aiyh.utils.tool.cn.hutool.core.util.CharsetUtil; +import aiyh.utils.tool.cn.hutool.core.util.ObjectUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.core.util.URLUtil; +import aiyh.utils.tool.cn.hutool.http.cookie.GlobalCookieManager; +import aiyh.utils.tool.cn.hutool.http.server.SimpleServer; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.CookieManager; +import java.net.HttpURLConnection; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Http请求工具类 + * + * @author xiaoleilu + */ +public class HttpUtil { + + /** + * 正则:Content-Type中的编码信息 + */ + public static final Pattern CHARSET_PATTERN = Pattern.compile("charset\\s*=\\s*([a-z0-9-]*)", Pattern.CASE_INSENSITIVE); + /** + * 正则:匹配meta标签的编码信息 + */ + public static final Pattern META_CHARSET_PATTERN = Pattern.compile("]*?charset\\s*=\\s*['\"]?([a-z0-9-]*)", Pattern.CASE_INSENSITIVE); + + /** + * 检测是否https + * + * @param url URL + * @return 是否https + */ + public static boolean isHttps(String url) { + return StrUtil.startWithIgnoreCase(url, "https:"); + } + + /** + * 检测是否http + * + * @param url URL + * @return 是否http + * @since 5.3.8 + */ + public static boolean isHttp(String url) { + return StrUtil.startWithIgnoreCase(url, "http:"); + } + + /** + * 创建Http请求对象 + * + * @param method 方法枚举{@link aiyh.utils.tool.cn.hutool.http.Method} + * @param url 请求的URL,可以使HTTP或者HTTPS + * @return {@link aiyh.utils.tool.cn.hutool.http.HttpRequest} + * @since 3.0.9 + */ + public static aiyh.utils.tool.cn.hutool.http.HttpRequest createRequest(Method method, String url) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.of(url).method(method); + } + + /** + * 创建Http GET请求对象 + * + * @param url 请求的URL,可以使HTTP或者HTTPS + * @return {@link aiyh.utils.tool.cn.hutool.http.HttpRequest} + * @since 3.2.0 + */ + public static aiyh.utils.tool.cn.hutool.http.HttpRequest createGet(String url) { + return createGet(url, false); + } + + /** + * 创建Http GET请求对象 + * + * @param url 请求的URL,可以使HTTP或者HTTPS + * @param isFollowRedirects 是否打开重定向 + * @return {@link aiyh.utils.tool.cn.hutool.http.HttpRequest} + * @since 5.6.4 + */ + public static aiyh.utils.tool.cn.hutool.http.HttpRequest createGet(String url, boolean isFollowRedirects) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.get(url).setFollowRedirects(isFollowRedirects); + } + + /** + * 创建Http POST请求对象 + * + * @param url 请求的URL,可以使HTTP或者HTTPS + * @return {@link aiyh.utils.tool.cn.hutool.http.HttpRequest} + * @since 3.2.0 + */ + public static aiyh.utils.tool.cn.hutool.http.HttpRequest createPost(String url) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.post(url); + } + + /** + * 发送get请求 + * + * @param urlString 网址 + * @param customCharset 自定义请求字符集,如果字符集获取不到,使用此字符集 + * @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null + */ + public static String get(String urlString, Charset customCharset) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.get(urlString).charset(customCharset).execute().body(); + } + + /** + * 发送get请求 + * + * @param urlString 网址 + * @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null + */ + public static String get(String urlString) { + return get(urlString, HttpGlobalConfig.getTimeout()); + } + + /** + * 发送get请求 + * + * @param urlString 网址 + * @param timeout 超时时长,-1表示默认超时,单位毫秒 + * @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null + * @since 3.2.0 + */ + public static String get(String urlString, int timeout) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.get(urlString).timeout(timeout).execute().body(); + } + + /** + * 发送get请求 + * + * @param urlString 网址 + * @param paramMap post表单数据 + * @return 返回数据 + */ + public static String get(String urlString, Map paramMap) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.get(urlString).form(paramMap).execute().body(); + } + + /** + * 发送get请求 + * + * @param urlString 网址 + * @param paramMap post表单数据 + * @param timeout 超时时长,-1表示默认超时,单位毫秒 + * @return 返回数据 + * @since 3.3.0 + */ + public static String get(String urlString, Map paramMap, int timeout) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.get(urlString).form(paramMap).timeout(timeout).execute().body(); + } + + /** + * 发送post请求 + * + * @param urlString 网址 + * @param paramMap post表单数据 + * @return 返回数据 + */ + public static String post(String urlString, Map paramMap) { + return post(urlString, paramMap, HttpGlobalConfig.getTimeout()); + } + + /** + * 发送post请求 + * + * @param urlString 网址 + * @param paramMap post表单数据 + * @param timeout 超时时长,-1表示默认超时,单位毫秒 + * @return 返回数据 + * @since 3.2.0 + */ + public static String post(String urlString, Map paramMap, int timeout) { + return aiyh.utils.tool.cn.hutool.http.HttpRequest.post(urlString).form(paramMap).timeout(timeout).execute().body(); + } + + /** + * 发送post请求
+ * 请求体body参数支持两种类型: + * + *
+	 * 1. 标准参数,例如 a=1&b=2 这种格式
+	 * 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
+	 * 
+ * + * @param urlString 网址 + * @param body post表单数据 + * @return 返回数据 + */ + public static String post(String urlString, String body) { + return post(urlString, body, HttpGlobalConfig.getTimeout()); + } + + /** + * 发送post请求
+ * 请求体body参数支持两种类型: + * + *
+	 * 1. 标准参数,例如 a=1&b=2 这种格式
+	 * 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
+	 * 
+ * + * @param urlString 网址 + * @param body post表单数据 + * @param timeout 超时时长,-1表示默认超时,单位毫秒 + * @return 返回数据 + * @since 3.2.0 + */ + public static String post(String urlString, String body, int timeout) { + return HttpRequest.post(urlString).timeout(timeout).body(body).execute().body(); + } + + // ---------------------------------------------------------------------------------------- download + + /** + * 下载远程文本 + * + * @param url 请求的url + * @param customCharsetName 自定义的字符集 + * @return 文本 + */ + public static String downloadString(String url, String customCharsetName) { + return downloadString(url, CharsetUtil.charset(customCharsetName), null); + } + + /** + * 下载远程文本 + * + * @param url 请求的url + * @param customCharset 自定义的字符集,可以使用{@link CharsetUtil#charset} 方法转换 + * @return 文本 + */ + public static String downloadString(String url, Charset customCharset) { + return downloadString(url, customCharset, null); + } + + /** + * 下载远程文本 + * + * @param url 请求的url + * @param customCharset 自定义的字符集,可以使用{@link CharsetUtil#charset} 方法转换 + * @param streamPress 进度条 {@link StreamProgress} + * @return 文本 + */ + public static String downloadString(String url, Charset customCharset, StreamProgress streamPress) { + return HttpDownloader.downloadString(url, customCharset, streamPress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param dest 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @return 文件大小 + */ + public static long downloadFile(String url, String dest) { + return downloadFile(url, FileUtil.file(dest)); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @return 文件大小 + */ + public static long downloadFile(String url, File destFile) { + return downloadFile(url, destFile, null); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @return 文件大小 + * @since 4.0.4 + */ + public static long downloadFile(String url, File destFile, int timeout) { + return downloadFile(url, destFile, timeout, null); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param streamProgress 进度条 + * @return 文件大小 + */ + public static long downloadFile(String url, File destFile, StreamProgress streamProgress) { + return downloadFile(url, destFile, -1, streamProgress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @param streamProgress 进度条 + * @return 文件大小 + * @since 4.0.4 + */ + public static long downloadFile(String url, File destFile, int timeout, StreamProgress streamProgress) { + return HttpDownloader.downloadFile(url, destFile, timeout, streamProgress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param dest 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @return 下载的文件对象 + * @since 5.4.1 + */ + public static File downloadFileFromUrl(String url, String dest) { + return downloadFileFromUrl(url, FileUtil.file(dest)); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @return 下载的文件对象 + * @since 5.4.1 + */ + public static File downloadFileFromUrl(String url, File destFile) { + return downloadFileFromUrl(url, destFile, null); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @return 下载的文件对象 + * @since 5.4.1 + */ + public static File downloadFileFromUrl(String url, File destFile, int timeout) { + return downloadFileFromUrl(url, destFile, timeout, null); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param streamProgress 进度条 + * @return 下载的文件对象 + * @since 5.4.1 + */ + public static File downloadFileFromUrl(String url, File destFile, StreamProgress streamProgress) { + return downloadFileFromUrl(url, destFile, -1, streamProgress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名 + * @param timeout 超时,单位毫秒,-1表示默认超时 + * @param streamProgress 进度条 + * @return 下载的文件对象 + * @since 5.4.1 + */ + public static File downloadFileFromUrl(String url, File destFile, int timeout, StreamProgress streamProgress) { + return HttpDownloader.downloadForFile(url, destFile, timeout, streamProgress); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param out 将下载内容写到输出流中 {@link OutputStream} + * @param isCloseOut 是否关闭输出流 + * @return 文件大小 + */ + public static long download(String url, OutputStream out, boolean isCloseOut) { + return download(url, out, isCloseOut, null); + } + + /** + * 下载远程文件 + * + * @param url 请求的url + * @param out 将下载内容写到输出流中 {@link OutputStream} + * @param isCloseOut 是否关闭输出流 + * @param streamProgress 进度条 + * @return 文件大小 + */ + public static long download(String url, OutputStream out, boolean isCloseOut, StreamProgress streamProgress) { + return HttpDownloader.download(url, out, isCloseOut, streamProgress); + } + + /** + * 下载远程文件数据,支持30x跳转 + * + * @param url 请求的url + * @return 文件数据 + * @since 5.3.6 + */ + public static byte[] downloadBytes(String url) { + return HttpDownloader.downloadBytes(url); + } + + /** + * 将Map形式的Form表单数据转换为Url参数形式,会自动url编码键和值 + * + * @param paramMap 表单数据 + * @return url参数 + */ + public static String toParams(Map paramMap) { + return toParams(paramMap, CharsetUtil.CHARSET_UTF_8); + } + + /** + * 将Map形式的Form表单数据转换为Url参数形式
+ * 编码键和值对 + * + * @param paramMap 表单数据 + * @param charsetName 编码 + * @return url参数 + * @deprecated 请使用 {@link #toParams(Map, Charset)} + */ + @Deprecated + public static String toParams(Map paramMap, String charsetName) { + return toParams(paramMap, CharsetUtil.charset(charsetName)); + } + + /** + * 将Map形式的Form表单数据转换为Url参数形式
+ * paramMap中如果key为空(null和"")会被忽略,如果value为null,会被做为空白符("")
+ * 会自动url编码键和值
+ * 此方法用于拼接URL中的Query部分,并不适用于POST请求中的表单 + * + *
+	 * key1=v1&key2=&key3=v3
+	 * 
+ * + * @param paramMap 表单数据 + * @param charset 编码,{@code null} 表示不encode键值对 + * @return url参数 + * @see #toParams(Map, Charset, boolean) + */ + public static String toParams(Map paramMap, Charset charset) { + return toParams(paramMap, charset, false); + } + + /** + * 将Map形式的Form表单数据转换为Url参数形式
+ * paramMap中如果key为空(null和"")会被忽略,如果value为null,会被做为空白符("")
+ * 会自动url编码键和值 + * + *
+	 * key1=v1&key2=&key3=v3
+	 * 
+ * + * @param paramMap 表单数据 + * @param charset 编码,null表示不encode键值对 + * @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+' + * @return url参数 + * @since 5.7.16 + */ + public static String toParams(Map paramMap, Charset charset, boolean isFormUrlEncoded) { + return UrlQuery.of(paramMap, isFormUrlEncoded).build(charset); + } + + /** + * 对URL参数做编码,只编码键和值
+ * 提供的值可以是url附带参数,但是不能只是url + * + *

注意,此方法只能标准化整个URL,并不适合于单独编码参数值

+ * + * @param urlWithParams url和参数,可以包含url本身,也可以单独参数 + * @param charset 编码 + * @return 编码后的url和参数 + * @since 4.0.1 + */ + public static String encodeParams(String urlWithParams, Charset charset) { + if (StrUtil.isBlank(urlWithParams)) { + return StrUtil.EMPTY; + } + + String urlPart = null; // url部分,不包括问号 + String paramPart; // 参数部分 + final int pathEndPos = urlWithParams.indexOf('?'); + if (pathEndPos > -1) { + // url + 参数 + urlPart = StrUtil.subPre(urlWithParams, pathEndPos); + paramPart = StrUtil.subSuf(urlWithParams, pathEndPos + 1); + if (StrUtil.isBlank(paramPart)) { + // 无参数,返回url + return urlPart; + } + } else if (false == StrUtil.contains(urlWithParams, '=')) { + // 无参数的URL + return urlWithParams; + } else { + // 无URL的参数 + paramPart = urlWithParams; + } + + paramPart = normalizeParams(paramPart, charset); + + return StrUtil.isBlank(urlPart) ? paramPart : urlPart + "?" + paramPart; + } + + /** + * 标准化参数字符串,即URL中?后的部分 + * + *

注意,此方法只能标准化整个URL,并不适合于单独编码参数值

+ * + * @param paramPart 参数字符串 + * @param charset 编码 + * @return 标准化的参数字符串 + * @since 4.5.2 + */ + public static String normalizeParams(String paramPart, Charset charset) { + if(StrUtil.isEmpty(paramPart)){ + return paramPart; + } + final StrBuilder builder = StrBuilder.create(paramPart.length() + 16); + final int len = paramPart.length(); + String name = null; + int pos = 0; // 未处理字符开始位置 + char c; // 当前字符 + int i; // 当前字符位置 + for (i = 0; i < len; i++) { + c = paramPart.charAt(i); + if (c == '=') { // 键值对的分界点 + if (null == name) { + // 只有=前未定义name时被当作键值分界符,否则做为普通字符 + name = (pos == i) ? StrUtil.EMPTY : paramPart.substring(pos, i); + pos = i + 1; + } + } else if (c == '&') { // 参数对的分界点 + if (pos != i) { + if (null == name) { + // 对于像&a&这类无参数值的字符串,我们将name为a的值设为"" + name = paramPart.substring(pos, i); + builder.append(RFC3986.QUERY_PARAM_NAME.encode(name, charset)).append('='); + } else { + builder.append(RFC3986.QUERY_PARAM_NAME.encode(name, charset)).append('=') + .append(RFC3986.QUERY_PARAM_VALUE.encode(paramPart.substring(pos, i), charset)).append('&'); + } + name = null; + } + pos = i + 1; + } + } + + // 结尾处理 + if (null != name) { + builder.append(URLUtil.encodeQuery(name, charset)).append('='); + } + if (pos != i) { + if (null == name && pos > 0) { + builder.append('='); + } + builder.append(URLUtil.encodeQuery(paramPart.substring(pos, i), charset)); + } + + // 以&结尾则去除之 + int lastIndex = builder.length() - 1; + if ('&' == builder.charAt(lastIndex)) { + builder.delTo(lastIndex); + } + return builder.toString(); + } + + /** + * 将URL参数解析为Map(也可以解析Post中的键值对参数) + * + * @param paramsStr 参数字符串(或者带参数的Path) + * @param charset 字符集 + * @return 参数Map + * @since 5.2.6 + */ + public static Map decodeParamMap(String paramsStr, Charset charset) { + final Map queryMap = UrlQuery.of(paramsStr, charset).getQueryMap(); + if (MapUtil.isEmpty(queryMap)) { + return MapUtil.empty(); + } + return Convert.toMap(String.class, String.class, queryMap); + } + + /** + * 将URL参数解析为Map(也可以解析Post中的键值对参数) + * + * @param paramsStr 参数字符串(或者带参数的Path) + * @param charset 字符集 + * @return 参数Map + */ + public static Map> decodeParams(String paramsStr, String charset) { + return decodeParams(paramsStr, charset, false); + } + + /** + * 将URL参数解析为Map(也可以解析Post中的键值对参数) + * + * @param paramsStr 参数字符串(或者带参数的Path) + * @param charset 字符集 + * @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+' + * @return 参数Map + * @since 5.8.12 + */ + public static Map> decodeParams(String paramsStr, String charset, boolean isFormUrlEncoded) { + return decodeParams(paramsStr, CharsetUtil.charset(charset), isFormUrlEncoded); + } + + /** + * 将URL QueryString参数解析为Map + * + * @param paramsStr 参数字符串(或者带参数的Path) + * @param charset 字符集 + * @return 参数Map + * @since 5.2.6 + */ + public static Map> decodeParams(String paramsStr, Charset charset) { + return decodeParams(paramsStr, charset, false); + } + + /** + * 将URL参数解析为Map(也可以解析Post中的键值对参数) + * + * @param paramsStr 参数字符串(或者带参数的Path) + * @param charset 字符集 + * @param isFormUrlEncoded 是否为x-www-form-urlencoded模式,此模式下空格会编码为'+' + * @return 参数Map + */ + public static Map> decodeParams(String paramsStr, Charset charset, boolean isFormUrlEncoded) { + final Map queryMap = + UrlQuery.of(paramsStr, charset, true, isFormUrlEncoded).getQueryMap(); + if (MapUtil.isEmpty(queryMap)) { + return MapUtil.empty(); + } + + final Map> params = new LinkedHashMap<>(); + queryMap.forEach((key, value) -> { + final List values = params.computeIfAbsent(StrUtil.str(key), k -> new ArrayList<>(1)); + // 一般是一个参数 + values.add(StrUtil.str(value)); + }); + return params; + } + + /** + * 将表单数据加到URL中(用于GET表单提交)
+ * 表单的键值对会被url编码,但是url中原参数不会被编码 + * + * @param url URL + * @param form 表单数据 + * @param charset 编码 + * @param isEncodeParams 是否对键和值做转义处理 + * @return 合成后的URL + */ + public static String urlWithForm(String url, Map form, Charset charset, boolean isEncodeParams) { + if (isEncodeParams && StrUtil.contains(url, '?')) { + // 在需要编码的情况下,如果url中已经有部分参数,则编码之 + url = encodeParams(url, charset); + } + + // url和参数是分别编码的 + return urlWithForm(url, toParams(form, charset), charset, false); + } + + /** + * 将表单数据字符串加到URL中(用于GET表单提交) + * + * @param url URL + * @param queryString 表单数据字符串 + * @param charset 编码 + * @param isEncode 是否对键和值做转义处理 + * @return 拼接后的字符串 + */ + public static String urlWithForm(String url, String queryString, Charset charset, boolean isEncode) { + if (StrUtil.isBlank(queryString)) { + // 无额外参数 + if (StrUtil.contains(url, '?')) { + // url中包含参数 + return isEncode ? encodeParams(url, charset) : url; + } + return url; + } + + // 始终有参数 + final StrBuilder urlBuilder = StrBuilder.create(url.length() + queryString.length() + 16); + int qmIndex = url.indexOf('?'); + if (qmIndex > 0) { + // 原URL带参数,则对这部分参数单独编码(如果选项为进行编码) + urlBuilder.append(isEncode ? encodeParams(url, charset) : url); + if (false == StrUtil.endWith(url, '&')) { + // 已经带参数的情况下追加参数 + urlBuilder.append('&'); + } + } else { + // 原url无参数,则不做编码 + urlBuilder.append(url); + if (qmIndex < 0) { + // 无 '?' 追加之 + urlBuilder.append('?'); + } + } + urlBuilder.append(isEncode ? encodeParams(queryString, charset) : queryString); + return urlBuilder.toString(); + } + + /** + * 从Http连接的头信息中获得字符集
+ * 从ContentType中获取 + * + * @param conn HTTP连接对象 + * @return 字符集 + */ + public static String getCharset(HttpURLConnection conn) { + if (conn == null) { + return null; + } + return getCharset(conn.getContentType()); + } + + /** + * 从Http连接的头信息中获得字符集
+ * 从ContentType中获取 + * + * @param contentType Content-Type + * @return 字符集 + * @since 5.2.6 + */ + public static String getCharset(String contentType) { + if (StrUtil.isBlank(contentType)) { + return null; + } + return ReUtil.get(CHARSET_PATTERN, contentType, 1); + } + + /** + * 从流中读取内容
+ * 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码; + * + * @param in 输入流 + * @param charset 字符集 + * @param isGetCharsetFromContent 是否从返回内容中获得编码信息 + * @return 内容 + */ + public static String getString(InputStream in, Charset charset, boolean isGetCharsetFromContent) { + final byte[] contentBytes = IoUtil.readBytes(in); + return getString(contentBytes, charset, isGetCharsetFromContent); + } + + /** + * 从流中读取内容
+ * 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码; + * + * @param contentBytes 内容byte数组 + * @param charset 字符集 + * @param isGetCharsetFromContent 是否从返回内容中获得编码信息 + * @return 内容 + */ + public static String getString(byte[] contentBytes, Charset charset, boolean isGetCharsetFromContent) { + if (null == contentBytes) { + return null; + } + + if (null == charset) { + charset = CharsetUtil.CHARSET_UTF_8; + } + String content = new String(contentBytes, charset); + if (isGetCharsetFromContent) { + final String charsetInContentStr = ReUtil.get(META_CHARSET_PATTERN, content, 1); + if (StrUtil.isNotBlank(charsetInContentStr)) { + Charset charsetInContent = null; + try { + charsetInContent = Charset.forName(charsetInContentStr); + } catch (Exception e) { + if (StrUtil.containsIgnoreCase(charsetInContentStr, "utf-8") || StrUtil.containsIgnoreCase(charsetInContentStr, "utf8")) { + charsetInContent = CharsetUtil.CHARSET_UTF_8; + } else if (StrUtil.containsIgnoreCase(charsetInContentStr, "gbk")) { + charsetInContent = CharsetUtil.CHARSET_GBK; + } + // ignore + } + if (null != charsetInContent && false == charset.equals(charsetInContent)) { + content = new String(contentBytes, charsetInContent); + } + } + } + return content; + } + + /** + * 根据文件扩展名获得MimeType + * + * @param filePath 文件路径或文件名 + * @param defaultValue 当获取MimeType为null时的默认值 + * @return MimeType + * @see FileUtil#getMimeType(String) + * @since 4.6.5 + */ + public static String getMimeType(String filePath, String defaultValue) { + return ObjectUtil.defaultIfNull(getMimeType(filePath), defaultValue); + } + + /** + * 根据文件扩展名获得MimeType + * + * @param filePath 文件路径或文件名 + * @return MimeType + * @see FileUtil#getMimeType(String) + */ + public static String getMimeType(String filePath) { + return FileUtil.getMimeType(filePath); + } + + /** + * 从请求参数的body中判断请求的Content-Type类型,支持的类型有: + * + *
+	 * 1. application/json
+	 * 1. application/xml
+	 * 
+ * + * @param body 请求参数体 + * @return Content-Type类型,如果无法判断返回null + * @see aiyh.utils.tool.cn.hutool.http.ContentType#get(String) + * @since 3.2.0 + */ + public static String getContentTypeByRequestBody(String body) { + final aiyh.utils.tool.cn.hutool.http.ContentType contentType = ContentType.get(body); + return (null == contentType) ? null : contentType.toString(); + } + + /** + * 创建简易的Http服务器 + * + * @param port 端口 + * @return {@link SimpleServer} + * @since 5.2.6 + */ + public static SimpleServer createServer(int port) { + return new SimpleServer(port); + } + + /** + * 构建简单的账号秘密验证信息,构建后类似于: + *
+	 *     Basic YWxhZGRpbjpvcGVuc2VzYW1l
+	 * 
+ * + * @param username 账号 + * @param password 密码 + * @param charset 编码(如果账号或密码中有非ASCII字符适用) + * @return 密码验证信息 + * @since 5.4.6 + */ + public static String buildBasicAuth(String username, String password, Charset charset) { + final String data = username.concat(":").concat(password); + return "Basic " + Base64.encode(data, charset); + } + + /** + * 关闭Cookie + * + * @see GlobalCookieManager#setCookieManager(CookieManager) + * @since 5.6.5 + */ + public static void closeCookie() { + GlobalCookieManager.setCookieManager(null); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/Method.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/Method.java new file mode 100644 index 0000000..2ef3498 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/Method.java @@ -0,0 +1,10 @@ +package aiyh.utils.tool.cn.hutool.http; + +/** + * Http方法枚举 + * + * @author Looly + */ +public enum Method { + GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT, PATCH +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/MultipartOutputStream.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/MultipartOutputStream.java new file mode 100644 index 0000000..a043513 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/MultipartOutputStream.java @@ -0,0 +1,185 @@ +package aiyh.utils.tool.cn.hutool.http; + +import aiyh.utils.tool.cn.hutool.core.convert.Convert; +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.io.resource.MultiResource; +import aiyh.utils.tool.cn.hutool.core.io.resource.Resource; +import aiyh.utils.tool.cn.hutool.core.io.resource.StringResource; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; + +/** + * Multipart/form-data输出流封装
+ * 遵循RFC2388规范 + * + * @author looly + * @since 5.7.17 + */ +public class MultipartOutputStream extends OutputStream { + + private static final String CONTENT_DISPOSITION_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"\r\n"; + private static final String CONTENT_DISPOSITION_FILE_TEMPLATE = "Content-Disposition: form-data; name=\"{}\"; filename=\"{}\"\r\n"; + + private static final String CONTENT_TYPE_FILE_TEMPLATE = "Content-Type: {}\r\n"; + + private final OutputStream out; + private final Charset charset; + private final String boundary; + + private boolean isFinish; + + /** + * 构造,使用全局默认的边界字符串 + * + * @param out HTTP写出流 + * @param charset 编码 + */ + public MultipartOutputStream(OutputStream out, Charset charset) { + this(out, charset, HttpGlobalConfig.getBoundary()); + } + + /** + * 构造 + * + * @param out HTTP写出流 + * @param charset 编码 + * @param boundary 边界符 + * @since 5.7.17 + */ + public MultipartOutputStream(OutputStream out, Charset charset, String boundary) { + this.out = out; + this.charset = charset; + this.boundary = boundary; + } + + /** + * 添加Multipart表单的数据项
+ *
+	 *     --分隔符(boundary)[换行]
+	 *     Content-Disposition: form-data; name="参数名"[换行]
+	 *     [换行]
+	 *     参数值[换行]
+	 * 
+ *

+ * 或者: + * + *

+	 *     --分隔符(boundary)[换行]
+	 *     Content-Disposition: form-data; name="表单名"; filename="文件名"[换行]
+	 *     Content-Type: MIME类型[换行]
+	 *     [换行]
+	 *     文件的二进制内容[换行]
+	 * 
+ * + * @param formFieldName 表单名 + * @param value 值,可以是普通值、资源(如文件等) + * @return this + * @throws IORuntimeException IO异常 + */ + public MultipartOutputStream write(String formFieldName, Object value) throws IORuntimeException { + // 多资源 + if (value instanceof MultiResource) { + for (Resource subResource : (MultiResource) value) { + write(formFieldName, subResource); + } + return this; + } + + // --分隔符(boundary)[换行] + beginPart(); + + if (value instanceof Resource) { + appendResource(formFieldName, (Resource) value); + } else { + appendResource(formFieldName, + new StringResource(Convert.toStr(value), null, this.charset)); + } + + write(StrUtil.CRLF); + return this; + } + + @Override + public void write(int b) throws IOException { + this.out.write(b); + } + + /** + * 上传表单结束 + * + * @throws IORuntimeException IO异常 + */ + public void finish() throws IORuntimeException { + if (!isFinish) { + write(StrUtil.format("--{}--\r\n", boundary)); + this.isFinish = true; + } + } + + @Override + public void close() { + finish(); + IoUtil.close(this.out); + } + + /** + * 添加Multipart表单的Resource数据项,支持包括{@link HttpResource}资源格式 + * + * @param formFieldName 表单名 + * @param resource 资源 + * @throws IORuntimeException IO异常 + */ + private void appendResource(String formFieldName, Resource resource) throws IORuntimeException { + final String fileName = resource.getName(); + + // Content-Disposition + if (null == fileName) { + // Content-Disposition: form-data; name="参数名"[换行] + write(StrUtil.format(CONTENT_DISPOSITION_TEMPLATE, formFieldName)); + } else { + // Content-Disposition: form-data; name="参数名"; filename="文件名"[换行] + write(StrUtil.format(CONTENT_DISPOSITION_FILE_TEMPLATE, formFieldName, fileName)); + } + + // Content-Type + if (resource instanceof HttpResource) { + final String contentType = ((HttpResource) resource).getContentType(); + if (StrUtil.isNotBlank(contentType)) { + // Content-Type: 类型[换行] + write(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, contentType)); + } + } else if (StrUtil.isNotEmpty(fileName)) { + // 根据name的扩展名指定互联网媒体类型,默认二进制流数据 + write(StrUtil.format(CONTENT_TYPE_FILE_TEMPLATE, + HttpUtil.getMimeType(fileName, ContentType.OCTET_STREAM.getValue()))); + } + + // 内容 + write("\r\n"); + resource.writeTo(this); + } + + /** + * part开始,写出:
+ *
+	 *     --分隔符(boundary)[换行]
+	 * 
+ */ + private void beginPart() { + // --分隔符(boundary)[换行] + write("--", boundary, StrUtil.CRLF); + } + + /** + * 写出对象 + * + * @param objs 写出的对象(转换为字符串) + */ + private void write(Object... objs) { + IoUtil.write(this, this.charset, false, objs); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/Status.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/Status.java new file mode 100644 index 0000000..6ea34fd --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/Status.java @@ -0,0 +1,189 @@ +package aiyh.utils.tool.cn.hutool.http; + +/** + * 返回状态码 + * + * @author Looly + */ +interface Status { + /** + * HTTP Status-Code 200: OK. + */ + int HTTP_OK = 200; + + /** + * HTTP Status-Code 201: Created. + */ + int HTTP_CREATED = 201; + + /** + * HTTP Status-Code 202: Accepted. + */ + int HTTP_ACCEPTED = 202; + + /** + * HTTP Status-Code 203: Non-Authoritative Information. + */ + int HTTP_NOT_AUTHORITATIVE = 203; + + /** + * HTTP Status-Code 204: No Content. + */ + int HTTP_NO_CONTENT = 204; + + /** + * HTTP Status-Code 205: Reset Content. + */ + int HTTP_RESET = 205; + + /** + * HTTP Status-Code 206: Partial Content. + */ + int HTTP_PARTIAL = 206; + + /* 3XX: relocation/redirect */ + + /** + * HTTP Status-Code 300: Multiple Choices. + */ + int HTTP_MULT_CHOICE = 300; + + /** + * HTTP Status-Code 301: Moved Permanently. + */ + int HTTP_MOVED_PERM = 301; + + /** + * HTTP Status-Code 302: Temporary Redirect. + */ + int HTTP_MOVED_TEMP = 302; + + /** + * HTTP Status-Code 303: See Other. + */ + int HTTP_SEE_OTHER = 303; + + /** + * HTTP Status-Code 304: Not Modified. + */ + int HTTP_NOT_MODIFIED = 304; + + /** + * HTTP Status-Code 305: Use Proxy. + */ + int HTTP_USE_PROXY = 305; + + /* 4XX: client error */ + + /** + * HTTP Status-Code 400: Bad Request. + */ + int HTTP_BAD_REQUEST = 400; + + /** + * HTTP Status-Code 401: Unauthorized. + */ + int HTTP_UNAUTHORIZED = 401; + + /** + * HTTP Status-Code 402: Payment Required. + */ + int HTTP_PAYMENT_REQUIRED = 402; + + /** + * HTTP Status-Code 403: Forbidden. + */ + int HTTP_FORBIDDEN = 403; + + /** + * HTTP Status-Code 404: Not Found. + */ + int HTTP_NOT_FOUND = 404; + + /** + * HTTP Status-Code 405: Method Not Allowed. + */ + int HTTP_BAD_METHOD = 405; + + /** + * HTTP Status-Code 406: Not Acceptable. + */ + int HTTP_NOT_ACCEPTABLE = 406; + + /** + * HTTP Status-Code 407: Proxy Authentication Required. + */ + int HTTP_PROXY_AUTH = 407; + + /** + * HTTP Status-Code 408: Request Time-Out. + */ + int HTTP_CLIENT_TIMEOUT = 408; + + /** + * HTTP Status-Code 409: Conflict. + */ + int HTTP_CONFLICT = 409; + + /** + * HTTP Status-Code 410: Gone. + */ + int HTTP_GONE = 410; + + /** + * HTTP Status-Code 411: Length Required. + */ + int HTTP_LENGTH_REQUIRED = 411; + + /** + * HTTP Status-Code 412: Precondition Failed. + */ + int HTTP_PRECON_FAILED = 412; + + /** + * HTTP Status-Code 413: Request Entity Too Large. + */ + int HTTP_ENTITY_TOO_LARGE = 413; + + /** + * HTTP Status-Code 414: Request-URI Too Large. + */ + int HTTP_REQ_TOO_LONG = 414; + + /** + * HTTP Status-Code 415: Unsupported Media Type. + */ + int HTTP_UNSUPPORTED_TYPE = 415; + + /* 5XX: server error */ + + /** + * HTTP Status-Code 500: Internal Server Error. + */ + int HTTP_INTERNAL_ERROR = 500; + + /** + * HTTP Status-Code 501: Not Implemented. + */ + int HTTP_NOT_IMPLEMENTED = 501; + + /** + * HTTP Status-Code 502: Bad Gateway. + */ + int HTTP_BAD_GATEWAY = 502; + + /** + * HTTP Status-Code 503: Service Unavailable. + */ + int HTTP_UNAVAILABLE = 503; + + /** + * HTTP Status-Code 504: Gateway Timeout. + */ + int HTTP_GATEWAY_TIMEOUT = 504; + + /** + * HTTP Status-Code 505: HTTP Version Not Supported. + */ + int HTTP_VERSION = 505; +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/body/BytesBody.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/BytesBody.java new file mode 100644 index 0000000..11643af --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/BytesBody.java @@ -0,0 +1,40 @@ +package aiyh.utils.tool.cn.hutool.http.body; + +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; + +import java.io.OutputStream; + +/** + * bytes类型的Http request body,主要发送编码后的表单数据或rest body(如JSON或XML) + * + * @author looly + * @since 5.7.17 + */ +public class BytesBody implements RequestBody { + + private final byte[] content; + + /** + * 创建 Http request body + * + * @param content body内容,编码后 + * @return BytesBody + */ + public static BytesBody create(byte[] content) { + return new BytesBody(content); + } + + /** + * 构造 + * + * @param content Body内容,编码后 + */ + public BytesBody(byte[] content) { + this.content = content; + } + + @Override + public void write(OutputStream out) { + IoUtil.write(out, false, content); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/body/FormUrlEncodedBody.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/FormUrlEncodedBody.java new file mode 100644 index 0000000..087b93f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/FormUrlEncodedBody.java @@ -0,0 +1,38 @@ +package aiyh.utils.tool.cn.hutool.http.body; + +import aiyh.utils.tool.cn.hutool.core.net.url.UrlQuery; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.nio.charset.Charset; +import java.util.Map; + +/** + * application/x-www-form-urlencoded 类型请求body封装 + * + * @author looly + * @since 5.7.17 + */ +public class FormUrlEncodedBody extends BytesBody { + + /** + * 创建 Http request body + * + * @param form 表单 + * @param charset 编码 + * @return FormUrlEncodedBody + */ + public static FormUrlEncodedBody create(Map form, Charset charset) { + return new FormUrlEncodedBody(form, charset); + } + + /** + * 构造 + * + * @param form 表单 + * @param charset 编码 + */ + public FormUrlEncodedBody(Map form, Charset charset) { + super(StrUtil.bytes(UrlQuery.of(form, true).build(charset), charset)); + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/body/MultipartBody.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/MultipartBody.java new file mode 100644 index 0000000..a03942d --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/MultipartBody.java @@ -0,0 +1,89 @@ +package aiyh.utils.tool.cn.hutool.http.body; + +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.http.ContentType; +import aiyh.utils.tool.cn.hutool.http.HttpGlobalConfig; +import aiyh.utils.tool.cn.hutool.http.MultipartOutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Map; + +/** + * Multipart/form-data数据的请求体封装
+ * 遵循RFC2388规范 + * + * @author looly + * @since 5.3.5 + */ +public class MultipartBody implements RequestBody { + + private static final String CONTENT_TYPE_MULTIPART_PREFIX = ContentType.MULTIPART.getValue() + "; boundary="; + + /** + * 存储表单数据 + */ + private final Map form; + /** + * 编码 + */ + private final Charset charset; + /** + * 边界 + */ + private final String boundary = HttpGlobalConfig.getBoundary(); + + /** + * 根据已有表单内容,构建MultipartBody + * + * @param form 表单 + * @param charset 编码 + * @return MultipartBody + */ + public static MultipartBody create(Map form, Charset charset) { + return new MultipartBody(form, charset); + } + + /** + * 获取Multipart的Content-Type类型 + * + * @return Multipart的Content-Type类型 + */ + public String getContentType() { + return CONTENT_TYPE_MULTIPART_PREFIX + boundary; + } + + /** + * 构造 + * + * @param form 表单 + * @param charset 编码 + */ + public MultipartBody(Map form, Charset charset) { + this.form = form; + this.charset = charset; + } + + /** + * 写出Multiparty数据,不关闭流 + * + * @param out out流 + */ + @Override + public void write(OutputStream out) { + final MultipartOutputStream stream = new MultipartOutputStream(out, this.charset, this.boundary); + if (MapUtil.isNotEmpty(this.form)) { + this.form.forEach(stream::write); + } + stream.finish(); + } + + @Override + public String toString() { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + write(out); + return IoUtil.toStr(out, this.charset); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/body/RequestBody.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/RequestBody.java new file mode 100644 index 0000000..a3a9709 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/RequestBody.java @@ -0,0 +1,32 @@ +package aiyh.utils.tool.cn.hutool.http.body; + +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; + +import java.io.OutputStream; + +/** + * 定义请求体接口 + */ +public interface RequestBody { + + /** + * 写出数据,不关闭流 + * + * @param out out流 + */ + void write(OutputStream out); + + /** + * 写出并关闭{@link OutputStream} + * + * @param out {@link OutputStream} + * @since 5.7.17 + */ + default void writeClose(OutputStream out) { + try { + write(out); + } finally { + IoUtil.close(out); + } + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/body/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/package-info.java new file mode 100644 index 0000000..92f47e0 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/body/package-info.java @@ -0,0 +1,6 @@ +/** + * 请求体封装实现 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.body; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/GlobalCookieManager.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/GlobalCookieManager.java new file mode 100644 index 0000000..f0e0c9a --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/GlobalCookieManager.java @@ -0,0 +1,109 @@ +package aiyh.utils.tool.cn.hutool.http.cookie; + +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.util.URLUtil; +import aiyh.utils.tool.cn.hutool.http.HttpConnection; + +import java.io.IOException; +import java.net.CookieManager; +import java.net.CookiePolicy; +import java.net.HttpCookie; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 全局Cookie管理器,只针对Hutool请求有效 + * + * @author Looly + * @since 4.5.15 + */ +public class GlobalCookieManager { + + /** Cookie管理 */ + private static CookieManager cookieManager; + + static { + cookieManager = new CookieManager(new ThreadLocalCookieStore(), CookiePolicy.ACCEPT_ALL); + } + + /** + * 自定义{@link CookieManager} + * + * @param customCookieManager 自定义的{@link CookieManager} + */ + public static void setCookieManager(CookieManager customCookieManager) { + cookieManager = customCookieManager; + } + + /** + * 获取全局{@link CookieManager} + * + * @return {@link CookieManager} + */ + public static CookieManager getCookieManager() { + return cookieManager; + } + + /** + * 获取指定域名下所有Cookie信息 + * + * @param conn HTTP连接 + * @return Cookie信息列表 + * @since 4.6.9 + */ + public static List getCookies(aiyh.utils.tool.cn.hutool.http.HttpConnection conn) { + return cookieManager.getCookieStore().get(getURI(conn)); + } + + /** + * 将本地存储的Cookie信息附带到Http请求中,不覆盖用户定义好的Cookie + * + * @param conn {@link aiyh.utils.tool.cn.hutool.http.HttpConnection} + */ + public static void add(aiyh.utils.tool.cn.hutool.http.HttpConnection conn) { + if (null == cookieManager) { + // 全局Cookie管理器关闭 + return; + } + + Map> cookieHeader; + try { + cookieHeader = cookieManager.get(getURI(conn), new HashMap<>(0)); + } catch (IOException e) { + throw new IORuntimeException(e); + } + + // 不覆盖模式回填Cookie头,这样用户定义的Cookie将优先 + conn.header(cookieHeader, false); + } + + /** + * 存储响应的Cookie信息到本地 + * + * @param conn {@link aiyh.utils.tool.cn.hutool.http.HttpConnection} + */ + public static void store(aiyh.utils.tool.cn.hutool.http.HttpConnection conn) { + if (null == cookieManager) { + // 全局Cookie管理器关闭 + return; + } + + try { + cookieManager.put(getURI(conn), conn.headers()); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + /** + * 获取连接的URL中URI信息 + * + * @param conn HttpConnection + * @return URI + */ + private static URI getURI(HttpConnection conn) { + return URLUtil.toURI(conn.getUrl()); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/ThreadLocalCookieStore.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/ThreadLocalCookieStore.java new file mode 100644 index 0000000..79a3af7 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/ThreadLocalCookieStore.java @@ -0,0 +1,75 @@ +package aiyh.utils.tool.cn.hutool.http.cookie; + +import java.net.CookieManager; +import java.net.CookieStore; +import java.net.HttpCookie; +import java.net.URI; +import java.util.List; + +/** + * 线程隔离的Cookie存储。多线程环境下Cookie隔离使用,防止Cookie覆盖
+ *

+ * 见:https://stackoverflow.com/questions/16305486/cookiemanager-for-multiple-threads + * + * @author looly + * @since 4.1.18 + */ +public class ThreadLocalCookieStore implements CookieStore { + + private final static ThreadLocal STORES = new ThreadLocal() { + @Override + protected synchronized CookieStore initialValue() { + /* InMemoryCookieStore */ + return (new CookieManager()).getCookieStore(); + } + }; + + /** + * 获取本线程下的CookieStore + * + * @return CookieStore + */ + public CookieStore getCookieStore() { + return STORES.get(); + } + + /** + * 移除当前线程的Cookie + * + * @return this + */ + public ThreadLocalCookieStore removeCurrent() { + STORES.remove(); + return this; + } + + @Override + public void add(URI uri, HttpCookie cookie) { + getCookieStore().add(uri, cookie); + } + + @Override + public List get(URI uri) { + return getCookieStore().get(uri); + } + + @Override + public List getCookies() { + return getCookieStore().getCookies(); + } + + @Override + public List getURIs() { + return getCookieStore().getURIs(); + } + + @Override + public boolean remove(URI uri, HttpCookie cookie) { + return getCookieStore().remove(uri, cookie); + } + + @Override + public boolean removeAll() { + return getCookieStore().removeAll(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/package-info.java new file mode 100644 index 0000000..38eaed5 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/cookie/package-info.java @@ -0,0 +1,6 @@ +/** + * 自定义Cookie + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.cookie; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/package-info.java new file mode 100644 index 0000000..7140c78 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/package-info.java @@ -0,0 +1,6 @@ +/** + * Hutool-http针对JDK的HttpUrlConnection做一层封装,简化了HTTPS请求、文件上传、Cookie记忆等操作,使Http请求变得无比简单。 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerBase.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerBase.java new file mode 100644 index 0000000..b5cd882 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerBase.java @@ -0,0 +1,57 @@ +package aiyh.utils.tool.cn.hutool.http.server; + +import aiyh.utils.tool.cn.hutool.core.util.CharsetUtil; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; + +import java.io.Closeable; +import java.nio.charset.Charset; + +/** + * HttpServer公用对象,提供HttpExchange包装和公用方法 + * + * @author looly + * @since 5.2.6 + */ +public class HttpServerBase implements Closeable { + + final static Charset DEFAULT_CHARSET = CharsetUtil.CHARSET_UTF_8; + + final HttpExchange httpExchange; + + /** + * 构造 + * + * @param httpExchange {@link HttpExchange} + */ + public HttpServerBase(HttpExchange httpExchange) { + this.httpExchange = httpExchange; + } + + /** + * 获取{@link HttpExchange}对象 + * + * @return {@link HttpExchange}对象 + */ + public HttpExchange getHttpExchange() { + return this.httpExchange; + } + + /** + * 获取{@link HttpContext} + * + * @return {@link HttpContext} + * @since 5.5.7 + */ + public HttpContext getHttpContext() { + return getHttpExchange().getHttpContext(); + } + + /** + * 调用{@link HttpExchange#close()},关闭请求流和响应流 + */ + @Override + public void close() { + this.httpExchange.close(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerRequest.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerRequest.java new file mode 100644 index 0000000..4f262cf --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerRequest.java @@ -0,0 +1,442 @@ +package aiyh.utils.tool.cn.hutool.http.server; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.map.CaseInsensitiveMap; +import aiyh.utils.tool.cn.hutool.core.map.multi.ListValueMap; +import aiyh.utils.tool.cn.hutool.core.net.NetUtil; +import aiyh.utils.tool.cn.hutool.core.net.multipart.MultipartFormData; +import aiyh.utils.tool.cn.hutool.core.net.multipart.UploadSetting; +import aiyh.utils.tool.cn.hutool.core.util.ArrayUtil; +import aiyh.utils.tool.cn.hutool.core.util.CharsetUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.http.Header; +import aiyh.utils.tool.cn.hutool.http.HttpUtil; +import aiyh.utils.tool.cn.hutool.http.Method; +import aiyh.utils.tool.cn.hutool.http.useragent.UserAgent; +import aiyh.utils.tool.cn.hutool.http.useragent.UserAgentUtil; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpCookie; +import java.net.URI; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Http请求对象,对{@link HttpExchange}封装 + * + * @author looly + * @since 5.2.6 + */ +public class HttpServerRequest extends HttpServerBase { + + private Map cookieCache; + private ListValueMap paramsCache; + private MultipartFormData multipartFormDataCache; + private Charset charsetCache; + private byte[] bodyCache; + + /** + * 构造 + * + * @param httpExchange {@link HttpExchange} + */ + public HttpServerRequest(HttpExchange httpExchange) { + super(httpExchange); + } + + /** + * 获得Http Method + * + * @return Http Method + */ + public String getMethod() { + return this.httpExchange.getRequestMethod(); + } + + /** + * 是否为GET请求 + * + * @return 是否为GET请求 + */ + public boolean isGetMethod() { + return aiyh.utils.tool.cn.hutool.http.Method.GET.name().equalsIgnoreCase(getMethod()); + } + + /** + * 是否为POST请求 + * + * @return 是否为POST请求 + */ + public boolean isPostMethod() { + return Method.POST.name().equalsIgnoreCase(getMethod()); + } + + /** + * 获得请求URI + * + * @return 请求URI + */ + public URI getURI() { + return this.httpExchange.getRequestURI(); + } + + /** + * 获得请求路径Path + * + * @return 请求路径 + */ + public String getPath() { + return getURI().getPath(); + } + + /** + * 获取请求参数 + * + * @return 参数字符串 + */ + public String getQuery() { + return getURI().getQuery(); + } + + /** + * 获得请求header中的信息 + * + * @return header值 + */ + public Headers getHeaders() { + return this.httpExchange.getRequestHeaders(); + } + + /** + * 获得请求header中的信息 + * + * @param headerKey 头信息的KEY + * @return header值 + */ + public String getHeader(aiyh.utils.tool.cn.hutool.http.Header headerKey) { + return getHeader(headerKey.toString()); + } + + /** + * 获得请求header中的信息 + * + * @param headerKey 头信息的KEY + * @return header值 + */ + public String getHeader(String headerKey) { + return getHeaders().getFirst(headerKey); + } + + /** + * 获得请求header中的信息 + * + * @param headerKey 头信息的KEY + * @param charset 字符集 + * @return header值 + */ + public String getHeader(String headerKey, Charset charset) { + final String header = getHeader(headerKey); + if (null != header) { + return CharsetUtil.convert(header, CharsetUtil.CHARSET_ISO_8859_1, charset); + } + return null; + } + + /** + * 获取Content-Type头信息 + * + * @return Content-Type头信息 + */ + public String getContentType() { + return getHeader(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE); + } + + /** + * 获取编码,获取失败默认使用UTF-8,获取规则如下: + * + *

+	 *     1、从Content-Type头中获取编码,类似于:text/html;charset=utf-8
+	 * 
+ * + * @return 编码,默认UTF-8 + */ + public Charset getCharset() { + if (null == this.charsetCache) { + final String contentType = getContentType(); + final String charsetStr = aiyh.utils.tool.cn.hutool.http.HttpUtil.getCharset(contentType); + this.charsetCache = CharsetUtil.parse(charsetStr, DEFAULT_CHARSET); + } + + return this.charsetCache; + } + + /** + * 获得User-Agent + * + * @return User-Agent字符串 + */ + public String getUserAgentStr() { + return getHeader(aiyh.utils.tool.cn.hutool.http.Header.USER_AGENT); + } + + /** + * 获得User-Agent,未识别返回null + * + * @return User-Agent字符串,未识别返回null + */ + public UserAgent getUserAgent() { + return UserAgentUtil.parse(getUserAgentStr()); + } + + /** + * 获得Cookie信息字符串 + * + * @return cookie字符串 + */ + public String getCookiesStr() { + return getHeader(Header.COOKIE); + } + + /** + * 获得Cookie信息列表 + * + * @return Cookie信息列表 + */ + public Collection getCookies() { + return getCookieMap().values(); + } + + /** + * 获得Cookie信息Map,键为Cookie名,值为HttpCookie对象 + * + * @return Cookie信息Map + */ + public Map getCookieMap() { + if (null == this.cookieCache) { + cookieCache = Collections.unmodifiableMap(CollUtil.toMap( + NetUtil.parseCookies(getCookiesStr()), + new CaseInsensitiveMap<>(), + HttpCookie::getName)); + } + return cookieCache; + } + + /** + * 获得指定Cookie名对应的HttpCookie对象 + * + * @param cookieName Cookie名 + * @return HttpCookie对象 + */ + public HttpCookie getCookie(String cookieName) { + return getCookieMap().get(cookieName); + } + + /** + * 是否为Multipart类型表单,此类型表单用于文件上传 + * + * @return 是否为Multipart类型表单,此类型表单用于文件上传 + */ + public boolean isMultipart() { + if (!isPostMethod()) { + return false; + } + + final String contentType = getContentType(); + if (StrUtil.isBlank(contentType)) { + return false; + } + return contentType.toLowerCase().startsWith("multipart/"); + } + + /** + * 获取请求体文本,可以是form表单、json、xml等任意内容
+ * 使用{@link #getCharset()}判断编码,判断失败使用UTF-8编码 + * + * @return 请求 + */ + public String getBody() { + return getBody(getCharset()); + } + + /** + * 获取请求体文本,可以是form表单、json、xml等任意内容 + * + * @param charset 编码 + * @return 请求 + */ + public String getBody(Charset charset) { + return StrUtil.str(getBodyBytes(), charset); + } + + /** + * 获取body的bytes数组 + * + * @return body的bytes数组 + */ + public byte[] getBodyBytes() { + if (null == this.bodyCache) { + this.bodyCache = IoUtil.readBytes(getBodyStream(), true); + } + return this.bodyCache; + } + + /** + * 获取请求体的流,流中可以读取请求内容,包括请求表单数据或文件上传数据 + * + * @return 流 + */ + public InputStream getBodyStream() { + return this.httpExchange.getRequestBody(); + } + + /** + * 获取指定名称的参数值,取第一个值 + * + * @param name 参数名 + * @return 参数值 + * @since 5.5.8 + */ + public String getParam(String name) { + return getParams().get(name, 0); + } + + /** + * 获取指定名称的参数值 + * + * @param name 参数名 + * @return 参数值 + * @since 5.5.8 + */ + public List getParams(String name) { + return getParams().get(name); + } + + /** + * 获取参数Map + * + * @return 参数map + */ + public ListValueMap getParams() { + if (null == this.paramsCache) { + this.paramsCache = new ListValueMap<>(); + final Charset charset = getCharset(); + + // 解析URL中的参数 + final String query = getQuery(); + if (StrUtil.isNotBlank(query)) { + this.paramsCache.putAll(aiyh.utils.tool.cn.hutool.http.HttpUtil.decodeParams(query, charset, false)); + } + + // 解析multipart中的参数 + if (isMultipart()) { + this.paramsCache.putAll(getMultipart().getParamListMap()); + } else { + // 解析body中的参数 + final String body = getBody(); + if (StrUtil.isNotBlank(body)) { + this.paramsCache.putAll(HttpUtil.decodeParams(body, charset, true)); + } + } + } + + return this.paramsCache; + } + + /** + * 获取客户端IP + * + *

+ * 默认检测的Header: + * + *

+	 * 1、X-Forwarded-For
+	 * 2、X-Real-IP
+	 * 3、Proxy-Client-IP
+	 * 4、WL-Proxy-Client-IP
+	 * 
+ * + *

+ * otherHeaderNames参数用于自定义检测的Header
+ * 需要注意的是,使用此方法获取的客户IP地址必须在Http服务器(例如Nginx)中配置头信息,否则容易造成IP伪造。 + *

+ * + * @param otherHeaderNames 其他自定义头文件,通常在Http服务器(例如Nginx)中配置 + * @return IP地址 + */ + public String getClientIP(String... otherHeaderNames) { + String[] headers = {"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; + if (ArrayUtil.isNotEmpty(otherHeaderNames)) { + headers = ArrayUtil.addAll(headers, otherHeaderNames); + } + + return getClientIPByHeader(headers); + } + + /** + * 获取客户端IP + * + *

+ * headerNames参数用于自定义检测的Header
+ * 需要注意的是,使用此方法获取的客户IP地址必须在Http服务器(例如Nginx)中配置头信息,否则容易造成IP伪造。 + *

+ * + * @param headerNames 自定义头,通常在Http服务器(例如Nginx)中配置 + * @return IP地址 + * @since 4.4.1 + */ + public String getClientIPByHeader(String... headerNames) { + String ip; + for (String header : headerNames) { + ip = getHeader(header); + if (!NetUtil.isUnknown(ip)) { + return NetUtil.getMultistageReverseProxyIp(ip); + } + } + + ip = this.httpExchange.getRemoteAddress().getHostName(); + return NetUtil.getMultistageReverseProxyIp(ip); + } + + /** + * 获得MultiPart表单内容,多用于获得上传的文件 + * + * @return MultipartFormData + * @throws IORuntimeException IO异常 + * @since 5.3.0 + */ + public MultipartFormData getMultipart() throws IORuntimeException { + if (null == this.multipartFormDataCache) { + this.multipartFormDataCache = parseMultipart(new UploadSetting()); + } + return this.multipartFormDataCache; + } + + /** + * 获得multipart/form-data 表单内容
+ * 包括文件和普通表单数据
+ * 在同一次请求中,此方法只能被执行一次! + * + * @param uploadSetting 上传文件的设定,包括最大文件大小、保存在内存的边界大小、临时目录、扩展名限定等 + * @return MultiPart表单 + * @throws IORuntimeException IO异常 + * @since 5.3.0 + */ + public MultipartFormData parseMultipart(UploadSetting uploadSetting) throws IORuntimeException { + final MultipartFormData formData = new MultipartFormData(uploadSetting); + try { + formData.parseRequestStream(getBodyStream(), getCharset()); + } catch (IOException e) { + throw new IORuntimeException(e); + } + + return formData; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerResponse.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerResponse.java new file mode 100644 index 0000000..eb30108 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/HttpServerResponse.java @@ -0,0 +1,429 @@ +package aiyh.utils.tool.cn.hutool.http.server; + +import aiyh.utils.tool.cn.hutool.core.io.FileUtil; +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.util.ObjectUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.core.util.URLUtil; +import aiyh.utils.tool.cn.hutool.http.ContentType; +import aiyh.utils.tool.cn.hutool.http.Header; +import aiyh.utils.tool.cn.hutool.http.HttpStatus; +import aiyh.utils.tool.cn.hutool.http.HttpUtil; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; + +/** + * Http响应对象,用于写出数据到客户端 + */ +public class HttpServerResponse extends HttpServerBase { + + private Charset charset; + /** + * 是否已经发送了Http状态码,如果没有,提前写出状态码 + */ + private boolean isSendCode; + + /** + * 构造 + * + * @param httpExchange {@link HttpExchange} + */ + public HttpServerResponse(HttpExchange httpExchange) { + super(httpExchange); + } + + /** + * 发送HTTP状态码,Content-Length为0不定长度,会输出Transfer-encoding: chunked + * + * @param httpStatusCode HTTP状态码,见HttpStatus + * @return this + */ + public HttpServerResponse send(int httpStatusCode) { + return send(httpStatusCode, 0); + } + + /** + * 发送成功状态码 + * + * @return this + */ + public HttpServerResponse sendOk() { + return send(aiyh.utils.tool.cn.hutool.http.HttpStatus.HTTP_OK); + } + + /** + * 发送成功状态码 + * + * @param bodyLength 响应体长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @return this + * @since 5.5.7 + */ + public HttpServerResponse sendOk(int bodyLength) { + return send(aiyh.utils.tool.cn.hutool.http.HttpStatus.HTTP_OK, bodyLength); + } + + /** + * 发送404错误页 + * + * @param content 错误页页面内容,默认text/html类型 + * @return this + */ + public HttpServerResponse send404(String content) { + return sendError(HttpStatus.HTTP_NOT_FOUND, content); + } + + /** + * 发送错误页 + * + * @param errorCode HTTP错误状态码,见HttpStatus + * @param content 错误页页面内容,默认text/html类型 + * @return this + */ + public HttpServerResponse sendError(int errorCode, String content) { + send(errorCode); + setContentType(aiyh.utils.tool.cn.hutool.http.ContentType.TEXT_HTML.toString()); + return write(content); + } + + /** + * 发送HTTP状态码 + * + * @param httpStatusCode HTTP状态码,见HttpStatus + * @param bodyLength 响应体长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @return this + */ + public HttpServerResponse send(int httpStatusCode, long bodyLength) { + if (this.isSendCode) { + throw new IORuntimeException("Http status code has been send!"); + } + + try { + this.httpExchange.sendResponseHeaders(httpStatusCode, bodyLength); + } catch (IOException e) { + throw new IORuntimeException(e); + } + + this.isSendCode = true; + return this; + } + + /** + * 获得所有响应头,获取后可以添加新的响应头 + * + * @return 响应头 + */ + public Headers getHeaders() { + return this.httpExchange.getResponseHeaders(); + } + + /** + * 添加响应头,如果已经存在,则追加 + * + * @param header 头key + * @param value 值 + * @return this + */ + public HttpServerResponse addHeader(String header, String value) { + getHeaders().add(header, value); + return this; + } + + /** + * 设置响应头,如果已经存在,则覆盖 + * + * @param header 头key + * @param value 值 + * @return this + */ + public HttpServerResponse setHeader(aiyh.utils.tool.cn.hutool.http.Header header, String value) { + return setHeader(header.getValue(), value); + } + + /** + * 设置响应头,如果已经存在,则覆盖 + * + * @param header 头key + * @param value 值 + * @return this + */ + public HttpServerResponse setHeader(String header, String value) { + getHeaders().set(header, value); + return this; + } + + /** + * 设置响应头,如果已经存在,则覆盖 + * + * @param header 头key + * @param value 值列表 + * @return this + */ + public HttpServerResponse setHeader(String header, List value) { + getHeaders().put(header, value); + return this; + } + + /** + * 设置所有响应头,如果已经存在,则覆盖 + * + * @param headers 响应头map + * @return this + */ + public HttpServerResponse setHeaders(Map> headers) { + getHeaders().putAll(headers); + return this; + } + + /** + * 设置Content-Type头,类似于:text/html;charset=utf-8
+ * 如果用户传入的信息无charset信息,自动根据charset补充,charset设置见{@link #setCharset(Charset)} + * + * @param contentType Content-Type头内容 + * @return this + */ + public HttpServerResponse setContentType(String contentType) { + if (null != contentType && null != this.charset) { + if (!contentType.contains(";charset=")) { + contentType = ContentType.build(contentType, this.charset); + } + } + + return setHeader(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_TYPE, contentType); + } + + /** + * 设置Content-Length头 + * + * @param contentLength Content-Length头内容 + * @return this + */ + public HttpServerResponse setContentLength(long contentLength) { + return setHeader(aiyh.utils.tool.cn.hutool.http.Header.CONTENT_LENGTH, String.valueOf(contentLength)); + } + + /** + * 设置响应的编码 + * + * @param charset 编码 + * @return this + */ + public HttpServerResponse setCharset(Charset charset) { + this.charset = charset; + return this; + } + + /** + * 设置属性 + * + * @param name 属性名 + * @param value 属性值 + * @return this + */ + public HttpServerResponse setAttr(String name, Object value) { + this.httpExchange.setAttribute(name, value); + return this; + } + + /** + * 获取响应数据流 + * + * @return 响应数据流 + */ + public OutputStream getOut() { + if (!this.isSendCode) { + sendOk(); + } + return this.httpExchange.getResponseBody(); + } + + /** + * 获取响应数据流 + * + * @return 响应数据流 + */ + public PrintWriter getWriter() { + final Charset charset = ObjectUtil.defaultIfNull(this.charset, DEFAULT_CHARSET); + return new PrintWriter(new OutputStreamWriter(getOut(), charset)); + } + + /** + * 写出数据到客户端 + * + * @param data 数据 + * @param contentType Content-Type类型 + * @return this + */ + public HttpServerResponse write(String data, String contentType) { + setContentType(contentType); + return write(data); + } + + /** + * 写出数据到客户端 + * + * @param data 数据 + * @return this + */ + public HttpServerResponse write(String data) { + final Charset charset = ObjectUtil.defaultIfNull(this.charset, DEFAULT_CHARSET); + return write(StrUtil.bytes(data, charset)); + } + + /** + * 写出数据到客户端 + * + * @param data 数据 + * @param contentType 返回的类型 + * @return this + */ + public HttpServerResponse write(byte[] data, String contentType) { + setContentType(contentType); + return write(data); + } + + /** + * 写出数据到客户端 + * + * @param data 数据 + * @return this + */ + public HttpServerResponse write(byte[] data) { + final ByteArrayInputStream in = new ByteArrayInputStream(data); + return write(in, in.available()); + } + + /** + * 返回数据给客户端 + * + * @param in 需要返回客户端的内容 + * @param contentType 返回的类型 + * @return this + * @since 5.2.6 + */ + public HttpServerResponse write(InputStream in, String contentType) { + return write(in, 0, contentType); + } + + /** + * 返回数据给客户端 + * + * @param in 需要返回客户端的内容 + * @param length 内容长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @param contentType 返回的类型 + * @return this + * @since 5.2.7 + */ + public HttpServerResponse write(InputStream in, int length, String contentType) { + setContentType(contentType); + return write(in, length); + } + + /** + * 写出数据到客户端 + * + * @param in 数据流 + * @return this + */ + public HttpServerResponse write(InputStream in) { + return write(in, 0); + } + + /** + * 写出数据到客户端 + * + * @param in 数据流 + * @param length 指定响应内容长度,默认0表示不定长度,会输出Transfer-encoding: chunked + * @return this + */ + public HttpServerResponse write(InputStream in, int length) { + if (!isSendCode) { + sendOk(Math.max(0, length)); + } + OutputStream out = null; + try { + out = this.httpExchange.getResponseBody(); + IoUtil.copy(in, out); + } finally { + IoUtil.close(out); + IoUtil.close(in); + } + return this; + } + + /** + * 返回文件给客户端(文件下载) + * + * @param file 写出的文件对象 + * @return this + * @since 5.2.6 + */ + public HttpServerResponse write(File file) { + return write(file, null); + } + + /** + * 返回文件给客户端(文件下载) + * + * @param file 写出的文件对象 + * @param fileName 文件名 + * @return this + * @since 5.5.8 + */ + public HttpServerResponse write(File file, String fileName) { + final long fileSize = file.length(); + if (fileSize > Integer.MAX_VALUE) { + throw new IllegalArgumentException("File size is too bigger than " + Integer.MAX_VALUE); + } + + if (StrUtil.isBlank(fileName)) { + fileName = file.getName(); + } + final String contentType = ObjectUtil.defaultIfNull(HttpUtil.getMimeType(fileName), "application/octet-stream"); + BufferedInputStream in = null; + try { + in = FileUtil.getInputStream(file); + write(in, (int) fileSize, contentType, fileName); + } finally { + IoUtil.close(in); + } + return this; + } + + /** + * 返回文件数据给客户端(文件下载) + * + * @param in 需要返回客户端的内容 + * @param contentType 返回的类型 + * @param fileName 文件名 + * @since 5.2.6 + */ + public void write(InputStream in, String contentType, String fileName) { + write(in, 0, contentType, fileName); + } + + /** + * 返回文件数据给客户端(文件下载) + * + * @param in 需要返回客户端的内容 + * @param length 长度 + * @param contentType 返回的类型 + * @param fileName 文件名 + * @return this + * @since 5.2.7 + */ + public HttpServerResponse write(InputStream in, int length, String contentType, String fileName) { + final Charset charset = ObjectUtil.defaultIfNull(this.charset, DEFAULT_CHARSET); + + if (!contentType.startsWith("text/")) { + // 非文本类型数据直接走下载 + setHeader(Header.CONTENT_DISPOSITION, StrUtil.format("attachment;filename={}", URLUtil.encode(fileName, charset))); + } + return write(in, length, contentType); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/SimpleServer.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/SimpleServer.java new file mode 100644 index 0000000..7c00924 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/SimpleServer.java @@ -0,0 +1,226 @@ +package aiyh.utils.tool.cn.hutool.http.server; + +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.lang.Console; +import aiyh.utils.tool.cn.hutool.core.thread.GlobalThreadPool; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.http.server.action.Action; +import aiyh.utils.tool.cn.hutool.http.server.action.RootAction; +import aiyh.utils.tool.cn.hutool.http.server.filter.HttpFilter; +import aiyh.utils.tool.cn.hutool.http.server.filter.SimpleFilter; +import aiyh.utils.tool.cn.hutool.http.server.handler.ActionHandler; +import com.sun.net.httpserver.*; + +import java.io.File; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +/** + * 简易Http服务器,基于{@link HttpServer} + * + * @author looly + * @since 5.2.5 + */ +public class SimpleServer { + + private final HttpServer server; + private final List filters; + + /** + * 构造 + * + * @param port 监听端口 + */ + public SimpleServer(int port) { + this(new InetSocketAddress(port)); + } + + /** + * 构造 + * + * @param hostname 监听地址 + * @param port 监听端口 + */ + public SimpleServer(String hostname, int port) { + this(new InetSocketAddress(hostname, port)); + } + + /** + * 构造 + * + * @param address 监听地址 + */ + public SimpleServer(InetSocketAddress address) { + this(address, null); + } + + /** + * 构造 + * + * @param address 监听地址 + * @param configurator https配置信息,用于使用自定义SSL(TLS)证书等 + */ + public SimpleServer(InetSocketAddress address, HttpsConfigurator configurator) { + try { + if (null != configurator) { + final HttpsServer server = HttpsServer.create(address, 0); + server.setHttpsConfigurator(configurator); + this.server = server; + } else { + this.server = HttpServer.create(address, 0); + } + } catch (IOException e) { + throw new IORuntimeException(e); + } + setExecutor(GlobalThreadPool.getExecutor()); + filters = new ArrayList<>(); + } + + /** + * 增加请求过滤器,此过滤器对所有请求有效
+ * 此方法需在以下方法前之前调用: + * + *
    + *
  • {@link #setRoot(File)}
  • + *
  • {@link #setRoot(String)}
  • + *
  • {@link #createContext(String, HttpHandler)}
  • + *
  • {@link #addHandler(String, HttpHandler)}
  • + *
  • {@link #addAction(String, Action)}
  • + *
+ * + * @param filter {@link Filter} 请求过滤器 + * @return this + * @since 5.5.7 + */ + public SimpleServer addFilter(Filter filter) { + this.filters.add(filter); + return this; + } + + /** + * 增加请求过滤器,此过滤器对所有请求有效
+ * 此方法需在以下方法前之前调用: + * + *
    + *
  • {@link #setRoot(File)}
  • + *
  • {@link #setRoot(String)}
  • + *
  • {@link #createContext(String, HttpHandler)}
  • + *
  • {@link #addHandler(String, HttpHandler)}
  • + *
  • {@link #addAction(String, Action)}
  • + *
+ * + * @param filter {@link Filter} 请求过滤器 + * @return this + * @since 5.5.7 + */ + public SimpleServer addFilter(HttpFilter filter) { + return addFilter(new SimpleFilter() { + @Override + public void doFilter(HttpExchange httpExchange, Chain chain) throws IOException { + filter.doFilter(new HttpServerRequest(httpExchange), new HttpServerResponse(httpExchange), chain); + } + }); + } + + /** + * 增加请求处理规则 + * + * @param path 路径,例如:/a/b 或者 a/b + * @param handler 处理器,包括请求和响应处理 + * @return this + * @see #createContext(String, HttpHandler) + */ + public SimpleServer addHandler(String path, HttpHandler handler) { + createContext(path, handler); + return this; + } + + /** + * 创建请求映射上下文,创建后,用户访问指定路径可使用{@link HttpHandler} 中的规则进行处理 + * + * @param path 路径,例如:/a/b 或者 a/b + * @param handler 处理器,包括请求和响应处理 + * @return {@link HttpContext} + * @since 5.5.7 + */ + public HttpContext createContext(String path, HttpHandler handler) { + // 非/开头的路径会报错 + path = StrUtil.addPrefixIfNot(path, StrUtil.SLASH); + final HttpContext context = this.server.createContext(path, handler); + // 增加整体过滤器 + context.getFilters().addAll(this.filters); + return context; + } + + /** + * 设置根目录,默认的页面从root目录中读取解析返回 + * + * @param root 路径 + * @return this + */ + public SimpleServer setRoot(String root) { + return setRoot(new File(root)); + } + + /** + * 设置根目录,默认的页面从root目录中读取解析返回 + * + * @param root 路径 + * @return this + */ + public SimpleServer setRoot(File root) { + return addAction("/", new RootAction(root)); + } + + /** + * 增加请求处理规则 + * + * @param path 路径 + * @param action 处理器 + * @return this + */ + public SimpleServer addAction(String path, Action action) { + return addHandler(path, new ActionHandler(action)); + } + + /** + * 设置自定义线程池 + * + * @param executor {@link Executor} + * @return this + */ + public SimpleServer setExecutor(Executor executor) { + this.server.setExecutor(executor); + return this; + } + + /** + * 获得原始HttpServer对象 + * + * @return {@link HttpServer} + */ + public HttpServer getRawServer() { + return this.server; + } + + /** + * 获取服务器地址信息 + * + * @return {@link InetSocketAddress} + */ + public InetSocketAddress getAddress() { + return this.server.getAddress(); + } + + /** + * 启动Http服务器,启动后会阻塞当前线程 + */ + public void start() { + final InetSocketAddress address = getAddress(); + Console.log("Hutool Simple Http Server listen on 【{}:{}】", address.getHostName(), address.getPort()); + this.server.start(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/Action.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/Action.java new file mode 100644 index 0000000..749a4fb --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/Action.java @@ -0,0 +1,26 @@ +package aiyh.utils.tool.cn.hutool.http.server.action; + +import aiyh.utils.tool.cn.hutool.http.server.HttpServerRequest; +import aiyh.utils.tool.cn.hutool.http.server.HttpServerResponse; + +import java.io.IOException; + +/** + * 请求处理接口
+ * 当用户请求某个Path,则调用相应Action的doAction方法 + * + * @author Looly + * @since 5.2.6 + */ +@FunctionalInterface +public interface Action { + + /** + * 处理请求 + * + * @param request 请求对象 + * @param response 响应对象 + * @throws IOException IO异常 + */ + void doAction(HttpServerRequest request, HttpServerResponse response) throws IOException; +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/RootAction.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/RootAction.java new file mode 100644 index 0000000..3731d3f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/RootAction.java @@ -0,0 +1,86 @@ +package aiyh.utils.tool.cn.hutool.http.server.action; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.io.FileUtil; +import aiyh.utils.tool.cn.hutool.http.server.HttpServerRequest; +import aiyh.utils.tool.cn.hutool.http.server.HttpServerResponse; + +import java.io.File; +import java.util.List; + +/** + * 默认的处理器,通过解析用户传入的path,找到网页根目录下对应文件后返回 + * + * @author looly + * @since 5.2.6 + */ +public class RootAction implements Action { + + public static final String DEFAULT_INDEX_FILE_NAME = "index.html"; + + private final File rootDir; + private final List indexFileNames; + + /** + * 构造 + * + * @param rootDir 网页根目录 + */ + public RootAction(String rootDir) { + this(new File(rootDir)); + } + + /** + * 构造 + * + * @param rootDir 网页根目录 + */ + public RootAction(File rootDir) { + this(rootDir, DEFAULT_INDEX_FILE_NAME); + } + + /** + * 构造 + * + * @param rootDir 网页根目录 + * @param indexFileNames 主页文件名列表 + */ + public RootAction(String rootDir, String... indexFileNames) { + this(new File(rootDir), indexFileNames); + } + + /** + * 构造 + * + * @param rootDir 网页根目录 + * @param indexFileNames 主页文件名列表 + * @since 5.4.0 + */ + public RootAction(File rootDir, String... indexFileNames) { + this.rootDir = rootDir; + this.indexFileNames = CollUtil.toList(indexFileNames); + } + + @Override + public void doAction(HttpServerRequest request, HttpServerResponse response) { + final String path = request.getPath(); + + File file = FileUtil.file(rootDir, path); + if (file.exists()) { + if (file.isDirectory()) { + for (String indexFileName : indexFileNames) { + // 默认读取主页 + file = FileUtil.file(file, indexFileName); + if (file.exists() && file.isFile()) { + response.write(file); + } + } + } else { + final String name = request.getParam("name"); + response.write(file, name); + } + } + + response.send404("404 Not Found !"); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/package-info.java new file mode 100644 index 0000000..ebb51f2 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/action/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link com.sun.net.httpserver.HttpServer} 封装 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.server.action; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/HttpFilter.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/HttpFilter.java new file mode 100644 index 0000000..9c291fc --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/HttpFilter.java @@ -0,0 +1,27 @@ +package aiyh.utils.tool.cn.hutool.http.server.filter; + +import aiyh.utils.tool.cn.hutool.http.server.HttpServerRequest; +import aiyh.utils.tool.cn.hutool.http.server.HttpServerResponse; +import com.sun.net.httpserver.Filter; + +import java.io.IOException; + +/** + * 过滤器接口,用于简化{@link Filter} 使用 + * + * @author looly + * @since 5.5.7 + */ +@FunctionalInterface +public interface HttpFilter { + + /** + * 执行过滤 + * + * @param req {@link aiyh.utils.tool.cn.hutool.http.server.HttpServerRequest} 请求对象,用于获取请求内容 + * @param res {@link aiyh.utils.tool.cn.hutool.http.server.HttpServerResponse} 响应对象,用于写出内容 + * @param chain {@link Filter.Chain} + * @throws IOException IO异常 + */ + void doFilter(HttpServerRequest req, HttpServerResponse res, Filter.Chain chain) throws IOException; +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/SimpleFilter.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/SimpleFilter.java new file mode 100644 index 0000000..0ab9e7f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/SimpleFilter.java @@ -0,0 +1,17 @@ +package aiyh.utils.tool.cn.hutool.http.server.filter; + +import com.sun.net.httpserver.Filter; + +/** + * 匿名简单过滤器,跳过了描述 + * + * @author looly + * @since 5.5.7 + */ +public abstract class SimpleFilter extends Filter { + + @Override + public String description() { + return "Anonymous Filter"; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/package-info.java new file mode 100644 index 0000000..91fdbb8 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/filter/package-info.java @@ -0,0 +1,4 @@ +/** + * {@link com.sun.net.httpserver.Filter} 实现包装 + */ +package aiyh.utils.tool.cn.hutool.http.server.filter; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/ActionHandler.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/ActionHandler.java new file mode 100644 index 0000000..17c0c6f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/ActionHandler.java @@ -0,0 +1,38 @@ +package aiyh.utils.tool.cn.hutool.http.server.handler; + +import aiyh.utils.tool.cn.hutool.http.server.HttpServerRequest; +import aiyh.utils.tool.cn.hutool.http.server.HttpServerResponse; +import aiyh.utils.tool.cn.hutool.http.server.action.Action; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +import java.io.IOException; + +/** + * Action处理器,用于将HttpHandler转换为Action形式 + * + * @author looly + * @since 5.2.6 + */ +public class ActionHandler implements HttpHandler { + + private final Action action; + + /** + * 构造 + * + * @param action Action + */ + public ActionHandler(Action action) { + this.action = action; + } + + @Override + public void handle(HttpExchange httpExchange) throws IOException { + action.doAction( + new HttpServerRequest(httpExchange), + new HttpServerResponse(httpExchange) + ); + httpExchange.close(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/package-info.java new file mode 100644 index 0000000..c4113d6 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/handler/package-info.java @@ -0,0 +1,4 @@ +/** + * {@link com.sun.net.httpserver.HttpHandler} 实现包装 + */ +package aiyh.utils.tool.cn.hutool.http.server.handler; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/server/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/package-info.java new file mode 100644 index 0000000..47d979f --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/server/package-info.java @@ -0,0 +1,6 @@ +/** + * Http服务器封装 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.server; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/AndroidSupportSSLFactory.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/AndroidSupportSSLFactory.java new file mode 100644 index 0000000..ceb0805 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/AndroidSupportSSLFactory.java @@ -0,0 +1,25 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.net.SSLProtocols; + +/** + * 兼容android低版本SSL连接
+ * 在测试HttpUrlConnection的时候,发现一部分手机无法连接[GithubPage] + * + *

+ * 最后发现原来是某些SSL协议没有开启 + * + * @author MikaGuraNTK + */ +public class AndroidSupportSSLFactory extends CustomProtocolsSSLFactory { + + // Android低版本不重置的话某些SSL访问就会失败 + private static final String[] protocols = { + SSLProtocols.SSLv3, SSLProtocols.TLSv1, SSLProtocols.TLSv11, SSLProtocols.TLSv12}; + + public AndroidSupportSSLFactory() throws IORuntimeException { + super(protocols); + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java new file mode 100644 index 0000000..22de69b --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/CustomProtocolsSSLFactory.java @@ -0,0 +1,97 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +import aiyh.utils.tool.cn.hutool.core.io.IORuntimeException; +import aiyh.utils.tool.cn.hutool.core.net.SSLUtil; +import aiyh.utils.tool.cn.hutool.core.util.ArrayUtil; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +/** + * 自定义支持协议类型的SSLSocketFactory + * + * @author looly + */ +public class CustomProtocolsSSLFactory extends SSLSocketFactory { + + private final String[] protocols; + private final SSLSocketFactory base; + + /** + * 构造 + * + * @param protocols 支持协议列表 + * @throws IORuntimeException IO异常 + */ + public CustomProtocolsSSLFactory(String... protocols) throws IORuntimeException { + this.protocols = protocols; + this.base = SSLUtil.createSSLContext(null).getSocketFactory(); + } + + @Override + public String[] getDefaultCipherSuites() { + return base.getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() { + return base.getSupportedCipherSuites(); + } + + @Override + public Socket createSocket() throws IOException { + final SSLSocket sslSocket = (SSLSocket) base.createSocket(); + resetProtocols(sslSocket); + return sslSocket; + } + + @Override + public SSLSocket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + final SSLSocket socket = (SSLSocket) base.createSocket(s, host, port, autoClose); + resetProtocols(socket); + return socket; + } + + @Override + public Socket createSocket(String host, int port) throws IOException { + final SSLSocket socket = (SSLSocket) base.createSocket(host, port); + resetProtocols(socket); + return socket; + } + + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { + final SSLSocket socket = (SSLSocket) base.createSocket(host, port, localHost, localPort); + resetProtocols(socket); + return socket; + } + + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + final SSLSocket socket = (SSLSocket) base.createSocket(host, port); + resetProtocols(socket); + return socket; + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + final SSLSocket socket = (SSLSocket) base.createSocket(address, port, localAddress, localPort); + resetProtocols(socket); + return socket; + } + + /** + * 重置可用策略 + * + * @param socket SSLSocket + */ + private void resetProtocols(SSLSocket socket) { + if (ArrayUtil.isNotEmpty(this.protocols)) { + socket.setEnabledProtocols(this.protocols); + } + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLFactory.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLFactory.java new file mode 100644 index 0000000..45c5d95 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLFactory.java @@ -0,0 +1,14 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +/** + * 默认的SSLSocketFactory + * + * @author Looly + * @since 5.1.2 + */ +public class DefaultSSLFactory extends CustomProtocolsSSLFactory { + + public DefaultSSLFactory() { + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLInfo.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLInfo.java new file mode 100644 index 0000000..fa4116a --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/DefaultSSLInfo.java @@ -0,0 +1,32 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import javax.net.ssl.SSLSocketFactory; + +/** + * 默认的全局SSL配置,当用户未设置相关信息时,使用默认设置,默认设置为单例模式。 + * + * @author looly + * @since 5.1.2 + */ +public class DefaultSSLInfo { + /** + * 默认信任全部的域名校验器 + */ + public static final aiyh.utils.tool.cn.hutool.http.ssl.TrustAnyHostnameVerifier TRUST_ANY_HOSTNAME_VERIFIER; + /** + * 默认的SSLSocketFactory,区分安卓 + */ + public static final SSLSocketFactory DEFAULT_SSF; + + static { + TRUST_ANY_HOSTNAME_VERIFIER = new TrustAnyHostnameVerifier(); + if (StrUtil.equalsIgnoreCase("dalvik", System.getProperty("java.vm.name"))) { + // 兼容android低版本SSL连接 + DEFAULT_SSF = new AndroidSupportSSLFactory(); + } else { + DEFAULT_SSF = new DefaultSSLFactory(); + } + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java new file mode 100755 index 0000000..f4d6050 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/SSLSocketFactoryBuilder.java @@ -0,0 +1,95 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +import aiyh.utils.tool.cn.hutool.core.net.SSLContextBuilder; +import aiyh.utils.tool.cn.hutool.core.net.SSLProtocols; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +/** + * SSLSocketFactory构建器 + * + * @author Looly + * @see SSLContextBuilder + * @deprecated 请使用 {@link SSLContextBuilder} + */ +@Deprecated +public class SSLSocketFactoryBuilder implements SSLProtocols { + + SSLContextBuilder sslContextBuilder; + + /** + * 构造 + */ + public SSLSocketFactoryBuilder() { + this.sslContextBuilder = SSLContextBuilder.create(); + } + + /** + * 创建 SSLSocketFactoryBuilder + * + * @return SSLSocketFactoryBuilder + */ + public static SSLSocketFactoryBuilder create() { + return new SSLSocketFactoryBuilder(); + } + + /** + * 设置协议 + * + * @param protocol 协议 + * @return 自身 + */ + public SSLSocketFactoryBuilder setProtocol(String protocol) { + this.sslContextBuilder.setProtocol(protocol); + return this; + } + + /** + * 设置信任信息 + * + * @param trustManagers TrustManager列表 + * @return 自身 + */ + public SSLSocketFactoryBuilder setTrustManagers(TrustManager... trustManagers) { + this.sslContextBuilder.setTrustManagers(trustManagers); + return this; + } + + /** + * 设置 JSSE key managers + * + * @param keyManagers JSSE key managers + * @return 自身 + */ + public SSLSocketFactoryBuilder setKeyManagers(KeyManager... keyManagers) { + this.sslContextBuilder.setKeyManagers(keyManagers); + return this; + } + + /** + * 设置 SecureRandom + * + * @param secureRandom SecureRandom + * @return 自己 + */ + public SSLSocketFactoryBuilder setSecureRandom(SecureRandom secureRandom) { + this.sslContextBuilder.setSecureRandom(secureRandom); + return this; + } + + /** + * 构建SSLSocketFactory + * + * @return SSLSocketFactory + * @throws NoSuchAlgorithmException 无此算法 + * @throws KeyManagementException Key管理异常 + */ + public SSLSocketFactory build() throws NoSuchAlgorithmException, KeyManagementException { + return this.sslContextBuilder.buildChecked().getSocketFactory(); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/TrustAnyHostnameVerifier.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/TrustAnyHostnameVerifier.java new file mode 100644 index 0000000..e60a685 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/TrustAnyHostnameVerifier.java @@ -0,0 +1,17 @@ +package aiyh.utils.tool.cn.hutool.http.ssl; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +/** + * https 域名校验 + * + * @author Looly + */ +public class TrustAnyHostnameVerifier implements HostnameVerifier { + + @Override + public boolean verify(String hostname, SSLSession session) { + return true;// 直接返回true + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/package-info.java new file mode 100644 index 0000000..3de697d --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/ssl/package-info.java @@ -0,0 +1,6 @@ +/** + * SSL封装 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.ssl; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Browser.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Browser.java new file mode 100755 index 0000000..f75fc07 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Browser.java @@ -0,0 +1,140 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * 浏览器对象 + * + * @author looly + * @since 4.2.1 + */ +public class Browser extends UserAgentInfo { + private static final long serialVersionUID = 1L; + + /** + * 未知 + */ + public static final Browser Unknown = new Browser(NameUnknown, null, null); + /** + * 其它版本 + */ + public static final String Other_Version = "[\\/ ]([\\d\\w\\.\\-]+)"; + + /** + * 支持的浏览器类型 + */ + public static final List browers = CollUtil.newArrayList( + // 部分特殊浏览器是基于安卓、Iphone等的,需要优先判断 + // 企业微信 企业微信使用微信浏览器内核,会包含 MicroMessenger 所以要放在前面 + new Browser("wxwork", "wxwork", "wxwork\\/([\\d\\w\\.\\-]+)"), + // 微信 + new Browser("MicroMessenger", "MicroMessenger", Other_Version), + // 微信小程序 + new Browser("miniProgram", "miniProgram", Other_Version), + // QQ浏览器 + new Browser("QQBrowser", "MQQBrowser", "MQQBrowser\\/([\\d\\w\\.\\-]+)"), + // 钉钉PC端浏览器 + new Browser("DingTalk-win", "dingtalk-win", "DingTalk\\(([\\d\\w\\.\\-]+)\\)"), + // 钉钉内置浏览器 + new Browser("DingTalk", "DingTalk", "AliApp\\(DingTalk\\/([\\d\\w\\.\\-]+)\\)"), + // 支付宝内置浏览器 + new Browser("Alipay", "AlipayClient", "AliApp\\(AP\\/([\\d\\w\\.\\-]+)\\)"), + // 淘宝内置浏览器 + new Browser("Taobao", "taobao", "AliApp\\(TB\\/([\\d\\w\\.\\-]+)\\)"), + // UC浏览器 + new Browser("UCBrowser", "UC?Browser", "UC?Browser\\/([\\d\\w\\.\\-]+)"), + // XiaoMi 浏览器 + new Browser("MiuiBrowser", "MiuiBrowser|mibrowser", "MiuiBrowser\\/([\\d\\w\\.\\-]+)"), + // 夸克浏览器 + new Browser("Quark", "Quark", Other_Version), + // 联想浏览器 + new Browser("Lenovo", "SLBrowser", "SLBrowser/([\\d\\w\\.\\-]+)"), + new Browser("MSEdge", "Edge|Edg", "(?:edge|Edg|EdgA)\\/([\\d\\w\\.\\-]+)"), + new Browser("Chrome", "chrome", Other_Version), + new Browser("Firefox", "firefox", Other_Version), + new Browser("IEMobile", "iemobile", Other_Version), + new Browser("Android Browser", "android", "version\\/([\\d\\w\\.\\-]+)"), + new Browser("Safari", "safari", "version\\/([\\d\\w\\.\\-]+)"), + new Browser("Opera", "opera", Other_Version), + new Browser("Konqueror", "konqueror", Other_Version), + new Browser("PS3", "playstation 3", "([\\d\\w\\.\\-]+)\\)\\s*$"), + new Browser("PSP", "playstation portable", "([\\d\\w\\.\\-]+)\\)?\\s*$"), + new Browser("Lotus", "lotus.notes", "Lotus-Notes\\/([\\w.]+)"), + new Browser("Thunderbird", "thunderbird", Other_Version), + new Browser("Netscape", "netscape", Other_Version), + new Browser("Seamonkey", "seamonkey", Other_Version), + new Browser("Outlook", "microsoft.outlook", Other_Version), + new Browser("Evolution", "evolution", Other_Version), + new Browser("MSIE", "msie", "msie ([\\d\\w\\.\\-]+)"), + new Browser("MSIE11", "rv:11", "rv:([\\d\\w\\.\\-]+)"), + new Browser("Gabble", "Gabble", Other_Version), + new Browser("Yammer Desktop", "AdobeAir", "([\\d\\w\\.\\-]+)\\/Yammer"), + new Browser("Yammer Mobile", "Yammer[\\s]+([\\d\\w\\.\\-]+)", "Yammer[\\s]+([\\d\\w\\.\\-]+)"), + new Browser("Apache HTTP Client", "Apache\\\\-HttpClient", "Apache\\-HttpClient\\/([\\d\\w\\.\\-]+)"), + new Browser("BlackBerry", "BlackBerry", "BlackBerry[\\d]+\\/([\\d\\w\\.\\-]+)") + ); + + /** + * 添加自定义的浏览器类型 + * + * @param name 浏览器名称 + * @param regex 关键字或表达式 + * @param versionRegex 匹配版本的正则 + * @since 5.7.4 + */ + synchronized public static void addCustomBrowser(String name, String regex, String versionRegex) { + browers.add(new Browser(name, regex, versionRegex)); + } + + private Pattern versionPattern; + + /** + * 构造 + * + * @param name 浏览器名称 + * @param regex 关键字或表达式 + * @param versionRegex 匹配版本的正则 + */ + public Browser(String name, String regex, String versionRegex) { + super(name, regex); + if (Other_Version.equals(versionRegex)) { + versionRegex = name + versionRegex; + } + if (null != versionRegex) { + this.versionPattern = Pattern.compile(versionRegex, Pattern.CASE_INSENSITIVE); + } + } + + /** + * 获取浏览器版本 + * + * @param userAgentString User-Agent字符串 + * @return 版本 + */ + public String getVersion(String userAgentString) { + if (isUnknown()) { + return null; + } + return ReUtil.getGroup1(this.versionPattern, userAgentString); + } + + /** + * 是否移动浏览器 + * + * @return 是否移动浏览器 + */ + public boolean isMobile() { + final String name = this.getName(); + return "PSP".equals(name) || + "Yammer Mobile".equals(name) || + "Android Browser".equals(name) || + "IEMobile".equals(name) || + "MicroMessenger".equals(name) || + "miniProgram".equals(name) || + "DingTalk".equals(name); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Engine.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Engine.java new file mode 100755 index 0000000..c424852 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Engine.java @@ -0,0 +1,62 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * 引擎对象 + * + * @author looly + * @since 4.2.1 + */ +public class Engine extends UserAgentInfo { + private static final long serialVersionUID = 1L; + + /** 未知 */ + public static final Engine Unknown = new Engine(NameUnknown, null); + + /** + * 支持的引擎类型 + */ + public static final List engines = CollUtil.newArrayList( + new Engine("Trident", "trident"), + new Engine("Webkit", "webkit"), + new Engine("Chrome", "chrome"), + new Engine("Opera", "opera"), + new Engine("Presto", "presto"), + new Engine("Gecko", "gecko"), + new Engine("KHTML", "khtml"), + new Engine("Konqueror", "konqueror"), + new Engine("MIDP", "MIDP") + ); + + private final Pattern versionPattern; + + /** + * 构造 + * + * @param name 引擎名称 + * @param regex 关键字或表达式 + */ + public Engine(String name, String regex) { + super(name, regex); + this.versionPattern = Pattern.compile(name + "[/\\- ]([\\d\\w.\\-]+)", Pattern.CASE_INSENSITIVE); + } + + /** + * 获取引擎版本 + * + * @param userAgentString User-Agent字符串 + * @return 版本 + * @since 5.7.4 + */ + public String getVersion(String userAgentString) { + if (isUnknown()) { + return null; + } + return ReUtil.getGroup1(this.versionPattern, userAgentString); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/OS.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/OS.java new file mode 100755 index 0000000..8e7c753 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/OS.java @@ -0,0 +1,107 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * 系统对象 + * + * @author looly + * @since 4.2.1 + */ +public class OS extends UserAgentInfo { + private static final long serialVersionUID = 1L; + + /** + * 未知 + */ + public static final OS Unknown = new OS(NameUnknown, null); + + /** + * 支持的引擎类型 + */ + public static final List oses = CollUtil.newArrayList(// + new OS("Windows 10 or Windows Server 2016", "windows nt 10\\.0", "windows nt (10\\.0)"),// + new OS("Windows 8.1 or Windows Server 2012R2", "windows nt 6\\.3", "windows nt (6\\.3)"),// + new OS("Windows 8 or Windows Server 2012", "windows nt 6\\.2", "windows nt (6\\.2)"),// + new OS("Windows Vista", "windows nt 6\\.0", "windows nt (6\\.0)"), // + new OS("Windows 7 or Windows Server 2008R2", "windows nt 6\\.1", "windows nt (6\\.1)"), // + new OS("Windows 2003", "windows nt 5\\.2", "windows nt (5\\.2)"), // + new OS("Windows XP", "windows nt 5\\.1", "windows nt (5\\.1)"), // + new OS("Windows 2000", "windows nt 5\\.0", "windows nt (5\\.0)"), // + new OS("Windows Phone", "windows (ce|phone|mobile)( os)?", "windows (?:ce|phone|mobile) (\\d+([._]\\d+)*)"), // + new OS("Windows", "windows"), // + new OS("OSX", "os x (\\d+)[._](\\d+)", "os x (\\d+([._]\\d+)*)"), // + new OS("Android", "Android", "Android (\\d+([._]\\d+)*)"),// + new OS("Android", "XiaoMi|MI\\s+", "\\(X(\\d+([._]\\d+)*)"),// + new OS("Linux", "linux"), // + new OS("Wii", "wii", "wii libnup/(\\d+([._]\\d+)*)"), // + new OS("PS3", "playstation 3", "playstation 3; (\\d+([._]\\d+)*)"), // + new OS("PSP", "playstation portable", "Portable\\); (\\d+([._]\\d+)*)"), // + new OS("iPad", "\\(iPad.*os (\\d+)[._](\\d+)", "\\(iPad.*os (\\d+([._]\\d+)*)"), // + new OS("iPhone", "\\(iPhone.*os (\\d+)[._](\\d+)", "\\(iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPod", "iPod touch[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPod touch[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPad", "iPad[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPad[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("YPhone", "iPhone[\\s\\;]+iPhone.*os (\\d+)[._](\\d+)", "iPhone[\\s\\;]+iPhone.*os (\\d+([._]\\d+)*)"), // + new OS("Symbian", "symbian(os)?"), // + new OS("Darwin", "Darwin\\/([\\d\\w\\.\\-]+)", "Darwin\\/([\\d\\w\\.\\-]+)"), // + new OS("Adobe Air", "AdobeAir\\/([\\d\\w\\.\\-]+)", "AdobeAir\\/([\\d\\w\\.\\-]+)"), // + new OS("Java", "Java[\\s]+([\\d\\w\\.\\-]+)", "Java[\\s]+([\\d\\w\\.\\-]+)")// + ); + + /** + * 添加自定义的系统类型 + * + * @param name 浏览器名称 + * @param regex 关键字或表达式 + * @param versionRegex 匹配版本的正则 + * @since 5.7.4 + */ + synchronized public static void addCustomOs(String name, String regex, String versionRegex) { + oses.add(new OS(name, regex, versionRegex)); + } + + private Pattern versionPattern; + + /** + * 构造 + * + * @param name 系统名称 + * @param regex 关键字或表达式 + */ + public OS(String name, String regex) { + this(name, regex, null); + } + + /** + * 构造 + * + * @param name 系统名称 + * @param regex 关键字或表达式 + * @param versionRegex 版本正则表达式 + * @since 5.7.4 + */ + public OS(String name, String regex, String versionRegex) { + super(name, regex); + if (null != versionRegex) { + this.versionPattern = Pattern.compile(versionRegex, Pattern.CASE_INSENSITIVE); + } + } + + /** + * 获取浏览器版本 + * + * @param userAgentString User-Agent字符串 + * @return 版本 + */ + public String getVersion(String userAgentString) { + if (isUnknown() || null == this.versionPattern) { + // 无版本信息 + return null; + } + return ReUtil.getGroup1(this.versionPattern, userAgentString); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Platform.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Platform.java new file mode 100644 index 0000000..4aed047 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/Platform.java @@ -0,0 +1,147 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * 平台对象 + * + * @author looly + * @since 4.2.1 + */ +public class Platform extends UserAgentInfo { + private static final long serialVersionUID = 1L; + + /** + * 未知 + */ + public static final Platform Unknown = new Platform(NameUnknown, null); + + /** + * Iphone + */ + public static final Platform IPHONE = new Platform("iPhone", "iphone"); + /** + * ipod + */ + public static final Platform IPOD = new Platform("iPod", "ipod"); + /** + * ipad + */ + public static final Platform IPAD = new Platform("iPad", "ipad"); + + /** + * android + */ + public static final Platform ANDROID = new Platform("Android", "android"); + /** + * android + */ + public static final Platform GOOGLE_TV = new Platform("GoogleTV", "googletv"); + + /** + * Windows Phone + */ + public static final Platform WINDOWS_PHONE = new Platform("Windows Phone", "windows (ce|phone|mobile)( os)?"); + + /** + * 支持的移动平台类型 + */ + public static final List mobilePlatforms = CollUtil.newArrayList(// + WINDOWS_PHONE, // + IPAD, // + IPOD, // + IPHONE, // + new Platform("Android", "XiaoMi|MI\\s+"), // + ANDROID, // + GOOGLE_TV, // + new Platform("htcFlyer", "htc_flyer"), // + new Platform("Symbian", "symbian(os)?"), // + new Platform("Blackberry", "blackberry") // + ); + + /** + * 支持的桌面平台类型 + */ + public static final List desktopPlatforms = CollUtil.newArrayList(// + new Platform("Windows", "windows"), // + new Platform("Mac", "(macintosh|darwin)"), // + new Platform("Linux", "linux"), // + new Platform("Wii", "wii"), // + new Platform("Playstation", "playstation"), // + new Platform("Java", "java") // + ); + + /** + * 支持的平台类型 + */ + public static final List platforms; + + static { + platforms = new ArrayList<>(13); + platforms.addAll(mobilePlatforms); + platforms.addAll(desktopPlatforms); + } + + /** + * 构造 + * + * @param name 平台名称 + * @param regex 关键字或表达式 + */ + public Platform(String name, String regex) { + super(name, regex); + } + + /** + * 是否为移动平台 + * + * @return 是否为移动平台 + */ + public boolean isMobile() { + return mobilePlatforms.contains(this); + } + + /** + * 是否为Iphone或者iPod设备 + * + * @return 是否为Iphone或者iPod设备 + * @since 5.2.3 + */ + public boolean isIPhoneOrIPod() { + return this.equals(IPHONE) || this.equals(IPOD); + } + + /** + * 是否为Iphone或者iPod设备 + * + * @return 是否为Iphone或者iPod设备 + * @since 5.2.3 + */ + public boolean isIPad() { + return this.equals(IPAD); + } + + /** + * 是否为IOS平台,包括IPhone、IPod、IPad + * + * @return 是否为IOS平台,包括IPhone、IPod、IPad + * @since 5.2.3 + */ + public boolean isIos() { + return isIPhoneOrIPod() || isIPad(); + } + + /** + * 是否为Android平台,包括Android和Google TV + * + * @return 是否为Android平台,包括Android和Google TV + * @since 5.2.3 + */ + public boolean isAndroid() { + return this.equals(ANDROID) || this.equals(GOOGLE_TV); + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgent.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgent.java new file mode 100644 index 0000000..6921422 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgent.java @@ -0,0 +1,196 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import java.io.Serializable; + +/** + * User-Agent信息对象 + * + * @author looly + * @since 4.2.1 + */ +public class UserAgent implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 是否为移动平台 + */ + private boolean mobile; + /** + * 浏览器类型 + */ + private aiyh.utils.tool.cn.hutool.http.useragent.Browser browser; + /** + * 浏览器版本 + */ + private String version; + + /** + * 平台类型 + */ + private aiyh.utils.tool.cn.hutool.http.useragent.Platform platform; + + /** + * 系统类型 + */ + private aiyh.utils.tool.cn.hutool.http.useragent.OS os; + /** + * 系统版本 + */ + private String osVersion; + + /** + * 引擎类型 + */ + private aiyh.utils.tool.cn.hutool.http.useragent.Engine engine; + /** + * 引擎版本 + */ + private String engineVersion; + + /** + * 是否为移动平台 + * + * @return 是否为移动平台 + */ + public boolean isMobile() { + return mobile; + } + + /** + * 设置是否为移动平台 + * + * @param mobile 是否为移动平台 + */ + public void setMobile(boolean mobile) { + this.mobile = mobile; + } + + /** + * 获取浏览器类型 + * + * @return 浏览器类型 + */ + public aiyh.utils.tool.cn.hutool.http.useragent.Browser getBrowser() { + return browser; + } + + /** + * 设置浏览器类型 + * + * @param browser 浏览器类型 + */ + public void setBrowser(Browser browser) { + this.browser = browser; + } + + /** + * 获取平台类型 + * + * @return 平台类型 + */ + public aiyh.utils.tool.cn.hutool.http.useragent.Platform getPlatform() { + return platform; + } + + /** + * 设置平台类型 + * + * @param platform 平台类型 + */ + public void setPlatform(Platform platform) { + this.platform = platform; + } + + /** + * 获取系统类型 + * + * @return 系统类型 + */ + public aiyh.utils.tool.cn.hutool.http.useragent.OS getOs() { + return os; + } + + /** + * 设置系统类型 + * + * @param os 系统类型 + */ + public void setOs(OS os) { + this.os = os; + } + + /** + * 获取系统版本 + * + * @return 系统版本 + * @since 5.7.4 + */ + public String getOsVersion() { + return this.osVersion; + } + + /** + * 设置系统版本 + * + * @param osVersion 系统版本 + * @since 5.7.4 + */ + public void setOsVersion(String osVersion) { + this.osVersion = osVersion; + } + + /** + * 获取引擎类型 + * + * @return 引擎类型 + */ + public aiyh.utils.tool.cn.hutool.http.useragent.Engine getEngine() { + return engine; + } + + /** + * 设置引擎类型 + * + * @param engine 引擎类型 + */ + public void setEngine(Engine engine) { + this.engine = engine; + } + + /** + * 获取浏览器版本 + * + * @return 浏览器版本 + */ + public String getVersion() { + return version; + } + + /** + * 设置浏览器版本 + * + * @param version 浏览器版本 + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * 获取引擎版本 + * + * @return 引擎版本 + */ + public String getEngineVersion() { + return engineVersion; + } + + /** + * 设置引擎版本 + * + * @param engineVersion 引擎版本 + */ + public void setEngineVersion(String engineVersion) { + this.engineVersion = engineVersion; + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentInfo.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentInfo.java new file mode 100755 index 0000000..c55e029 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentInfo.java @@ -0,0 +1,114 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.util.ReUtil; + +import java.io.Serializable; +import java.util.regex.Pattern; + +/** + * User-agent信息 + * + * @author looly + * @since 4.2.1 + */ +public class UserAgentInfo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 未知类型 + */ + public static final String NameUnknown = "Unknown"; + + /** 信息名称 */ + private final String name; + /** 信息匹配模式 */ + private final Pattern pattern; + + /** + * 构造 + * + * @param name 名字 + * @param regex 表达式 + */ + public UserAgentInfo(String name, String regex) { + this(name, (null == regex) ? null : Pattern.compile(regex, Pattern.CASE_INSENSITIVE)); + } + + /** + * 构造 + * + * @param name 名字 + * @param pattern 匹配模式 + */ + public UserAgentInfo(String name, Pattern pattern) { + this.name = name; + this.pattern = pattern; + } + + /** + * 获取信息名称 + * + * @return 信息名称 + */ + public String getName() { + return name; + } + + /** + * 获取匹配模式 + * + * @return 匹配模式 + */ + public Pattern getPattern() { + return pattern; + } + + /** + * 指定内容中是否包含匹配此信息的内容 + * + * @param content User-Agent字符串 + * @return 是否包含匹配此信息的内容 + */ + public boolean isMatch(String content) { + return ReUtil.contains(this.pattern, content); + } + + /** + * 是否为Unknown + * + * @return 是否为Unknown + */ + public boolean isUnknown() { + return NameUnknown.equals(this.name); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final UserAgentInfo other = (UserAgentInfo) obj; + if (name == null) { + return other.name == null; + } else return name.equals(other.name); + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentParser.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentParser.java new file mode 100644 index 0000000..8285b9a --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentParser.java @@ -0,0 +1,108 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +/** + * User-Agent解析器 + * + * @author looly + * @since 4.2.1 + */ +public class UserAgentParser { + + /** + * 解析User-Agent + * + * @param userAgentString User-Agent字符串 + * @return {@link UserAgent} + */ + public static UserAgent parse(String userAgentString) { + if (StrUtil.isBlank(userAgentString)) { + return null; + } + final UserAgent userAgent = new UserAgent(); + + // 浏览器 + final aiyh.utils.tool.cn.hutool.http.useragent.Browser browser = parseBrowser(userAgentString); + userAgent.setBrowser(browser); + userAgent.setVersion(browser.getVersion(userAgentString)); + + // 浏览器引擎 + final aiyh.utils.tool.cn.hutool.http.useragent.Engine engine = parseEngine(userAgentString); + userAgent.setEngine(engine); + userAgent.setEngineVersion(engine.getVersion(userAgentString)); + + // 操作系统 + final aiyh.utils.tool.cn.hutool.http.useragent.OS os = parseOS(userAgentString); + userAgent.setOs(os); + userAgent.setOsVersion(os.getVersion(userAgentString)); + + // 平台 + final aiyh.utils.tool.cn.hutool.http.useragent.Platform platform = parsePlatform(userAgentString); + userAgent.setPlatform(platform); + userAgent.setMobile(platform.isMobile() || browser.isMobile()); + + + return userAgent; + } + + /** + * 解析浏览器类型 + * + * @param userAgentString User-Agent字符串 + * @return 浏览器类型 + */ + private static aiyh.utils.tool.cn.hutool.http.useragent.Browser parseBrowser(String userAgentString) { + for (aiyh.utils.tool.cn.hutool.http.useragent.Browser browser : aiyh.utils.tool.cn.hutool.http.useragent.Browser.browers) { + if (browser.isMatch(userAgentString)) { + return browser; + } + } + return Browser.Unknown; + } + + /** + * 解析引擎类型 + * + * @param userAgentString User-Agent字符串 + * @return 引擎类型 + */ + private static aiyh.utils.tool.cn.hutool.http.useragent.Engine parseEngine(String userAgentString) { + for (aiyh.utils.tool.cn.hutool.http.useragent.Engine engine : aiyh.utils.tool.cn.hutool.http.useragent.Engine.engines) { + if (engine.isMatch(userAgentString)) { + return engine; + } + } + return Engine.Unknown; + } + + /** + * 解析系统类型 + * + * @param userAgentString User-Agent字符串 + * @return 系统类型 + */ + private static aiyh.utils.tool.cn.hutool.http.useragent.OS parseOS(String userAgentString) { + for (aiyh.utils.tool.cn.hutool.http.useragent.OS os : aiyh.utils.tool.cn.hutool.http.useragent.OS.oses) { + if (os.isMatch(userAgentString)) { + return os; + } + } + return OS.Unknown; + } + + /** + * 解析平台类型 + * + * @param userAgentString User-Agent字符串 + * @return 平台类型 + */ + private static aiyh.utils.tool.cn.hutool.http.useragent.Platform parsePlatform(String userAgentString) { + for (aiyh.utils.tool.cn.hutool.http.useragent.Platform platform : aiyh.utils.tool.cn.hutool.http.useragent.Platform.platforms) { + if (platform.isMatch(userAgentString)) { + return platform; + } + } + return Platform.Unknown; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentUtil.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentUtil.java new file mode 100644 index 0000000..0590b4e --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/UserAgentUtil.java @@ -0,0 +1,20 @@ +package aiyh.utils.tool.cn.hutool.http.useragent; + +/** + * User-Agent工具类 + * + * @author looly + */ +public class UserAgentUtil { + + /** + * 解析User-Agent + * + * @param userAgentString User-Agent字符串 + * @return {@link UserAgent} + */ + public static UserAgent parse(String userAgentString) { + return UserAgentParser.parse(userAgentString); + } + +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/package-info.java new file mode 100644 index 0000000..5a697db --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/useragent/package-info.java @@ -0,0 +1,6 @@ +/** + * User-Agent解析 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.useragent; \ No newline at end of file diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapClient.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapClient.java new file mode 100644 index 0000000..51b91fd --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapClient.java @@ -0,0 +1,654 @@ +package aiyh.utils.tool.cn.hutool.http.webservice; + +import aiyh.utils.tool.cn.hutool.core.collection.CollUtil; +import aiyh.utils.tool.cn.hutool.core.io.IoUtil; +import aiyh.utils.tool.cn.hutool.core.map.MapUtil; +import aiyh.utils.tool.cn.hutool.core.util.ObjectUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.cn.hutool.core.util.XmlUtil; +import aiyh.utils.tool.cn.hutool.http.HttpBase; +import aiyh.utils.tool.cn.hutool.http.HttpGlobalConfig; +import aiyh.utils.tool.cn.hutool.http.HttpRequest; +import aiyh.utils.tool.cn.hutool.http.HttpResponse; + +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.soap.*; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +/** + * SOAP客户端 + * + *

+ * 此对象用于构建一个SOAP消息,并通过HTTP接口发出消息内容。 + * SOAP消息本质上是一个XML文本,可以通过调用{@link #getMsgStr(boolean)} 方法获取消息体 + *

+ * 使用方法: + * + *

+ * SoapClient client = SoapClient.create(url)
+ * .setMethod(methodName, namespaceURI)
+ * .setCharset(CharsetUtil.CHARSET_GBK)
+ * .setParam(param1, "XXX");
+ *
+ * String response = client.send(true);
+ *
+ * 
+ * + * @author looly + * @since 4.5.4 + */ +public class SoapClient extends HttpBase { + + /** + * XML消息体的Content-Type + * soap1.1 : text/xml + * soap1.2 : application/soap+xml + * soap1.1与soap1.2区别: https://www.cnblogs.com/qlqwjy/p/7577147.html + */ + private static final String CONTENT_TYPE_SOAP11_TEXT_XML = "text/xml;charset="; + private static final String CONTENT_TYPE_SOAP12_SOAP_XML = "application/soap+xml;charset="; + + /** + * 请求的URL地址 + */ + private String url; + + /** + * 默认连接超时 + */ + private int connectionTimeout = aiyh.utils.tool.cn.hutool.http.HttpGlobalConfig.getTimeout(); + /** + * 默认读取超时 + */ + private int readTimeout = HttpGlobalConfig.getTimeout(); + + /** + * 消息工厂,用于创建消息 + */ + private MessageFactory factory; + /** + * SOAP消息 + */ + private SOAPMessage message; + /** + * 消息方法节点 + */ + private SOAPBodyElement methodEle; + /** + * 应用于方法上的命名空间URI + */ + private final String namespaceURI; + /** + * Soap协议 + * soap1.1 : text/xml + * soap1.2 : application/soap+xml + */ + private final SoapProtocol protocol; + + /** + * 创建SOAP客户端,默认使用soap1.1版本协议 + * + * @param url WS的URL地址 + * @return this + */ + public static SoapClient create(String url) { + return new SoapClient(url); + } + + /** + * 创建SOAP客户端 + * + * @param url WS的URL地址 + * @param protocol 协议,见{@link SoapProtocol} + * @return this + */ + public static SoapClient create(String url, SoapProtocol protocol) { + return new SoapClient(url, protocol); + } + + /** + * 创建SOAP客户端 + * + * @param url WS的URL地址 + * @param protocol 协议,见{@link SoapProtocol} + * @param namespaceURI 方法上的命名空间URI + * @return this + * @since 4.5.6 + */ + public static SoapClient create(String url, SoapProtocol protocol, String namespaceURI) { + return new SoapClient(url, protocol, namespaceURI); + } + + /** + * 构造,默认使用soap1.1版本协议 + * + * @param url WS的URL地址 + */ + public SoapClient(String url) { + this(url, SoapProtocol.SOAP_1_1); + } + + /** + * 构造 + * + * @param url WS的URL地址 + * @param protocol 协议版本,见{@link SoapProtocol} + */ + public SoapClient(String url, SoapProtocol protocol) { + this(url, protocol, null); + } + + /** + * 构造 + * + * @param url WS的URL地址 + * @param protocol 协议版本,见{@link SoapProtocol} + * @param namespaceURI 方法上的命名空间URI + * @since 4.5.6 + */ + public SoapClient(String url, SoapProtocol protocol, String namespaceURI) { + this.url = url; + this.namespaceURI = namespaceURI; + this.protocol = protocol; + init(protocol); + } + + /** + * 初始化 + * + * @param protocol 协议版本枚举,见{@link SoapProtocol} + * @return this + */ + public SoapClient init(SoapProtocol protocol) { + // 创建消息工厂 + try { + this.factory = MessageFactory.newInstance(protocol.getValue()); + // 根据消息工厂创建SoapMessage + this.message = factory.createMessage(); + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + + return this; + } + + /** + * 重置SOAP客户端,用于客户端复用 + * + *

+ * 重置后需调用serMethod方法重新指定请求方法,并调用setParam方法重新定义参数 + * + * @return this + * @since 4.6.7 + */ + public SoapClient reset() { + try { + this.message = factory.createMessage(); + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + this.methodEle = null; + + return this; + } + + /** + * 设置编码 + * + * @param charset 编码 + * @return this + * @see #charset(Charset) + */ + public SoapClient setCharset(Charset charset) { + return this.charset(charset); + } + + @Override + public SoapClient charset(Charset charset) { + super.charset(charset); + try { + this.message.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, this.charset()); + this.message.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true"); + } catch (SOAPException e) { + // ignore + } + + return this; + } + + /** + * 设置Webservice请求地址 + * + * @param url Webservice请求地址 + * @return this + */ + public SoapClient setUrl(String url) { + this.url = url; + return this; + } + + /** + * 增加SOAP头信息,方法返回{@link SOAPHeaderElement}可以设置具体属性和子节点 + * + * @param name 头信息标签名 + * @param actorURI 中间的消息接收者 + * @param roleUri Role的URI + * @param mustUnderstand 标题项对于要对其进行处理的接收者来说是强制的还是可选的 + * @param relay relay属性 + * @return {@link SOAPHeaderElement} + * @since 5.4.4 + */ + public SOAPHeaderElement addSOAPHeader(QName name, String actorURI, String roleUri, Boolean mustUnderstand, Boolean relay) { + final SOAPHeaderElement ele = addSOAPHeader(name); + try { + if (StrUtil.isNotBlank(roleUri)) { + ele.setRole(roleUri); + } + if (null != relay) { + ele.setRelay(relay); + } + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + + if (StrUtil.isNotBlank(actorURI)) { + ele.setActor(actorURI); + } + if (null != mustUnderstand) { + ele.setMustUnderstand(mustUnderstand); + } + + return ele; + } + + /** + * 增加SOAP头信息,方法返回{@link SOAPHeaderElement}可以设置具体属性和子节点 + * + * @param localName 头节点名称 + * @return {@link SOAPHeaderElement} + * @since 5.4.7 + */ + public SOAPHeaderElement addSOAPHeader(String localName) { + return addSOAPHeader(new QName(localName)); + } + + /** + * 增加SOAP头信息,方法返回{@link SOAPHeaderElement}可以设置具体属性和子节点 + * + * @param localName 头节点名称 + * @param value 头节点的值 + * @return {@link SOAPHeaderElement} + * @since 5.4.7 + */ + public SOAPHeaderElement addSOAPHeader(String localName, String value) { + final SOAPHeaderElement soapHeaderElement = addSOAPHeader(localName); + soapHeaderElement.setTextContent(value); + return soapHeaderElement; + } + + /** + * 增加SOAP头信息,方法返回{@link SOAPHeaderElement}可以设置具体属性和子节点 + * + * @param name 头节点名称 + * @return {@link SOAPHeaderElement} + * @since 5.4.4 + */ + public SOAPHeaderElement addSOAPHeader(QName name) { + SOAPHeaderElement ele; + try { + ele = this.message.getSOAPHeader().addHeaderElement(name); + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + return ele; + } + + /** + * 设置请求方法 + * + * @param name 方法名及其命名空间 + * @param params 参数 + * @param useMethodPrefix 是否使用方法的命名空间前缀 + * @return this + */ + public SoapClient setMethod(Name name, Map params, boolean useMethodPrefix) { + return setMethod(new QName(name.getURI(), name.getLocalName(), name.getPrefix()), params, useMethodPrefix); + } + + /** + * 设置请求方法 + * + * @param name 方法名及其命名空间 + * @param params 参数 + * @param useMethodPrefix 是否使用方法的命名空间前缀 + * @return this + */ + public SoapClient setMethod(QName name, Map params, boolean useMethodPrefix) { + setMethod(name); + final String prefix = useMethodPrefix ? name.getPrefix() : null; + final SOAPBodyElement methodEle = this.methodEle; + for (Entry entry : MapUtil.wrap(params)) { + setParam(methodEle, entry.getKey(), entry.getValue(), prefix); + } + + return this; + } + + /** + * 设置请求方法
+ * 方法名自动识别前缀,前缀和方法名使用“:”分隔
+ * 当识别到前缀后,自动添加xmlns属性,关联到默认的namespaceURI + * + * @param methodName 方法名 + * @return this + */ + public SoapClient setMethod(String methodName) { + return setMethod(methodName, ObjectUtil.defaultIfNull(this.namespaceURI, XMLConstants.NULL_NS_URI)); + } + + /** + * 设置请求方法
+ * 方法名自动识别前缀,前缀和方法名使用“:”分隔
+ * 当识别到前缀后,自动添加xmlns属性,关联到传入的namespaceURI + * + * @param methodName 方法名(可有前缀也可无) + * @param namespaceURI 命名空间URI + * @return this + */ + public SoapClient setMethod(String methodName, String namespaceURI) { + final List methodNameList = StrUtil.split(methodName, ':'); + final QName qName; + if (2 == methodNameList.size()) { + qName = new QName(namespaceURI, methodNameList.get(1), methodNameList.get(0)); + } else { + qName = new QName(namespaceURI, methodName); + } + return setMethod(qName); + } + + /** + * 设置请求方法 + * + * @param name 方法名及其命名空间 + * @return this + */ + public SoapClient setMethod(QName name) { + try { + this.methodEle = this.message.getSOAPBody().addBodyElement(name); + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + + return this; + } + + /** + * 设置方法参数,使用方法的前缀 + * + * @param name 参数名 + * @param value 参数值,可以是字符串或Map或{@link SOAPElement} + * @return this + */ + public SoapClient setParam(String name, Object value) { + return setParam(name, value, true); + } + + /** + * 设置方法参数 + * + * @param name 参数名 + * @param value 参数值,可以是字符串或Map或{@link SOAPElement} + * @param useMethodPrefix 是否使用方法的命名空间前缀 + * @return this + */ + public SoapClient setParam(String name, Object value, boolean useMethodPrefix) { + setParam(this.methodEle, name, value, useMethodPrefix ? this.methodEle.getPrefix() : null); + return this; + } + + /** + * 批量设置参数,使用方法的前缀 + * + * @param params 参数列表 + * @return this + * @since 4.5.6 + */ + public SoapClient setParams(Map params) { + return setParams(params, true); + } + + /** + * 批量设置参数 + * + * @param params 参数列表 + * @param useMethodPrefix 是否使用方法的命名空间前缀 + * @return this + * @since 4.5.6 + */ + public SoapClient setParams(Map params, boolean useMethodPrefix) { + for (Entry entry : MapUtil.wrap(params)) { + setParam(entry.getKey(), entry.getValue(), useMethodPrefix); + } + return this; + } + + /** + * 获取方法节点
+ * 用于创建子节点等操作 + * + * @return {@link SOAPBodyElement} + * @since 4.5.6 + */ + public SOAPBodyElement getMethodEle() { + return this.methodEle; + } + + /** + * 获取SOAP消息对象 {@link SOAPMessage} + * + * @return {@link SOAPMessage} + * @since 4.5.6 + */ + public SOAPMessage getMessage() { + return this.message; + } + + /** + * 获取SOAP请求消息 + * + * @param pretty 是否格式化 + * @return 消息字符串 + */ + public String getMsgStr(boolean pretty) { + return SoapUtil.toString(this.message, pretty, this.charset); + } + + /** + * 将SOAP消息的XML内容输出到流 + * + * @param out 输出流 + * @return this + * @since 4.5.6 + */ + public SoapClient write(OutputStream out) { + try { + this.message.writeTo(out); + } catch (SOAPException | IOException e) { + throw new SoapRuntimeException(e); + } + return this; + } + + /** + * 设置超时,单位:毫秒
+ * 超时包括: + * + *

+	 * 1. 连接超时
+	 * 2. 读取响应超时
+	 * 
+ * + * @param milliseconds 超时毫秒数 + * @return this + * @see #setConnectionTimeout(int) + * @see #setReadTimeout(int) + */ + public SoapClient timeout(int milliseconds) { + setConnectionTimeout(milliseconds); + setReadTimeout(milliseconds); + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + * @since 4.5.6 + */ + public SoapClient setConnectionTimeout(int milliseconds) { + this.connectionTimeout = milliseconds; + return this; + } + + /** + * 设置连接超时,单位:毫秒 + * + * @param milliseconds 超时毫秒数 + * @return this + * @since 4.5.6 + */ + public SoapClient setReadTimeout(int milliseconds) { + this.readTimeout = milliseconds; + return this; + } + + /** + * 执行Webservice请求,即发送SOAP内容 + * + * @return 返回结果 + */ + public SOAPMessage sendForMessage() { + final aiyh.utils.tool.cn.hutool.http.HttpResponse res = sendForResponse(); + final MimeHeaders headers = new MimeHeaders(); + for (Entry> entry : res.headers().entrySet()) { + if (StrUtil.isNotEmpty(entry.getKey())) { + headers.setHeader(entry.getKey(), CollUtil.get(entry.getValue(), 0)); + } + } + try { + return this.factory.createMessage(headers, res.bodyStream()); + } catch (IOException | SOAPException e) { + throw new SoapRuntimeException(e); + } finally { + IoUtil.close(res); + } + } + + /** + * 执行Webservice请求,即发送SOAP内容 + * + * @return 返回结果 + */ + public String send() { + return send(false); + } + + /** + * 执行Webservice请求,即发送SOAP内容 + * + * @param pretty 是否格式化 + * @return 返回结果 + */ + public String send(boolean pretty) { + final String body = sendForResponse().body(); + return pretty ? XmlUtil.format(body) : body; + } + + // -------------------------------------------------------------------------------------------------------- Private method start + + /** + * 发送请求,获取异步响应 + * + * @return 响应对象 + */ + public HttpResponse sendForResponse() { + return HttpRequest.post(this.url)// + .setFollowRedirects(true)// + .setConnectionTimeout(this.connectionTimeout) + .setReadTimeout(this.readTimeout) + .contentType(getXmlContentType())// + .header(this.headers()) + .body(getMsgStr(false))// + .executeAsync(); + } + + /** + * 获取请求的Content-Type,附加编码信息 + * + * @return 请求的Content-Type + */ + private String getXmlContentType() { + switch (this.protocol) { + case SOAP_1_1: + return CONTENT_TYPE_SOAP11_TEXT_XML.concat(this.charset.toString()); + case SOAP_1_2: + return CONTENT_TYPE_SOAP12_SOAP_XML.concat(this.charset.toString()); + default: + throw new SoapRuntimeException("Unsupported protocol: {}", this.protocol); + } + } + + /** + * 设置方法参数 + * + * @param ele 方法节点 + * @param name 参数名 + * @param value 参数值 + * @param prefix 命名空间前缀, {@code null}表示不使用前缀 + * @return {@link SOAPElement}子节点 + */ + @SuppressWarnings("rawtypes") + private static SOAPElement setParam(SOAPElement ele, String name, Object value, String prefix) { + final SOAPElement childEle; + try { + if (StrUtil.isNotBlank(prefix)) { + childEle = ele.addChildElement(name, prefix); + } else { + childEle = ele.addChildElement(name); + } + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + + if (null != value) { + if (value instanceof SOAPElement) { + // 单个子节点 + try { + ele.addChildElement((SOAPElement) value); + } catch (SOAPException e) { + throw new SoapRuntimeException(e); + } + } else if (value instanceof Map) { + // 多个字节点 + Entry entry; + for (Object obj : ((Map) value).entrySet()) { + entry = (Entry) obj; + setParam(childEle, entry.getKey().toString(), entry.getValue(), prefix); + } + } else { + // 单个值 + childEle.setValue(value.toString()); + } + } + + return childEle; + } + // -------------------------------------------------------------------------------------------------------- Private method end +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapProtocol.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapProtocol.java new file mode 100644 index 0000000..6c0cbbc --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapProtocol.java @@ -0,0 +1,35 @@ +package aiyh.utils.tool.cn.hutool.http.webservice; + +import javax.xml.soap.SOAPConstants; + +/** + * SOAP协议版本枚举 + * + * @author looly + */ +public enum SoapProtocol { + /** SOAP 1.1协议 */ + SOAP_1_1(SOAPConstants.SOAP_1_1_PROTOCOL), + /** SOAP 1.2协议 */ + SOAP_1_2(SOAPConstants.SOAP_1_2_PROTOCOL); + + /** + * 构造 + * + * @param value {@link SOAPConstants} 中的协议版本值 + */ + SoapProtocol(String value) { + this.value = value; + } + + private final String value; + + /** + * 获取版本值信息 + * + * @return 版本值信息 + */ + public String getValue() { + return this.value; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapRuntimeException.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapRuntimeException.java new file mode 100644 index 0000000..eaf7cf9 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapRuntimeException.java @@ -0,0 +1,32 @@ +package aiyh.utils.tool.cn.hutool.http.webservice; + +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +/** + * SOAP异常 + * + * @author xiaoleilu + */ +public class SoapRuntimeException extends RuntimeException { + private static final long serialVersionUID = 8247610319171014183L; + + public SoapRuntimeException(Throwable e) { + super(e.getMessage(), e); + } + + public SoapRuntimeException(String message) { + super(message); + } + + public SoapRuntimeException(String messageTemplate, Object... params) { + super(StrUtil.format(messageTemplate, params)); + } + + public SoapRuntimeException(String message, Throwable throwable) { + super(message, throwable); + } + + public SoapRuntimeException(Throwable throwable, String messageTemplate, Object... params) { + super(StrUtil.format(messageTemplate, params), throwable); + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapUtil.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapUtil.java new file mode 100644 index 0000000..b64b294 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/SoapUtil.java @@ -0,0 +1,91 @@ +package aiyh.utils.tool.cn.hutool.http.webservice; + +import aiyh.utils.tool.cn.hutool.core.exceptions.UtilException; +import aiyh.utils.tool.cn.hutool.core.util.CharsetUtil; +import aiyh.utils.tool.cn.hutool.core.util.XmlUtil; + +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPMessage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +/** + * SOAP相关工具类 + * + * @author looly + * @since 4.5.7 + */ +public class SoapUtil { + + /** + * 创建SOAP客户端,默认使用soap1.1版本协议 + * + * @param url WS的URL地址 + * @return {@link aiyh.utils.tool.cn.hutool.http.webservice.SoapClient} + */ + public static aiyh.utils.tool.cn.hutool.http.webservice.SoapClient createClient(String url) { + return aiyh.utils.tool.cn.hutool.http.webservice.SoapClient.create(url); + } + + /** + * 创建SOAP客户端 + * + * @param url WS的URL地址 + * @param protocol 协议,见{@link SoapProtocol} + * @return {@link aiyh.utils.tool.cn.hutool.http.webservice.SoapClient} + */ + public static aiyh.utils.tool.cn.hutool.http.webservice.SoapClient createClient(String url, SoapProtocol protocol) { + return aiyh.utils.tool.cn.hutool.http.webservice.SoapClient.create(url, protocol); + } + + /** + * 创建SOAP客户端 + * + * @param url WS的URL地址 + * @param protocol 协议,见{@link SoapProtocol} + * @param namespaceURI 方法上的命名空间URI + * @return {@link aiyh.utils.tool.cn.hutool.http.webservice.SoapClient} + * @since 4.5.6 + */ + public static aiyh.utils.tool.cn.hutool.http.webservice.SoapClient createClient(String url, SoapProtocol protocol, String namespaceURI) { + return SoapClient.create(url, protocol, namespaceURI); + } + + /** + * {@link SOAPMessage} 转为字符串 + * + * @param message SOAP消息对象 + * @param pretty 是否格式化 + * @return SOAP XML字符串 + */ + public static String toString(SOAPMessage message, boolean pretty) { + return toString(message, pretty, CharsetUtil.CHARSET_UTF_8); + } + + /** + * {@link SOAPMessage} 转为字符串 + * + * @param message SOAP消息对象 + * @param pretty 是否格式化 + * @param charset 编码 + * @return SOAP XML字符串 + * @since 4.5.7 + */ + public static String toString(SOAPMessage message, boolean pretty, Charset charset) { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + message.writeTo(out); + } catch (SOAPException | IOException e) { + throw new SoapRuntimeException(e); + } + String messageToString; + try { + messageToString = out.toString(charset.toString()); + } catch (UnsupportedEncodingException e) { + throw new UtilException(e); + } + return pretty ? XmlUtil.format(messageToString) : messageToString; + } +} diff --git a/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/package-info.java b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/package-info.java new file mode 100644 index 0000000..5fa3834 --- /dev/null +++ b/src/main/java/aiyh/utils/tool/cn/hutool/http/webservice/package-info.java @@ -0,0 +1,6 @@ +/** + * Webservice客户端封装实现 + * + * @author looly + */ +package aiyh.utils.tool.cn.hutool.http.webservice; \ No newline at end of file diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java new file mode 100644 index 0000000..dbb67f5 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java @@ -0,0 +1,61 @@ +package com.api.youhong.ai.ihgzhouji.taskele.contoller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.youhong.ai.ihgzhouji.taskele.service.TaskElementService; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.apache.log4j.Logger; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.Map; + +/** + *

任务列表元素

+ * + *

create: 2023/5/4 17:13

+ * + * @author youHong.ai + */ +@Path("aiyh/ihg/task") +public class TaskElementController { + private final Logger log = Util.getLogger(); + + private final TaskElementService service = new TaskElementService(); + + @Path("/list-get") + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String getList(@Context HttpServletRequest request, @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + try { + return ApiResult.success(service.getList(user)); + } catch (Exception e) { + log.error("get task list error!\n" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + } + + @Path("/search-list") + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String searchList(@Context HttpServletRequest request, + @Context HttpServletResponse response, + @RequestBody Map params, + @QueryParam("id") String configId) { + User user = HrmUserVarify.getUser(request, response); + try { + return ApiResult.success(service.getList(user, params,configId)); + } catch (Exception e) { + log.error("get task list error!\n" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + } +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java new file mode 100644 index 0000000..5504335 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java @@ -0,0 +1,43 @@ +package com.api.youhong.ai.ihgzhouji.taskele.entity; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

配置表

+ * + *

create: 2023/5/4 17:35

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +@EqualsAndHashCode +public class IhgTaskElementConfigItem { + /** id */ + private String id; + /** 标题 */ + private String title; + /** 单位 */ + private String unit; + /** 标题英文 */ + private String titleEn; + /** 单位英文 */ + private String unitEn; + /** icon */ + private String icon; + /** 激活icon */ + private String iconActive; + /** 查看权限 */ + private String viewAuthority; + /** 数据来源 */ + private String dataSource; + + /** 跳转链接 */ + private String link; + /** 数据来源值 */ + private String customerValue; +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java new file mode 100644 index 0000000..607155d --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java @@ -0,0 +1,97 @@ +package com.api.youhong.ai.ihgzhouji.taskele.mapper; + +import aiyh.utils.annotation.recordset.*; +import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; +import weaver.hrm.User; + +import java.util.List; +import java.util.Map; + +/** + *

+ * + *

create: 2023/5/4 17:23

+ * + * @author youHong.ai + */ +@SqlMapper +public interface TaskElementMapper { + + + /** + *

查询配置信息

+ * + * @return 配置信息 + */ + @Select("select * from uf_ihg_el_config ") + @Associations({ + @Association( + property = "icon", + column = "icon", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconActive", + column = "icon_active", + id = @Id(methodId = 1, value = String.class)) + }) + List selectConfig(); + + /** + *

查询配置信息

+ * + * @param configId 配置id + * @return 配置信息 + */ + @Select("select * from uf_ihg_el_config where id = #{configId}") + @Associations({ + @Association( + property = "icon", + column = "icon", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconActive", + column = "icon_active", + id = @Id(methodId = 1, value = String.class)) + }) + IhgTaskElementConfigItem selectConfig(@ParamMapper("configId") String configId); + + + /** + *

查询图片地址

+ * + * @param id docId + * @return 图片地址 + */ + @Select("select concat('/weaver/weaver.file.FileDownload?fileid=',IMAGEFILEID) from docimagefile where DOCID = #{id}") + @AssociationMethod(1) + String selectImageFileId(String id); + + /** + *

查询权限信息

+ * + * @param viewAuthoritySql 自定义权限sql + * @param user 用户 + * @param map 参数 + * @param where 条件参数 + * @return 权限信息 + */ + @Select(custom = true) + List> selectAuthority(@SqlString String viewAuthoritySql, + @ParamMapper("user") User user, + @ParamMapper("param") Map map); + + /** + *

查询任务信息

+ * + * @param customerValue 自定义sql + * @param item 参数 + * @param user 用户 + * @param where 条件参数 + * @return 任务信息 + */ + @Select(custom = true) + List> selectWorkList(@SqlString String customerValue, + @ParamMapper("param") Map item, + @ParamMapper("user") User user, + @ParamMapper("where") Map where); +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapstruct/TaskElementMapstruct.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapstruct/TaskElementMapstruct.java new file mode 100644 index 0000000..4d1045f --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapstruct/TaskElementMapstruct.java @@ -0,0 +1,30 @@ +package com.api.youhong.ai.ihgzhouji.taskele.mapstruct; + +import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; +import com.api.youhong.ai.ihgzhouji.taskele.vo.IhgTaskElementVo; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + *

vo、pojo映射类

+ * + *

create: 2023/5/6 11:11

+ * + * @author youHong.ai + */ +@Mapper +public interface TaskElementMapstruct { + + TaskElementMapstruct INSTANCE = Mappers.getMapper(TaskElementMapstruct.class); + + /** + *

entity转换为vo对象

+ * + * @param item 配置数据 + * @return vo对象 + */ + @Mapping(target = "size", ignore = true) + @Mapping(target = "list", ignore = true) + IhgTaskElementVo entity2Vo(IhgTaskElementConfigItem item); +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementGetValueInterface.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementGetValueInterface.java new file mode 100644 index 0000000..15ecdc9 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementGetValueInterface.java @@ -0,0 +1,20 @@ +package com.api.youhong.ai.ihgzhouji.taskele.service; + +import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; +import weaver.hrm.User; + +import java.util.List; +import java.util.Map; + +/** + *

自定义获取值接口

+ * + *

create: 2023/5/5 17:42

+ * + * @author youHong.ai + */ +public interface TaskElementGetValueInterface { + + List> getValue(IhgTaskElementConfigItem taskElementConfigItem, + Map param, User user); +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java new file mode 100644 index 0000000..8df2385 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java @@ -0,0 +1,160 @@ +package com.api.youhong.ai.ihgzhouji.taskele.service; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.lang.Assert; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; +import com.api.youhong.ai.ihgzhouji.taskele.mapper.TaskElementMapper; +import com.api.youhong.ai.ihgzhouji.taskele.mapstruct.TaskElementMapstruct; +import com.api.youhong.ai.ihgzhouji.taskele.vo.IhgTaskElementVo; +import weaver.hrm.User; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + *

任务列表元素service

+ * + *

create: 2023/5/4 17:17

+ * + * @author youHong.ai + */ +public class TaskElementService { + private final TaskElementMapper mapper = Util.getMapper(TaskElementMapper.class); + + public List getList(User user) { + List ihgTaskElementConfItemList = mapper.selectConfig(); + if (CollectionUtil.isEmpty(ihgTaskElementConfItemList)) { + return Collections.emptyList(); + } + Map>> taskConfigMap = new HashMap<>(); + // 设置查询基础参数 + Map map = new HashMap<>(8); + map.put("currentDate", Util.getTime("yyyy-MM-dd")); + map.put("currentTime", Util.getTime("HH:mm:ss")); + // 查询每个item的可查看权限并进行过滤 + for (IhgTaskElementConfigItem ihgTaskElementConfItem : ihgTaskElementConfItemList) { + String viewAuthoritySql = ihgTaskElementConfItem.getViewAuthority(); + List> authorityList = mapper.selectAuthority(viewAuthoritySql, user, map); + if (CollectionUtil.isNotEmpty(authorityList)) { + taskConfigMap.put(ihgTaskElementConfItem, authorityList); + } + } + // 查询数据 + List result = new ArrayList<>(); + for (Map.Entry>> entry : taskConfigMap.entrySet()) { + IhgTaskElementConfigItem taskElementConfigItem = entry.getKey(); + List> authorityList = entry.getValue(); + List> workList = queryWorkList(taskElementConfigItem, authorityList, user, "", Collections.emptyMap()); + IhgTaskElementVo ihgTaskElementVo = TaskElementMapstruct.INSTANCE.entity2Vo(taskElementConfigItem); + ihgTaskElementVo.setList(workList); + ihgTaskElementVo.setSize(workList.size()); + if (user.getLanguage() == 8) { + ihgTaskElementVo.setTitle(taskElementConfigItem.getTitleEn()); + ihgTaskElementVo.setUnit(taskElementConfigItem.getUnitEn()); + } + result.add(ihgTaskElementVo); + } + return result; + } + + private List> queryWorkList(IhgTaskElementConfigItem taskElementConfigItem, + List> authorityList, + User user, String whereStr, + Map whereMap) { + String dataSource = taskElementConfigItem.getDataSource(); + String customerValue = taskElementConfigItem.getCustomerValue(); + if (StrUtil.isBlank(customerValue)) { + throw new CustomerException("自定义sql或自定义接口不能为空!"); + } + List> result = new ArrayList<>(); + for (Map item : authorityList) { + if ("0".equals(dataSource)) { + // 自定义sql + customerValue += " " + whereStr; + List> list = mapper.selectWorkList(customerValue, item, user, whereMap); + if (CollectionUtil.isNotEmpty(list)) { + result.addAll(list); + } + } else { + // 自定义接口 + Map map = Util.parseCusInterfacePathParam(customerValue); + map.put("whereStr", whereStr); + if (CollectionUtil.isNotEmpty(whereMap)) { + for (Map.Entry entry : whereMap.entrySet()) { + map.put(entry.getKey(), Util.null2String(entry.getValue())); + } + } + String classPath = map.remove("_ClassPath"); + item.putAll(map); + TaskElementGetValueInterface instance = Util.getClassInstance(classPath, TaskElementGetValueInterface.class); + List> list = instance.getValue(taskElementConfigItem, item, user); + if (CollectionUtil.isNotEmpty(list)) { + result.addAll(list); + } + } + } + // 去重 + result = result.stream() + .filter(distinctByKey(item -> item.get("id"))) + .collect(Collectors.toList()); + return result; + } + + + static Predicate distinctByKey(Function keyExtractor) { + Map seen = new ConcurrentHashMap<>(8); + return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + } + + /** + *

查询自定义的数据

+ * + * @param user 用户 + * @param params 参数 + * @return 结果 + */ + public IhgTaskElementVo getList(User user, Map params, String configId) { + Assert.notBlank(configId, "查询配置表Id为空!"); + IhgTaskElementConfigItem ihgTaskElementConfItem = mapper.selectConfig(configId); + if (Objects.isNull(ihgTaskElementConfItem)) { + return null; + } + // 设置查询基础参数 + Map map = new HashMap<>(8); + map.put("currentDate", Util.getTime("yyyy-MM-dd")); + map.put("currentTime", Util.getTime("HH:mm:ss")); + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : params.entrySet()) { + Map valueMap = (Map) entry.getValue(); + String key = Util.null2String(valueMap.get("key")); + String value = Util.null2String(valueMap.get("value")); + if (StrUtil.isNotBlank(value)) { + builder.append(" and ").append(key).append(" = ").append("#{where.").append(key).append("}"); + map.put(key, value); + } + } + String whereStr = builder.toString(); + // 查询可查看权限并进行过滤 + String viewAuthoritySql = ihgTaskElementConfItem.getViewAuthority(); + List> authorityList = mapper.selectAuthority(viewAuthoritySql, user, map); + if (CollectionUtil.isEmpty(authorityList)) { + return null; + } + // 查询数据 + List> workList = this.queryWorkList(ihgTaskElementConfItem, authorityList, user, whereStr, map); + IhgTaskElementVo ihgTaskElementVo = TaskElementMapstruct.INSTANCE.entity2Vo(ihgTaskElementConfItem); + ihgTaskElementVo.setList(workList); + ihgTaskElementVo.setSize(workList.size()); + if (user.getLanguage() == 8) { + ihgTaskElementVo.setTitle(ihgTaskElementConfItem.getTitleEn()); + ihgTaskElementVo.setUnit(ihgTaskElementConfItem.getUnitEn()); + } + return ihgTaskElementVo; + } +} diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java new file mode 100644 index 0000000..5202fc3 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java @@ -0,0 +1,41 @@ +package com.api.youhong.ai.ihgzhouji.taskele.vo; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; +import java.util.Map; + +/** + *

配置表

+ * + *

create: 2023/5/4 17:35

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class IhgTaskElementVo { + + /** id */ + private String id; + /** 标题 */ + private String title; + /** 单位 */ + private String unit; + + /** icon */ + private String icon; + + /** 激活icon */ + private String iconActive; + /** 跳转链接 */ + private String link; + + /** 数据长度 */ + private Integer size; + /** 数据 */ + private List> list; +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenTheBillController.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenTheBillController.java new file mode 100644 index 0000000..fb76a8f --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenTheBillController.java @@ -0,0 +1,73 @@ +package com.api.youhong.ai.yashilandai.openbill.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.youhong.ai.yashilandai.openbill.service.OpenTheBillService; +import org.apache.log4j.Logger; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.net.URLEncoder; + +/** + *

拆单api接口

+ * + *

create: 2023/4/25 10:09

+ * + * @author youHong.ai + */ + +@Path("/ayh/estee-Lauder/open-bill") +public class OpenTheBillController { + + private final OpenTheBillService service = new OpenTheBillService(); + private final Logger log = Util.getLogger(); + + @Path("/data/get") + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String dataGet(@QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate, + @QueryParam("orderNo") String orderNo) { + try { + return ApiResult.success(service.getOpenBillListData(startDate, endDate, orderNo)); + } catch (Exception e) { + log.error("get open the bill data error!" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + } + + @Path("/data/export") + @GET + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes(MediaType.APPLICATION_JSON) + @SuppressWarnings("all") + public Response export(@QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate, + @QueryParam("orderNo") String orderNo) { + try { + // File file = service.exportExcel(); + // StreamingOutput streamingOutput = output -> { + // try (InputStream input = Files.newInputStream(file.toPath())) { + // IOUtils.copy(input, output); + // } + // }; + // // 获取文件大小 + // long fileSize = file.length(); + StreamingOutput streamingOutput = outputStream -> { + service.exportExcel(outputStream, startDate, endDate,orderNo); + }; + String fileName = new String(("疑似拆单数据-" + Util.getTime("yyyy-MM-dd") + ".xlsx")); + String encodedFileName = URLEncoder.encode(fileName, "UTF-8"); + Response.ResponseBuilder builder = Response.ok(streamingOutput) + // 指定编码方式为 UTF-8 + .header("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName); + return builder.build(); + } catch (Exception e) { + log.error("导出excel文件失败!" + Util.getErrString(e)); + return Response.ok(ApiResult.error("导出文件失败!"), MediaType.APPLICATION_JSON).build(); + } + + } +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenThenBillController.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenThenBillController.java deleted file mode 100644 index 746cc72..0000000 --- a/src/main/java/com/api/youhong/ai/yashilandai/openbill/controller/OpenThenBillController.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.api.youhong.ai.yashilandai.openbill.controller; - -import aiyh.utils.ApiResult; -import aiyh.utils.Util; -import com.api.youhong.ai.yashilandai.openbill.service.OpenThenBillService; -import org.apache.log4j.Logger; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -/** - *

拆单api接口

- * - *

create: 2023/4/25 10:09

- * - * @author youHong.ai - */ - -@Path("/ayh/estee-Lauder/open-bill") -public class OpenThenBillController { - - private final OpenThenBillService service = new OpenThenBillService(); - private final Logger log = Util.getLogger(); - - @Path("/data/get") - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public String dataGet() { - try { - return ApiResult.success(service.getOpenBillListData()); - } catch (Exception e) { - log.error("get open the bill data error!" + Util.getErrString(e)); - return ApiResult.error("system error!"); - } - } -} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenTheBillMapper.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenTheBillMapper.java new file mode 100644 index 0000000..c06f445 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenTheBillMapper.java @@ -0,0 +1,69 @@ +package com.api.youhong.ai.yashilandai.openbill.mapper; + +import aiyh.utils.annotation.recordset.*; +import com.api.youhong.ai.yashilandai.openbill.pojo.ConditionDetail; +import com.api.youhong.ai.yashilandai.openbill.pojo.ConditionEntity; + +import java.util.List; +import java.util.Map; + +/** + *

+ * + *

create: 2023/4/25 10:15

+ * + * @author youHong.ai + */ +@SqlMapper +public interface OpenTheBillMapper { + + /** + *

查询数据列表

+ * + * @param tableName 表名 + * @return 数据列表 + */ + @Select("select * from $t{tableName}") + List> selectList(@ParamMapper("tableName") String tableName); + + @Select("select * from $t{tableName} where $t{dateField} between #{startDate} and #{endDate} $t{condition}") + List> selectList(@ParamMapper("tableName") String tableName, + @ParamMapper("startDate") String startDate, + @ParamMapper("endDate") String endDate, + @ParamMapper("dateField") String dateField, + @ParamMapper("condition") String condition); + + /** + *

查询条件参数信息

+ * + * @param id 条件参数id + * @return 条件参数信息 + */ + @Select("select * from uf_ncotjcs where id = #{id}") + @CollectionMappings({ + @CollectionMapping(property = "list", + column = "id", + id = @Id(methodId = 1, value = String.class)) + }) + ConditionEntity selectCondition(@ParamMapper("id") String id); + + /** + *

查询条件参数信息明细表

+ * + * @param mainId 主表id + * @return 条件参数明细表 + */ + @Select("select * from uf_ncotjcs_dt1 where mainid = #{mainId}") + @CollectionMethod(1) + List selectConditionDetail(@ParamMapper("mainId") String mainId); + + /** + *

查询workflowId 通过requestId

+ * + * @param requestId requestId + * @return workflowId + */ + @Select("select WORKFLOWID from workflow_requestbase where REQUESTID = #{requestId}") + String selectWorkflowId(@ParamMapper("requestId") String requestId); + +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenThenBillMapper.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenThenBillMapper.java deleted file mode 100644 index 600faf6..0000000 --- a/src/main/java/com/api/youhong/ai/yashilandai/openbill/mapper/OpenThenBillMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.api.youhong.ai.yashilandai.openbill.mapper; - -import aiyh.utils.annotation.recordset.Select; -import aiyh.utils.annotation.recordset.SqlMapper; - -import java.util.List; -import java.util.Map; - -/** - *

- * - *

create: 2023/4/25 10:15

- * - * @author youHong.ai - */ -@SqlMapper -public interface OpenThenBillMapper { - - /** - *

查询数据列表

- * - * @return 数据列表 - */ - @Select("select * from v_online") - List> selectList(); -} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionDetail.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionDetail.java new file mode 100644 index 0000000..37d3ce4 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionDetail.java @@ -0,0 +1,23 @@ +package com.api.youhong.ai.yashilandai.openbill.pojo; + +import aiyh.utils.annotation.recordset.SqlDbFieldAnn; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class ConditionDetail { + private Integer id; + @SqlDbFieldAnn("tjmc") + private String conditionName; + @SqlDbFieldAnn("tjzdmc") + private String conditionFieldName; + + @SqlDbFieldAnn("tjgx") + private Integer conditionType; + + @SqlDbFieldAnn("tjzdz") + private String conditionValue; +} \ No newline at end of file diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionEntity.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionEntity.java new file mode 100644 index 0000000..b0efb10 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/pojo/ConditionEntity.java @@ -0,0 +1,26 @@ +package com.api.youhong.ai.yashilandai.openbill.pojo; + +import aiyh.utils.annotation.recordset.SqlDbFieldAnn; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +/** + *

条件参数配置表

+ * + *

create: 2023/4/25 15:07

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ConditionEntity { + private Integer id; + @SqlDbFieldAnn("mxbjgx") + private String condition; + private List list; +} + diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenTheBillService.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenTheBillService.java new file mode 100644 index 0000000..f4720c2 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenTheBillService.java @@ -0,0 +1,572 @@ +package com.api.youhong.ai.yashilandai.openbill.service; + +import aiyh.utils.ScriptUtil; +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.Assert; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; +import aiyh.utils.tool.org.apache.commons.jexl3.JexlException; +import com.alibaba.fastjson.JSON; +import com.api.youhong.ai.yashilandai.openbill.mapper.OpenTheBillMapper; +import com.api.youhong.ai.yashilandai.openbill.pojo.ConditionDetail; +import com.api.youhong.ai.yashilandai.openbill.pojo.ConditionEntity; +import com.api.youhong.ai.yashilandai.openbill.util.ExcelCell; +import com.api.youhong.ai.yashilandai.openbill.util.ExcelPort; +import com.api.youhong.ai.yashilandai.openbill.util.ExcelRow; +import org.apache.log4j.Logger; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; + +import java.io.OutputStream; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + + +/** + *

拆单service

+ * + *

create: 2023/4/25 10:12

+ * + * @author youHong.ai + */ +public class OpenTheBillService { + + private final OpenTheBillMapper mapper = Util.getMapper(OpenTheBillMapper.class); + + private final Logger log = Util.getLogger(); + + public Map getOpenBillListData(String startDate, String endDate, String orderNo) { + return getData(startDate, endDate, orderNo); + } + + + public void exportExcel(OutputStream outputStream, String startDate, String endDate, String orderNo) { + Map data = getData(startDate, endDate, orderNo); + Map head = (Map) data.get("head"); + List> body = (List>) data.get("body"); + List list = new ArrayList<>(); + List excelHeadCellList = new ArrayList<>(); + List fieldList = new ArrayList<>(); + ExcelRow excelRow = new ExcelRow(); + excelRow.setRowHeight(21F); + excelRow.setDataList(excelHeadCellList); + list.add(excelRow); + List headFieldList = (List) head.get("field"); + List headTitleList = (List) head.get("title"); + for (int i = 0; i < headFieldList.size(); i++) { + String title = headTitleList.get(i); + String field = headFieldList.get(i); + ExcelCell excelCell = new ExcelCell(); + excelCell.setValue(title); + excelHeadCellList.add(excelCell); + fieldList.add(field); + } + for (Map item : body) { + ExcelRow excelBodyRow = new ExcelRow(); + List excelCellList = new ArrayList<>(); + for (String key : fieldList) { + Object value = item.get(key); + ExcelCell excelCell = new ExcelCell(); + excelCell.setValue(value); + excelCellList.add(excelCell); + } + excelBodyRow.setDataList(excelCellList); + list.add(excelBodyRow); + } + Map headStyle = new HashMap<>(); + Map singularLine = new HashMap<>(); + Map evenNumberLine = new HashMap<>(); + ExcelPort.exportFile("疑似拆单-" + Util.getTime("yyyy-MM-dd"), list, + outputStream, + this::setHeaderStyle, + this::setBodyStyle, + headStyle, singularLine, evenNumberLine); + } + + + private CellStyle setHeaderStyle(SXSSFWorkbook workbook, + Integer rowIndex, + Integer colIndex, + SXSSFRow row, + SXSSFCell cell, + SXSSFSheet sheet, Map headStyle, + Map headStyle2) { + + if (headStyle.containsKey(colIndex)) { + return headStyle.get(colIndex); + } + // 设置表格单元格格式 + CellStyle cellStyle = workbook.createCellStyle(); + cellStyle.setAlignment(HorizontalAlignment.CENTER); + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setWrapText(true); + // 设置字体格式 + Font font = workbook.createFont(); + font.setFontName("微软雅黑"); + font.setFontHeightInPoints((short) 14); + font.setBold(true); + font.setColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex()); + int columnWidth = sheet.getColumnWidth(colIndex); + String value = cell.getStringCellValue(); + /** 计算字符串中中文字符的数量 */ + int count = chineseCharCountOf(value); + /**在该列字符长度的基础上加上汉字个数计算列宽 */ + int length = (value.length() - count) * 256 + (count + 4) * 512; + length = length * font.getFontHeightInPoints() / 11; + if (length >= columnWidth && length < 256 * 256) { + sheet.setColumnWidth(colIndex, length); + } + cellStyle.setFont(font); + cellStyle.setFillBackgroundColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex()); + cellStyle.setFillPattern(FillPatternType.BRICKS); + headStyle.put(colIndex, cellStyle); + return cellStyle; + } + + + private CellStyle setBodyStyle(SXSSFWorkbook workbook, + Integer rowIndex, + Integer colIndex, + SXSSFRow row, + SXSSFCell cell, + SXSSFSheet sheet, Map singularLine, Map evenNumberLine) { + + int columnWidth = sheet.getColumnWidth(colIndex); + String value = cell.getStringCellValue(); + /** 计算字符串中中文字符的数量 */ + int count = chineseCharCountOf(value); + /**在该列字符长度的基础上加上汉字个数计算列宽 */ + int length = (value.length() - count) * 256 + (count + 4) * 512; + length = length * 10 / 11; + if (length >= columnWidth && length < 256 * 256) { + sheet.setColumnWidth(colIndex, length); + } + if (rowIndex % 2 == 1) { + if (singularLine.containsKey(colIndex)) { + return singularLine.get(colIndex); + } + CellStyle cellStyle = getCellStyle(workbook, rowIndex, colIndex, cell, sheet); + singularLine.put(colIndex, cellStyle); + return cellStyle; + } else { + if (evenNumberLine.containsKey(colIndex)) { + return evenNumberLine.get(colIndex); + } + CellStyle cellStyle = getCellStyle(workbook, rowIndex, colIndex, cell, sheet); + // 设置字体格式 + Font font = workbook.createFont(); + font.setFontName("微软雅黑"); + font.setFontHeightInPoints((short) 10); + + cellStyle.setFont(font); + evenNumberLine.put(colIndex, cellStyle); + return cellStyle; + } + } + + private CellStyle getCellStyle(SXSSFWorkbook workbook, Integer rowIndex, Integer colIndex, SXSSFCell cell, SXSSFSheet sheet) { + + + // 设置表格单元格格式 + CellStyle style = workbook.createCellStyle(); + style.setVerticalAlignment(VerticalAlignment.CENTER); + style.setAlignment(HorizontalAlignment.CENTER); + style.setBorderRight(BorderStyle.THIN); + style.setRightBorderColor(IndexedColors.BLACK.getIndex()); + style.setBorderLeft(BorderStyle.THIN); + style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + style.setBorderTop(BorderStyle.THIN); + style.setTopBorderColor(IndexedColors.BLACK.getIndex()); + style.setBorderBottom(BorderStyle.THIN); + style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + style.setWrapText(true); + // if (rowIndex % 2 == 1) { + // XSSFColor color = new XSSFColor(new java.awt.Color(242, 242, 242), new DefaultIndexedColorMap()); + // style.setFillBackgroundColor(color.getIndex()); + // style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + // } + return style; + } + + /** + * 计算字符串中中文字符的数量 + * 参见 《汉字unicode编码范围》 + * + * @param input + * @return + */ + private static int chineseCharCountOf(String input) { + // 汉字数量 + int count = 0; + if (null != input) { + String regEx = "[\\u4e00-\\u9fa5]"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(input); + int len = m.groupCount(); + // 获取汉字个数 + while (m.find()) { + for (int i = 0; i <= len; i++) { + count = count + 1; + } + } + } + return count; + } + + public Map getData(String startDate, String endDate, String orderNo) { + Map config = Util.readProperties2Map("esteeLauderExcelExport", "export"); + Assert.notEmpty(config, "esteeLauderExcelExport.properties文件读取配置为空,请检查配置信息"); + List> dataList; + String condition = ""; + if (StrUtil.isNotBlank(orderNo)) { + condition = " and " + Util.null2String(config.get("orderNo")) + " like '%" + orderNo.replace("%'", "''") + "'"; + } + if (StrUtil.isNotBlank(startDate) && StrUtil.isNotBlank(endDate)) { + dataList = mapper.selectList(Util.null2String(config.get("tableName")), + startDate, endDate, + Util.null2String(config.get("createDate")), + condition); + } else { + dataList = mapper.selectList(Util.null2String(config.get("tableName"))); + } + Object head = config.get("head"); + Map result = new HashMap<>(16); + result.put("head", head); + if (CollectionUtil.isEmpty(dataList)) { + return result; + } + calculationCondition(dataList, config); + List>> groupData = groupData(dataList, config); + List> groupDataList = new ArrayList<>(); + AtomicInteger n = new AtomicInteger(1); + for (int i = 0; i < groupData.size(); i++) { + List> list = groupData.get(i); + int finalI = i; + list.forEach(item -> { + item.put("groupId", finalI); + item.put("no", n.getAndIncrement()); + }); + calculationOpenBill(list, config); + groupDataList.addAll(list); + } + // for (List> list : groupData) { + // calculationOpenBill(list, config); + // + // groupDataList.addAll(list); + // } + result.put("body", groupDataList); + return result; + } + + + private void calculationOpenBill(List> list, Map config) { + String orderTypeKey = Util.null2String(config.get("orderType")); + String finalOrderType = ""; + for (Map item : list) { + String orderType = Util.null2String(item.get(orderTypeKey)); + if (StrUtil.isNotBlank(finalOrderType)) { + if (!finalOrderType.equals(orderType)) { + throw new CustomerException("分组条件中存在不同流程数据,请检查分组逻辑以及分组条件组合逻辑是否保证分组正确!"); + } + } else { + finalOrderType = orderType; + } + } + boolean flag = false; + String finalBgm = ""; + for (Map item : list) { + String bgm = Util.null2String(item.get(Util.null2String(config.get("bgmKey")))); + if (StrUtil.isNotBlank(finalBgm)) { + if (!finalBgm.equals(bgm)) { + flag = true; + break; + } + } else { + finalBgm = bgm; + } + } + if (!flag) { + // 所有分组bgm都一样 + if (finalBgm.equals("Y")) { + // 都过了bgm + for (Map item : list) { + item.put(Util.null2String(config.get("openBillKey")), ""); + } + } else { + // 都没过bgm,计算条件 + calculationOpenBillN(list, config); + } + } else { + // 不全部都是y或者n + for (Map item : list) { + item.put(Util.null2String(config.get("openBillKey")), "全部订单总金额达到GM审批标准,拆分后无法到达GM审批节点。"); + } + } + + } + + private void calculationOpenBillN(List> list, Map config) { + Map fristMap = list.get(0); + String orderType = Util.null2String(fristMap.get(Util.null2String(config.get("orderType")))); + Map condition = (Map) config.get("condition"); + Map conditionInfo = (Map) condition.get(orderType); + if (Objects.isNull(conditionInfo)) { + return; + } + String id = Util.null2String(conditionInfo.get("id")); + ConditionEntity conditionEntity = mapper.selectCondition(id); + if (Objects.isNull(conditionEntity)) { + return; + } + List conditionDetailList = conditionEntity.getList(); + if (CollectionUtil.isEmpty(conditionDetailList)) { + return; + } + List booleanList = new ArrayList<>(); + Map mapping = (Map) conditionInfo.get("mapping"); + Map totalMap = new HashMap<>(); + for (Map.Entry entry : mapping.entrySet()) { + String key = entry.getKey(); + double totalValue = 0.0; + for (Map item : list) { + String value = Util.null2String(entry.getValue()); + Object o = ""; + if (StrUtil.isNotBlank(value)) { + try { + o = ScriptUtil.invokeScript(value, item); + } catch (JexlException e) { + log.error("执行脚本失败:=》" + e.getMessage()); + } + } + try { + double v = Double.parseDouble(Util.null2String("".equals(Util.null2String(o)) ? null : Util.null2String(o), "0.0")); + totalValue += v; + } catch (Exception e) { + log.error("求和转换失败:" + JSON.toJSONString(entry)); + log.error("item:" + JSON.toJSONString(item)); + throw new CustomerException("求和字段转化失败!", e); + } + } + totalMap.put(key, totalValue); + } + for (Map.Entry entry : totalMap.entrySet()) { + for (ConditionDetail conditionDetail : conditionDetailList) { + Integer conditionType = conditionDetail.getConditionType(); + String value = Util.null2String(entry.getValue()); + String conditionValue = conditionDetail.getConditionValue(); + boolean b = this.compareCondition(conditionType, value, conditionValue); + booleanList.add(b); + } + } + boolean flag = false; + String conditionType = conditionEntity.getCondition(); + if ("0".equals(conditionType)) { + // 或者 + for (Boolean aBoolean : booleanList) { + if (aBoolean) { + flag = true; + break; + } + } + } else if ("1".equals(conditionType)) { + // 且 + for (Boolean aBoolean : booleanList) { + if (!aBoolean) { + flag = true; + break; + } + } + } + // 拆单 + if (flag) { + for (Map item : list) { + item.put(Util.null2String(config.get("openBillKey")), "全部订单总金额达到GM审批标准,拆分后无法到达GM审批节点。"); + } + } else { + for (Map item : list) { + item.put(Util.null2String(config.get("openBillKey")), ""); + } + } + } + + private boolean compareCondition(Integer conditionType, String value, String conditionValue) { + boolean res = false; + double valueNum = 0.0; + double conditionValueNum = 0.0; + if (conditionType < 5) { + valueNum = Double.parseDouble(value); + conditionValueNum = Double.parseDouble(conditionValue); + } + + switch (conditionType) { + case 0: + if (conditionValueNum > valueNum) { + res = true; + } + break; + case 1: + if (conditionValueNum >= valueNum) { + res = true; + } + break; + case 2: + if (conditionValueNum < valueNum) { + res = true; + } + break; + case 3: + if (conditionValueNum <= valueNum) { + res = true; + } + break; + case 4: + if (conditionValueNum == valueNum) { + res = true; + } + break; + case 5: + if (!Objects.equals(conditionValue, "") && conditionValue.contains(value)) { + res = true; + } + break; + case 6: + if (Objects.equals(conditionValue, "")) { + res = true; + } else if (!conditionValue.contains(value)) { + res = true; + } + break; + case 7: + if (!Objects.equals(conditionValue, "") && conditionValue.equals(value)) { + res = true; + } + default: + break; + } + + return res; + } + + + private void calculationCondition(List> dataList, Map config) { + for (Map map : dataList) { + // 订单分类 + String orderType = Util.null2String(map.get(Util.null2String(config.get("orderType")))); + // 订单用途 + String orderUse = Util.null2String(map.get(Util.null2String(config.get("orderUse")))); + // shipTo + String shipTo = Util.null2String(map.get(Util.null2String(config.get("shipTo")))); + // 成本中心 + String costCenter = Util.null2String(map.get(Util.null2String(config.get("costCenter")))); + // sku + String sku = Util.null2String(map.get(Util.null2String(config.get("sku")))); + String condition = ""; + switch (orderType) { + case "2": { + // 内部领用 + // orderUse + " " + shipTo + " " + costCenter + " " + sku + // condition = "订单用途:" + orderUse + " " + "ShipTo:" + shipTo + " CostCenter:" + costCenter + " sku:" + sku; + condition = orderUse + " :" + shipTo + ":" + costCenter + ":" + sku; + } + break; + case "1": + case "3": + case "4": { + // 第三方 + 柜台订单 + // orderUse + ":" + shipTo + ":" + sku + // condition = "订单用途:" + orderUse + " " + "ShipTo:" + shipTo + " sku:" + sku + " 订单分类:" + orderType; + condition = orderUse + ":" + shipTo + ":" + sku + ":" + orderType; + } + break; + default: + break; + } + map.put(Util.null2String(config.get("conditionKey")), condition); + } + } + + private List>> groupData(List> dataList, Map config) { + // 根据condition进行分组 + Map>> typeMap = + dataList.stream() + .collect(Collectors.groupingBy( + item -> String.valueOf( + item.get( + Util.null2String(config.get("conditionKey")) + ) + ) + ) + ); + // 对每个type的数据进行日期分组 + List>> result = new ArrayList<>(); + DateFormat dateFormat = new SimpleDateFormat(Util.null2String(config.get("createType"))); + for (String type : typeMap.keySet()) { + List> typeDataList = typeMap.get(type); + typeDataList.sort((o1, o2) -> { + try { + Date date1 = dateFormat.parse(o1.get(Util.null2String(config.get("createDate"))).toString()); + Date date2 = dateFormat.parse(o2.get(Util.null2String(config.get("createDate"))).toString()); + return date1.compareTo(date2); + } catch (ParseException e) { + log.error("日期格式化出错,排序失败!"); + return 0; + } + }); + Map baseData = typeDataList.get(0); + Date baseDate; + try { + baseDate = dateFormat.parse(baseData.get(Util.null2String(config.get("createDate"))).toString()); + } catch (ParseException e) { + throw new CustomerException("日期转换异常!", e); + } + List> groupList = new ArrayList<>(); + groupList.add(baseData); + for (int i = 1; i < typeDataList.size(); i++) { + Map data = typeDataList.get(i); + Date date; + try { + date = dateFormat.parse(data.get(Util.null2String(config.get("createDate"))).toString()); + } catch (ParseException e) { + throw new CustomerException("日期转换异常!", e); + } + + if (date == null || baseDate == null) { + continue; + } + if (Math.abs(date.getTime() - baseDate.getTime()) <= 7 * 24 * 60 * 60 * 1000) { + groupList.add(data); + } else { + baseDate = date; + result.add(groupList); + groupList = new ArrayList<>(); + groupList.add(data); + } + } + if (groupList.size() > 0) { + result.add(groupList); + } + } + + return result; + } + +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenThenBillService.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenThenBillService.java deleted file mode 100644 index 0c3ae99..0000000 --- a/src/main/java/com/api/youhong/ai/yashilandai/openbill/service/OpenThenBillService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.api.youhong.ai.yashilandai.openbill.service; - -import aiyh.utils.Util; -import com.api.youhong.ai.yashilandai.openbill.mapper.OpenThenBillMapper; - -import java.util.List; -import java.util.Map; - -/** - *

- * - *

create: 2023/4/25 10:12

- * - * @author youHong.ai - */ -public class OpenThenBillService { - - - private final OpenThenBillMapper mapper = Util.getMapper(OpenThenBillMapper.class); - - public Object getOpenBillListData() { - return null; - } - - public List> getData() { - List> dataList = mapper.selectList(); - return null; - } - -} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelBody.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelBody.java new file mode 100644 index 0000000..ff0d99c --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelBody.java @@ -0,0 +1,18 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

表内容

+ * + *

create: 2023/4/19 10:48

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ExcelBody extends ExcelCell { +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelCell.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelCell.java new file mode 100644 index 0000000..33b5bed --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelCell.java @@ -0,0 +1,23 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

单元格内容

+ * + *

create: 2023/4/19 10:49

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ExcelCell { + /** 表头名称 */ + private Object value; + + /** 单元格格式 */ + private IExcelCellStyleCreator cellStyle; +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelHead.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelHead.java new file mode 100644 index 0000000..386a0dd --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelHead.java @@ -0,0 +1,20 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

excel表头

+ * + *

create: 2023/4/19 10:46

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ExcelHead extends ExcelCell { + + +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelPort.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelPort.java new file mode 100644 index 0000000..b4651fb --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelPort.java @@ -0,0 +1,135 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import aiyh.utils.Util; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + *

excel导出

+ * + *

create: 2023/4/19 10:39

+ * + * @author youHong.ai + */ +public class ExcelPort { + + public static void exportFile(String sheetName, List dataList, + OutputStream outputStream, + IExcelCellStyleCreator headStyle, + IExcelCellStyleCreator bodyStyle, + Map headStyleMap, + Map singularLine, + Map evenNumberLine) { + SXSSFWorkbook workbook = new SXSSFWorkbook(); + createSheet(sheetName, workbook, dataList, headStyle, bodyStyle, headStyleMap, singularLine, evenNumberLine); + // String excel = Util.getTempFilePath("excel", ".xlsx"); + try { + workbook.write(outputStream); + // workbook.write(Files.newOutputStream(Paths.get(excel))); + // return new File(excel); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String export(String sheetName, List dataList, + IExcelCellStyleCreator headStyle, + IExcelCellStyleCreator bodyStyle, Map headStyleMap, + Map singularLine, + Map evenNumberLine) { + SXSSFWorkbook workbook = new SXSSFWorkbook(); + createSheet(sheetName, workbook, dataList, headStyle, bodyStyle, headStyleMap, singularLine, evenNumberLine); + String excel = Util.getTempFilePath("excel", ".xlsx"); + try { + workbook.write(Files.newOutputStream(Paths.get(excel))); + } catch (IOException e) { + throw new RuntimeException(e); + } + return excel; + } + + + public static String export(List sheetList, + IExcelCellStyleCreator headStyle, + IExcelCellStyleCreator bodyStyle, Map headStyleMap, + Map singularLine, + Map evenNumberLine) { + SXSSFWorkbook workbook = new SXSSFWorkbook(); + for (ExcelSheet excelSheet : sheetList) { + createSheet(excelSheet.getSheetName(), workbook, excelSheet.getDataList(), headStyle, bodyStyle, headStyleMap, singularLine, evenNumberLine); + } + String excel = Util.getTempFilePath("excel", ".xlsx"); + try { + workbook.write(Files.newOutputStream(Paths.get(excel))); + } catch (IOException e) { + throw new RuntimeException(e); + } + return excel; + } + + + private static void createSheet(String sheetName, SXSSFWorkbook wb, List dataList, + IExcelCellStyleCreator headStyle, + IExcelCellStyleCreator bodyStyle, + Map headStyleMap, + Map singularLine, + Map evenNumberLine) { + SXSSFSheet sheet = wb.createSheet(sheetName); + createDate(sheet, wb, dataList, headStyle, bodyStyle, headStyleMap, singularLine, evenNumberLine); + } + + private static void createDate(SXSSFSheet sheet, SXSSFWorkbook wb, List dataList, + IExcelCellStyleCreator headStyle, + IExcelCellStyleCreator bodyStyle, + Map headStyleMap, + Map singularLine, + Map evenNumberLine) { + if (CollectionUtil.isEmpty(dataList) || dataList.size() < 1) { + return; + } + for (int i = 0; i < dataList.size(); i++) { + ExcelRow excelRow = dataList.get(i); + SXSSFRow row = sheet.createRow(i); + if (!Objects.isNull(excelRow.getRowHeight()) && excelRow.getRowHeight() > 0) { + row.setHeightInPoints(excelRow.getRowHeight()); + } + List rowData = excelRow.getDataList(); + for (int j = 0; j < rowData.size(); j++) { + ExcelCell cellValue = rowData.get(j); + SXSSFCell cell = row.createCell(j); + CellStyle style = null; + XSSFRichTextString text = new XSSFRichTextString(Util.null2String(cellValue.getValue())); + cell.setCellValue(text); + // sheet.trackAllColumnsForAutoSizing(); + // sheet.autoSizeColumn(i); + if (i == 0) { + if (Objects.nonNull(headStyle)) { + style = headStyle.createStyle(wb, i, j, row, cell, sheet, headStyleMap, null); + } + } else { + if (Objects.nonNull(bodyStyle)) { + style = bodyStyle.createStyle(wb, i, j, row, cell, sheet, singularLine, evenNumberLine); + } + } + if (Objects.nonNull(style)) { + cell.setCellStyle(style); + } + + } + } + } + +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelRow.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelRow.java new file mode 100644 index 0000000..5e056d1 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelRow.java @@ -0,0 +1,23 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +/** + *

表行

+ * + *

create: 2023/4/19 10:56

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ExcelRow { + + private Float rowHeight; + private List dataList; +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelSheet.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelSheet.java new file mode 100644 index 0000000..99a524a --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/ExcelSheet.java @@ -0,0 +1,22 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.util.List; + +/** + *

excel表

+ * + *

create: 2023/4/19 11:14

+ * + * @author youHong.ai + */ +@Getter +@Setter +@ToString +public class ExcelSheet { + private String sheetName; + private List dataList; +} diff --git a/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/IExcelCellStyleCreator.java b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/IExcelCellStyleCreator.java new file mode 100644 index 0000000..b0038e8 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/yashilandai/openbill/util/IExcelCellStyleCreator.java @@ -0,0 +1,28 @@ +package com.api.youhong.ai.yashilandai.openbill.util; + +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; + +import java.util.Map; + +/** + *

创建样式

+ * + *

create: 2023/4/19 13:53

+ * + * @author youHong.ai + */ +@FunctionalInterface +public interface IExcelCellStyleCreator { + + CellStyle createStyle(SXSSFWorkbook workbook, + Integer rowIndex, + Integer colIndex, + SXSSFRow row, + SXSSFCell cell, + SXSSFSheet sheet, Map style2, + Map style1); +} diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index 6f165eb..f025602 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -756,7 +756,7 @@ public class DealWithMapping extends ToolUtil { } else { value = Util.null2String(mainMap.get(fieldName)); if ("".equals(value)) { - value = Util.null2String(detailMap.get(fieldNameLower)); + value = Util.null2String(mainMap.get(fieldNameLower)); } } diff --git a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java index 6bc4e62..b9ef555 100644 --- a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java +++ b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/VoucherPayableNewAction.java @@ -172,22 +172,19 @@ public class VoucherPayableNewAction extends SafeCusBaseAction { } headKeys = sortKey(headKeys); for (String headKey : headKeys) { - sb.append(heads.get(headKey)).append("\t"); + sb.append(Util.null2String(heads.get(headKey)).replace(" ", " ")).append("\t"); } sb.deleteCharAt(sb.lastIndexOf("\t")); sb.append("\r\n"); - log.info("头写入的数据:" + sb); // 写入借方信息 writeList(debit, sb); - log.info("debit写入的数据:" + sb); // 写入贷方信息 writeList(creditSide, sb); - log.info("creditSide写入的数据:" + sb); String filePath = getFilePath(); try { OutputStreamWriter out = new OutputStreamWriter( Files.newOutputStream(Paths.get(filePath)), StandardCharsets.UTF_8); - out.write(sb.toString()); + out.write(sb.toString().replace(" ", " ")); out.close(); } catch (IOException e) { diff --git a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/service/VoucherPayableService.java b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/service/VoucherPayableService.java index c435866..b8ed1b7 100644 --- a/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/service/VoucherPayableService.java +++ b/src/main/java/weaver/youhong/ai/haripijiu/action/sapdocking/service/VoucherPayableService.java @@ -84,7 +84,7 @@ public class VoucherPayableService { StringBuilder voucherDetailBuilder = new StringBuilder(); List> voucherDetail = voucherData.getVoucherDetail(); for (List voucherItems : voucherDetail) { - voucherDetailBuilder.append(appendVoucherItems(voucherItems)) + voucherDetailBuilder.append(appendVoucherItems(voucherItems).replace(" ", " ")) .append("\r\n"); } String voucherDetailStr = voucherDetailBuilder.substring(0, voucherDetailBuilder.lastIndexOf("\r\n")); @@ -95,8 +95,8 @@ public class VoucherPayableService { // )); OutputStreamWriter out = new OutputStreamWriter( Files.newOutputStream(Paths.get(filePath)), StandardCharsets.UTF_8); - out.write(voucherHeadStr); - out.write(voucherDetailStr); + out.write(voucherHeadStr.replace(" ", " ")); + out.write(voucherDetailStr.replace(" ", " ")); out.close(); // writer.write(voucherHeadStr); // writer.write(voucherDetailStr); @@ -118,7 +118,7 @@ public class VoucherPayableService { List voucherItems = voucherDetail.get(i); if (i == 0) { for (VoucherItem voucherItem : voucherItems) { - voucherHeadBuilder.append(voucherItem.getName()) + voucherHeadBuilder.append(voucherItem.getName().replace(" ", " ")) .append("\t"); } voucherHeadBuilder = new StringBuilder(voucherHeadBuilder @@ -126,7 +126,7 @@ public class VoucherPayableService { } for (VoucherItem voucherItem : voucherItems) { - voucherHeadBuilder.append(voucherItem.getValue()) + voucherHeadBuilder.append(Util.null2String(voucherItem.getValue()).replace(" ", " ")) .append("\t"); } if (i < voucherDetail.size() - 1) { @@ -142,7 +142,7 @@ public class VoucherPayableService { try { OutputStreamWriter out = new OutputStreamWriter( Files.newOutputStream(Paths.get(filePath)), StandardCharsets.UTF_8); - out.write(voucherHaredStr); + out.write(voucherHaredStr.replace(" ", " ")); out.close(); // BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( // Files.newOutputStream(Paths.get(filePath)) @@ -186,7 +186,7 @@ public class VoucherPayableService { // )); OutputStreamWriter out = new OutputStreamWriter( Files.newOutputStream(Paths.get(filePath)), StandardCharsets.UTF_8); - out.write(voucherHeadStr); + out.write(voucherHeadStr.replace(" ", " ")); // writer.write(voucherHeadStr); // writer.flush(); // writer.close(); diff --git a/src/main/java/weaver/youhong/ai/intellectualproperty/action/CaElectronicSignatureAction.java b/src/main/java/weaver/youhong/ai/intellectualproperty/action/CaElectronicSignatureAction.java index fba8965..c9d1abb 100644 --- a/src/main/java/weaver/youhong/ai/intellectualproperty/action/CaElectronicSignatureAction.java +++ b/src/main/java/weaver/youhong/ai/intellectualproperty/action/CaElectronicSignatureAction.java @@ -88,12 +88,12 @@ public class CaElectronicSignatureAction extends SafeCusBaseAction { } Map responseMap = responeVo.getResponseMap(); String documentNo = Util.null2String(responseMap.get("document_no")); - String pdf = Util.null2String(responseMap.get("pdf")); + String pdf = Util.null2String(responseMap.get("ofd")); InputStream inputStream = base64ContentToFile(pdf); String docCategorys = Util.getDocCategorysByTable(String.valueOf(workflowId), signFileField, billTable); String[] docCategoryArr = docCategorys.split(","); int docCategory = Integer.parseInt(docCategoryArr[docCategoryArr.length - 1]); - int docId = Util.createDoc(Strings.isNullOrEmpty(docName.get()) ? "sign.pdf" : docName.get(), docCategory, inputStream, 1); + int docId = Util.createDoc(Strings.isNullOrEmpty(docName.get()) ? "sign.ofd" : docName.get(), docCategory, inputStream, 1); docName.remove(); writeBack(documentNo, billTable, requestId, docId); } catch (Exception e) { diff --git a/src/main/java/weaver/youhong/ai/intellectualproperty/cusgetvalue/FileToBase64CusGetValue.java b/src/main/java/weaver/youhong/ai/intellectualproperty/cusgetvalue/FileToBase64CusGetValue.java index d9cbb55..3fd2b05 100644 --- a/src/main/java/weaver/youhong/ai/intellectualproperty/cusgetvalue/FileToBase64CusGetValue.java +++ b/src/main/java/weaver/youhong/ai/intellectualproperty/cusgetvalue/FileToBase64CusGetValue.java @@ -9,6 +9,7 @@ import weaver.file.ImageFileManager; import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; import weaver.youhong.ai.intellectualproperty.action.CaElectronicSignatureAction; +import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.util.Base64; import java.util.Map; @@ -35,9 +36,14 @@ public class FileToBase64CusGetValue implements CusInterfaceGetValue { } DocImageInfo docImageInfo = Util.selectImageInfoByDocId(currentValue); InputStream inputStream = ImageFileManager.getInputStreamById(docImageInfo.getImageFileId()); - byte[] src = new byte[inputStream.available()]; - inputStream.read(src); - String fileBase64 = Base64.getEncoder().encodeToString(src); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + byte[] data = outputStream.toByteArray(); + String fileBase64 = Base64.getEncoder().encodeToString(data); CaElectronicSignatureAction.docName.set(docImageInfo.getImageFileName()); return fileBase64; } catch (Exception e) { diff --git a/src/main/resources/WEB-INF/prop/prop2map/esteeLauderExcelExport.properties b/src/main/resources/WEB-INF/prop/prop2map/esteeLauderExcelExport.properties new file mode 100644 index 0000000..05ab7ad --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/esteeLauderExcelExport.properties @@ -0,0 +1,112 @@ +#导出设置 +export.tableName=v_yscd +#订单分类 +export.orderType=ddlx +#订单用途 +export.orderUse=ddyt +# 点单编号 +export.orderNo=ddbh +#shipto +export.shipTo=shipto +# 疑似拆单 +export.openBillKey=openBill +# 日期时间字段 +export.createDate=createdate +# 日期格式化类型 +export.createType=yyyy-MM-dd +#成本中心 +export.costCenter=cbzxyh +# 条件key +export.conditionKey=condition +#流水号-requestId +export.requestId=lcid +# bgm字段 +export.bgmKey=bgm +# 条件参数id配置 +export.condition.1.id=42 +export.condition.2.id=42 +export.condition.3.id=42 +export.condition.4.id=42 +#条件参数字段映射关系 +export.condition.1.mapping.giftsQty=sl +export.condition.1.mapping.giftsTotalCost=kxpmxzlsj +export.condition.2.mapping.giftsQty=sl +export.condition.2.mapping.giftsTotalCost=kxpmxzlsj +export.condition.3.mapping.giftsQty=sl +export.condition.3.mapping.giftsTotalCost=kxpmxzlsj +export.condition.4.mapping.giftsQty=sl +export.condition.4.mapping.giftsTotalCost=kxpmxzlsj +#sku +export.sku=sku +#导出表头设置 +export.head.title[0]=序号 +export.head.field[0]=no +export.head.title[1]=分组编号 +export.head.field[1]=groupId +export.head.title[2]=ID +export.head.field[2]=id +export.head.title[3]=条件 +export.head.field[3]=condition +export.head.title[4]=疑似拆单 +export.head.field[4]=openBill +export.head.title[5]=流水号 +export.head.field[5]=lcid +export.head.title[6]=shipTo +export.head.field[6]=shipto +export.head.title[7]=推送时间 +export.head.field[7]=insertTime +export.head.title[8]=审批开始时间 +export.head.field[8]=createdate +export.head.title[9]=申请提交时间 +export.head.field[9]=sqtjrq +export.head.title[10]=审批开始时间 +export.head.field[10]=LASTOPERATEDATE +export.head.title[11]=收方限制 +export.head.field[11]=ddlxms +export.head.title[12]=部门团队 +export.head.field[12]=SPART +export.head.title[13]=品牌部门 +export.head.field[13]=yjpp +export.head.title[14]=订单编号 +export.head.field[14]=ddbh +export.head.title[15]=订单说明 +export.head.field[15]=ddsm +export.head.title[16]=备注 +export.head.field[16]=bz +export.head.title[17]=成本中心-sap +export.head.field[17]=KOSTL +export.head.title[18]=成本中心-用户 +export.head.field[18]=cbzxyh +export.head.title[19]=财务科目 +export.head.field[19]=cwkm +export.head.title[20]=审批开始时间 +export.head.field[20]=LASTOPERATEDATE +export.head.title[21]=活动编号 +export.head.field[21]=hdbh +export.head.title[22]=businessKey +export.head.field[22]=businesskey +export.head.title[23]=申请人 +export.head.field[23]=SQRRLZY +export.head.title[24]=订单类型 +export.head.field[24]=AUART +export.head.title[25]=订单用途 +export.head.field[25]=VKAUS +export.head.title[26]=收货人 +export.head.field[26]=KUNNRSHIPTO +export.head.title[27]=收货人地址 +export.head.field[27]=shdz +export.head.title[28]=收货编号 +export.head.field[28]=hwbh +export.head.title[29]=收货类型 +export.head.field[29]=fl +export.head.title[30]=收货中文名 +export.head.field[30]=ZWMS +export.head.title[31]=数量 +export.head.field[31]=SL +export.head.title[32]=零售总额 +export.head.field[32]=kxpmxzlsj +export.head.title[33]=订单分类 +export.head.field[33]=ddlx +export.head.title[34]=gbm +export.head.field[34]=bgm + diff --git a/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/contraller/CommonFaCallbackController.java b/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/contraller/CommonFaCallbackController.java index 7068961..6f232d6 100644 --- a/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/contraller/CommonFaCallbackController.java +++ b/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/contraller/CommonFaCallbackController.java @@ -1,7 +1,10 @@ package com.api.aiyh_pcn.common_fadada.contraller; +import aiyh.utils.Util; import com.alibaba.fastjson.JSON; +import com.api.aiyh_pcn.common_fadada.service.CommonFaService; import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.apache.log4j.Logger; import javax.ws.rs.Consumes; import javax.ws.rs.POST; @@ -20,15 +23,35 @@ import java.util.Map; @Path("/common_fadada/callback") public class CommonFaCallbackController { - - @Path("/dealers/callback") - @POST - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_JSON) - public String dealersCallback(@RequestBody Map params) { - Map result = new HashMap<>(); - result.put("code", 200); - result.put("msg", "操作成功!"); - return JSON.toJSONString(result); - } + + private final CommonFaService service = new CommonFaService(); + private final Logger log = Util.getLogger(); + + @Path("/dealers/callback") + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String dealersCallback(@RequestBody Map params) { + Map result = new HashMap<>(); + result.put("code", 200); + result.put("msg", "操作成功!"); + return JSON.toJSONString(result); + } + + + @Path("/submit/callback") + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String submitCallback(@RequestBody Map params) { + Map result = new HashMap<>(); + result.put("code", 200); + result.put("msg", "操作成功!"); + try { + service.submitCallback(params); + } catch (Exception e) { + log.error("流程回调处理失败!" + Util.getErrString(e)); + } + return JSON.toJSONString(result); + } } diff --git a/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/service/CommonFaService.java b/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/service/CommonFaService.java index 87c7da8..1845275 100644 --- a/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/service/CommonFaService.java +++ b/src/main/youhong_ai_old_src/com/api/aiyh_pcn/common_fadada/service/CommonFaService.java @@ -3,6 +3,7 @@ package com.api.aiyh_pcn.common_fadada.service; import aiyh.utils.Util; import aiyh.utils.entity.WorkflowNodeConfig; import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.common.base.Strings; import org.jetbrains.annotations.Nullable; @@ -28,222 +29,234 @@ import java.util.Map; */ public class CommonFaService { - private final ActionMapper mapper = Util.getMapper(ActionMapper.class); - - public Map createContract(User user, Map params) { - List resultList = null; - try { - resultList = requestFaDaDa(user, params, new CreateContractService()); - } catch (JsonProcessingException e) { - throw new CustomerException("合同创建失败!"); - } - String requestId = String.valueOf(params.get("requestId")); - String workflowId = String.valueOf(params.get("workflowId")); - String contractNoField = String.valueOf(params.get("contractNoField")); - String billTable = Util.getMainTable(workflowId); - for (FaResultEntity result : resultList) { - writeBackContractNo(result, contractNoField, requestId, billTable); - } - return null; - } - - private void writeBackContractNo(FaResultEntity result, String contractNoField, String requestId, String billTable) { - Map entityMap = null; - try { - entityMap = result.getResponeVo().getEntityMap(); - } catch (JsonProcessingException e) { - throw new CustomerException("获取合同号失败,JSON转换错误"); - } - Map data = (Map) entityMap.get("data"); - String contractNo = String.valueOf(data.get("contractNo")); - if (result.getType() == 1) { + private final ActionMapper mapper = Util.getMapper(ActionMapper.class); + + public Map createContract(User user, Map params) { + List resultList = null; + try { + resultList = requestFaDaDa(user, params, new CreateContractService()); + } catch (JsonProcessingException e) { + throw new CustomerException("合同创建失败!"); + } + String requestId = String.valueOf(params.get("requestId")); + String workflowId = String.valueOf(params.get("workflowId")); + String contractNoField = String.valueOf(params.get("contractNoField")); + String billTable = Util.getMainTable(workflowId); + for (FaResultEntity result : resultList) { + writeBackContractNo(result, contractNoField, requestId, billTable); + } + return null; + } + + private void writeBackContractNo(FaResultEntity result, String contractNoField, String requestId, String billTable) { + Map entityMap = null; + try { + entityMap = result.getResponeVo().getEntityMap(); + } catch (JsonProcessingException e) { + throw new CustomerException("获取合同号失败,JSON转换错误"); + } + Map data = (Map) entityMap.get("data"); + String contractNo = String.valueOf(data.get("contractNo")); + if (result.getType() == 1) { // 回写主表 - boolean flag = mapper.updateContractInMainTable(billTable, contractNoField, contractNo, requestId); - if (!flag) { - throw new CustomerException("回写主表失败,更新语句执行false"); - } - return; - } + boolean flag = mapper.updateContractInMainTable(billTable, contractNoField, contractNo, requestId); + if (!flag) { + throw new CustomerException("回写主表失败,更新语句执行false"); + } + return; + } // 回写明细表 - mapper.updateContractInDetailTable(result.getDetailTable(), contractNoField, contractNo, String.valueOf(result.getDetailId())); - } - - - public Map pigeonholeContract(User user, Map params) { - List resultList = null; - try { - resultList = requestFaDaDa(user, params, new PigeonholeContractService()); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - for (FaResultEntity result : resultList) { - Map entityMap = null; - try { - entityMap = result.getResponeVo().getEntityMap(); - } catch (JsonProcessingException e) { - throw new CustomerException("合同归档失败!"); - } - String code = String.valueOf(entityMap.get("code")); - if (!"200".equals(code)) { - throw new CustomerException("合同归档失败!"); - } - } + mapper.updateContractInDetailTable(result.getDetailTable(), contractNoField, contractNo, String.valueOf(result.getDetailId())); + } + + + public Map pigeonholeContract(User user, Map params) { + List resultList = null; + try { + resultList = requestFaDaDa(user, params, new PigeonholeContractService()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + for (FaResultEntity result : resultList) { + Map entityMap = null; + try { + entityMap = result.getResponeVo().getEntityMap(); + } catch (JsonProcessingException e) { + throw new CustomerException("合同归档失败!"); + } + String code = String.valueOf(entityMap.get("code")); + if (!"200".equals(code)) { + throw new CustomerException("合同归档失败!"); + } + } // String requestId = String.valueOf(params.get("requestId")); // Util.submitWorkflow(Integer.valueOf(requestId), 1, "流程自动提交!"); - return null; - } - - public Map downloadContract(User user, Map params) { - List resultList = null; - try { - resultList = requestFaDaDa(user, params, new DownloadContractService()); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - String requestId = String.valueOf(params.get("requestId")); - String workflowId = String.valueOf(params.get("workflowId")); - String contractField = String.valueOf(params.get("contractField")); - int userId = user.getUID(); - for (FaResultEntity result : resultList) { - Map entityMap = null; - try { - entityMap = result.getResponeVo().getEntityMap(); - } catch (JsonProcessingException e) { - throw new CustomerException("合同签署失败!"); - } - String code = String.valueOf(entityMap.get("code")); - if (!"200".equals(code)) { - throw new CustomerException("合同签署失败!"); - } + return null; + } + + public Map downloadContract(User user, Map params) { + List resultList = null; + try { + resultList = requestFaDaDa(user, params, new DownloadContractService()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + String requestId = String.valueOf(params.get("requestId")); + String workflowId = String.valueOf(params.get("workflowId")); + String contractField = String.valueOf(params.get("contractField")); + int userId = user.getUID(); + for (FaResultEntity result : resultList) { + Map entityMap = null; + try { + entityMap = result.getResponeVo().getEntityMap(); + } catch (JsonProcessingException e) { + throw new CustomerException("合同签署失败!"); + } + String code = String.valueOf(entityMap.get("code")); + if (!"200".equals(code)) { + throw new CustomerException("合同签署失败!"); + } // 获取result中的responeVo中的imageFileId并命名为imageFileId - int imageFileId = result.getImageFileId(); + int imageFileId = result.getImageFileId(); // 调用Util中的方法获取目录id - writeBackContractFile(String.valueOf(imageFileId),result,contractField,workflowId,requestId,userId); - } - return null; - } - - private boolean writeBackContractFile(String imgFileId,FaResultEntity result,String contractField ,String workflowId,String requestId,int userId) { - if (result.getType() == 1) { + writeBackContractFile(String.valueOf(imageFileId), result, contractField, workflowId, requestId, userId); + } + return null; + } + + private boolean writeBackContractFile(String imgFileId, FaResultEntity result, String contractField, String workflowId, String requestId, int userId) { + if (result.getType() == 1) { // 回写到主表 - String docCategorys = Util.getDocCategorysByTable(workflowId, contractField,""); - String[] docCategoryArr = docCategorys.split(","); - int docId = 0; - try { - docId = Util.createDocByImageFileId(Integer.parseInt(docCategoryArr[docCategoryArr.length - 1]), Integer.parseInt(imgFileId),userId); - } catch (Exception e) { - throw new CustomerException("生成文档信息失败"); - } - String billTable = Util.getWorkflowMainTable(workflowId); - return mapper.updateContractInMainTable(billTable, contractField, String.valueOf(docId), requestId); - } - // 回写明细表 - String docCategorys = Util.getDocCategorysByTable(workflowId, contractField, result.getDetailTable()); - String[] docCategoryArr = docCategorys.split(","); - int docId = 0; - try { - docId = Util.createDocByImageFileId(Integer.parseInt(docCategoryArr[docCategoryArr.length - 1]), Integer.parseInt(imgFileId),userId); - } catch (Exception e) { - throw new CustomerException("生成文档信息失败"); - } - return mapper.updateContractInDetailTable(result.getDetailTable(), contractField, String.valueOf(docId), String.valueOf(result.getDetailId())); - } - - public Map signOneself(User user, Map params) { - List resultList = null; - try { - resultList = requestFaDaDa(user, params, new OneselfSignContractService()); - } catch (JsonProcessingException e) { - throw new CustomerException("合同签署失败!"); - } - for (FaResultEntity result : resultList) { - Map entityMap = null; - try { - entityMap = result.getResponeVo().getEntityMap(); - } catch (JsonProcessingException e) { - throw new CustomerException("合同签署失败!"); - } - String code = String.valueOf(entityMap.get("code")); - if (!"200".equals(code)) { - throw new CustomerException("合同签署失败!"); - } - } + String docCategorys = Util.getDocCategorysByTable(workflowId, contractField, ""); + String[] docCategoryArr = docCategorys.split(","); + int docId = 0; + try { + docId = Util.createDocByImageFileId(Integer.parseInt(docCategoryArr[docCategoryArr.length - 1]), Integer.parseInt(imgFileId), userId); + } catch (Exception e) { + throw new CustomerException("生成文档信息失败"); + } + String billTable = Util.getWorkflowMainTable(workflowId); + return mapper.updateContractInMainTable(billTable, contractField, String.valueOf(docId), requestId); + } + // 回写明细表 + String docCategorys = Util.getDocCategorysByTable(workflowId, contractField, result.getDetailTable()); + String[] docCategoryArr = docCategorys.split(","); + int docId = 0; + try { + docId = Util.createDocByImageFileId(Integer.parseInt(docCategoryArr[docCategoryArr.length - 1]), Integer.parseInt(imgFileId), userId); + } catch (Exception e) { + throw new CustomerException("生成文档信息失败"); + } + return mapper.updateContractInDetailTable(result.getDetailTable(), contractField, String.valueOf(docId), String.valueOf(result.getDetailId())); + } + + public Map signOneself(User user, Map params) { + List resultList = null; + try { + resultList = requestFaDaDa(user, params, new OneselfSignContractService()); + } catch (JsonProcessingException e) { + throw new CustomerException("合同签署失败!"); + } + for (FaResultEntity result : resultList) { + Map entityMap = null; + try { + entityMap = result.getResponeVo().getEntityMap(); + } catch (JsonProcessingException e) { + throw new CustomerException("合同签署失败!"); + } + String code = String.valueOf(entityMap.get("code")); + if (!"200".equals(code)) { + throw new CustomerException("合同签署失败!"); + } + } // String requestId = String.valueOf(params.get("requestId")); // Util.submitWorkflow(Integer.valueOf(requestId),1,"流程自动提交!"); - return null; - } - - public Map signContract(User user, Map params) { - List resultList = null; - try { - resultList = requestFaDaDa(user, params, new SignContractService()); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } - for (FaResultEntity result : resultList) { - Map entityMap = null; - try { - entityMap = result.getResponeVo().getEntityMap(); - } catch (JsonProcessingException e) { - throw new CustomerException("合同签署失败!"); - } - String code = String.valueOf(entityMap.get("code")); - if (!"200".equals(code)) { - throw new CustomerException("合同签署失败!"); - } - } - return null; - } - - @Nullable - private List requestFaDaDa(User user, Map params, IFaIntegration utilService) throws JsonProcessingException { - String requestId = String.valueOf(params.get("requestId")); - String workflowId = String.valueOf(params.get("workflowId")); - int userId = user.getUID(); - return utilService.execute(workflowId, requestId, userId); - } - - /** - * 重新推送合同数据到d-flow - * @param user 当前用户 - * @param params 请求参数 - */ - public void resignContract(User user, Map params) { - String requestId = Util.null2DefaultStr(params.get("requestId"), ""); - String dealersConfigMark = Util.null2String(params.get("dealersConfigMark")); - String apiKey = Util.null2String(params.get("apiKey")); - if(Strings.isNullOrEmpty(requestId) || Strings.isNullOrEmpty(dealersConfigMark) || Strings.isNullOrEmpty(apiKey)) { - throw new CustomerException("请求参数不能为空!"); - } - RequestService requestService = new RequestService(); - RequestInfo req = requestService.getRequest(Integer.parseInt(requestId)); - req.getRequestManager().setUser(user); - PushContractInfoAction pushContractInfoAction = new PushContractInfoAction(); - pushContractInfoAction.setApikey(apiKey); - pushContractInfoAction.setDealersConfigMark(dealersConfigMark); - try { - String execute = pushContractInfoAction.execute(req); - if(Action.FAILURE_AND_CONTINUE.equals(execute)) { - throw new CustomerException("重新推送合同数据到d-flow失败!"); - } - }catch (Exception e){ - throw new CustomerException("重新推送合同数据到d-flow失败!",e); - } - } - - public Map getContractButton(String workflowId,String markOnly) { - String allVersion = WorkflowVersion.getVersionStringByWfid(workflowId); - WorkflowNodeConfig workflowNodeConfig = Util.selectNodeConfig(allVersion,markOnly); - Util.getLogger().info("查询到的数据:" + workflowNodeConfig); - if(workflowNodeConfig == null){ - return null; - } - String workflowType = workflowNodeConfig.getWorkflowType(); - allVersion = WorkflowVersion.getVersionStringByWfid(workflowType); - Map map = new HashMap<>(8); - map.put("nodes", workflowNodeConfig.getWorkflowNodes().split(",")); - map.put("allVersion", allVersion.split(",")); - Util.getLogger().info("最终数据:" + map); - return map; - } + return null; + } + + public Map signContract(User user, Map params) { + List resultList = null; + try { + resultList = requestFaDaDa(user, params, new SignContractService()); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + for (FaResultEntity result : resultList) { + Map entityMap = null; + try { + entityMap = result.getResponeVo().getEntityMap(); + } catch (JsonProcessingException e) { + throw new CustomerException("合同签署失败!"); + } + String code = String.valueOf(entityMap.get("code")); + if (!"200".equals(code)) { + throw new CustomerException("合同签署失败!"); + } + } + return null; + } + + @Nullable + private List requestFaDaDa(User user, Map params, IFaIntegration utilService) throws JsonProcessingException { + String requestId = String.valueOf(params.get("requestId")); + String workflowId = String.valueOf(params.get("workflowId")); + int userId = user.getUID(); + return utilService.execute(workflowId, requestId, userId); + } + + /** + * 重新推送合同数据到d-flow + * + * @param user 当前用户 + * @param params 请求参数 + */ + public void resignContract(User user, Map params) { + String requestId = Util.null2DefaultStr(params.get("requestId"), ""); + String dealersConfigMark = Util.null2String(params.get("dealersConfigMark")); + String apiKey = Util.null2String(params.get("apiKey")); + if (Strings.isNullOrEmpty(requestId) || Strings.isNullOrEmpty(dealersConfigMark) || Strings.isNullOrEmpty(apiKey)) { + throw new CustomerException("请求参数不能为空!"); + } + RequestService requestService = new RequestService(); + RequestInfo req = requestService.getRequest(Integer.parseInt(requestId)); + req.getRequestManager().setUser(user); + PushContractInfoAction pushContractInfoAction = new PushContractInfoAction(); + pushContractInfoAction.setApikey(apiKey); + pushContractInfoAction.setDealersConfigMark(dealersConfigMark); + try { + String execute = pushContractInfoAction.execute(req); + if (Action.FAILURE_AND_CONTINUE.equals(execute)) { + throw new CustomerException("重新推送合同数据到d-flow失败!"); + } + } catch (Exception e) { + throw new CustomerException("重新推送合同数据到d-flow失败!", e); + } + } + + public Map getContractButton(String workflowId, String markOnly) { + String allVersion = WorkflowVersion.getVersionStringByWfid(workflowId); + WorkflowNodeConfig workflowNodeConfig = Util.selectNodeConfig(allVersion, markOnly); + Util.getLogger().info("查询到的数据:" + workflowNodeConfig); + if (workflowNodeConfig == null) { + return null; + } + String workflowType = workflowNodeConfig.getWorkflowType(); + allVersion = WorkflowVersion.getVersionStringByWfid(workflowType); + Map map = new HashMap<>(8); + map.put("nodes", workflowNodeConfig.getWorkflowNodes().split(",")); + map.put("allVersion", allVersion.split(",")); + Util.getLogger().info("最终数据:" + map); + return map; + } + + public void submitCallback(Map params) { + String contractNo = Util.null2String(params.get("docNo")); + String requestId = mapper.selectRequestId(contractNo); + RequestService requestService = new RequestService(); + RequestInfo request = requestService.getRequest(Integer.parseInt(requestId)); + boolean b = requestService.nextNodeBySubmit(request, Integer.parseInt(requestId), 1, "auto submit for callback !"); + if (!b) { + Util.getLogger().error("回调流程自动提交失败!" + JSON.toJSONString(params)); + } + } } diff --git a/src/main/youhong_ai_old_src/com/api/supportCenter/controller/MobileController.java b/src/main/youhong_ai_old_src/com/api/supportCenter/controller/MobileController.java new file mode 100644 index 0000000..d56c181 --- /dev/null +++ b/src/main/youhong_ai_old_src/com/api/supportCenter/controller/MobileController.java @@ -0,0 +1,85 @@ +package com.api.supportCenter.controller; + +import com.alibaba.fastjson.JSON; +import com.api.supportCenter.service.Impl.SupportServiceImpl; +import com.api.supportCenter.service.SupportService; +import com.engine.common.service.HrmCommonService; +import com.engine.common.service.impl.HrmCommonServiceImpl; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Path("/MobileController") +public class MobileController { + BaseBean baseBean=new BaseBean(); + @POST + @Path("/getCount") + public String getCount(@Context HttpServletRequest request, @Context HttpServletResponse response){ + HashMap map=new HashMap<>(); + SupportService supportService=new SupportServiceImpl(); + //45\35角色ID权限验证 + String roleid1 = request.getParameter("roleid1"); + String roleid2 = request.getParameter("roleid2"); + HashMap result=new HashMap<>(); + User user = HrmUserVarify.getUser(request, response); + HrmCommonService hrmCommonService = new HrmCommonServiceImpl(); + //获得人员的所有角色 + String roleids = hrmCommonService.getRoleIds(user.getUID()); + baseBean.writeLog("当前人名称"+user.getUsername()+"当前人员所有角色"+roleids); + //符合条件 + RecordSet rs=new RecordSet(); + + if(roleids.indexOf(roleid1)>0||roleids.indexOf(roleid2)>0 || user.getUID()==1){ + List xiafa = supportService.currWeekxiafa(String.valueOf(user.getUID())); + map.put("num1", xiafa.get(0)); + map.put("num2", xiafa.get(1)); + map.put("num3", xiafa.get(2)); + map.put("num4", xiafa.get(3)); + result.put("code",200); + result.put("message","返回成功"); + result.put("datas",map); + }else{//40 45不为的时候提示没有权限 + result.put("code",-1); + result.put("message","没有营运日历中心访问权限"); + } + + return JSON.toJSONString(result); + } + @GET + @Path("/getListBySearch") + public String getListBySearch(@Context HttpServletRequest request, @Context HttpServletResponse response) throws Exception { + SupportService supportService=new SupportServiceImpl(); + User user = HrmUserVarify.getUser(request, response); +// HrmCommonService hrmCommonService = new HrmCommonServiceImpl(); + HashMap result=new HashMap<>(); + String taskTitle = request.getParameter("TaskTitle");//任务标题 + String creator = request.getParameter("Creator");//执行人 + String stopTime = request.getParameter("StopTime");//截止时间 + String taskStatus = request.getParameter("TaskStatus");//任务状态 + String type=request.getParameter("type"); + try { + ArrayList listBySearch = supportService.getListBySearch(String.valueOf(user.getUID()), taskTitle, creator, stopTime, taskStatus,type); + (new BaseBean()).writeLog("查询输出listBySearch"+JSON.toJSONString(listBySearch)); + result.put("data",listBySearch); + result.put("code","success"); + result.put("message","访问成功"); + (new BaseBean()).writeLog("查询输出result"+JSON.toJSONString(result)); + + }catch (Exception e){ + result.put("code","faild"); + result.put("message",e.toString()); + } + return JSON.toJSONString(result); + } +} diff --git a/src/main/youhong_ai_old_src/com/api/supportCenter/controller/SupportAction.java b/src/main/youhong_ai_old_src/com/api/supportCenter/controller/SupportAction.java new file mode 100644 index 0000000..7f0a786 --- /dev/null +++ b/src/main/youhong_ai_old_src/com/api/supportCenter/controller/SupportAction.java @@ -0,0 +1,258 @@ +package com.api.supportCenter.controller; + +import com.api.supportCenter.service.Impl.SupportServiceImpl; +import com.api.supportCenter.service.SupportService; +import com.icbc.api.internal.util.internal.util.fastjson.JSON; +import net.sf.json.JSONArray; +import weaver.general.BaseBean; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; + +@Path("/supportcenter") +public class SupportAction { + SupportService supportService=new SupportServiceImpl(); + //获取酒店任务完成前10名(根据月) + @GET + @Path("/getTopTenForMonth") + public String getTopTenForMonth(@Context HttpServletRequest request,@Context HttpServletResponse response){ + String tenBeforeByMonth = supportService.getTenBeforeByMonth(); + return tenBeforeByMonth; + } + //获取酒店任务完成前10名(根据年) + @GET + @Path("/getTopTenForYear") + public String getTopTenForYear(@Context HttpServletRequest request,@Context HttpServletResponse response){ + String tenBeforeByYear = supportService.getTenBeforeByYear(); + return tenBeforeByYear; + } + //获取酒店任务完成后10名(根据月) + @GET + @Path("/getLastTenForMonth") + public String getLastTenForMonth(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String tenAfterByMonth = supportService.getTenAfterByMonth(); + return tenAfterByMonth; + } + //获取酒店任务完成后10名(根据年) + @GET + @Path("/getLastTenForYear") + public String getLastTenForYear(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String tenAfterByYear = supportService.getTenAfterByYear(); + return tenAfterByYear; + } + //任务完成排名 + @GET + @Path("/getTaskElementByMonth") //√ + public Object getTaskElementByMonth(@Context HttpServletRequest request, @Context HttpServletResponse response){ + Object taskElementByMonth = supportService.getTaskElementByMonth(); + return taskElementByMonth; + } + //任务完成排名(全部) + @GET + @Path("/getTaskElementByYear") //√ + public Object getTaskElementByYear(@Context HttpServletRequest request, @Context HttpServletResponse response){ + Object taskElementByYear = supportService.getTaskElementByYear(); + return taskElementByYear; + } + //日常工作任务 + @GET + @Path("/daliyTaskBag")//√ + public String daliyTaskBag(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String s = supportService.daliyTaskBag(); + return s; + } + //开业任务节点(全部) + @GET + @Path("/openTaskNode")//√ + public String openTaskNode(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String s = supportService.openTaskNode(); + return s; + } + //开业筹备进度(当前酒店) + @GET + @Path("/openload") //√ + public String openload(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String jdcode = request.getParameter("jdcode"); + String openload = supportService.openload(jdcode); + return openload; + } + //日程日历 + @GET + @Path("/getWorkplan") //√ + public String getWorkplan(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getworkplan(id); + return res; + } + + //延期任务量(支持中心/总经理) + @GET + @Path("/getdelayTask") //√ + public String getdelayTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getdelayTask(id); + return res; + } + //每日任务达成率 + @GET + @Path("/getdaliyTask") //√ + public String getdaliyTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getdaliyTask(id); + return res; + } + //本年任务达成率 + @GET + @Path("/getYearTask") //√ + public String getYearTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getYearTask(id); + return res; + } + //开业筹备延期任务量(支持中心/总经理) + @GET + @Path("/getPreDelayTask") //√ + public String getPreDelayTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getPreDelayTask(id); + return res; + } + //开业筹备今日任务量 + @GET + @Path("/getPreDaliyTask") //√ + public String getPreDaliyTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getPreDaliyTask(id); + return res; + } + //开业筹备任务达标率 + @GET + @Path("/getPreTaskRate") //√ + public String getPreTaskRate(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getPreTaskRate(id); + return res; + } + //待办任务 + @GET + @Path("/getNotStartTask") //√ + public String getNotStartTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + + String res = supportService.getNotStartTask(id); + return res; + } + //进行中任务 + @GET + @Path("/getOnGoingTask") //√ + public String getOnGoingTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getOnGoingTask(id); + return res; + } + //获取转办延期任务 + @GET + @Path("/getComplaintDelayTask") + public String getComplaintDelayTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getComplaintDelayTask(id); + return res; + } + //获取转办待办任务 + @GET + @Path("/getComplaintNotStartTask") + public String getComplaintNotStartTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getComplaintNotStartTask(id); + return res; + } + //获取转办进行中任务 + @GET + @Path("/getComplaintOnGoingTask") + public String getComplaintOnGoingTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getComplaintOnGoingTask(id); + return res; + } + //修改需求-逾期任务量 + @GET + @Path("/newgetTask") //√ + public String newgetdelayTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String stau=request.getParameter("stau"); + String id = request.getParameter("id"); + String res = supportService.newgetdelayTask(stau,id); + return res; + } + @GET + @Path("/zjnewgetTask") //√ + public String zjnewgetTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String stau=request.getParameter("stau"); + String id = request.getParameter("id"); + String res = supportService.zjnewgetdelayTask(stau,id); + return res; + } + //新日常工作任务 + @GET + @Path("/newdaliyTaskBag")//√ + public String newdaliyTaskBag(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String jdcode=request.getParameter("jdcode"); + String s = supportService.newdaliyTaskBag(jdcode); + return s; + } + //本周需完成任务 + @GET + @Path("/currWeekTask")//√ + public String currWeekTask(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String jdcode=request.getParameter("id"); + String s = supportService.currWeekTask(jdcode); + return s; + } + @GET + @Path("/newgetWorkplan") //√ + public String newgetWorkplan(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String id = request.getParameter("id"); + String res = supportService.getworkplan(id); + return res; + } + @POST + @Path("/getnewWorkplan") //√ + public String getnewWorkplan(@Context HttpServletRequest request, @Context HttpServletResponse response) { + BaseBean baseBean=new BaseBean(); + String events = request.getParameter("events"); + String currentDate = request.getParameter("currentDate"); + JSONArray list= JSONArray.fromObject(events); + String res = supportService.getnewWorkplan(list,currentDate); +// baseBean.writeLog("=================================>"+list.toString()); + return JSON.toJSONString(res); + } + //区域酒店开业数量 + @GET + @Path("/codeky")//√ + public String codeky(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String region=request.getParameter("region"); + String s = supportService.codeky(region); + return s; + } + //空缺总经理 + @GET + @Path("/emptyMananger")//√ + public String emptyMananger(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String s = supportService.emptyMananger(); + return s; + } + //进行中任务 + @GET + @Path("/zhichiOnGoing") //√ + public String zhichiOnGoing(@Context HttpServletRequest request, @Context HttpServletResponse response){ + String res = supportService.zhichiOnGoing(); + return res; + } + + + + +} diff --git a/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/ChartBean.java b/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/ChartBean.java new file mode 100644 index 0000000..9e14506 --- /dev/null +++ b/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/ChartBean.java @@ -0,0 +1,71 @@ +package com.api.supportCenter.pojo; + +import org.jetbrains.annotations.NotNull; + +public class ChartBean implements Comparable{ + public String num; + public String childnum; + public String jdname; + public String jdcode; + public String comrate; + + @Override + public String toString() { + return "ChartBean{" + + "num='" + num + '\'' + + ", childnum='" + childnum + '\'' + + ", jdname='" + jdname + '\'' + + ", jdcode='" + jdcode + '\'' + + ", comrate='" + comrate + '\'' + + '}'; + } + + public String getNum() { + return num; + } + + public void setNum(String num) { + this.num = num; + } + + public String getChildnum() { + return childnum; + } + + public void setChildnum(String childnum) { + this.childnum = childnum; + } + + public String getJdname() { + return jdname; + } + + public void setJdname(String jdname) { + this.jdname = jdname; + } + + public String getJdcode() { + return jdcode; + } + + public void setJdcode(String jdcode) { + this.jdcode = jdcode; + } + + public String getComrate() { + return comrate; + } + + public void setComrate(String comrate) { + this.comrate = comrate; + } + + public ChartBean() { + } + + @Override + public int compareTo(@NotNull ChartBean o) { + return Double.compare(Double.parseDouble(this.getComrate()),Double.parseDouble(o.getComrate())); + } + +} diff --git a/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/MobileEvents.java b/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/MobileEvents.java new file mode 100644 index 0000000..26cd58b --- /dev/null +++ b/src/main/youhong_ai_old_src/com/api/supportCenter/pojo/MobileEvents.java @@ -0,0 +1,247 @@ +package com.api.supportCenter.pojo; + +public class MobileEvents { + String remindTimeBeforeEnd; + String remindTimesBeforeStart; + String address; + String color; + String remindDateBeforeEnd; + String workPlanTypeName; + String endDate; + String remindDateBeforeStart; + String planName; + String remindBeforeEnd; + String beginDate; + String urgentLevel; + String remindTimeBeforeStart; + String remindTimesBeforeEnd; + String workplanType; + String remindBeforeStart; + String id; + String beginTime; + String endTime; + String remindTypeName; + String remindType; + + public MobileEvents() { + } + + @Override + public String toString() { + return "MobileEvents{" + + "remindTimeBeforeEnd='" + remindTimeBeforeEnd + '\'' + + ", remindTimesBeforeStart='" + remindTimesBeforeStart + '\'' + + ", address='" + address + '\'' + + ", color='" + color + '\'' + + ", remindDateBeforeEnd='" + remindDateBeforeEnd + '\'' + + ", workPlanTypeName='" + workPlanTypeName + '\'' + + ", endDate='" + endDate + '\'' + + ", remindDateBeforeStart='" + remindDateBeforeStart + '\'' + + ", planName='" + planName + '\'' + + ", remindBeforeEnd='" + remindBeforeEnd + '\'' + + ", beginDate='" + beginDate + '\'' + + ", urgentLevel='" + urgentLevel + '\'' + + ", remindTimeBeforeStart='" + remindTimeBeforeStart + '\'' + + ", remindTimesBeforeEnd='" + remindTimesBeforeEnd + '\'' + + ", workplanType='" + workplanType + '\'' + + ", remindBeforeStart='" + remindBeforeStart + '\'' + + ", id='" + id + '\'' + + ", beginTime='" + beginTime + '\'' + + ", endTime='" + endTime + '\'' + + ", remindTypeName='" + remindTypeName + '\'' + + ", remindType='" + remindType + '\'' + + '}'; + } + + public void setRemindTimeBeforeEnd(String remindTimeBeforeEnd) { + this.remindTimeBeforeEnd = remindTimeBeforeEnd; + } + + public void setRemindTimesBeforeStart(String remindTimesBeforeStart) { + this.remindTimesBeforeStart = remindTimesBeforeStart; + } + + public void setAddress(String address) { + this.address = address; + } + + public void setColor(String color) { + this.color = color; + } + + public void setRemindDateBeforeEnd(String remindDateBeforeEnd) { + this.remindDateBeforeEnd = remindDateBeforeEnd; + } + + public void setWorkPlanTypeName(String workPlanTypeName) { + this.workPlanTypeName = workPlanTypeName; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } + + public void setRemindDateBeforeStart(String remindDateBeforeStart) { + this.remindDateBeforeStart = remindDateBeforeStart; + } + + public void setPlanName(String planName) { + this.planName = planName; + } + + public void setRemindBeforeEnd(String remindBeforeEnd) { + this.remindBeforeEnd = remindBeforeEnd; + } + + public void setBeginDate(String beginDate) { + this.beginDate = beginDate; + } + + public void setUrgentLevel(String urgentLevel) { + this.urgentLevel = urgentLevel; + } + + public void setRemindTimeBeforeStart(String remindTimeBeforeStart) { + this.remindTimeBeforeStart = remindTimeBeforeStart; + } + + public void setRemindTimesBeforeEnd(String remindTimesBeforeEnd) { + this.remindTimesBeforeEnd = remindTimesBeforeEnd; + } + + public void setWorkplanType(String workplanType) { + this.workplanType = workplanType; + } + + public void setRemindBeforeStart(String remindBeforeStart) { + this.remindBeforeStart = remindBeforeStart; + } + + public void setId(String id) { + this.id = id; + } + + public void setBeginTime(String beginTime) { + this.beginTime = beginTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public void setRemindTypeName(String remindTypeName) { + this.remindTypeName = remindTypeName; + } + + public void setRemindType(String remindType) { + this.remindType = remindType; + } + + public String getRemindTimeBeforeEnd() { + return remindTimeBeforeEnd; + } + + public String getRemindTimesBeforeStart() { + return remindTimesBeforeStart; + } + + public String getAddress() { + return address; + } + + public String getColor() { + return color; + } + + public String getRemindDateBeforeEnd() { + return remindDateBeforeEnd; + } + + public String getWorkPlanTypeName() { + return workPlanTypeName; + } + + public String getEndDate() { + return endDate; + } + + public String getRemindDateBeforeStart() { + return remindDateBeforeStart; + } + + public String getPlanName() { + return planName; + } + + public String getRemindBeforeEnd() { + return remindBeforeEnd; + } + + public String getBeginDate() { + return beginDate; + } + + public String getUrgentLevel() { + return urgentLevel; + } + + public String getRemindTimeBeforeStart() { + return remindTimeBeforeStart; + } + + public String getRemindTimesBeforeEnd() { + return remindTimesBeforeEnd; + } + + public String getWorkplanType() { + return workplanType; + } + + public String getRemindBeforeStart() { + return remindBeforeStart; + } + + public String getId() { + return id; + } + + public String getBeginTime() { + return beginTime; + } + + public String getEndTime() { + return endTime; + } + + public String getRemindTypeName() { + return remindTypeName; + } + + public String getRemindType() { + return remindType; + } + + public MobileEvents(String remindTimeBeforeEnd, String remindTimesBeforeStart, String address, String color, String remindDateBeforeEnd, String workPlanTypeName, String endDate, String remindDateBeforeStart, String planName, String remindBeforeEnd, String beginDate, String urgentLevel, String remindTimeBeforeStart, String remindTimesBeforeEnd, String workplanType, String remindBeforeStart, String id, String beginTime, String endTime, String remindTypeName, String remindType) { + this.remindTimeBeforeEnd = remindTimeBeforeEnd; + this.remindTimesBeforeStart = remindTimesBeforeStart; + this.address = address; + this.color = color; + this.remindDateBeforeEnd = remindDateBeforeEnd; + this.workPlanTypeName = workPlanTypeName; + this.endDate = endDate; + this.remindDateBeforeStart = remindDateBeforeStart; + this.planName = planName; + this.remindBeforeEnd = remindBeforeEnd; + this.beginDate = beginDate; + this.urgentLevel = urgentLevel; + this.remindTimeBeforeStart = remindTimeBeforeStart; + this.remindTimesBeforeEnd = remindTimesBeforeEnd; + this.workplanType = workplanType; + this.remindBeforeStart = remindBeforeStart; + this.id = id; + this.beginTime = beginTime; + this.endTime = endTime; + this.remindTypeName = remindTypeName; + this.remindType = remindType; + } +} diff --git a/src/main/youhong_ai_old_src/com/api/supportCenter/service/Impl/SupportServiceImpl.java b/src/main/youhong_ai_old_src/com/api/supportCenter/service/Impl/SupportServiceImpl.java new file mode 100644 index 0000000..da4749c --- /dev/null +++ b/src/main/youhong_ai_old_src/com/api/supportCenter/service/Impl/SupportServiceImpl.java @@ -0,0 +1,1671 @@ +package com.api.supportCenter.service.Impl; + +import com.api.supportCenter.pojo.ChartBean; +import com.api.supportCenter.service.SupportService; +import com.icbc.api.internal.util.internal.util.fastjson.JSON; +import com.icbc.api.internal.util.internal.util.fastjson.JSONObject; +import com.weaver.general.BaseBean; +import net.sf.json.JSONArray; +import org.apache.commons.lang3.StringUtils; +import weaver.conn.RecordSet; +import weaver.hrm.resource.ResourceComInfo; + +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +public class SupportServiceImpl implements SupportService { + BaseBean baseBean = new BaseBean(); + @Override + public String getTenBeforeByMonth() { + + //全部任务 + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + //获取酒店 任务总量、名称、jdcode + boolean execute = rs1.execute("select count(r.jdcode) as num,h.hotelnamezh as jdname,r.jdcode from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where DATE_FORMAT(r.modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m') and jdcode!='' or jdcode!=null group by r.jdcode"); + rs1.next(); + ArrayList list = new ArrayList<>(); + if(execute){//查询成功 + if (rs1.getArray().size() > 0) {//总数、酒店名称、jdcode + for (int i = 0; i < rs1.getArray().size(); i++) { + ChartBean chartBean = new ChartBean(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + String jdcode = rs1.getString("jdcode"); + chartBean.setNum(num); + chartBean.setJdcode(jdcode); + if(!"".equals("jdname") && jdname!=null){ + chartBean.setJdname(jdname); + }else{ + chartBean.setJdname("未填写"); + } + boolean execute1 = rs2.execute("select count(jdcode) as num,jdcode from view_totallist where DATE_FORMAT(modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m') and rwzt='2' and jdcode!='' group by jdcode"); + rs2.next(); + boolean flag=true; + int rsg=rs2.getArray().size(); +// baseBean.writeLog("长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度"+rs2.getArray().size()); + if (rs2.getArray().size() > 0&&execute1) {//已完成和jdcode + for (int j = 0; j < rs2.getArray().size(); j++) { + +// baseBean.writeLog("循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环"+j); + String num1 = rs2.getString("num"); + String jdcode1 = rs2.getString("jdcode"); +// baseBean.writeLog(jdcode1+"--------------------"+ jdcode); + if (jdcode1.equals(jdcode)) {//如果同一酒店标识 + chartBean.setChildnum(num1); +// baseBean.writeLog("chartBean==================>"+chartBean.toString()); + //完成率 + Double comrate = Double.parseDouble(num1) / Double.parseDouble(num) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + chartBean.setComrate(df.format(comrate)); + list.add(chartBean); + rs2.next(); + flag=false; + break; + } else { + rs2.next(); + } + } + } else {//如果r2没有值 + continue; + } + if(flag){ + chartBean.setChildnum("0"); + chartBean.setComrate("0.00"); + list.add(chartBean); + } + rs1.next(); + } + list.sort(Comparator.comparing(ChartBean::getComrate)); + } else { + return JSON.toJSONString(list); + } + }else{//对应查询sql是否成功 + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + +// rs1.execute("select count(r.jdcode) as num,h.hotelnamezh as jdname,r.jdcode from uf_rwwcqd as r left join uf_hotelinfo as h on r.jdcode=h.holidex WHERE YEAR(r.modedatacreatedate)=YEAR(NOW()) group by r.jdcode"); +// rs2.execute("select count(jdcode) as num,jdcode from uf_rwwcqd where rwzt='2' group by jdcode"); + @Override + public String getTenBeforeByYear() { + //全部任务 + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + //获取酒店 任务总量、名称、jdcode + boolean execute = rs1.execute("select count(r.jdcode) as num,h.hotelnamezh as jdname,r.jdcode from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where YEAR(r.modedatacreatedate)=YEAR(NOW()) and jdcode!='' or jdcode!=null group by r.jdcode"); + + rs1.next(); + ArrayList list = new ArrayList<>(); + if(execute){//查询成功 + if (rs1.getArray().size() > 0) {//总数、酒店名称、jdcode + for (int i = 0; i < rs1.getArray().size(); i++) { + ChartBean chartBean = new ChartBean(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + String jdcode = rs1.getString("jdcode"); + chartBean.setNum(num); + chartBean.setJdcode(jdcode); + if(!"".equals("jdname") && jdname!=null){ + chartBean.setJdname(jdname); + }else{ + chartBean.setJdname("未填写"); + } + boolean execute1 = rs2.execute("select count(jdcode) as num,jdcode from view_totallist where YEAR(modedatacreatedate)=YEAR(NOW()) and rwzt='2' and jdcode!='' group by jdcode"); + rs2.next(); + boolean flag=true; +// baseBean.writeLog("长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度"+rs2.getArray().size()); + if (rs2.getArray().size() > 0&&execute1) {//已完成和jdcode + for (int j = 0; j < rs2.getArray().size(); j++) { + +// baseBean.writeLog("循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环"+j); + String num1 = rs2.getString("num"); + String jdcode1 = rs2.getString("jdcode"); +// baseBean.writeLog(jdcode1+"--------------------"+ jdcode); + if (jdcode1.equals(jdcode)) {//如果同一酒店标识 + chartBean.setChildnum(num1); +// baseBean.writeLog("chartBean==================>"+chartBean.toString()); + //完成率 + Double comrate = Double.parseDouble(num1) / Double.parseDouble(num) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + chartBean.setComrate(df.format(comrate)); + list.add(chartBean); + rs2.next(); + flag=false; + break; + } else { + rs2.next(); + } + } + } else {//如果r2没有值 + continue; + } + if(flag){ + chartBean.setChildnum("0"); + chartBean.setComrate("0.00"); + list.add(chartBean); + } + rs1.next(); + } + list.sort(Comparator.comparing(ChartBean::getComrate)); + } else { + return JSON.toJSONString(list); + } + }else{//对应查询sql是否成功 + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + + @Override + public String getTenAfterByMonth() { +// BaseBean baseBean = new BaseBean(); + //全部任务 + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + //获取酒店 任务总量、名称、jdcode + boolean execute = rs1.execute("select count(r.jdcode) as num,h.hotelnamezh as jdname,r.jdcode from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where DATE_FORMAT(r.modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m') and jdcode!='' or jdcode!=null group by r.jdcode"); + rs1.next(); + ArrayList list = new ArrayList<>(); + if(execute){//查询成功 + if (rs1.getArray().size() > 0) {//总数、酒店名称、jdcode + for (int i = 0; i < rs1.getArray().size(); i++) { + ChartBean chartBean = new ChartBean(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + String jdcode = rs1.getString("jdcode"); + chartBean.setNum(num); + chartBean.setJdcode(jdcode); + if(!"".equals("jdname") && jdname!=null){ + chartBean.setJdname(jdname); + }else{ + chartBean.setJdname("未填写"); + } + boolean execute1 = rs2.execute("select count(jdcode) as num,jdcode from view_totallist where DATE_FORMAT(modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m') and rwzt='2' and jdcode!='' group by jdcode"); + rs2.next(); + boolean flag=true; +// baseBean.writeLog("长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度"+rs2.getArray().size()); + if (rs2.getArray().size() > 0&&execute1) {//已完成和jdcode + for (int j = 0; j < rs2.getArray().size(); j++) { + +// baseBean.writeLog("循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环"+j); + String num1 = rs2.getString("num"); + String jdcode1 = rs2.getString("jdcode"); +// baseBean.writeLog(jdcode1+"--------------------"+ jdcode); + if (jdcode1.equals(jdcode)) {//如果同一酒店标识 + chartBean.setChildnum(num1); +// baseBean.writeLog("chartBean==================>"+chartBean.toString()); + //完成率 + Double comrate = Double.parseDouble(num1) / Double.parseDouble(num) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + chartBean.setComrate(df.format(comrate)); + list.add(chartBean); + rs2.next(); + flag=false; + break; + } else { + rs2.next(); + } + } + } else {//如果r2没有值 + continue; + } + if(flag){ + chartBean.setChildnum("0"); + chartBean.setComrate("0.00"); + list.add(chartBean); + } + rs1.next(); + } + list.sort(Comparator.comparing(ChartBean::getComrate)); + } else { + return JSON.toJSONString(list); + } + }else{//对应查询sql是否成功 + return JSON.toJSONString(list); + } +// baseBean.writeLog("list=====================>"+list); + return JSON.toJSONString(list); + } + + @Override + public String getTenAfterByYear() { + //全部任务 + RecordSet rs1 = new RecordSet(); + RecordSet rs2 = new RecordSet(); + //获取酒店 任务总量、名称、jdcode + boolean execute = rs1.execute("select count(r.jdcode) as num,h.hotelnamezh as jdname,r.jdcode from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where YEAR(r.modedatacreatedate)=YEAR(NOW()) and jdcode!='' or jdcode!=null group by r.jdcode"); + + rs1.next(); + ArrayList list = new ArrayList<>(); + if(execute){//查询成功 + if (rs1.getArray().size() > 0) {//总数、酒店名称、jdcode + for (int i = 0; i < rs1.getArray().size(); i++) { + ChartBean chartBean = new ChartBean(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + String jdcode = rs1.getString("jdcode"); + chartBean.setNum(num); + chartBean.setJdcode(jdcode); + if(!"".equals("jdname") && jdname!=null){ + chartBean.setJdname(jdname); + }else{ + chartBean.setJdname("未填写"); + } + boolean execute1 = rs2.execute("select count(jdcode) as num,jdcode from view_totallist where YEAR(modedatacreatedate)=YEAR(NOW()) and rwzt='2' and jdcode!='' group by jdcode"); + rs2.next(); + boolean flag=true; +// baseBean.writeLog("长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度长度"+rs2.getArray().size()); + if (rs2.getArray().size() > 0&&execute1) {//已完成和jdcode + for (int j = 0; j < rs2.getArray().size(); j++) { + +// baseBean.writeLog("循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环几次循环"+j); + String num1 = rs2.getString("num"); + String jdcode1 = rs2.getString("jdcode"); +// baseBean.writeLog(jdcode1+"--------------------"+ jdcode); + if (jdcode1.equals(jdcode)) {//如果同一酒店标识 + chartBean.setChildnum(num1); +// baseBean.writeLog("chartBean==================>"+chartBean.toString()); + //完成率 + Double comrate = Double.parseDouble(num1) / Double.parseDouble(num) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + chartBean.setComrate(df.format(comrate)); + list.add(chartBean); + rs2.next(); + flag=false; + break; + } else { + rs2.next(); + } + } + } else {//如果r2没有值 + continue; + } + if(flag){ + chartBean.setChildnum("0"); + chartBean.setComrate("0.00"); + list.add(chartBean); + } + rs1.next(); + } + list.sort(Comparator.comparing(ChartBean::getComrate)); + } else { + return JSON.toJSONString(list); + } + }else{//对应查询sql是否成功 + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + + @Override + public Object getTaskElementByMonth() {//达成元素本月数据 + //排名前10 + RecordSet rs1=new RecordSet(); + //任务完成量 + RecordSet rs2=new RecordSet(); + String sql1="select count(1) as num,h.hotelnamezh as jdname from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where rwzt='2' and DATE_FORMAT(r.modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m') group by r.jdcode order by num desc limit 10"; + String sql2="select r.totalcount,t.succount from(select count(1) as totalcount from view_totallist where rwzt <>4 and DATE_FORMAT(modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m')) as r,(select count(1) as succount from view_totallist where rwzt='2' and DATE_FORMAT(modedatacreatedate,'%Y%m')=DATE_FORMAT(CURDATE(),'%Y%m')) as t"; + rs1.execute(sql1); + rs2.execute(sql2); + rs1.next(); + rs2.next(); + ArrayList list=new ArrayList(); + ArrayList list2=new ArrayList(); + + if(rs1.getArray().size()>0){//如果rs1查询数组大于0说明有值 + for (int i = 0; i < rs1.getArray().size(); i++) { + Map map=new HashMap<>(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + map.put("num",num); + map.put("jdname",jdname); + list.add(map); + rs1.next();//下移 + } + } + if(rs2.getArray().size()>0){ + for (int i = 0; i < rs2.getArray().size(); i++) { + Map map2=new HashMap<>(); + String totalcount = rs2.getString("totalcount"); + String succount = rs2.getString("succount"); + map2.put("totalcount",totalcount); + map2.put("succount",succount); + list2.add(map2); + rs2.next(); + } + } + JSONArray jsonArray1= JSONArray.fromObject(list); + JSONArray jsonArray2= JSONArray.fromObject(list2); + JSONObject object = new JSONObject(); + object.put("mainInfo",jsonArray1); + object.put("topInfo",jsonArray2); + + return JSON.toJSONString(object); + } + + @Override + public Object getTaskElementByYear() {//达成元素本年数据 + //排名前10 + RecordSet rs1=new RecordSet(); + //任务完成量 + RecordSet rs2=new RecordSet(); + String sql1="select count(1) as num,h.hotelnamezh as jdname from view_totallist as r left join uf_hotelinfo as h on r.jdcode=h.holidex where rwzt='2' and YEAR(r.modedatacreatedate)=YEAR(NOW()) group by r.jdcode order by num desc limit 10"; + String sql2="select r.totalcount,t.succount from(select count(1) as totalcount from view_totallist where rwzt <>4 and YEAR(modedatacreatedate)=YEAR(NOW())) as r,(select count(1) as succount from view_totallist where rwzt='2' and YEAR(modedatacreatedate)=YEAR(NOW())) as t"; + rs1.execute(sql1); + boolean execute = rs2.execute(sql2); + rs1.next(); + rs2.next(); + ArrayList list=new ArrayList(); + ArrayList list2=new ArrayList(); + if(rs1.getArray().size()>0){//如果rs1查询数组大于0说明有值 + for (int i = 0; i < rs1.getArray().size(); i++) { + Map map=new HashMap<>(); + String num = rs1.getString("num"); + String jdname = rs1.getString("jdname"); + map.put("num",num); + map.put("jdname",jdname); + list.add(map); + rs1.next();//下移 + } + } + if(rs2.getArray().size()>0){ + for (int i = 0; i < rs2.getArray().size(); i++) { + Map map2=new HashMap<>(); + String totalcount = rs2.getString("totalcount"); + String succount = rs2.getString("succount"); + map2.put("totalcount",totalcount); + map2.put("succount",succount); + list2.add(map2); + rs2.next(); + } + } + JSONArray jsonArray1= JSONArray.fromObject(list); + JSONArray jsonArray2= JSONArray.fromObject(list2); + JSONObject object = new JSONObject(); + object.put("mainInfo",jsonArray1); + object.put("topInfo",jsonArray2); + + return JSON.toJSONString(object); + } + + @Override + public String daliyTaskBag() {//日常工作任务 √ + RecordSet rs1=new RecordSet(); + String sql="SELECT rwbt,lb FROM uf_rwqd where zq='0'"; + rs1.execute(sql); + rs1.next(); + ArrayList list = new ArrayList(); + if(rs1.getArray().size()>0){//如果有值 + for (int i = 0; i < rs1.getArray().size(); i++) { + String rwbt = rs1.getString("rwbt"); + String lb = rs1.getString("lb"); + Map map=new HashMap<>(); + map.put("rwbt",rwbt); + map.put("lb",lb); + list.add(map); + rs1.next(); + } + }else{//如果没值 + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + + + @Override + public String openTaskNode() {//开业任务节点 + RecordSet rs=new RecordSet(); + String sql="SELECT jdmc,kysx,zt FROM uf_txjl"; + rs.execute(sql); + rs.next(); + ArrayList list=new ArrayList(); + if(rs.getArray().size()>0){ + for (int i = 0; i < rs.getArray().size(); i++) { + Map map=new HashMap<>(); + String jdmc = rs.getString("jdmc"); + String kysx = rs.getString("kysx"); + String zt = rs.getString("zt"); + map.put("jdmc",jdmc); + map.put("kysx",kysx); + map.put("zt",zt); + list.add(map); + rs.next(); + } + }else{ + return JSON.toJSONString(list); + } + + return JSON.toJSONString(list); + } + + @Override + public String openload(String jdcode) {//开业 + RecordSet rs=new RecordSet(); + String sql="SELECT kysx,xmjl,jhksrqsjcs,jhjsrqsjcs,zt FROM uf_txjl WHERE jdcode="+"'"+jdcode+"'"; + rs.execute(sql); + rs.next(); + ArrayList list=new ArrayList(); + if(rs.getArray().size()>0){ + for (int i = 0; i < rs.getArray().size(); i++) { + Map map=new HashMap<>(); + String kysx = rs.getString("kysx"); + String xmjl = rs.getString("xmjl"); + String begintime = rs.getString("jhksrqsjcs"); + String endtime = rs.getString("jhjsrqsjcs"); + String zt = rs.getString("zt"); + map.put("kysx",kysx); + map.put("xmjl",xmjl); + map.put("begintime",begintime); + map.put("endtime",endtime); + map.put("zt",zt); + list.add(map); + rs.next(); + } + }else{ + return JSON.toJSONString(list); + } + + return JSON.toJSONString(list); + } + + //获取日程日历 + @Override + public String getworkplan(String id) { + RecordSet rs=new RecordSet(); + String sql="SELECT status,REQUESTID from workplan WHERE id="+"'"+id+"'"; + rs.execute(sql); + rs.next(); + ArrayList list=new ArrayList(); + if(rs.getArray().size()>0){ + for (int i = 0; i < rs.getArray().size(); i++) { + Map map=new HashMap<>(); + String requestid = rs.getString("REQUESTID"); + String status = rs.getString("status"); + map.put("requestid",requestid); + map.put("status",status); + list.add(map); + rs.next(); + } + }else{ + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + + @Override + public String getdelayTask(String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + //延期任务量 + String desql="select count(1) as c from view_EmpTask where rwzt = 3"; + //前一天数据b + //如果是总经理登录 + if(!"".equals(id) && id!=null){ + desql=desql+" and zbr="+"'"+id+"'"; + } + rs.execute(desql); + //当天数据 + String curdata=""; + //昨日数据 + String status="0"; //0/平 1/上升 2/下降 + rs.next(); + if(rs.getArray().size()>0){ + String res1 = rs.getString("c"); + curdata=res1; + rs.next(); + } +// ye.next(); +// if(ye.getArray().size()>0){ +// String res2 = ye.getString("c"); +// yesdata=res2; +// } + Map map=new HashMap(); + if(!curdata.equals("")){ +// if(Double.parseDouble(curdata)Double.parseDouble(yesdata)){ +// status="1"; +// } + map.put("count",curdata); + map.put("status","0"); + return JSON.toJSONString(map); + } + map.put("count", "0"); + map.put("status", "0"); + return JSON.toJSONString(map); + } + //每日任务达成率 + @Override + public String getdaliyTask(String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + String sql=""; + String yesql=""; + + if(!"".equals(id) && id!=null){ + sql="select a.total,b.suc from(select count(1) as total from uf_rwwcqd where rwzt='3' and zjln="+"'"+id+"'"+") as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y%m%d')=CURDATE() and rwzt='2' and zjln="+"'"+id+"'"+") as b"; + yesql="select a.total,b.suc from(select count(1) as total from uf_rwwcqd where rwzt='3' and zjln="+"'"+id+"'"+") as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y%m%d')=date_sub(curdate(),interval 1 day) and rwzt='2' and zjln="+"'"+id+"'"+") as b"; + }else{ + sql="select a.total,b.suc from(select count(1) as total from uf_rwwcqd where rwzt='3') as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y%m%d')=CURDATE() and rwzt='2') as b"; + yesql="select a.total,b.suc from(select count(1) as total from uf_rwwcqd where rwzt='3') as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y%m%d')=date_sub(curdate(),interval 1 day) and rwzt='2') as b"; + } + rs.execute(sql); + ye.execute(yesql); + //当天数据 + String curdata=""; + //昨日数据 + String yesdata=""; + String status="0"; //0/平 1/上升 2/下降 + rs.next(); + if(rs.getArray().size()>0){ + String total = rs.getString("total"); + String suc = rs.getString("suc"); + if(total.equals("0")){ + curdata="0.00"; + }else{ + Double comrate = Double.parseDouble(suc)/Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + curdata=format; + } + } + ye.next(); + if(ye.getArray().size()>0){ + String total = ye.getString("total"); + String suc = ye.getString("suc"); + if(total.equals("0")){ + yesdata="0.00"; + }else{ + Double comrate = Double.parseDouble(suc) / Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + yesdata=format; + } + + } + Map map=new HashMap(); + if(!curdata.equals("") && !yesdata.equals("")){ + if(Double.parseDouble(curdata)Double.parseDouble(yesdata)){ + status="1"; + } + map.put("count",curdata); + map.put("status",status); + return JSON.toJSONString(map); + } + map.put("count", "-.--"); + map.put("status", "0"); + + return JSON.toJSONString(map); + } + //本年任务达成率 + + @Override + public String getYearTask(String id) { + RecordSet rs = new RecordSet(); + RecordSet ye = new RecordSet(); + String sql = ""; + String yesql = ""; + + if (!"".equals(id) && id != null) { + sql = "select a.total,b.suc from(select count(1) as total from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now()) and zjln=" + "'" + id + "'" + ") as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now()) and rwzt='2' and zjln=" + "'" + id + "'" + ") as b"; + yesql = "select a.total,b.suc from(select count(1) as total from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now())-1) and zjln=" + "'" + id + "'" + ") as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now())-1 and rwzt='2' and zjln=" + "'" + id + "'" + ") as b"; + } else { + sql = "select a.total,b.suc from(select count(1) as total from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now()) ) as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now()) and rwzt='2') as b"; + yesql = "select a.total,b.suc from(select count(1) as total from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now())-1 ) as a,(select count(1) as suc from uf_rwwcqd where DATE_FORMAT(modedatacreatedate,'%Y')=year(now())-1 and rwzt='2') as b"; + } + rs.execute(sql); + ye.execute(yesql); + //当天数据 + String curdata = ""; + //昨日数据 + String yesdata = ""; + String status = "0"; //0/平 1/上升 2/下降 + rs.next(); + if (rs.getArray().size() > 0) { + String total = rs.getString("total"); + String suc = rs.getString("suc"); + if (total.equals("0")) { + curdata = "0.00"; + } else { + Double comrate = Double.parseDouble(suc) / Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + curdata = format; + } + } + ye.next(); + if (ye.getArray().size() > 0) { + String total = ye.getString("total"); + String suc = ye.getString("suc"); + if (total.equals("0")) { + yesdata = "0.00"; + } else { + Double comrate = Double.parseDouble(suc) / Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + yesdata = format; + } + + } + Map map = new HashMap(); + if (!curdata.equals("") && !yesdata.equals("")) { + if (Double.parseDouble(curdata) < Double.parseDouble(yesdata)) { + status = "2"; + } else if (Double.parseDouble(curdata) > Double.parseDouble(yesdata)) { + status = "1"; + } + map.put("count", curdata); + map.put("status", status); + return JSON.toJSONString(map); + } + map.put("count", "-.--"); + map.put("status", "0"); + + return JSON.toJSONString(map); + } + //开业筹备--------------------------------------- + //延期任务量 + @Override + public String getPreDelayTask(String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + //延期任务量 + String desql="select count(1) as c from uf_txjl WHERE jhjsrqsjcs0){ + String res1 = rs.getString("c"); + curdata=res1; + rs.next(); + } + ye.next(); + if(ye.getArray().size()>0){ + String res2 = ye.getString("c"); + yesdata=res2; + } + Map map=new HashMap(); + if(!curdata.equals("") && !yesdata.equals("")){ + if(Double.parseDouble(curdata)Double.parseDouble(yesdata)){ + status="1"; + } + map.put("count",curdata); + map.put("status",status); + return JSON.toJSONString(map); + } + map.put("count", "-"); + map.put("status", "0"); + return JSON.toJSONString(map); + } + //今日任务 + @Override + public String getPreDaliyTask(String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + //今日任务 + String desql="select count(1) as c from uf_txjl WHERE DATE_FORMAT(jhksrqsjcs,'%Y%m%d')=curdate()"; + //前一天数据 + String yesql="select count(1) as c from uf_txjl WHERE DATE_FORMAT(jhksrqsjcs,'%Y%m%d')=date_sub(curdate(),interval 1 day)"; + //如果是总经理登录 + if(!"".equals(id) && id!=null){ + desql=desql+" and pm="+"'"+id+"'"; + yesql=yesql+" and pm="+"'"+id+"'"; + } + + rs.execute(desql); + ye.execute(yesql); + //当天数据 + String curdata=""; + //昨日数据 + String yesdata=""; + String status="0"; //0/平 1/上升 2/下降 + rs.next(); + if(rs.getArray().size()>0){ + String res1 = rs.getString("c"); + curdata=res1; + rs.next(); + } + ye.next(); + if(ye.getArray().size()>0){ + String res2 = ye.getString("c"); + yesdata=res2; + } + Map map=new HashMap(); + if(!curdata.equals("") && !yesdata.equals("")){ + if(Double.parseDouble(curdata)Double.parseDouble(yesdata)){ + status="1"; + } + map.put("count",curdata); + map.put("status",status); + return JSON.toJSONString(map); + } + map.put("count", "-"); + map.put("status", "0"); + return JSON.toJSONString(map); + } + + @Override + public String getPreTaskRate(String id) { + RecordSet rs = new RecordSet(); + RecordSet ye = new RecordSet(); + String sql = ""; + String yesql = ""; + + if (!"".equals(id) && id != null) { + sql = "select a.total,b.suc from (select count(1) as total from uf_txjl where pm="+"'"+id+"'"+") as a,(select count(1) as suc from uf_txjl where zt='2' and pm="+"'"+id+"'"+") as b"; + yesql = "select a.total,b.suc from (select count(1) as total from uf_txjl where DATE_FORMAT(jhjsrqsjcs,'%Y%m%d') 0) { + String total = rs.getString("total"); + String suc = rs.getString("suc"); + if (total.equals("0")) { + curdata = "0.00"; + } else { + Double comrate = Double.parseDouble(suc) / Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + curdata = format; + } + } + ye.next(); + if (ye.getArray().size() > 0) { + String total = ye.getString("total"); + String suc = ye.getString("suc"); + if (total.equals("0")) { + yesdata = "0.00"; + } else { + Double comrate = Double.parseDouble(suc) / Double.parseDouble(total) * 100; + DecimalFormat df = new DecimalFormat("#.##"); + String format = df.format(comrate); + yesdata = format; + } + + } + Map map = new HashMap(); + if (!curdata.equals("") && !yesdata.equals("")) { + if (Double.parseDouble(curdata) < Double.parseDouble(yesdata)) { + status = "2"; + } else if (Double.parseDouble(curdata) > Double.parseDouble(yesdata)) { + status = "1"; + } + map.put("count", curdata); + map.put("status", status); + return JSON.toJSONString(map); + } + map.put("count", "-.--"); + map.put("status", "0"); + + return JSON.toJSONString(map); + } + + //获取经理待办任务 + @Override + public String getNotStartTask(String id) { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) + String desql=""; + String res1 = "0"; + if(!"".equals(id) && id!=null){ + desql="select count(1) as c from view_EmpTask where rwzt in (0,1) and zbr = '"+id+"'"; + }else{ + desql="select count(1) as c from view_EmpTask where rwzt in (0,1)"; + } + boolean execute = rs.execute(desql); + if(execute&&rs.next()){ + res1= rs.getString("c"); + } + return JSON.toJSONString(res1); + } + //获取经理进行中任务 + @Override + public String getOnGoingTask(String id) { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) + String desql=""; + if(!"".equals(id) && id!=null){ + desql="SELECT count(zjln) as c FROM uf_rwwcqd where rwzt='1' and zjln='"+id+"'"; + }else{ + desql="SELECT count(zjln) as c FROM uf_rwwcqd where rwzt='1' "; + } + rs.execute(desql); + rs.next(); + String res1="0"; + if(rs.getArray().size()>0){ + res1 = rs.getString("c"); + } + return JSON.toJSONString(res1); + } +//----------------------------------------------------------新需求 + @Override + public String getComplaintDelayTask(String id) { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) + String desql=""; + if(!"".equals(id) && id!=null){ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwzt='3' and zbr='"+id+"'"; + }else{ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwzt='3' "; + } + rs.execute(desql); + rs.next(); + String res1="0"; + if(rs.getArray().size()>0){ + res1 = rs.getString("c"); + } + return JSON.toJSONString(res1); + } + + @Override + public String getComplaintNotStartTask(String id) { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) + String desql=""; + if(!"".equals(id) && id!=null){ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwzt='0' and zbr='"+id+"'"; + }else{ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwzt='0'"; + } + rs.execute(desql); + rs.next(); + String res1="0"; + if(rs.getArray().size()>0){ + res1 = rs.getString("c"); + } + return JSON.toJSONString(res1); + } + + @Override + public String getComplaintOnGoingTask(String id) { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) + String desql=""; + if(!"".equals(id) && id!=null){ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwzt='1' and zbr='"+id+"'"; + }else{ + desql="SELECT count(zbr) as c FROM uf_rwwcqd where rwcodekyzt='1' "; + } + rs.execute(desql); + rs.next(); + String res1="0"; + if(rs.getArray().size()>0){ + res1 = rs.getString("c"); + } + return JSON.toJSONString(res1); + } + + @Override + public String newgetdelayTask(String stau,String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + //延期任务量 + if("".equals(stau) && stau==null){ + stau="3"; + } + String desql="select count(1) as c from view_totaltask_supportcenter where rwzt='"+stau+"'"; + //前一天数据 +// String yesql="select count(1) as c from uf_rwwcqd where csrq0){ + String res1 = rs.getString("c"); + curdata=res1; + rs.next(); + } + Map map=new HashMap(); + if(!curdata.equals("")){ + map.put("count",curdata); + map.put("status","0"); + return JSON.toJSONString(map); + } + map.put("count", "0"); + map.put("status", "0"); + return JSON.toJSONString(map); + } + + @Override + public String newdaliyTaskBag(String jdcode) {//TODO +// BaseBean baseBean=new BaseBean(); + RecordSet rs1=new RecordSet(); + RecordSet rs2=new RecordSet(); + RecordSet rs3=new RecordSet(); + ArrayList list=new ArrayList(); + //查到任务包类型 + String sql="select rwblx from uf_hotelinfo where holidex='"+jdcode+"'"; + String sql2="SELECT rwlb from uf_rwbpzb where rwbid='"; + String sql3="SELECT rwbt,lb,rwnr,zq from uf_rwqd where zq='0' and id in"; + boolean execute = rs1.execute(sql); + if(execute && rs1.next()){ + String rwblx = rs1.getString("rwblx"); + sql2=sql2+Integer.parseInt(rwblx)+"'"; + boolean execute1 = rs2.execute(sql2); + //获取列表数组 + if(execute1 && rs2.next()){ + String rwlb = rs2.getString("rwlb").replace("\"", ""); +// baseBean.writeLog("列表数组为"+rwlb); + sql3=sql3+"("+rwlb+")"; +// baseBean.writeLog("sql3===========>"+sql3); + boolean execute2 = rs3.execute(sql3); + if(execute2){ + while (rs3.next()){ + Map map=new HashMap(); + String rwbt = rs3.getString("rwbt"); + String lb = rs3.getString("lb"); + String rwnr = rs3.getString("rwnr"); + String zq = rs3.getString("zq"); + map.put("rwbt",rwbt); + map.put("lb",lb); + map.put("rwnr",rwnr); + map.put("zq",zq); + list.add(map); + } + return JSON.toJSONString(list); + } + } + } + return JSON.toJSONString(list); + } + + @Override + public String newgetWorkplan(List mobileEvents,String id) { + RecordSet rs=new RecordSet(); + String sql="SELECT status,REQUESTID from workplan WHERE id="+"'"+id+"'"; + rs.execute(sql); + rs.next(); + ArrayList list=new ArrayList(); + if(rs.getArray().size()>0){ + for (int i = 0; i < rs.getArray().size(); i++) { + Map map=new HashMap<>(); + String requestid = rs.getString("REQUESTID"); + String status = rs.getString("status"); + map.put("requestid",requestid); + map.put("status",status); + list.add(map); + rs.next(); + } + }else{ + return JSON.toJSONString(list); + } + return JSON.toJSONString(list); + } + //本周需完成任务 + @Override + public String currWeekTask(String jdcode) { + Calendar cal = Calendar.getInstance(); + Date date=new Date(); + cal.setTime(date); + // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 + int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天 + if (1 == dayWeek) { + cal.add(Calendar.DAY_OF_MONTH, -1); + } + // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 + cal.setFirstDayOfWeek(Calendar.MONDAY); + // 获得当前日期是一个星期的第几天 + int day = cal.get(Calendar.DAY_OF_WEEK); + // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 + cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String imptimeBegin = sdf.format(cal.getTime()); + // System.out.println("所在周星期一的日期:" + imptimeBegin); + cal.add(Calendar.DATE, 6); + String imptimeEnd = sdf.format(cal.getTime()); + + int num=0; + RecordSet rs=new RecordSet(); + String sql="SELECT csrq from view_totallist WHERE rwzt in(0,1) and find_in_set('"+jdcode+"',zjln)"; + boolean execute = rs.execute(sql); + if(execute){ + while(rs.next()){ + String csrq = rs.getString("csrq").replace("-",""); + if(Integer.valueOf(csrq)>=Integer.valueOf(imptimeBegin) && Integer.valueOf(csrq)<=Integer.valueOf(imptimeEnd)){ + num++; + } + } + } + return String.valueOf(num); + } + + @Override + public String getnewWorkplan(JSONArray list,String currentDate) { +// BaseBean baseBean=new BaseBean(); + ArrayList> list1=new ArrayList(); + ArrayList> list2=new ArrayList(); + ArrayList> uncomrelist=new ArrayList();//未完成的添加 + ArrayList> comrelist=new ArrayList();//已完成的添加 + ArrayList> norelist=new ArrayList();//无requestid + Map>> stringArrayListMap=new HashMap<>(); + String idsql=" where id in("; + for (int i = 0; i map = new HashMap<>(); + net.sf.json.JSONObject object = list.getJSONObject(i); +// baseBean.writeLog("封装传来的对象"+object); +// String color = object.getString("color"); + String workPlanTypeName = object.getString("workPlanTypeName"); + String planName = object.getString("planName"); + String beginDate = object.getString("beginDate"); + String endDate = object.getString("endDate"); + String beginTime = object.getString("beginTime"); + String endTime = object.getString("endTime"); + String id = object.getString("id"); + String workplanType = object.getString("workplanType"); +// String address = object.getString("address"); +// String urgentLevel = object.getString("urgentLevel"); +// String remindTypeName = object.getString("remindTypeName"); + +// map.put("color",color); + map.put("workPlanTypeName",workPlanTypeName); + map.put("planName",planName); + map.put("beginDate",beginDate); + map.put("endDate",endDate); + map.put("beginTime",beginTime); + map.put("endTime",endTime); + map.put("id",id); + map.put("workplanType",workplanType); +// map.put("address",address); +// map.put("urgentLevel",urgentLevel); +// map.put("remindTypeName",remindTypeName); + list1.add(map); + idsql+="'"+id+"',"; + } + //确定有数据 + if(list1.size()>0){ + //处理下sql +// baseBean.writeLog("sql:"+idsql); + String substring = idsql.substring(0, idsql.length() - 1); + + substring+=")"; + RecordSet recordSet = new RecordSet(); + boolean execute = recordSet.execute("select id,status,REQUESTID from workplan"+substring); +// baseBean.writeLog("sql为==========>>>select id,status,REQUESTID from workplan"+substring); + if(execute){ + while (recordSet.next()){ +// baseBean.writeLog("封装截取的id"+recordSet.getString("id")); + Map map = new HashMap<>(); + String id = recordSet.getString("id"); + String status = recordSet.getString("status"); + String requestid = recordSet.getString("REQUESTID"); + map.put("id", id); + map.put("status", status); + map.put("requestid", requestid); +// baseBean.writeLog("封装截取的id"+map); + list2.add(map); + } + } + //根据id查出来的数据查询 + for (Map map : list2) { +// baseBean.writeLog("封装封装开始,3个数组"); + for (Map stringMap : list1) { + if(stringMap.get("workplanType").equals("15")){//临时任务 + stringMap.put("workplanType","0"); + }// + if(stringMap.get("id").equals(map.get("id"))){//如果id相同,匹配对象了,说明是点击,或今天的数据 + if(!"".equals(map.get("requestid"))){//如果有requestid + if(map.get("status").equals("0")){ + // console.log("未完成的添加",daily) + +// baseBean.writeLog("未完成"+stringMap.toString()); + uncomrelist.add(stringMap); + }else{ + // console.log("已完成的添加",aily) +// baseBean.writeLog("已完成" + stringMap.toString()); + comrelist.add(stringMap); + } + }else{//如果没有requestid +// baseBean.writeLog("无requestid" + stringMap.toString()); + norelist.add(stringMap); + } + } + } + } +// baseBean.writeLog("未完成的结果集"+uncomrelist.toString()); + stringArrayListMap.put("uncomrelist",uncomrelist); +// baseBean.writeLog("已完成的结果集"+comrelist.toString()); + stringArrayListMap.put("comrelist",comrelist); +// baseBean.writeLog("无requestid的结果集"+norelist.toString()); + stringArrayListMap.put("norelist",norelist); + + }else{//今天无数据 + return JSON.toJSONString(stringArrayListMap); + } + + + return JSON.toJSONString(stringArrayListMap); + } + + @Override + public String codeky(String region) { + RecordSet rs=new RecordSet(); + //延期任务量 + String desql="select count(1) as num from uf_hotelinfo where region like '"+region+"' and kyzt = '0'"; + //前一天数据 + String yesql="select count(1) as c from uf_rwwcqd where csrq map=new HashMap(); + if(execute&&rs.next()){ + String num = rs.getString("num"); + map.put("num",num); + } + return JSON.toJSONString(map); + } + + @Override + public String emptyMananger() { + RecordSet rs=new RecordSet(); + RecordSet rs1=new RecordSet(); +// boolean execute = rs.execute("select count(1) as num from uf_hotelinfo where region like 'HIEX%' and kyzt = 0"); + boolean execute = rs.execute("select count(1) as num from view_kqManager"); + boolean execute1 = rs1.execute("select count(1) as c from view_kqManager where zjn is null or zjn=''"); + Map map=new HashMap(); + rs1.next(); + if(execute&&rs.next()) { + String num = rs.getString("num"); + String qu = rs1.getString("c"); + map.put("num", num); + map.put("qu", qu); + } + return JSON.toJSONString(map); + } + + @Override + + public String zhichiOnGoing() { + RecordSet rs=new RecordSet(); + //待办任务(状态为未完成) +// String desql="select count(1) as c from view_totallist where rwzt = '1'"; + String desql="select count(1) as c from view_totaltask_supportcenter where rwzt = '2'"; + rs.execute(desql); + rs.next(); + String res1="0"; + if(rs.getArray().size()>0){ + res1 = rs.getString("c"); + } + return JSON.toJSONString(res1); + } + + @Override + public String zjnewgetdelayTask(String stau, String id) { + RecordSet rs=new RecordSet(); + RecordSet ye=new RecordSet(); + //延期任务量 + if("".equals(stau) && stau==null){ + stau="3"; + } + String desql="select count(1) as c from view_totallist where rwzt='"+stau+"'"; + //如果是总经理登录 + if(!"".equals(id) && id!=null){ + desql=desql+" and find_in_set('"+id+"',zjln)"; + } + rs.execute(desql); + //当天数据 + String curdata=""; + //昨日数据 + String status="0"; //0/平 1/上升 2/下降 + rs.next(); + if(rs.getArray().size()>0){ + String res1 = rs.getString("c"); + curdata=res1; + rs.next(); + } + Map map=new HashMap(); + if(!curdata.equals("")){ + map.put("count",curdata); + map.put("status","0"); + return JSON.toJSONString(map); + } + map.put("count", "0"); + map.put("status", "0"); + return JSON.toJSONString(map); + } + //本周总经理下发 + @Override + public List currWeekxiafa(String id) { + ArrayList list=new ArrayList<>(); + RecordSet rs=new RecordSet(); + String num1=getdelay(id); + baseBean.writeLog("逾期时任务"+num1); + String num2=getnum2(id); + baseBean.writeLog("本周需完成任务"+num1); + String num3=getnum3(id); + baseBean.writeLog("本周总经理下发任务"+num1); + String num4=getnum4(id); + baseBean.writeLog("本月完成任务"+num1); + list.add(num1); + list.add(num2); + list.add(num3); + list.add(num4); + return list; + } + + @Override + public ArrayList getListBySearch(String uid, String taskTitle, String creator, String stopTime, String taskStatus,String type) throws Exception { + ArrayList list=new ArrayList<>(); + if(type.equals("1")){ + List hashMaps = getdelayBySearch(uid, taskTitle, creator, stopTime, taskStatus); + list.add(hashMaps); + } + if(type.equals("2")){ + List hashMaps2 = getList2BySearch(uid, taskTitle, creator, stopTime, taskStatus); + list.add(hashMaps2); + } + if(type.equals("3")){ + List hashMaps3 = getList3BySearch(uid, taskTitle, creator, stopTime, taskStatus); + list.add(hashMaps3); + } + if(type.equals("4")){ + List hashMaps4 = getList4BySearch(uid, taskTitle, creator, stopTime, taskStatus); + list.add(hashMaps4); + } + + return list; + } + + private List getList4BySearch(String uid, String taskTitle, String creator, String stopTime, String taskStatus) throws Exception { + RecordSet rs=new RecordSet(); + ArrayList list=new ArrayList<>(); + + String sql="SELECT requestId,rwbt,zbr,csrq,zjln,zxr,rwzt from view_totallist WHERE rwzt = 2 and find_in_set('"+uid+"',zjln) and rq30 map=new HashMap<>(); + map.put("id",rs.getString("requestId")); + map.put("title",rs.getString("rwbt")); + map.put("zbr",resourceComInfo.getLastname(rs.getString("zxr"))); + map.put("csrq",rs.getString("csrq")); + String rwzt=""; + if(rs.getString("rwzt").equals("0")){ + rwzt="未开始"; + } + if(rs.getString("rwzt").equals("1")){ + rwzt="进行中"; + } + if(rs.getString("rwzt").equals("2")){ + rwzt="已提交"; + } + if(rs.getString("rwzt").equals("3")){ + rwzt="逾期"; + } + map.put("rwzt",rwzt); + list.add(map); + } + } + return list; + } + + private List getList3BySearch(String uid, String taskTitle, String creator, String stopTime, String taskStatus) throws Exception { + ArrayList list=new ArrayList<>(); + Calendar cal = Calendar.getInstance(); + Date date=new Date(); + cal.setTime(date); + // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 + int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天 + if (1 == dayWeek) { + cal.add(Calendar.DAY_OF_MONTH, -1); + } + // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 + cal.setFirstDayOfWeek(Calendar.MONDAY); + // 获得当前日期是一个星期的第几天 + int day = cal.get(Calendar.DAY_OF_WEEK); + // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 + cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String imptimeBegin = sdf.format(cal.getTime()); + // System.out.println("所在周星期一的日期:" + imptimeBegin); + cal.add(Calendar.DATE, 6); + String imptimeEnd = sdf.format(cal.getTime()); + + RecordSet rs=new RecordSet(); +// String sql="SELECT ksrq,lcsjid,rwbt,jsr,jzrq,zjln,rwzt from uf_xfrw WHERE rwzt in(0,1) and find_in_set('"+uid+"',xfr)"; + String sql="SELECT ksrq,lcsjid,rwbt,jsr,jzrq,zjln,rwzt from uf_xfrw WHERE find_in_set('"+uid+"',xfr)"; + if(StringUtils.isNotBlank(taskTitle)){ + sql+=" and rwbt like '%"+taskTitle+"%'"; + } + if(StringUtils.isNotBlank(creator)){ + sql+=" and jsr = '"+creator+"'"; + } + if(StringUtils.isNotBlank(stopTime)){ + sql+=" and jzrq <= '"+stopTime+"'"; + } + if(StringUtils.isNotBlank(taskStatus)){ + sql+=" and rwzt = '"+taskStatus+"'"; + } + sql+=" order by jzrq desc"; + baseBean.writeLog("移动端本周总经理下发sql"+sql); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + boolean execute = rs.execute(sql); + if(execute){ + baseBean.writeLog("移动端本周总经理下发sql完成"); + while(rs.next()){ + baseBean.writeLog("移动端本周总经理循环"); + String ksrq = rs.getString("ksrq").replace("-",""); + if(Integer.valueOf(ksrq)>=Integer.valueOf(imptimeBegin) && Integer.valueOf(ksrq)<=Integer.valueOf(imptimeEnd)){ + HashMap map=new HashMap<>(); + map.put("id",rs.getString("lcsjid")); + baseBean.writeLog("移动端本周总经理循环添加map"+JSON.toJSONString(map)); + map.put("title",rs.getString("rwbt")); + baseBean.writeLog("移动端本周总经理循环添加map"+JSON.toJSONString(map)); + if(!rs.getString("jsr").equals("")){ + map.put("zbr",resourceComInfo.getLastname(rs.getString("jsr"))); + }else if(!rs.getString("zjln").equals("")){ + map.put("zbr",resourceComInfo.getLastname(rs.getString("zjln"))); + }else{ + map.put("zbr","暂无"); + } + baseBean.writeLog("移动端本周总经理循环添加map"+JSON.toJSONString(map)); + map.put("csrq",rs.getString("jzrq")); + baseBean.writeLog("移动端本周总经理循环添加map"+JSON.toJSONString(map)); + String rwzt=""; + baseBean.writeLog("移动端本周总经理循环添加map=============================>"+rs.getString("rwzt")); + if(rs.getString("rwzt").equals("0")){ + rwzt="未开始"; + } + if(rs.getString("rwzt").equals("1")){ + rwzt="进行中"; + } + if(rs.getString("rwzt").equals("2")){ + rwzt="已提交"; + } + if(rs.getString("rwzt").equals("3")){ + rwzt="逾期"; + } + + map.put("rwzt",rwzt); + baseBean.writeLog("移动端本周总经理循环添加map"+JSON.toJSONString(map)); + list.add(map); + } + } + } + baseBean.writeLog("移动端本周总经理最终list"+JSON.toJSONString(list)); + return list; + } + public String getnum3(String id){ + Calendar cal = Calendar.getInstance(); + Date date=new Date(); + cal.setTime(date); + // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 + int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天 + if (1 == dayWeek) { + cal.add(Calendar.DAY_OF_MONTH, -1); + } + // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 + cal.setFirstDayOfWeek(Calendar.MONDAY); + // 获得当前日期是一个星期的第几天 + int day = cal.get(Calendar.DAY_OF_WEEK); + // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 + cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String imptimeBegin = sdf.format(cal.getTime()); + // System.out.println("所在周星期一的日期:" + imptimeBegin); + cal.add(Calendar.DATE, 6); + String imptimeEnd = sdf.format(cal.getTime()); + + int num=0; + RecordSet rs=new RecordSet(); + String sql="SELECT ksrq from uf_xfrw WHERE find_in_set('"+id+"',xfr)"; + baseBean.writeLog("本周总经理下发sql"+sql); + boolean execute = rs.execute(sql); + if(execute){ + baseBean.writeLog("本周总经理下发sql完成"); + while(rs.next()){ + String ksrq = rs.getString("ksrq").replace("-",""); + if(Integer.valueOf(ksrq)>=Integer.valueOf(imptimeBegin) && Integer.valueOf(ksrq)<=Integer.valueOf(imptimeEnd)){ + num++; + } + } + } + return String.valueOf(num); + } + + private List getList2BySearch(String uid, String taskTitle, String creator, String stopTime, String taskStatus) throws Exception { + ArrayList list=new ArrayList<>(); + Calendar cal = Calendar.getInstance(); + Date date=new Date(); + cal.setTime(date); + // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 + int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天 + if (1 == dayWeek) { + cal.add(Calendar.DAY_OF_MONTH, -1); + } + // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 + cal.setFirstDayOfWeek(Calendar.MONDAY); + // 获得当前日期是一个星期的第几天 + int day = cal.get(Calendar.DAY_OF_WEEK); + // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 + cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String imptimeBegin = sdf.format(cal.getTime()); + // System.out.println("所在周星期一的日期:" + imptimeBegin); + cal.add(Calendar.DATE, 6); + String imptimeEnd = sdf.format(cal.getTime()); +// 开始查询sql + String sql="SELECT requestId,rwbt,zbr,csrq,zjln,zxr,rwzt from view_totallist WHERE rwzt in(0,1) and find_in_set('"+uid+"',zjln)"; + if(StringUtils.isNotBlank(taskTitle)){ + sql+=" and rwbt like '%"+taskTitle+"%'"; + } + if(StringUtils.isNotBlank(creator)){ + sql+=" and zxr = '"+creator+"'"; + } + if(StringUtils.isNotBlank(stopTime)){ + sql+=" and csrq <= '"+stopTime+"'"; + } + if(StringUtils.isNotBlank(taskStatus)){ + sql+=" and rwzt = '"+taskStatus+"'"; + } + RecordSet rs=new RecordSet(); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + baseBean.writeLog("本周需完成任务列表sql"+sql); + boolean execute = rs.execute(sql); + if(execute){ + baseBean.writeLog("本周需完成任务sql执行成功"); + while(rs.next()){ + String csrq = rs.getString("csrq").replace("-",""); + baseBean.writeLog("周需完成任务截取时间"+csrq); + if(Integer.valueOf(csrq)>=Integer.valueOf(imptimeBegin) && Integer.valueOf(csrq)<=Integer.valueOf(imptimeEnd)){ + HashMap map=new HashMap<>(); + map.put("id",rs.getString("requestId")); + baseBean.writeLog("本周需完成任务map添加数据"+JSON.toJSONString(map)); + map.put("title",rs.getString("rwbt")); + map.put("zbr",resourceComInfo.getLastname(rs.getString("zxr"))); + baseBean.writeLog("本周需完成任务map添加数据"+JSON.toJSONString(map)); + map.put("csrq",rs.getString("csrq")); + baseBean.writeLog("本周需完成任务map添加数据"+JSON.toJSONString(map)); + String rwzt=""; + if(rs.getString("rwzt").equals("0")){ + rwzt="未开始"; + } + if(rs.getString("rwzt").equals("1")){ + rwzt="进行中"; + } + if(rs.getString("rwzt").equals("2")){ + rwzt="已提交"; + } + if(rs.getString("rwzt").equals("3")){ + rwzt="逾期"; + } + baseBean.writeLog("本周需完成任务map添加数据"+JSON.toJSONString(map)); + map.put("rwzt",rwzt); + baseBean.writeLog("本周需完成任务map添加数据"+JSON.toJSONString(map)); + list.add(map); + } + } + } + return list; + } + + private List getdelayBySearch(String uid, String taskTitle, String creator, String stopTime, String taskStatus) throws Exception { + ArrayList list=new ArrayList<>(); + String sql="select requestId,rwbt,zbr,zxr,zjln,csrq,rwzt from view_totallist where rwzt = '3' and zjln="+ uid; + if(StringUtils.isNotBlank(taskTitle)){ + sql+=" and rwbt like '%"+taskTitle+"%'"; + } + if(StringUtils.isNotBlank(creator)){ + sql+=" and zxr = '"+creator+"'"; + } + if(StringUtils.isNotBlank(stopTime)){ + sql+=" and csrq <= '"+stopTime+"'"; + } + if(StringUtils.isNotBlank(taskStatus)){ + sql+=" and rwzt = '"+taskStatus+"'"; + } + RecordSet rs=new RecordSet(); + baseBean.writeLog("逾期任务sql条件查询"+sql); + ResourceComInfo resourceComInfo = new ResourceComInfo(); + boolean b = rs.executeQuery(sql); + if(b){ + while (rs.next()){ + HashMap map=new HashMap<>(); + map.put("id",rs.getString("requestId")); + map.put("title",rs.getString("rwbt")); + map.put("zbr",resourceComInfo.getLastname(rs.getString("zxr"))); + map.put("csrq",rs.getString("csrq")); + String rwzt=""; + if(rs.getString("rwzt").equals("0")){ + rwzt="未开始"; + } + if(rs.getString("rwzt").equals("1")){ + rwzt="进行中"; + } + if(rs.getString("rwzt").equals("2")){ + rwzt="已提交"; + } + if(rs.getString("rwzt").equals("3")){ + rwzt="逾期"; + } + map.put("rwzt",rwzt); + list.add(map); + } + } + return list; + } + + //逾期任务 + public String getdelay(String id){ + RecordSet rs=new RecordSet(); + String sql="select count(1) as c from view_totallist where rwzt = '3' and zjln="+ id; + baseBean.writeLog("逾期任务sql"+sql); + boolean b = rs.executeQuery(sql); + if(b&&rs.next()){ + baseBean.writeLog("逾期任务sql执行成功"); + String c = rs.getString("c"); + return c; + }else{ + return null; + } + } + + //本周需完成任务 + public String getnum2(String id){ + Calendar cal = Calendar.getInstance(); + Date date=new Date(); + cal.setTime(date); + // 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 + int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天 + if (1 == dayWeek) { + cal.add(Calendar.DAY_OF_MONTH, -1); + } + // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 + cal.setFirstDayOfWeek(Calendar.MONDAY); + // 获得当前日期是一个星期的第几天 + int day = cal.get(Calendar.DAY_OF_WEEK); + // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值 + cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + String imptimeBegin = sdf.format(cal.getTime()); + // System.out.println("所在周星期一的日期:" + imptimeBegin); + cal.add(Calendar.DATE, 6); + String imptimeEnd = sdf.format(cal.getTime()); + + int num=0; + RecordSet rs=new RecordSet(); + String sql="SELECT csrq from view_totallist WHERE rwzt in(0,1) and find_in_set('"+id+"',zjln)"; + baseBean.writeLog("本周需完成任务sql"+sql); + boolean execute = rs.execute(sql); + if(execute){ + baseBean.writeLog("本周需完成任务sql执行成功"); + while(rs.next()){ + String csrq = rs.getString("csrq").replace("-",""); + if(Integer.valueOf(csrq)>=Integer.valueOf(imptimeBegin) && Integer.valueOf(csrq)<=Integer.valueOf(imptimeEnd)){ + num++; + } + } + } + return String.valueOf(num); + } + //本周总经理下发 + + //总经理本月已完成任务 + public String getnum4(String id){ + RecordSet rs=new RecordSet(); + String sql="SELECT count(1) as num from view_totallist WHERE rwzt = 2 and find_in_set('"+id+"',zjln) and rq30 mobileEvents,String id); + + String currWeekTask(String jdcode); + + String getnewWorkplan(JSONArray list,String currentDate); + + String codeky(String region); + + String emptyMananger(); + + String zhichiOnGoing(); + + String zjnewgetdelayTask(String stau, String id); + + List currWeekxiafa(String id); + + ArrayList getListBySearch(String uid,String taskTitle, String creator, String stopTime, String taskStatus,String type) throws Exception; +} diff --git a/src/main/youhong_ai_old_src/weaver/aiyh_pcn/common_fadada/mapper/ActionMapper.java b/src/main/youhong_ai_old_src/weaver/aiyh_pcn/common_fadada/mapper/ActionMapper.java index a2d6957..85d115b 100644 --- a/src/main/youhong_ai_old_src/weaver/aiyh_pcn/common_fadada/mapper/ActionMapper.java +++ b/src/main/youhong_ai_old_src/weaver/aiyh_pcn/common_fadada/mapper/ActionMapper.java @@ -1,6 +1,9 @@ package weaver.aiyh_pcn.common_fadada.mapper; -import aiyh.utils.annotation.recordset.*; +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.Update; import weaver.conn.RecordSet; import java.util.Map; @@ -14,76 +17,88 @@ import java.util.Map; @SqlMapper public interface ActionMapper { - - - /** - * 更新合同号 - * - * @param tableName 表名 - * @param contractField 合同字段 - * @param contractNo 合同号 - * @param requestId 流程类型 - * @return 是否更新成功 - */ - @Update("update $t{tableName} set $t{contractField} = #{contractNo} " + - " where requestid = #{requestId}") - boolean updateContractInMainTable(@ParamMapper("tableName") String tableName, - @ParamMapper("contractField") String contractField, - @ParamMapper("contractNo") String contractNo, - @ParamMapper("requestId") String requestId); - - - /** - * 更新合同号 - * - * @param tableName 表名 - * @param contractField 合同字段 - * @param contractNo 合同号 - * @param detailId 明细表ID - * @return 是否更新成功 - */ - @Update("update $t{tableName} set $t{contractField} = #{contractNo} " + - " where id = #{detailId}") - boolean updateContractInDetailTable(@ParamMapper("tableName") String tableName, - @ParamMapper("contractField") String contractField, - @ParamMapper("contractNo") String contractNo, - @ParamMapper("detailId") String detailId); - - /** - * 查询主表rs - * @param billTable 表名 - * @param requestId requestid - * @return 结果rs - */ - @Select("select * from $t{tableName} where requestid = #{requestId}") - RecordSet selectMainRs(@ParamMapper("tableName") String billTable, @ParamMapper("requestId") String requestId); - - /** - * 跟新合同状态到主表 - * @param workflowTableName 流程表名 - * @param signStatusField 签署状态字段 - * @param requestId 请求id - * @param signSuccessValue 签署状态值 - */ - @Update("update $t{workflowTableName} set $t{signStatusField} = #{signSuccessValue} where requestid = #{requestId}") - void updateSignStatusMain(@ParamMapper("workflowTableName") String workflowTableName, - @ParamMapper("signStatusField") String signStatusField, - @ParamMapper("requestId") String requestId, - @ParamMapper("signSuccessValue") String signSuccessValue); - - /** - * 跟新合同状态到明细表 - * @param workflowTableName 流程表名 - * @param signStatusField 签署状态字段 - * @param detailId 请求id - * @param signSuccessValue 签署状态值 - */ - @Update("update $t{workflowTableName} set $t{signStatusField} = #{signSuccessValue} where id = #{detailId}") - void updateSignStatusDetail(@ParamMapper("workflowTableName") String workflowTableName, - @ParamMapper("signStatusField") String signStatusField, - @ParamMapper("signSuccessValue") String signSuccessValue, - @ParamMapper("detailId") Integer detailId); - - @Update("update $t{_billTable} set $t{_updateField} where requestid = #{_requestId}") - boolean updateFields(Map param); + + + /** + * 更新合同号 + * + * @param tableName 表名 + * @param contractField 合同字段 + * @param contractNo 合同号 + * @param requestId 流程类型 + * @return 是否更新成功 + */ + @Update("update $t{tableName} set $t{contractField} = #{contractNo} " + + " where requestid = #{requestId}") + boolean updateContractInMainTable(@ParamMapper("tableName") String tableName, + @ParamMapper("contractField") String contractField, + @ParamMapper("contractNo") String contractNo, + @ParamMapper("requestId") String requestId); + + + /** + * 更新合同号 + * + * @param tableName 表名 + * @param contractField 合同字段 + * @param contractNo 合同号 + * @param detailId 明细表ID + * @return 是否更新成功 + */ + @Update("update $t{tableName} set $t{contractField} = #{contractNo} " + + " where id = #{detailId}") + boolean updateContractInDetailTable(@ParamMapper("tableName") String tableName, + @ParamMapper("contractField") String contractField, + @ParamMapper("contractNo") String contractNo, + @ParamMapper("detailId") String detailId); + + /** + * 查询主表rs + * + * @param billTable 表名 + * @param requestId requestid + * @return 结果rs + */ + @Select("select * from $t{tableName} where requestid = #{requestId}") + RecordSet selectMainRs(@ParamMapper("tableName") String billTable, @ParamMapper("requestId") String requestId); + + /** + * 跟新合同状态到主表 + * + * @param workflowTableName 流程表名 + * @param signStatusField 签署状态字段 + * @param requestId 请求id + * @param signSuccessValue 签署状态值 + */ + @Update("update $t{workflowTableName} set $t{signStatusField} = #{signSuccessValue} where requestid = #{requestId}") + void updateSignStatusMain(@ParamMapper("workflowTableName") String workflowTableName, + @ParamMapper("signStatusField") String signStatusField, + @ParamMapper("requestId") String requestId, + @ParamMapper("signSuccessValue") String signSuccessValue); + + /** + * 跟新合同状态到明细表 + * + * @param workflowTableName 流程表名 + * @param signStatusField 签署状态字段 + * @param detailId 请求id + * @param signSuccessValue 签署状态值 + */ + @Update("update $t{workflowTableName} set $t{signStatusField} = #{signSuccessValue} where id = #{detailId}") + void updateSignStatusDetail(@ParamMapper("workflowTableName") String workflowTableName, + @ParamMapper("signStatusField") String signStatusField, + @ParamMapper("signSuccessValue") String signSuccessValue, + @ParamMapper("detailId") Integer detailId); + + @Update("update $t{_billTable} set $t{_updateField} where requestid = #{_requestId}") + boolean updateFields(Map param); + + /** + *

查询流程请求id

+ * + * @param docNo 合同编号 + * @return 流程id + */ + @Select("select request_id from uf_contract_log where contract_id = #{docNo}") + String selectRequestId(@ParamMapper("docNo") String docNo); } diff --git a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java index 057a32b..2db4f9b 100644 --- a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java +++ b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java @@ -3,10 +3,15 @@ package xuanran.wang.shyl.dataasync; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; import aiyh.utils.httpUtil.util.HttpUtils; +import aiyh.utils.tool.cn.hutool.http.HttpRequest; import basetest.BaseTest; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.api.xuanran.wang.shyl.entity.MQMessage; import org.apache.commons.lang3.StringUtils; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; @@ -22,25 +27,13 @@ import org.junit.Test; import weaver.xuanran.wang.common.annocation.SqlFieldMapping; import weaver.xuanran.wang.common.annocation.SqlUpdateWhereField; import weaver.xuanran.wang.shyl.dataasync.entity.StudentClass; - -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; -import java.util.*; - -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.crypto.asymmetric.KeyType; -import cn.hutool.crypto.asymmetric.RSA; -import cn.hutool.http.HttpRequest; -import cn.hutool.json.JSONUtil; import weaver.xuanran.wang.shyl_mq.RocketMQFactory; import weaver.xuanran.wang.shyl_mq.consumer.OrgConsumer; import weaver.xuanran.wang.shyl_mq.util.RocketConsumerUtil; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.util.*; /** *

上海团校测试类

@@ -49,335 +42,335 @@ import java.util.Objects; * @date 2023/2/9 13:23 */ public class AsyncTest extends BaseTest { - - @Test - public void testExecuteBatchByEntity() { - HttpUtils httpUtils = new HttpUtils(); - String json = "{\n" + - "\t\"msg\": \"success\",\n" + - "\t\"code\": 0,\n" + - "\t\"data\": [{\n" + - "\t\t\"id\": \"2f44f6c8626c4e328af10fd3af4122a3\",\n" + - "\t\t\"classNo\": null,\n" + - "\t\t\"className\": \"BB班202301\",\n" + - "\t\t\"belongYear\": 2023\n" + - "\t}, {\n" + - "\t\t\"id\": \"134fdb4ef8b4432cb66c03eb34dc94f7\",\n" + - "\t\t\"classNo\": null,\n" + - "\t\t\"className\": \"1\",\n" + - "\t\t\"belongYear\": 2023\n" + - "\t}]\n" + - "}"; - HashMap responseMap = JSONObject.parseObject(json, HashMap.class); - log.info("responseMap : " + responseMap); - Object data = responseMap.get("data"); - List list = JSONObject.parseArray(data.toString(), StudentClass.class); - List> params = new ArrayList<>(); - List> whereParams = new ArrayList<>(); - for (Object o : list) { - if (Objects.isNull(o)) { - continue; - } - Class clazz = o.getClass(); - Field[] fields = clazz.getDeclaredFields(); - LinkedHashMap linkedHashMap = new LinkedHashMap<>(); - ArrayList whereParam = new ArrayList<>(); - for (Field field : fields) { - field.setAccessible(true); - String fieldName = field.getName(); - Object fieldValue; - try { - fieldValue = field.get(o); - } catch (IllegalAccessException e) { - throw new CustomerException(Util.logStr("field get error! the error is :[{}]," + - "current field is: [{}], current obj is: [{}]", e.getMessage(), fieldName, JSONObject.toJSONString(o))); - } - if (Objects.isNull(fieldValue)) { - continue; - } - // 数据库字段映射 如果注解中没有值那么写入数据库就是实体类字段名 - SqlFieldMapping sqlFieldMapping = field.getAnnotation(SqlFieldMapping.class); - if (null == sqlFieldMapping) { - continue; - } - String sqlFieldMappingValue = sqlFieldMapping.value(); - if (StringUtils.isNotBlank(sqlFieldMappingValue)) { - fieldName = sqlFieldMappingValue; - } - linkedHashMap.put(fieldName, fieldValue); - - // 更新条件字段注解 - SqlUpdateWhereField sqlUpdateWhereField = field.getAnnotation(SqlUpdateWhereField.class); - if (null == sqlUpdateWhereField || !sqlUpdateWhereField.value()) { - continue; - } - whereParam.add(fieldValue.toString()); - } - params.add(linkedHashMap); - whereParams.add(whereParam); - } - log.info("params : " + JSONObject.toJSONString(params)); - log.info("wheres : " + whereParams); - } - - @Test - public void testSql() { - String json = "[{\"requestName\":\"放松放松\",\"mainData\":[{\"fieldName\":\"yysy\",\"fieldValue\":\"测试20230309\"}],\"workflowId\":\"45\"},{\"requestName\":\"放松放松\",\"mainData\":[{\"fieldName\":\"yysy\",\"fieldValue\":\"测试20230309\"}],\"workflowId\":\"451\"}]"; - JSONArray temp = new JSONArray(); - JSONArray arr = JSONObject.parseObject(json, JSONArray.class); - for (int i = 0; i < arr.size() - 1; i++) { - for (int j = 0; j < 25; j++) { - Object o = arr.get(i); - JSONObject object = JSONObject.parseObject(o.toString()); - temp.add(object); - } - } - JSONArray arrr = new JSONArray(); - for (Object o : temp) { - JSONObject object = JSONObject.parseObject(o.toString()); - List mainData = (List)object.get("mainData"); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("fieldName","customId"); - jsonObject.put("fieldValue",UUID.randomUUID().toString()); - mainData.add(jsonObject); - object.put("mainData", mainData); - arrr.add(object); - } - arr.addAll(arrr); - log.info("json arr size " + arr.size()); - log.info("arr : \n" + JSONObject.toJSONString(arr)); + + @Test + public void testExecuteBatchByEntity() { + HttpUtils httpUtils = new HttpUtils(); + String json = "{\n" + + "\t\"msg\": \"success\",\n" + + "\t\"code\": 0,\n" + + "\t\"data\": [{\n" + + "\t\t\"id\": \"2f44f6c8626c4e328af10fd3af4122a3\",\n" + + "\t\t\"classNo\": null,\n" + + "\t\t\"className\": \"BB班202301\",\n" + + "\t\t\"belongYear\": 2023\n" + + "\t}, {\n" + + "\t\t\"id\": \"134fdb4ef8b4432cb66c03eb34dc94f7\",\n" + + "\t\t\"classNo\": null,\n" + + "\t\t\"className\": \"1\",\n" + + "\t\t\"belongYear\": 2023\n" + + "\t}]\n" + + "}"; + HashMap responseMap = JSONObject.parseObject(json, HashMap.class); + log.info("responseMap : " + responseMap); + Object data = responseMap.get("data"); + List list = JSONObject.parseArray(data.toString(), StudentClass.class); + List> params = new ArrayList<>(); + List> whereParams = new ArrayList<>(); + for (Object o : list) { + if (Objects.isNull(o)) { + continue; + } + Class clazz = o.getClass(); + Field[] fields = clazz.getDeclaredFields(); + LinkedHashMap linkedHashMap = new LinkedHashMap<>(); + ArrayList whereParam = new ArrayList<>(); + for (Field field : fields) { + field.setAccessible(true); + String fieldName = field.getName(); + Object fieldValue; + try { + fieldValue = field.get(o); + } catch (IllegalAccessException e) { + throw new CustomerException(Util.logStr("field get error! the error is :[{}]," + + "current field is: [{}], current obj is: [{}]", e.getMessage(), fieldName, JSONObject.toJSONString(o))); + } + if (Objects.isNull(fieldValue)) { + continue; + } + // 数据库字段映射 如果注解中没有值那么写入数据库就是实体类字段名 + SqlFieldMapping sqlFieldMapping = field.getAnnotation(SqlFieldMapping.class); + if (null == sqlFieldMapping) { + continue; + } + String sqlFieldMappingValue = sqlFieldMapping.value(); + if (StringUtils.isNotBlank(sqlFieldMappingValue)) { + fieldName = sqlFieldMappingValue; + } + linkedHashMap.put(fieldName, fieldValue); + + // 更新条件字段注解 + SqlUpdateWhereField sqlUpdateWhereField = field.getAnnotation(SqlUpdateWhereField.class); + if (null == sqlUpdateWhereField || !sqlUpdateWhereField.value()) { + continue; + } + whereParam.add(fieldValue.toString()); + } + params.add(linkedHashMap); + whereParams.add(whereParam); + } + log.info("params : " + JSONObject.toJSONString(params)); + log.info("wheres : " + whereParams); + } + + @Test + public void testSql() { + String json = "[{\"requestName\":\"放松放松\",\"mainData\":[{\"fieldName\":\"yysy\",\"fieldValue\":\"测试20230309\"}],\"workflowId\":\"45\"},{\"requestName\":\"放松放松\",\"mainData\":[{\"fieldName\":\"yysy\",\"fieldValue\":\"测试20230309\"}],\"workflowId\":\"451\"}]"; + JSONArray temp = new JSONArray(); + JSONArray arr = JSONObject.parseObject(json, JSONArray.class); + for (int i = 0; i < arr.size() - 1; i++) { + for (int j = 0; j < 25; j++) { + Object o = arr.get(i); + JSONObject object = JSONObject.parseObject(o.toString()); + temp.add(object); + } + } + JSONArray arrr = new JSONArray(); + for (Object o : temp) { + JSONObject object = JSONObject.parseObject(o.toString()); + List mainData = (List) object.get("mainData"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("fieldName", "customId"); + jsonObject.put("fieldValue", UUID.randomUUID().toString()); + mainData.add(jsonObject); + object.put("mainData", mainData); + arrr.add(object); + } + arr.addAll(arrr); + log.info("json arr size " + arr.size()); + log.info("arr : \n" + JSONObject.toJSONString(arr)); // try { // List s = batchCreateWorkflowService.batchCreateWorkflow2(arr); // log.info("创建流程接口返回 " + s); // } catch (Exception e) { // log.error("创建流程失败 ! " + e.getMessage()); // } - } - - @Test - public void testC() { - try { - // 声明一个消费者consumer,需要传入一个组 weaver-consumer - DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("weaver-consumer"); - // 设置集群的NameServer地址,多个地址之间以分号分隔 183.192.65.118:9876 - consumer.setNamesrvAddr("114.115.168.220:9876"); - // 设置consumer的消费策略 - consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); - // 集群模式消费,广播消费不会重试 - consumer.setMessageModel(MessageModel.CLUSTERING); - // 设置最大重试次数,默认是16次 - consumer.setMaxReconsumeTimes(1); - // 设置consumer所订阅的Topic和Tag,*代表全部的Tag AUTH_CONSOLE_USERINFO_TOPIC - consumer.subscribe("AUTH_CONSOLE_ORG_TOPIC", "*"); - consumer.setVipChannelEnabled(false); - // Listener,主要进行消息的逻辑处理,监听topic,如果有消息就会立即去消费 - consumer.registerMessageListener(new MessageListenerConcurrently() { - @Override - public ConsumeConcurrentlyStatus consumeMessage(List list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { - System.out.println("msgs : " + JSONObject.toJSONString(list)); - System.out.println("context : " + JSONObject.toJSONString(consumeConcurrentlyContext)); - return ConsumeConcurrentlyStatus.RECONSUME_LATER; - } - }); - consumer.start(); - } catch (Exception e) { - log.error(" e => " + e.getMessage()); - } - } - - @Test - public void testD() throws UnsupportedEncodingException, MQBrokerException, RemotingException, InterruptedException, MQClientException { - String msg = "{\n" + - "\t\"actionType\": \"CREATE_ACTION\",\n" + - "\t\"topic\": \"OA_MEETING_TOPIC\",\n" + - "\t\"id\": \"29039\",\n" + - "\t\"content\": {\n" + - "\t\t\"sourceId\": \"29050\",\n" + - "\t\t\"mrtype\": \"2\",\n" + - "\t\t\"EndTime\": \"17:10\",\n" + - "\t\t\"meetingStatus\": \"1\",\n" + - "\t\t\"BeginTime\": \"17:36\",\n" + - "\t\t\"meetingTitle\": \"MQ测试20230223\",\n" + - "\t\t\"roomCode\": \"青年会堂会议室\",\n" + - "\t\t\"signCode\": \"\",\n" + - "\t\t\"EndDate\": \"2023-02-24\",\n" + - "\t\t\"BeginDate\": \"2023-02-23\",\n" + - "\t\t\"meetingHost\": \"96\",\n" + - "\t\t\"userList\": \"96\",\n" + - "\t\t\"meetingContent\": \"测试MQ20230223\"\n" + - "\t},\n" + - "\t\"sendTime\": \"2023-02-23 17:49:11\"\n" + - "}"; - RocketConsumerUtil.producerSendMsg("OAMeeting", msg,""); - // 先从本地缓存中获取生产者对象 - } - - @Test - public void testE() { - DefaultMQPushConsumer consumer = null; - log.info(Util.logStr("---- consumer : {} initialized start ----", "OrgConsumer")); - try { - try { - // 根据配置文件初始化一个consumer对象 - consumer = RocketMQFactory.getMQPushConsumer("OrgConsumer", new OrgConsumer().service()); - } catch (Exception e) { - throw new CustomerException(Util.logStr("the consumer init exception : {}", e.getMessage())); - } - try { - // 调用start()方法启动consumer - consumer.start(); - } catch (Exception e) { - throw new CustomerException(Util.logStr("the consumer start exception : {}", e.getMessage())); - } - log.info(Util.logStr("---- consumer : {} initialized end ----", "OrgConsumer")); - } catch (Exception e) { - log.info(Util.logStr("---- consumer : {} initialized error ----", "OrgConsumer")); - log.error(Util.getErrString(e)); - } - - } - - private static final Map SYSTEM_CACHE = new HashMap<>(); - /** - * ecology系统发放的授权许可证(appid) - */ - private static final String APPID = "JYZ"; - - @Test - public void testB() { - String json = "[{\n" + - "\t\"requestName\": \"你个沙雕32323\",\n" + - "\t\"workflowId\": \"45\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"测试20230309\"\n" + - "\t}]\n" + - "}, {\n" + - "\t\"requestName\": \"沙雕2号\",\n" + - "\t\"workflowId\": \"45\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + - "\t}]\n" + - "}, {\n" + - "\t\"requestName\": \"沙雕2号\",\n" + - "\t\"workflowId\": \"451\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + - "\t}]\n" + - "}]"; - testRestful("http://183.192.65.115:8080", "/api/wxr/shyl/workflow/batchCreate233", json); - } - - /** - * 第一步: - *

- * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息 - */ - public static Map testRegist(String address) { - //获取当前系统RSA加密的公钥 - RSA rsa = new RSA(); - String publicKey = rsa.getPublicKeyBase64(); - String privateKey = rsa.getPrivateKeyBase64(); - // 客户端RSA私钥 - SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY", privateKey); - // 客户端RSA公钥 - SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY", publicKey); - //调用ECOLOGY系统接口进行注册 - String data = HttpRequest.post(address + "/api/ec/dev/auth/regist") - .header("appid", APPID) - .header("cpk", publicKey) - .timeout(2000) - .execute().body(); - // 打印ECOLOGY响应信息 - System.out.println("testRegist():" + data); - Map datas = JSONUtil.parseObj(data); - //ECOLOGY返回的系统公钥 - SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String) datas.get("spk"))); - //ECOLOGY返回的系统密钥 - SYSTEM_CACHE.put("SERVER_SECRET", StrUtil.nullToEmpty((String) datas.get("secrit"))); - return datas; - } - - /** - * 第二步: - *

- * 通过第一步中注册系统返回信息进行获取token信息 - */ - public static Map testGetoken(String address) { - // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息 - String secret = SYSTEM_CACHE.get("SERVER_SECRET"); - String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); - // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新 - if (Objects.isNull(secret) || Objects.isNull(spk)) { - testRegist(address); - // 重新获取最新ECOLOGY系统公钥和Secret信息 - secret = SYSTEM_CACHE.get("SERVER_SECRET"); - spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); - } - // 公钥加密,所以RSA对象私钥为null - RSA rsa = new RSA(null, spk); - //对秘钥进行加密传输,防止篡改数据 - String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); - //调用ECOLOGY系统接口进行注册 - String data = HttpRequest.post(address + "/api/ec/dev/auth/applytoken") - .header("appid", APPID) - .header("secret", encryptSecret) - .header("time", "3600") - .execute().body(); - System.out.println("testGetoken():" + data); - Map datas = JSONUtil.parseObj(data); - //ECOLOGY返回的token - // TODO 为Token缓存设置过期时间 - SYSTEM_CACHE.put("SERVER_TOKEN", StrUtil.nullToEmpty((String) datas.get("token"))); - return datas; - } - - /** - * 第三步: - *

- * 调用ecology系统的rest接口,请求头部带上token和用户标识认证信息 - * - * @param address ecology系统地址 - * @param api rest api 接口地址(该测试代码仅支持GET请求) - * @param jsonParams 请求参数json串 - *

- * 注意:ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8" - */ - public String testRestful(String address, String api, String jsonParams) { - //ECOLOGY返回的token - String token = SYSTEM_CACHE.get("SERVER_TOKEN"); - if (StrUtil.isEmpty(token)) { - token = (String) testGetoken(address).get("token"); - } - String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); - //封装请求头参数 - RSA rsa = new RSA(null, spk); - //对用户信息进行加密传输,暂仅支持传输OA用户ID - String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); - List list = JSONObject.parseObject(jsonParams, List.class); - HttpUtils httpUtils = new HttpUtils(); - HashMap headers = new HashMap<>(); - headers.put("appid", APPID); - headers.put("token", token); - headers.put("userid", encryptUserid); - headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); - log.info("请求头 = > " + headers); + } + + @Test + public void testC() { + try { + // 声明一个消费者consumer,需要传入一个组 weaver-consumer + DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("weaver-consumer"); + // 设置集群的NameServer地址,多个地址之间以分号分隔 183.192.65.118:9876 + consumer.setNamesrvAddr("114.115.168.220:9876"); + // 设置consumer的消费策略 + consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); + // 集群模式消费,广播消费不会重试 + consumer.setMessageModel(MessageModel.CLUSTERING); + // 设置最大重试次数,默认是16次 + consumer.setMaxReconsumeTimes(1); + // 设置consumer所订阅的Topic和Tag,*代表全部的Tag AUTH_CONSOLE_USERINFO_TOPIC + consumer.subscribe("AUTH_CONSOLE_ORG_TOPIC", "*"); + consumer.setVipChannelEnabled(false); + // Listener,主要进行消息的逻辑处理,监听topic,如果有消息就会立即去消费 + consumer.registerMessageListener(new MessageListenerConcurrently() { + @Override + public ConsumeConcurrentlyStatus consumeMessage(List list, ConsumeConcurrentlyContext consumeConcurrentlyContext) { + System.out.println("msgs : " + JSONObject.toJSONString(list)); + System.out.println("context : " + JSONObject.toJSONString(consumeConcurrentlyContext)); + return ConsumeConcurrentlyStatus.RECONSUME_LATER; + } + }); + consumer.start(); + } catch (Exception e) { + log.error(" e => " + e.getMessage()); + } + } + + @Test + public void testD() throws UnsupportedEncodingException, MQBrokerException, RemotingException, InterruptedException, MQClientException { + String msg = "{\n" + + "\t\"actionType\": \"CREATE_ACTION\",\n" + + "\t\"topic\": \"OA_MEETING_TOPIC\",\n" + + "\t\"id\": \"29039\",\n" + + "\t\"content\": {\n" + + "\t\t\"sourceId\": \"29050\",\n" + + "\t\t\"mrtype\": \"2\",\n" + + "\t\t\"EndTime\": \"17:10\",\n" + + "\t\t\"meetingStatus\": \"1\",\n" + + "\t\t\"BeginTime\": \"17:36\",\n" + + "\t\t\"meetingTitle\": \"MQ测试20230223\",\n" + + "\t\t\"roomCode\": \"青年会堂会议室\",\n" + + "\t\t\"signCode\": \"\",\n" + + "\t\t\"EndDate\": \"2023-02-24\",\n" + + "\t\t\"BeginDate\": \"2023-02-23\",\n" + + "\t\t\"meetingHost\": \"96\",\n" + + "\t\t\"userList\": \"96\",\n" + + "\t\t\"meetingContent\": \"测试MQ20230223\"\n" + + "\t},\n" + + "\t\"sendTime\": \"2023-02-23 17:49:11\"\n" + + "}"; + RocketConsumerUtil.producerSendMsg("OAMeeting", msg, ""); + // 先从本地缓存中获取生产者对象 + } + + @Test + public void testE() { + DefaultMQPushConsumer consumer = null; + log.info(Util.logStr("---- consumer : {} initialized start ----", "OrgConsumer")); + try { + try { + // 根据配置文件初始化一个consumer对象 + consumer = RocketMQFactory.getMQPushConsumer("OrgConsumer", new OrgConsumer().service()); + } catch (Exception e) { + throw new CustomerException(Util.logStr("the consumer init exception : {}", e.getMessage())); + } + try { + // 调用start()方法启动consumer + consumer.start(); + } catch (Exception e) { + throw new CustomerException(Util.logStr("the consumer start exception : {}", e.getMessage())); + } + log.info(Util.logStr("---- consumer : {} initialized end ----", "OrgConsumer")); + } catch (Exception e) { + log.info(Util.logStr("---- consumer : {} initialized error ----", "OrgConsumer")); + log.error(Util.getErrString(e)); + } + + } + + private static final Map SYSTEM_CACHE = new HashMap<>(); + /** + * ecology系统发放的授权许可证(appid) + */ + private static final String APPID = "JYZ"; + + @Test + public void testB() { + String json = "[{\n" + + "\t\"requestName\": \"你个沙雕32323\",\n" + + "\t\"workflowId\": \"45\",\n" + + "\t\"mainData\": [{\n" + + "\t\t\"fieldName\": \"yysy\",\n" + + "\t\t\"fieldValue\": \"测试20230309\"\n" + + "\t}]\n" + + "}, {\n" + + "\t\"requestName\": \"沙雕2号\",\n" + + "\t\"workflowId\": \"45\",\n" + + "\t\"mainData\": [{\n" + + "\t\t\"fieldName\": \"yysy\",\n" + + "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + + "\t}]\n" + + "}, {\n" + + "\t\"requestName\": \"沙雕2号\",\n" + + "\t\"workflowId\": \"451\",\n" + + "\t\"mainData\": [{\n" + + "\t\t\"fieldName\": \"yysy\",\n" + + "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + + "\t}]\n" + + "}]"; + testRestful("http://183.192.65.115:8080", "/api/wxr/shyl/workflow/batchCreate233", json); + } + + /** + * 第一步: + *

+ * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息 + */ + public static Map testRegist(String address) { + // 获取当前系统RSA加密的公钥 + RSA rsa = new RSA(); + String publicKey = rsa.getPublicKeyBase64(); + String privateKey = rsa.getPrivateKeyBase64(); + // 客户端RSA私钥 + SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY", privateKey); + // 客户端RSA公钥 + SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY", publicKey); + // 调用ECOLOGY系统接口进行注册 + String data = HttpRequest.post(address + "/api/ec/dev/auth/regist") + .header("appid", APPID) + .header("cpk", publicKey) + .timeout(2000) + .execute().body(); + // 打印ECOLOGY响应信息 + System.out.println("testRegist():" + data); + Map datas = JSONUtil.parseObj(data); + // ECOLOGY返回的系统公钥 + SYSTEM_CACHE.put("SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String) datas.get("spk"))); + // ECOLOGY返回的系统密钥 + SYSTEM_CACHE.put("SERVER_SECRET", StrUtil.nullToEmpty((String) datas.get("secrit"))); + return datas; + } + + /** + * 第二步: + *

+ * 通过第一步中注册系统返回信息进行获取token信息 + */ + public static Map testGetoken(String address) { + // 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息 + String secret = SYSTEM_CACHE.get("SERVER_SECRET"); + String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); + // 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新 + if (Objects.isNull(secret) || Objects.isNull(spk)) { + testRegist(address); + // 重新获取最新ECOLOGY系统公钥和Secret信息 + secret = SYSTEM_CACHE.get("SERVER_SECRET"); + spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); + } + // 公钥加密,所以RSA对象私钥为null + RSA rsa = new RSA(null, spk); + // 对秘钥进行加密传输,防止篡改数据 + String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); + // 调用ECOLOGY系统接口进行注册 + String data = HttpRequest.post(address + "/api/ec/dev/auth/applytoken") + .header("appid", APPID) + .header("secret", encryptSecret) + .header("time", "3600") + .execute().body(); + System.out.println("testGetoken():" + data); + Map datas = JSONUtil.parseObj(data); + // ECOLOGY返回的token + // TODO 为Token缓存设置过期时间 + SYSTEM_CACHE.put("SERVER_TOKEN", StrUtil.nullToEmpty((String) datas.get("token"))); + return datas; + } + + /** + * 第三步: + *

+ * 调用ecology系统的rest接口,请求头部带上token和用户标识认证信息 + * + * @param address ecology系统地址 + * @param api rest api 接口地址(该测试代码仅支持GET请求) + * @param jsonParams 请求参数json串 + *

+ * 注意:ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8" + */ + public String testRestful(String address, String api, String jsonParams) { + // ECOLOGY返回的token + String token = SYSTEM_CACHE.get("SERVER_TOKEN"); + if (StrUtil.isEmpty(token)) { + token = (String) testGetoken(address).get("token"); + } + String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY"); + // 封装请求头参数 + RSA rsa = new RSA(null, spk); + // 对用户信息进行加密传输,暂仅支持传输OA用户ID + String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); + List list = JSONObject.parseObject(jsonParams, List.class); + HttpUtils httpUtils = new HttpUtils(); + HashMap headers = new HashMap<>(); + headers.put("appid", APPID); + headers.put("token", token); + headers.put("userid", encryptUserid); + headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); + log.info("请求头 = > " + headers); // try { // ResponeVo responeVo = httpUtils.apiPostObject(address + api, list, headers); // log.info("reslut => " + JSONObject.toJSON(responeVo)); // } catch (Exception e) { // log.error("e => " + e.getMessage()); // } - return ""; - } - - @Test - public void testF() { - Map test = Util.getProperties2Map("test"); - log.info("test => " + JSONObject.toJSONString(test)); - } - - + return ""; + } + + @Test + public void testF() { + Map test = Util.getProperties2Map("test"); + log.info("test => " + JSONObject.toJSONString(test)); + } + + } diff --git a/src/test/java/youhong/ai/utiltest/GenericTest.java b/src/test/java/youhong/ai/utiltest/GenericTest.java index 1369871..b88d6ed 100644 --- a/src/test/java/youhong/ai/utiltest/GenericTest.java +++ b/src/test/java/youhong/ai/utiltest/GenericTest.java @@ -4,6 +4,7 @@ import aiyh.utils.GenerateFileUtil; import aiyh.utils.Util; import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; import basetest.BaseTest; +import com.alibaba.fastjson.JSON; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.streaming.SXSSFCell; @@ -11,6 +12,8 @@ import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Test; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.RequestService; import weaver.youhong.ai.haripijiu.action.sapdocking.VoucherPayableNewAction; import java.lang.reflect.Field; @@ -172,12 +175,8 @@ public class GenericTest extends BaseTest { if (length >= columnWidth && length < 256 * 256) { sheet.setColumnWidth(colIndex, length); } - if (colIndex == 1 || colIndex == 2 || colIndex == 3) { - style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.RED.getIndex()); - } else { - style.setFillBackgroundColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex()); - } - style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + style.setFillBackgroundColor(HSSFColor.HSSFColorPredefined.BLACK.getIndex()); + style.setFillPattern(FillPatternType.BRICKS); return style; } @@ -215,6 +214,10 @@ public class GenericTest extends BaseTest { if (length >= columnWidth && length < 256 * 256) { sheet.setColumnWidth(colIndex, length); } + if (rowIndex % 2 == 0) { + style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex()); + style.setFillPattern(FillPatternType.SOLID_FOREGROUND); + } return style; } @@ -241,4 +244,11 @@ public class GenericTest extends BaseTest { } return count; } + + @Test + public void tesetAction() { + RequestService requestService = new RequestService(); + RequestInfo request = requestService.getRequest(433436); + System.out.println(JSON.toJSONString(request)); + } } \ No newline at end of file diff --git a/src/test/java/youhong/ai/yashilandai/GroupByTime.java b/src/test/java/youhong/ai/yashilandai/GroupByTime.java index 7c02caf..0ae96da 100644 --- a/src/test/java/youhong/ai/yashilandai/GroupByTime.java +++ b/src/test/java/youhong/ai/yashilandai/GroupByTime.java @@ -104,14 +104,6 @@ public class GroupByTime { public static Map>> groupData(List> dataList) { // 根据type进行分组 - // Map>> typeMap = new HashMap<>(); - // for (Map data : dataList) { - // String type = data.get("type").toString(); - // if (!typeMap.containsKey(type)) { - // typeMap.put(type, new ArrayList<>()); - // } - // typeMap.get(type).add(data); - // } Map>> typeMap = dataList.stream() .collect(Collectors.groupingBy(item -> String.valueOf(item.get("type")))); // 对每个type的数据进行日期分组 diff --git a/src/test/java/youhong/ai/yashilandai/MyTest.java b/src/test/java/youhong/ai/yashilandai/MyTest.java index fe496d9..c67357e 100644 --- a/src/test/java/youhong/ai/yashilandai/MyTest.java +++ b/src/test/java/youhong/ai/yashilandai/MyTest.java @@ -1,13 +1,11 @@ package youhong.ai.yashilandai; +import aiyh.utils.Util; import basetest.BaseTest; -import com.alibaba.fastjson.JSON; +import org.junit.Test; +import youhong.ai.mymapper.util.ScriptUtil; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -18,7 +16,18 @@ import java.util.Map; * @author youHong.ai */ public class MyTest extends BaseTest { - + + + @Test + public void test() { + Map map = new HashMap<>(); + map.put("test", "100"); + map.put("obj", "20"); + System.out.println(ScriptUtil.invokeScript("test", map)); + System.out.println(ScriptUtil.invokeScript("obj", map)); + System.out.println(ScriptUtil.invokeScript("test * obj", map)); + System.out.println(Double.parseDouble(Util.null2String(Util.null2String(null), "0.0"))); + } } diff --git a/src/test/java/youhong/ai/yihong/YiHongTest.java b/src/test/java/youhong/ai/yihong/YiHongTest.java index 4539fa9..30e826a 100644 --- a/src/test/java/youhong/ai/yihong/YiHongTest.java +++ b/src/test/java/youhong/ai/yihong/YiHongTest.java @@ -7,6 +7,10 @@ import org.junit.Test; import weaver.youhong.ai.yihong.formmode.stagediagram.mapper.ModeExpandSaveActionMapper; import weaver.youhong.ai.yihong.formmode.stagediagram.pojo.StageUpdateFieldConfig; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + /** *

屹宏测试

* @@ -23,4 +27,12 @@ public class YiHongTest extends BaseTest { StageUpdateFieldConfig testWrite = mapper.selectConfigUpdate("test_write"); System.out.println(JSON.toJSONString(testWrite)); } + + + @Test + public void test2() { + List strings = Arrays.asList("1", "2", "3", "4"); + System.out.println(strings.stream().filter(item -> !item.equals("2")).collect(Collectors.toList())); + + } } diff --git a/view-sql-server.sql b/view-sql-server.sql index 8bf2a25..53de47a 100644 --- a/view-sql-server.sql +++ b/view-sql-server.sql @@ -1,51 +1,49 @@ -- 流程类型视图,可用于数据集成或流览按钮 -if exists (select * from sysobjects where name = 'workflow_type_info_view') +if +exists (select * from sysobjects where name = 'workflow_type_info_view') drop view workflow_type_info_view -go + go create view workflow_type_info_view as select wb.id, wb.workflowname, wt.typename, wb.workflowdesc, - (IIF(wb.version is null, 1, wb.version)) version + (case when wb.version is null then 1 else wb.version end) version from workflow_base wb - RIGHT JOIN workflow_type wt on wb.workflowtype = wt.id -go + RIGHT JOIN workflow_type wt on wb.workflowtype = wt.id go -- 流程表单视图,用于流览按钮或数据集成,配置流程类型表可以用字段联动获取流程表表名 if exists (select * from sysobjects where name = 'workflow_table_view') - drop view workflow_table_view -go +drop view workflow_table_view + go create view workflow_table_view as select base.id, base.workflowname, base.formid, bill.tablename, - (IIF(base.version is null, 1, base.version)) version + (case when base.version is null then 1 else base.version end) version from workflow_bill bill - join workflow_base base on base.formid = bill.id -go + join workflow_base base on base.formid = bill.id go -- 流程明细表信息,可用流程主表查询对应的明细表信息,用于流览框 if exists (select * from sysobjects where name = 'workflow_detail_table_view') - drop view workflow_detail_table_view -go +drop view workflow_detail_table_view + go create view workflow_detail_table_view as -select (bill.id + '-' + base.id) id, - bill.id bill_id, - base.id workflow_id, +select (bill.id + '-' + base.id) id, + bill.id bill_id, + base.id workflow_id, base.workflowname, - base.formid main_formid, + base.formid main_formid, bill.tablename from workflow_billdetailtable bill - join workflow_base base on base.formid = bill.billid -go + join workflow_base base on base.formid = bill.billid go -- 流程和建模字段视图,更具流程和建模的billid可以查询流程和建模中的字段信息 if exists (select * from sysobjects where name = 'workflow_field_table_view') - drop view workflow_field_table_view -go +drop view workflow_field_table_view + go create view workflow_field_table_view as select wb.id, wb.fieldname, @@ -57,41 +55,39 @@ select wb.id, then (select distinct tablename from workflow_bill where id = wb.billid) else wb.detailtable end - ) tablename, + ) tablename, billid, ( case when wb.detailtable = '' then 'main table' when wb.detailtable is null then 'main table' else wb.detailtable end - ) showtablename, + ) showtablename, (case when wb.fieldhtmltype = '1' then '单行文本框' when wb.FIELDHTMLTYPE = '2' then '多行文本框' when wb.FIELDHTMLTYPE = '3' then '流览框' when wb.FIELDHTMLTYPE = '4' then 'check框' when wb.FIELDHTMLTYPE = '5' then '选择框' - else '附件上传' end) fieldhtmltype + else '附件上传' end) fieldhtmltype from workflow_billfield wb - left join htmllabelindex ht on wb.fieldlabel = ht.id -go + left join htmllabelindex ht on wb.fieldlabel = ht.id go -- 建模表信息视图 if exists (select * from sysobjects where name = 'mode_bill_info_view') - drop view mode_bill_info_view -go +drop view mode_bill_info_view + go create view mode_bill_info_view as select bill.id, bill.tablename, hti.indexdesc from workflow_bill bill left join htmllabelindex hti on hti.id = bill.namelabel where bill.id < 0 - and bill.tablename like 'uf%' -go + and bill.tablename like 'uf%' go -- 流程节点信息视图 if exists (select * from sysobjects where name = 'workflow_node_info_view') - drop view workflow_node_info_view -go +drop view workflow_node_info_view + go create view workflow_node_info_view as select distinct nb.id, nb.nodename, @@ -100,4 +96,4 @@ select distinct nb.id, from workflow_nodebase nb left join workflow_flownode fn on nb.id = fn.nodeid left join workflow_base wb on wb.id = fn.workflowid -go + go diff --git a/常用信息.md b/常用信息.md index fa60097..0dad4cb 100644 --- a/常用信息.md +++ b/常用信息.md @@ -67,6 +67,16 @@ git pull 远程服务名称 分支名称 # git pull origin dev ``` +## 移动端模拟地址 + +| 描述 | 移动端模拟地址 | +|--------|----------------------------------------------------------------------------------| +| 流程代办页面 | /spa/workflow/static4mobile/index.html#/center/doing | +| 工作台 | /spa/coms/static4mobile/index.html#/menu-preview?id=appDefaultPage&checkAccess=1 | +| 新建流程 | /spa/workflow/static4mobile/index.html#/add | +| 日程 | /spa/workplan/static4mobile/index.html#/calendar/myCalendar | +| 我的请求 | /spa/workflow/static4mobile/index.html#/center/mine | + ## 常用代码 ### 前端 @@ -206,7 +216,7 @@ myComp.setState({test1: test2}); ```js $(() => { - if (window.location.hash.indexOf("${appId}_organization-chart") !== -1) { + if (window.location.hash.indexOf("${appId}_") !== -1) { loadCssArr(['index.css']) /* ******************** 下面两个文件为开发新页面时候,如果用户登陆超时,用于集成系统登陆弹窗的依赖和css样式文件 ******************* */ // loadJs('/spa/portal/public/index.js') From cb02ca6184ecafdc4fc548b9fdd517829370fddc Mon Sep 17 00:00:00 2001 From: wangxuanran <3055088966@qq.com> Date: Thu, 11 May 2023 15:25:53 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=B8=AD=E8=88=B9=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E6=8E=A8=E9=80=81cms=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/xuanran.wang/bme/js/PayApply.js | 219 +++++++++++++----- .../xuanran/wang/cssc/cms/WorkflowToCms.java | 2 +- 2 files changed, 162 insertions(+), 59 deletions(-) diff --git a/javascript/xuanran.wang/bme/js/PayApply.js b/javascript/xuanran.wang/bme/js/PayApply.js index 3923e3f..8bf8f4c 100644 --- a/javascript/xuanran.wang/bme/js/PayApply.js +++ b/javascript/xuanran.wang/bme/js/PayApply.js @@ -3,49 +3,68 @@ const yjfksj = WfForm.convertFieldNameToId('yjfksj'); // 主表比例 const bl = WfForm.convertFieldNameToId('bcfkbl'); // 明细要求付款日期 -const detail3Yqfkrq = WfForm.convertFieldNameToId('yqfkrq', "detail_3"); +const detail3Yqfkrq = WfForm.convertFieldNameToId('yqfkrq',"detail_3"); // 明细本次付款比例 -const detailBl = WfForm.convertFieldNameToId('bcfkbl', "detail_3"); +const detailBl = WfForm.convertFieldNameToId('bcfkbl',"detail_3"); // 关联订单 -const relationOrder = WfForm.convertFieldNameToId("gldd"); +const relationOrder = WfForm.convertFieldNameToId("gldd"); // 明细4施工合同字段 -const detail4SgField = WfForm.convertFieldNameToId("sght", "detail_4"); +const detail4SgField = WfForm.convertFieldNameToId("sght","detail_4"); // 明细4采购合同字段 -const detail4CgField = WfForm.convertFieldNameToId("cght", "detail_4"); +const detail4CgField = WfForm.convertFieldNameToId("cght","detail_4"); // 明细4发票字段 -const detail4FpField = WfForm.convertFieldNameToId("fpje", "detail_4"); +const detail4FpField = WfForm.convertFieldNameToId("fpje","detail_4"); // 明细4合同发票金额和 let detail4Map = new Map(); // 明细3施工合同字段 -const detail3SgField = WfForm.convertFieldNameToId("sght", "detail_3"); +const detail3SgField = WfForm.convertFieldNameToId("sght","detail_3"); // 明细3采购合同字段 -const detail3CgField = WfForm.convertFieldNameToId("cght", "detail_3"); +const detail3CgField = WfForm.convertFieldNameToId("cght","detail_3"); // 明细3 含税金额 -const detail3TaxField = WfForm.convertFieldNameToId("ddhsje", "detail_3"); +const detail3TaxField = WfForm.convertFieldNameToId("ddhsje","detail_3"); // 明细3以收票金额 -const detail3YspField = WfForm.convertFieldNameToId("yspje", "detail_3"); +const detail3YspField = WfForm.convertFieldNameToId("yspje","detail_3"); + +const detail3ApplyMoneyField = WfForm.convertFieldNameToId("bcfkje", "detail_3"); +const detail3CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_3"); +const detail3Bl = WfForm.convertFieldNameToId('bcfkbl', "detail_3"); +let detailBlMap = new Map(); +const detail1Bl = WfForm.convertFieldNameToId('bcljfkbl', "detail_1"); +const detail1CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_1"); WfForm.registerCheckEvent(WfForm.OPER_ADDROW + "3", function (callback) { callback(); - setTimeout(() => { + setTimeout(()=>{ initDeatail3Date(); - }, 5) + },5) }); -// 关联订单变化时将明细四的合同-金额map进行初始化 +// // 关联订单变化时将明细四的合同-金额map进行初始化 +// WfForm.bindFieldChangeEvent(relationOrder, function(obj,id,value){ +// setTimeout(()=>{ +// initDetail4Map(); +// changeDetail3SpMoney(); +// },2000); +// }); + WfForm.bindFieldChangeEvent(relationOrder, function (obj, id, value) { setTimeout(() => { initDetail4Map(); changeDetail3SpMoney(); + changeDetail1ApplyAMount(); + }, 2000); +}); +WfForm.bindDetailFieldChangeEvent(detail3ApplyMoneyField, function () { + setTimeout(() => { + changeDetail1ApplyAMount(); }, 2000); }); - -WfForm.bindFieldChangeEvent(`${yjfksj},${bl}`, function (obj, id, value) { +WfForm.bindFieldChangeEvent(`${yjfksj},${bl}`, function(obj,id,value){ initDeatail3Date(); }); // 计算明细三开票金额 -function changeDetail3SpMoney() { +function changeDetail3SpMoney(){ let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); for (let i = 0; i < detail3RowArr.length; i++) { let rowIndex = detail3RowArr[i]; @@ -55,49 +74,49 @@ function changeDetail3SpMoney() { let fpje = detail4Map.get(detail3SgFieldVal) ?? detail4Map.get(detail3CgFieldVal); let mapVal = detail4Map.get(detail3SgFieldVal); let key = detail3SgFieldVal; - if (!mapVal) { + if(!mapVal){ key = detail3CgFieldVal; } console.log('key ', key); - if (fpje) { + if(fpje){ console.log('fpje => ', fpje); -// 0.1 0.3 + // 0.1 0.3 let detail3TaxVal = WfForm.getFieldValue(`${detail3TaxField}_${rowIndex}`); console.log('detail3TaxVal => ', detail3TaxVal); let tempJe = fpje - detail3TaxVal; console.log('tempJe => ', tempJe); - if (fpje > detail3TaxVal) { - WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: detail3TaxVal}); - } else if (tempJe <= 0 && fpje == 0) { - WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: 0}); - } else if (tempJe < 0) { - WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: fpje}); + if(fpje > detail3TaxVal){ + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`,{value: detail3TaxVal}); + }else if(tempJe <= 0 && fpje == 0){ + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`,{value: 0}); + }else if(tempJe < 0){ + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`,{value: fpje}); tempJe = 0; } detail4Map.set(key, tempJe); console.log('detail4Map ', detail4Map) - } else { - WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`, {value: 0}); + }else{ + WfForm.changeFieldValue(`${detail3YspField}_${rowIndex}`,{value: 0}); } } } } -function initDeatail3Date() { +function initDeatail3Date(){ let dateVal = WfForm.getFieldValue(yjfksj); let blVal = WfForm.getFieldValue(bl); let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); for (let i = 0; i < detail3RowArr.length; i++) { let rowIndex = detail3RowArr[i]; if (rowIndex !== "") { - WfForm.changeFieldValue(`${detail3Yqfkrq}_${rowIndex}`, {value: dateVal}); - WfForm.changeFieldValue(`${detailBl}_${rowIndex}`, {value: blVal}); + WfForm.changeFieldValue(`${detail3Yqfkrq}_${rowIndex}`,{value: dateVal}); + WfForm.changeFieldValue(`${detailBl}_${rowIndex}`,{value: blVal}); } } } -function initDetail4Map() { +function initDetail4Map(){ let detail4RowArr = WfForm.getDetailAllRowIndexStr('detail_4').split(","); console.log('detail4RowArr ', detail4RowArr); for (let i = 0; i < detail4RowArr.length; i++) { @@ -110,7 +129,7 @@ function initDetail4Map() { console.log('detail4SgFieldVal ', detail4SgFieldVal); console.log('detail4CgFieldVal ', detail4CgFieldVal); console.log('detail4FpFieldVal ', detail4FpFieldVal); - if (!detail4FpFieldVal) { + if(!detail4FpFieldVal){ continue; } key = detail4CgFieldVal ?? detail4SgFieldVal; @@ -123,37 +142,121 @@ function initDetail4Map() { console.log('detail4Map ', detail4Map) } -const detail3ApplyMoneyField = WfForm.convertFieldNameToId("bcfkje", "detail_3"); -const detail3CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_3"); -const detail3Bl = WfForm.convertFieldNameToId('bcfkbl', "detail_3"); -let detailBlMap = new Map(); -const detail1Bl = WfForm.convertFieldNameToId('fkbl', "detail_1"); -const detail1CgId = WfForm.convertFieldNameToId("cgddzbid", "detail_1"); + WfForm.bindDetailFieldChangeEvent(detail3ApplyMoneyField, (id, rowIndex, value) => { - let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); - detailBlMap = new Map(); - for (let i = 0; i < detail3RowArr.length; i++) { - let rowIndex = detail3RowArr[i]; - if (rowIndex !== "") { - let bl = parseFloat(WfForm.getFieldValue(`${detail3Bl}_${rowIndex}`)); - let cg = WfForm.getFieldValue(`${detail3CgId}_${rowIndex}`); - let mapVal = parseFloat(detailBlMap.get(cg) ?? 0) + bl; - detailBlMap.set(cg, mapVal); + setTimeout(()=>{ + let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); + detailBlMap = new Map(); + for (let i = 0; i < detail3RowArr.length; i++) { + let rowIndex = detail3RowArr[i]; + if (rowIndex !== "") { + let blStr = WfForm.getFieldValue(`${detail3Bl}_${rowIndex}`); + if(blStr == ''){ + console.log('111') + continue; + } + let bl = parseFloat(blStr); + console.log('bl => ' , bl); + let cg = WfForm.getFieldValue(`${detail3CgId}_${rowIndex}`); + let mapVal = detailBlMap.get(cg); + if(!mapVal){ + mapVal = 0; + } + mapVal+= bl; + detailBlMap.set(cg, mapVal); + } } - } - console.log('detailBlMap ', detailBlMap) - let detail1RowArr = WfForm.getDetailAllRowIndexStr('detail_1').split(","); - for (let i = 0; i < detail1RowArr.length; i++) { - let rowIndex = detail1RowArr[i]; - if (rowIndex !== "") { - let cg = WfForm.getFieldValue(`${detail1CgId}_${rowIndex}`); - let val = detailBlMap.get(cg) === '' ? 0 : detailBlMap.get(cg); - WfForm.changeFieldValue(`${detail1Bl}_${rowIndex}`, {value: val}) + console.log('detailBlMap ', detailBlMap) + let detail1RowArr = WfForm.getDetailAllRowIndexStr('detail_1').split(","); + for (let i = 0; i < detail1RowArr.length; i++) { + let rowIndex = detail1RowArr[i]; + if (rowIndex !== "") { + let cg = WfForm.getFieldValue(`${detail1CgId}_${rowIndex}`); + let val = detailBlMap.get(cg) === '' ? 0 : detailBlMap.get(cg); + WfForm.changeFieldValue(`${detail1Bl}_${rowIndex}`, {value: val}) + } } - } + },300); }); - +// 明细3合同总金额 +const detail3AmountField = WfForm.convertFieldNameToId("htzje", "detail_3"); +// 明细3订单号字段 +const detail3OrderField = WfForm.convertFieldNameToId("ddh","detail_3"); +// 明细1本次付款金额字段 +const detail1ApplyAmountField = WfForm.convertFieldNameToId("bcsqfkje","detail_1"); +// 明细1含税金额 +const detail1AmountTaxField = WfForm.convertFieldNameToId("ddmxxj","detail_1"); +// 明细1订单号 +const detail1OrderField = WfForm.convertFieldNameToId("ddh","detail_1"); +// 明细1预计付款日期 +const detail1ApplyDate = WfForm.convertFieldNameToId("yjfkrq","detail_1"); +function changeDetail1ApplyAMount(){ + let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); + // 明细3 订单号-合同总金额map + let detail3ContractAmountMap = new Map(); + let detail3ApplyAmountMap = new Map(); + let detail3ApplyMoneyField = WfForm.convertFieldNameToId("bcfkje", "detail_3"); + for (let i = 0; i < detail3RowArr.length; i++) { + let rowIndex = detail3RowArr[i]; + if (rowIndex !== "") { + let detail3Order = WfForm.getFieldValue(`${detail3OrderField}_${rowIndex}`); + if(!detail3ContractAmountMap.has(detail3Order)){ + detail3ContractAmountMap.set(detail3Order, parseFloat(WfForm.getFieldValue(`${detail3AmountField}_${rowIndex}`))); + } + let detail3Amount = parseFloat(WfForm.getFieldValue(`${detail3ApplyMoneyField}_${rowIndex}`)); + let sum = detail3ApplyAmountMap.get(detail3Order) ?? 0; + detail3ApplyAmountMap.set(detail3Order, sum + detail3Amount); + } + } + console.log('detail3ContractAmountMap : ', detail3ContractAmountMap); + console.log('detail3ApplyAmountMap : ', detail3ApplyAmountMap); + let detail1RowArr = WfForm.getDetailAllRowIndexStr('detail_1').split(","); + for (let i = 0; i < detail1RowArr.length; i++) { + let rowIndex = detail1RowArr[i]; + if (rowIndex !== "") { + let detail1Order =WfForm.getFieldValue(`${detail1OrderField}_${rowIndex}`); + console.log('detail1Order ', detail1Order); + // 含税金额 + let detail1AmountTax = parseFloat(WfForm.getFieldValue(`${detail1AmountTaxField}_${rowIndex}`) ?? 0); + console.log('detail1AmountTax ', detail1AmountTax); + // 本次付款金额和 + let applySum = parseFloat(detail3ApplyAmountMap.get(detail1Order) ?? 0); + console.log('applySum ', applySum); + // 合同总金额 + let contractAmount = parseFloat(detail3ContractAmountMap.get(detail1Order) ?? 0); + console.log('contractAmount ', contractAmount); + let val = (applySum / contractAmount) * detail1AmountTax; + console.log('计算金额 : ', val) + WfForm.changeFieldValue(`${detail1ApplyAmountField}_${rowIndex}`, {value: val}) + } + } +} +WfForm.bindDetailFieldChangeEvent(detail3Yqfkrq,()=>{ + initDetail1ApplyDate(); +}); +function initDetail1ApplyDate(){ + let detail3RowArr = WfForm.getDetailAllRowIndexStr('detail_3').split(","); + let detail3DateMap = new Map(); + for (let i = 0; i < detail3RowArr.length; i++) { + let rowIndex = detail3RowArr[i]; + if (rowIndex !== "") { + let detail3Order = WfForm.getFieldValue(`${detail3OrderField}_${rowIndex}`); + if(!detail3DateMap.has(detail3Order)){ + detail3DateMap.set(detail3Order, WfForm.getFieldValue(`${detail3Yqfkrq}_${rowIndex}`)); + } + } + } + console.log('detail3DateMap ', detail3DateMap); + let detail1RowArr = WfForm.getDetailAllRowIndexStr('detail_1').split(","); + for (let i = 0; i < detail1RowArr.length; i++) { + let rowIndex = detail1RowArr[i]; + if (rowIndex !== "") { + let detail1Order =WfForm.getFieldValue(`${detail1OrderField}_${rowIndex}`); + WfForm.changeFieldValue(`${detail1ApplyDate}_${rowIndex}`, {value: detail3DateMap.get(detail1Order)}) + } + } +} \ No newline at end of file diff --git a/src/main/java/weaver/xuanran/wang/cssc/cms/WorkflowToCms.java b/src/main/java/weaver/xuanran/wang/cssc/cms/WorkflowToCms.java index d9f5b35..b1eded5 100644 --- a/src/main/java/weaver/xuanran/wang/cssc/cms/WorkflowToCms.java +++ b/src/main/java/weaver/xuanran/wang/cssc/cms/WorkflowToCms.java @@ -57,7 +57,7 @@ public class WorkflowToCms extends SafeCusBaseAction { .successField(Util.null2DefaultStr(successField, "success")) .successValue(Util.null2DefaultStr(successVal, "true")) .errorMsg(Util.null2DefaultStr(msg, "error")) - .dataKey(Util.null2DefaultStr(dataKey, "result.accessToken")) + .dataKey(Util.null2DefaultStr(dataKey, "")) .build(); log.info(""); From 0cc0b9889abf811123b06076221347ea09e224ae Mon Sep 17 00:00:00 2001 From: "youhong.ai" Date: Fri, 12 May 2023 11:15:29 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E6=B4=B2=E9=99=85=E9=85=92=E5=BA=97?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=85=83=E7=B4=A0=E5=BC=80=E5=8F=91=E3=80=81?= =?UTF-8?q?delwithbug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/common/Utils.js | 13 + .../aiyh/utils/httpUtil/util/HttpUtils.java | 7 +- .../aiyh/utils/recordset/ResultMapper.java | 12 +- .../contoller/TaskElementController.java | 32 +- .../entity/IhgTaskElementConfigItem.java | 8 + .../taskele/mapper/TaskElementMapper.java | 35 +- .../taskele/service/TaskElementService.java | 115 +++++- .../taskele/vo/IhgTaskElementVo.java | 9 +- .../config/service/DealWithMapping.java | 9 +- .../IHGWorkListInfoConvert.properties | 2 + .../DecentralizationOfPowersCronJob.java | 343 +++++++++--------- .../java/youhong/ai/yihong/YiHongTest.java | 10 + 12 files changed, 386 insertions(+), 209 deletions(-) create mode 100644 src/main/resources/WEB-INF/prop/prop2map/IHGWorkListInfoConvert.properties diff --git a/javascript/common/Utils.js b/javascript/common/Utils.js index 5b7d700..45b545c 100644 --- a/javascript/common/Utils.js +++ b/javascript/common/Utils.js @@ -115,6 +115,19 @@ class CusUtils { return Utils.convertNameObjToId(fieldName) } + getQueryString(name) { + let reg = new RegExp("(^|&|\/?)" + name + "=([^&]*)(&|$)", "i"); + let searchStr = window.location.href + if (searchStr.startsWith('&')) { + searchStr = searchStr.substr(1) + } + let search = searchStr.match(reg) + if (search != null) { + return unescape(search[2]); + } + return null; + } + /** * 将字段名称转为字段id * @param fieldObj 字段名称对象 {string|object} diff --git a/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java b/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java index 6aabc85..f728648 100644 --- a/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java +++ b/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java @@ -32,6 +32,7 @@ import weaver.file.ImageFileManager; import javax.ws.rs.core.MediaType; import java.io.*; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.*; @@ -127,7 +128,11 @@ public class HttpUtils { builder.append("&"); builder.append(entry.getKey()); builder.append("="); - builder.append(entry.getValue()); + try { + builder.append(URLEncoder.encode(Util.null2String(entry.getValue()), "UTF-8")); + } catch (UnsupportedEncodingException e) { + builder.append(entry.getKey()); + } } return removeSeparator(builder); } diff --git a/src/main/java/aiyh/utils/recordset/ResultMapper.java b/src/main/java/aiyh/utils/recordset/ResultMapper.java index cd3a2d7..1f1389d 100644 --- a/src/main/java/aiyh/utils/recordset/ResultMapper.java +++ b/src/main/java/aiyh/utils/recordset/ResultMapper.java @@ -460,7 +460,7 @@ public class ResultMapper { } if ("int".equalsIgnoreCase(columnType) || "long".equalsIgnoreCase(columnType) || "number".equalsIgnoreCase(columnType) || "MEDIUMINT".equalsIgnoreCase(columnType) || "TINYINT".equalsIgnoreCase(columnType) || "SMALLINT".equalsIgnoreCase(columnType) || "BIGINT".equalsIgnoreCase(columnType) || "INTEGER".equalsIgnoreCase(columnType)) { if (enable) { - ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getInt(i + 1)); + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getInt(columnName[i])); continue; } if (DBConstant.DB_TYPE_ORACLE.equals(rs.getDBType())) { @@ -473,11 +473,11 @@ public class ResultMapper { } if ("FLOAT".equalsIgnoreCase(columnType) || "DOUBLE".equalsIgnoreCase(columnType) || "DECIMAL".equalsIgnoreCase(columnType)) { if (enable) { - ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(i + 1)); + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(columnName[i])); continue; } if (DBConstant.DB_TYPE_ORACLE.equals(rs.getDBType())) { - ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(i + 1)); + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(columnName[i])); } ((Map) o).put(columnName[i].toLowerCase(), rs.getString(i + 1)); ((Map) o).put(columnName[i].toUpperCase(), rs.getString(i + 1)); @@ -507,7 +507,7 @@ public class ResultMapper { } } if (enable) { - ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(i + 1)); + ((Map) o).put(Util.toCamelCase(columnName[i]), rs.getString(columnName[i])); continue; } if (DBConstant.DB_TYPE_ORACLE.equals(rs.getDBType())) { @@ -569,7 +569,7 @@ public class ResultMapper { cassociationValue = paramType.get(declaredField.getType()).apply(String.valueOf(cassociationValue)); } try { - if (Objects.nonNull(value)) { + if (Objects.nonNull(cassociationValue)) { propertyDescriptor.getWriteMethod().invoke(o, cassociationValue); } } catch (Exception e) { @@ -651,7 +651,6 @@ public class ResultMapper { Association[] mappings = annotation.value(); Association mapping = null; for (Association item : mappings) { - Util.getLogger().info("column: " + item.column() + " ===property: " + item.property() + " ====fieldName: " + filedName); String property = isMap ? item.column() : item.property(); if (isMap ? filedName.equalsIgnoreCase(property) : filedName.equals(property)) { mapping = item; @@ -664,7 +663,6 @@ public class ResultMapper { Id id = annotation.id(); String column = annotation.column(); String columnValue = rs.getString(column); - Util.getLogger().info(Arrays.toString(rs.getColumnName())); if (Objects.isNull(columnValue) || "".equals(columnValue)) { columnValue = rs.getString(column.toUpperCase()); } diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java index dbb67f5..7e5ea84 100644 --- a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/contoller/TaskElementController.java @@ -52,10 +52,40 @@ public class TaskElementController { @QueryParam("id") String configId) { User user = HrmUserVarify.getUser(request, response); try { - return ApiResult.success(service.getList(user, params,configId)); + return ApiResult.success(service.getList(user, params, configId)); } catch (Exception e) { log.error("get task list error!\n" + Util.getErrString(e)); return ApiResult.error("system error!"); } } + + + @Path("/get-btn") + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String buttonInfo(@Context HttpServletRequest request, + @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + try { + return ApiResult.success(service.buttonInfo(user)); + } catch (Exception e) { + log.error("get button info error!\n" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + } + + + @Path("/clear-config") + @GET + @Produces(MediaType.APPLICATION_JSON) + public String clearConfig() { + try { + service.clearConfig(); + return ApiResult.successNoData(); + } catch (Exception e) { + log.error("clear config error!\n" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + } } diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java index 5504335..e802d7e 100644 --- a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/entity/IhgTaskElementConfigItem.java @@ -29,6 +29,11 @@ public class IhgTaskElementConfigItem { private String unitEn; /** icon */ private String icon; + + /** 移动端图标 */ + private String iconMobile; + /** 移动端激活图标 */ + private String iconMobileActive; /** 激活icon */ private String iconActive; /** 查看权限 */ @@ -36,6 +41,9 @@ public class IhgTaskElementConfigItem { /** 数据来源 */ private String dataSource; + /** 序号 */ + private String sortNum; + /** 跳转链接 */ private String link; /** 数据来源值 */ diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java index 607155d..164c565 100644 --- a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/mapper/TaskElementMapper.java @@ -23,7 +23,7 @@ public interface TaskElementMapper { * * @return 配置信息 */ - @Select("select * from uf_ihg_el_config ") + @Select("select * from uf_ihg_el_config where enable_status = 1") @Associations({ @Association( property = "icon", @@ -32,6 +32,14 @@ public interface TaskElementMapper { @Association( property = "iconActive", column = "icon_active", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconMobile", + column = "icon_mobile", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconMobileActive", + column = "icon_mobile_active", id = @Id(methodId = 1, value = String.class)) }) List selectConfig(); @@ -42,7 +50,7 @@ public interface TaskElementMapper { * @param configId 配置id * @return 配置信息 */ - @Select("select * from uf_ihg_el_config where id = #{configId}") + @Select("select * from uf_ihg_el_config where id = #{configId} and enable_status = 1") @Associations({ @Association( property = "icon", @@ -51,6 +59,14 @@ public interface TaskElementMapper { @Association( property = "iconActive", column = "icon_active", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconMobile", + column = "icon_mobile", + id = @Id(methodId = 1, value = String.class)), + @Association( + property = "iconMobileActive", + column = "icon_mobile_active", id = @Id(methodId = 1, value = String.class)) }) IhgTaskElementConfigItem selectConfig(@ParamMapper("configId") String configId); @@ -72,7 +88,6 @@ public interface TaskElementMapper { * @param viewAuthoritySql 自定义权限sql * @param user 用户 * @param map 参数 - * @param where 条件参数 * @return 权限信息 */ @Select(custom = true) @@ -86,6 +101,7 @@ public interface TaskElementMapper { * @param customerValue 自定义sql * @param item 参数 * @param user 用户 + * @param map 当前参数 * @param where 条件参数 * @return 任务信息 */ @@ -93,5 +109,16 @@ public interface TaskElementMapper { List> selectWorkList(@SqlString String customerValue, @ParamMapper("param") Map item, @ParamMapper("user") User user, - @ParamMapper("where") Map where); + @ParamMapper("where") Map where, + @ParamMapper("current") Map map); + + /** + *

查询自定义转换规则

+ * + * @param sql 自定义转换规则 + * @param o 值 + * @return 转换后的值 + */ + @Select(custom = true) + String selectConvert(@SqlString String sql, @ParamMapper("value") String o); } diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java index 8df2385..5845bc2 100644 --- a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/service/TaskElementService.java @@ -9,13 +9,11 @@ import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; import com.api.youhong.ai.ihgzhouji.taskele.mapper.TaskElementMapper; import com.api.youhong.ai.ihgzhouji.taskele.mapstruct.TaskElementMapstruct; import com.api.youhong.ai.ihgzhouji.taskele.vo.IhgTaskElementVo; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; import weaver.hrm.User; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; /** *

任务列表元素service

@@ -26,6 +24,29 @@ import java.util.stream.Collectors; */ public class TaskElementService { private final TaskElementMapper mapper = Util.getMapper(TaskElementMapper.class); + private final Logger log = Util.getLogger(); + + private final RecordSet rs = new RecordSet(); + + private volatile Map config = null; + + public void clearConfig() { + this.config = null; + } + + private Map getConfig() { + if (this.config == null) { + synchronized (TaskElementService.class) { + if (this.config == null) { + this.config = Util.readProperties2Map("IHGWorkListInfoConvert", "cus"); + if (config == null) { + this.config = Collections.emptyMap(); + } + } + } + } + return config; + } public List getList(User user) { List ihgTaskElementConfItemList = mapper.selectConfig(); @@ -50,7 +71,7 @@ public class TaskElementService { for (Map.Entry>> entry : taskConfigMap.entrySet()) { IhgTaskElementConfigItem taskElementConfigItem = entry.getKey(); List> authorityList = entry.getValue(); - List> workList = queryWorkList(taskElementConfigItem, authorityList, user, "", Collections.emptyMap()); + List> workList = queryWorkList(taskElementConfigItem, authorityList, user, "", Collections.emptyMap(), map); IhgTaskElementVo ihgTaskElementVo = TaskElementMapstruct.INSTANCE.entity2Vo(taskElementConfigItem); ihgTaskElementVo.setList(workList); ihgTaskElementVo.setSize(workList.size()); @@ -60,26 +81,44 @@ public class TaskElementService { } result.add(ihgTaskElementVo); } + result.sort(Comparator.comparing(item -> StrUtil.isBlank(item.getSortNum()) ? -1 : Integer.parseInt(item.getSortNum()))); return result; } private List> queryWorkList(IhgTaskElementConfigItem taskElementConfigItem, List> authorityList, User user, String whereStr, - Map whereMap) { + Map whereMap, + Map currentMap) { String dataSource = taskElementConfigItem.getDataSource(); String customerValue = taskElementConfigItem.getCustomerValue(); if (StrUtil.isBlank(customerValue)) { throw new CustomerException("自定义sql或自定义接口不能为空!"); } List> result = new ArrayList<>(); + Map convertConfig = getConfig(); for (Map item : authorityList) { if ("0".equals(dataSource)) { // 自定义sql customerValue += " " + whereStr; - List> list = mapper.selectWorkList(customerValue, item, user, whereMap); + List> list = mapper.selectWorkList(customerValue, item, user, whereMap, currentMap); if (CollectionUtil.isNotEmpty(list)) { result.addAll(list); + Map convert = (Map) convertConfig.get("convert"); + if (Objects.nonNull(convert)) { + // 自定义转换设置 + for (Map listItem : list) { + for (Map.Entry entry : convert.entrySet()) { + String sql = Util.null2String(entry.getValue()); + String replace = sql.replace("$?$", "#{value}"); + if (StrUtil.isNotBlank(replace)) { + String value = mapper.selectConvert(replace, Util.null2String(listItem.get(Util.null2String(entry.getKey())))); + listItem.put(entry.getKey(), value); + } + } + } + + } } } else { // 自定义接口 @@ -99,19 +138,24 @@ public class TaskElementService { } } } - // 去重 - result = result.stream() - .filter(distinctByKey(item -> item.get("id"))) - .collect(Collectors.toList()); - return result; + return removeDuplicates(result); } - static Predicate distinctByKey(Function keyExtractor) { - Map seen = new ConcurrentHashMap<>(8); - return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + public List> removeDuplicates(List> list) { + Set idSet = new HashSet<>(); + List> resultList = new ArrayList<>(); + for (Map map : list) { + String id = Util.null2String(map.get("id")); + if (!idSet.contains(id)) { + idSet.add(id); + resultList.add(map); + } + } + return resultList; } + /** *

查询自定义的数据

* @@ -134,8 +178,14 @@ public class TaskElementService { Map valueMap = (Map) entry.getValue(); String key = Util.null2String(valueMap.get("key")); String value = Util.null2String(valueMap.get("value")); + String type = Util.null2String(valueMap.get("type")); if (StrUtil.isNotBlank(value)) { - builder.append(" and ").append(key).append(" = ").append("#{where.").append(key).append("}"); + if ("like".equalsIgnoreCase(type)) { + value = "%" + value + "%"; + builder.append(" and ").append(key).append(" like ").append("#{where.").append(key).append("}"); + } else { + builder.append(" and ").append(key).append(" = ").append("#{where.").append(key).append("}"); + } map.put(key, value); } } @@ -147,7 +197,7 @@ public class TaskElementService { return null; } // 查询数据 - List> workList = this.queryWorkList(ihgTaskElementConfItem, authorityList, user, whereStr, map); + List> workList = this.queryWorkList(ihgTaskElementConfItem, authorityList, user, whereStr, map, map); IhgTaskElementVo ihgTaskElementVo = TaskElementMapstruct.INSTANCE.entity2Vo(ihgTaskElementConfItem); ihgTaskElementVo.setList(workList); ihgTaskElementVo.setSize(workList.size()); @@ -157,4 +207,35 @@ public class TaskElementService { } return ihgTaskElementVo; } + + /** + *

查询按钮权限和链接地址

+ * + * @param user 当前用户 + * @return 查询结果 + */ + public Map buttonInfo(User user) { + String sendWorkButtonAuthority = Util.getCusConfigValue("SEND_WORK_BUTTON_AUTHORITY"); + String sendWorkButtonLink = Util.getCusConfigValue("SEND_WORK_BUTTON_LINK"); + String workListButtonAuthority = Util.getCusConfigValue("WORK_LIST_BUTTON_AUTHORITY"); + String workListButtonLink = Util.getCusConfigValue("WORK_LIST_BUTTON_LINK"); + Map result = new HashMap<>(8); + // 设置查询基础参数 + Map map = new HashMap<>(8); + map.put("currentDate", Util.getTime("yyyy-MM-dd")); + map.put("currentTime", Util.getTime("HH:mm:ss")); + if (StrUtil.isNotBlank(sendWorkButtonAuthority)) { + List> maps = mapper.selectAuthority(sendWorkButtonAuthority, user, map); + if (CollectionUtil.isNotEmpty(maps)) { + result.put("sendWork", sendWorkButtonLink); + } + } + if (StrUtil.isNotBlank(sendWorkButtonAuthority)) { + List> maps = mapper.selectAuthority(workListButtonAuthority, user, map); + if (CollectionUtil.isNotEmpty(maps)) { + result.put("workList", workListButtonLink); + } + } + return result; + } } diff --git a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java index 5202fc3..27feaee 100644 --- a/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java +++ b/src/main/java/com/api/youhong/ai/ihgzhouji/taskele/vo/IhgTaskElementVo.java @@ -25,15 +25,18 @@ public class IhgTaskElementVo { private String title; /** 单位 */ private String unit; - /** icon */ private String icon; - /** 激活icon */ private String iconActive; + /** 移动端图标 */ + private String iconMobile; + /** 移动端激活图标 */ + private String iconMobileActive; /** 跳转链接 */ private String link; - + /** 序号 */ + private String sortNum; /** 数据长度 */ private Integer size; /** 数据 */ diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index f025602..a893b70 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -1297,8 +1297,11 @@ public class DealWithMapping extends ToolUtil { if (null == resultList || resultList.isEmpty()) { return; } + if (Objects.isNull(childList) || childList.isEmpty()) { + list.addAll(resultList); + return; + } if ("0".equals(childType)) { - // 对象类型 for (Object o : resultList) { Map item = new HashMap<>(); @@ -1376,6 +1379,10 @@ public class DealWithMapping extends ToolUtil { if (null == resultList || resultList.isEmpty()) { return; } + if (Objects.isNull(childList) || childList.isEmpty()) { + list.addAll(resultList); + return; + } if ("0".equals(childType)) { // 对象类型 diff --git a/src/main/resources/WEB-INF/prop/prop2map/IHGWorkListInfoConvert.properties b/src/main/resources/WEB-INF/prop/prop2map/IHGWorkListInfoConvert.properties new file mode 100644 index 0000000..d5ee66a --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/IHGWorkListInfoConvert.properties @@ -0,0 +1,2 @@ +# 任务接受人转换规则 +cus.convert.rwjsr=select lastname from hrmresource where id = $?$ diff --git a/src/main/youhong_ai_old_src/weaver/aiyh_igh/schedule/decentralization/DecentralizationOfPowersCronJob.java b/src/main/youhong_ai_old_src/weaver/aiyh_igh/schedule/decentralization/DecentralizationOfPowersCronJob.java index 931f97d..a859682 100644 --- a/src/main/youhong_ai_old_src/weaver/aiyh_igh/schedule/decentralization/DecentralizationOfPowersCronJob.java +++ b/src/main/youhong_ai_old_src/weaver/aiyh_igh/schedule/decentralization/DecentralizationOfPowersCronJob.java @@ -30,190 +30,183 @@ import java.util.stream.Collectors; @Setter @ActionDesc(value = "部门属于酒店的部门分级分权控制定时任务,只能查看到同层的酒店部门信息", author = "aiyh") public class DecentralizationOfPowersCronJob extends BaseCronJob { - - @RequiredMark("支持中心部门ID") - @PrintParamMark - private String supportCenterDeptId; - - @Setter(AccessLevel.NONE) - private final Logger log = Util.getLogger(); - - private final RecordSet recordSet = new RecordSet(); - - private final DecentralizationMapper mapper = Util.getMapper(DecentralizationMapper.class); - - - @Override - public void execute() { - try { - Util.verifyRequiredField(this); - doExecute(); - } catch (Exception e) { - log.error(Util.logStr("execute cronJob fail! error msg is [{}],stack trace is [\n{}\n]", - e.getMessage(), Util.getErrString(e))); - throw new CustomerException("execute cronJob fail," + e.getMessage()); - } - } - - - public void doExecute() { - List hotelInfoList = mapper.selectCnTileFromOrginfo(); - - for (OrgInfoHotelEntity orgInfoHotelEntity : hotelInfoList) { - insertSysdetachinfo(orgInfoHotelEntity); - } - log.info("查询酒店后信息数据: " + hotelInfoList.size()); + + @RequiredMark("支持中心部门ID") + @PrintParamMark + private String supportCenterDeptId; + + @Setter(AccessLevel.NONE) + private final Logger log = Util.getLogger(); + + private final RecordSet recordSet = new RecordSet(); + + private final DecentralizationMapper mapper = Util.getMapper(DecentralizationMapper.class); + + + @Override + public void execute() { + try { + Util.verifyRequiredField(this); + doExecute(); + } catch (Exception e) { + log.error(Util.logStr("execute cronJob fail! error msg is [{}],stack trace is [\n{}\n]", + e.getMessage(), Util.getErrString(e))); + throw new CustomerException("execute cronJob fail," + e.getMessage()); + } + } + + + public void doExecute() { + List hotelInfoList = mapper.selectCnTileFromOrginfo(); + + for (OrgInfoHotelEntity orgInfoHotelEntity : hotelInfoList) { + insertSysdetachinfo(orgInfoHotelEntity); + } // 将没有infoID的数据过滤 - List hasInfoIdHotelInfo = hotelInfoList.stream() - .filter(item -> item.getInfoId() != null && item.getInfoId() > 0) - .collect(Collectors.toList()); - log.info("过滤后数据信息:" + hasInfoIdHotelInfo.size()); - Map> groupByUpdate = hasInfoIdHotelInfo - .stream().collect(Collectors.groupingBy(OrgInfoHotelEntity::getUpdate)); - - log.info("分组后数据信息:" + groupByUpdate.size()); - List updateInfo = groupByUpdate.get("true"); - List insertInfo = groupByUpdate.get("false"); - if (updateInfo == null) { - updateInfo = new ArrayList<>(); - } - if (insertInfo == null) { - insertInfo = new ArrayList<>(); - } - List insertSqlArgs = new ArrayList<>(); - insertInfo.forEach(item -> { - List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(item, ""); - insertSqlArgs.addAll(lists); - }); - log.info("将待插入数据插入数据表中: " + insertSqlArgs.size()); - if (!insertSqlArgs.isEmpty()) { - boolean insertSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), insertSqlArgs); - if (!insertSuccess) { - log.error("批量插入权限数据失败!" + OrgInfoHotelEntity.getInsertSql() + "; " + - JSON.toJSONString(insertSqlArgs.get(0))); - } - } - List updateDetachDetailList = new ArrayList<>(); - List insertDetachDetailList = new ArrayList<>(); - for (OrgInfoHotelEntity orgInfoHotelEntity : updateInfo) { - log.info("循环查询权限ID: " + orgInfoHotelEntity); - Integer detachdetailId1 = mapper.selectSysdetachdetailByInfoIdAndYh(orgInfoHotelEntity.getInfoId(), 1); - if (null != detachdetailId1 && detachdetailId1 > 0) { + List hasInfoIdHotelInfo = hotelInfoList.stream() + .filter(item -> item.getInfoId() != null && item.getInfoId() > 0) + .collect(Collectors.toList()); + Map> groupByUpdate = hasInfoIdHotelInfo + .stream().collect(Collectors.groupingBy(OrgInfoHotelEntity::getUpdate)); + + List updateInfo = groupByUpdate.get("true"); + List insertInfo = groupByUpdate.get("false"); + if (updateInfo == null) { + updateInfo = new ArrayList<>(); + } + if (insertInfo == null) { + insertInfo = new ArrayList<>(); + } + List insertSqlArgs = new ArrayList<>(); + insertInfo.forEach(item -> { + List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(item, ""); + insertSqlArgs.addAll(lists); + }); + if (!insertSqlArgs.isEmpty()) { + boolean insertSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), insertSqlArgs); + if (!insertSuccess) { + log.error("批量插入权限数据失败!" + OrgInfoHotelEntity.getInsertSql() + "; " + + JSON.toJSONString(insertSqlArgs.get(0))); + } + } + List updateDetachDetailList = new ArrayList<>(); + List insertDetachDetailList = new ArrayList<>(); + for (OrgInfoHotelEntity orgInfoHotelEntity : updateInfo) { + Integer detachdetailId1 = mapper.selectSysdetachdetailByInfoIdAndYh(orgInfoHotelEntity.getInfoId(), 1); + if (null != detachdetailId1 && detachdetailId1 > 0) { // 需要更新 - OrgInfoHotelEntity copy = OrgInfoHotelEntity.copy(orgInfoHotelEntity); - copy.setId(String.valueOf(detachdetailId1)); - copy.setSourceType(1); - updateDetachDetailList.add(copy); - } - Integer detachdetailId2 = mapper.selectSysdetachdetailByInfoIdAndYh(orgInfoHotelEntity.getInfoId(), 2); - if (null != detachdetailId2 && detachdetailId2 > 0) { + OrgInfoHotelEntity copy = OrgInfoHotelEntity.copy(orgInfoHotelEntity); + copy.setId(String.valueOf(detachdetailId1)); + copy.setSourceType(1); + updateDetachDetailList.add(copy); + } + Integer detachdetailId2 = mapper.selectSysdetachdetailByInfoIdAndYh(orgInfoHotelEntity.getInfoId(), 2); + if (null != detachdetailId2 && detachdetailId2 > 0) { // 需要更新 - OrgInfoHotelEntity copy = OrgInfoHotelEntity.copy(orgInfoHotelEntity); - copy.setId(String.valueOf(detachdetailId2)); - copy.setSourceType(2); - updateDetachDetailList.add(copy); - } - boolean hasSourceType1 = null == detachdetailId1 || detachdetailId1 < 0; - boolean hasSourceType2 = null == detachdetailId2 || detachdetailId2 < 0; - if (hasSourceType1 && hasSourceType2) { + OrgInfoHotelEntity copy = OrgInfoHotelEntity.copy(orgInfoHotelEntity); + copy.setId(String.valueOf(detachdetailId2)); + copy.setSourceType(2); + updateDetachDetailList.add(copy); + } + boolean hasSourceType1 = null == detachdetailId1 || detachdetailId1 < 0; + boolean hasSourceType2 = null == detachdetailId2 || detachdetailId2 < 0; + if (hasSourceType1 && hasSourceType2) { // 需要插入 - insertDetachDetailList.add(orgInfoHotelEntity); - } - } - log.info("需要插入的数据: " + insertDetachDetailList.size()); - log.info("需要更新的数据: " + updateDetachDetailList.size()); - insertSqlArgs.clear(); - insertDetachDetailList.forEach(item -> { - List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(item, ""); - insertSqlArgs.addAll(lists); - }); - if (!insertSqlArgs.isEmpty()) { - boolean insertSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), insertSqlArgs); - if (!insertSuccess) { - log.error("批量插入权限数据失败!" + OrgInfoHotelEntity.getInsertSql() + "; " + - JSON.toJSONString(insertSqlArgs.get(0))); - } - } - - List updateSqlArgs = new ArrayList<>(); - updateDetachDetailList.forEach(item -> { - List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlUpdateList(item); - updateSqlArgs.add(lists); - }); - if (!updateSqlArgs.isEmpty()) { - boolean updateSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getUpdateSql(), updateSqlArgs); - if (!updateSuccess) { - log.error("批量跟新权限数据失败!" + OrgInfoHotelEntity.getUpdateSql() + "; " + - JSON.toJSONString(insertSqlArgs.get(0))); - } - } + insertDetachDetailList.add(orgInfoHotelEntity); + } + } + insertSqlArgs.clear(); + insertDetachDetailList.forEach(item -> { + List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(item, ""); + insertSqlArgs.addAll(lists); + }); + if (!insertSqlArgs.isEmpty()) { + boolean insertSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), insertSqlArgs); + if (!insertSuccess) { + log.error("批量插入权限数据失败!" + OrgInfoHotelEntity.getInsertSql() + "; " + + JSON.toJSONString(insertSqlArgs.get(0))); + } + } + + List updateSqlArgs = new ArrayList<>(); + updateDetachDetailList.forEach(item -> { + List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlUpdateList(item); + updateSqlArgs.add(lists); + }); + if (!updateSqlArgs.isEmpty()) { + boolean updateSuccess = recordSet.executeBatchSql(OrgInfoHotelEntity.getUpdateSql(), updateSqlArgs); + if (!updateSuccess) { + log.error("批量跟新权限数据失败!" + OrgInfoHotelEntity.getUpdateSql() + "; " + + JSON.toJSONString(insertSqlArgs.get(0))); + } + } // 特殊权限设置 - List idList = mapper.selectBrotherDeptIds(supportCenterDeptId); - Integer infoId = mapper.selectInfoIdByCnTitle("支持中心分权查看"); - - if (null == infoId || infoId < 0) { + List idList = mapper.selectBrotherDeptIds(supportCenterDeptId); + Integer infoId = mapper.selectInfoIdByCnTitle("支持中心分权查看"); + + if (null == infoId || infoId < 0) { // 插入 - OrgInfoHotelEntity orgInfoHotelEntity = new OrgInfoHotelEntity(); - orgInfoHotelEntity.setDeptId(Util.join(idList, ",")); - boolean insertSuccess = mapper.insertSysdetachinfo("支持中心分权查看"); - if (insertSuccess) { + OrgInfoHotelEntity orgInfoHotelEntity = new OrgInfoHotelEntity(); + orgInfoHotelEntity.setDeptId(Util.join(idList, ",")); + boolean insertSuccess = mapper.insertSysdetachinfo("支持中心分权查看"); + if (insertSuccess) { // 查询最大ID - infoId = mapper.selectIdByCntitle("支持中心分权查看"); - orgInfoHotelEntity.setInfoId(infoId); - List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(orgInfoHotelEntity, supportCenterDeptId); - if (!lists.isEmpty()) { - boolean b = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), lists); - if (!b) { - log.error("插入特殊权限失败!" + OrgInfoHotelEntity.getInsertSql() + " : " + JSON.toJSONString(lists)); - } - } - } - } else { + infoId = mapper.selectIdByCntitle("支持中心分权查看"); + orgInfoHotelEntity.setInfoId(infoId); + List lists = OrgInfoHotelEntity.orgInfoHotelEntityToSqlList(orgInfoHotelEntity, supportCenterDeptId); + if (!lists.isEmpty()) { + boolean b = recordSet.executeBatchSql(OrgInfoHotelEntity.getInsertSql(), lists); + if (!b) { + log.error("插入特殊权限失败!" + OrgInfoHotelEntity.getInsertSql() + " : " + JSON.toJSONString(lists)); + } + } + } + } else { // 更新 - Integer sysdetachId1 = mapper.selectSysdetachdetailByInfoIdAndYh(infoId, 1); - Integer sysdetachId2 = mapper.selectSysdetachdetailByInfoIdAndYh(infoId, 2); - OrgInfoHotelEntity orgInfoHotelEntity = new OrgInfoHotelEntity(); - orgInfoHotelEntity.setDeptId(Util.join(idList, ",")); - orgInfoHotelEntity.setInfoId(infoId); - orgInfoHotelEntity.setId(String.valueOf(sysdetachId1)); - orgInfoHotelEntity.setSourceType(1); - List list = OrgInfoHotelEntity.orgInfoHotelEntityToSqlUpdateList(orgInfoHotelEntity); - if (!list.isEmpty()) { - recordSet.executeUpdate(OrgInfoHotelEntity.getUpdateSql(), list); - } - orgInfoHotelEntity.setId(String.valueOf(sysdetachId2)); - orgInfoHotelEntity.setSourceType(2); - if (!list.isEmpty()) { - recordSet.executeUpdate(OrgInfoHotelEntity.getUpdateSql(), list); - } - } - - AppDetachComInfo appDetachComInfo = new AppDetachComInfo(); - appDetachComInfo.resetAppDetachInfo(); - } - - /** - * 插入信息表数据 - * - * @param orgInfoHotelEntity 信息数据实体 - */ - private void insertSysdetachinfo(OrgInfoHotelEntity orgInfoHotelEntity) { - Integer integer = mapper.selectIdByCntitle(orgInfoHotelEntity.getCnTitle()); - if (null != integer && integer > 0) { - orgInfoHotelEntity.setInfoId(integer); - orgInfoHotelEntity.setUpdate("true"); - return; - } - boolean insertSuccess = mapper.insertSysdetachinfo(orgInfoHotelEntity.getCnTitle()); - if (insertSuccess) { + Integer sysdetachId1 = mapper.selectSysdetachdetailByInfoIdAndYh(infoId, 1); + Integer sysdetachId2 = mapper.selectSysdetachdetailByInfoIdAndYh(infoId, 2); + OrgInfoHotelEntity orgInfoHotelEntity = new OrgInfoHotelEntity(); + orgInfoHotelEntity.setDeptId(Util.join(idList, ",")); + orgInfoHotelEntity.setInfoId(infoId); + orgInfoHotelEntity.setId(String.valueOf(sysdetachId1)); + orgInfoHotelEntity.setSourceType(1); + List list = OrgInfoHotelEntity.orgInfoHotelEntityToSqlUpdateList(orgInfoHotelEntity); + if (!list.isEmpty()) { + recordSet.executeUpdate(OrgInfoHotelEntity.getUpdateSql(), list); + } + orgInfoHotelEntity.setId(String.valueOf(sysdetachId2)); + orgInfoHotelEntity.setSourceType(2); + if (!list.isEmpty()) { + recordSet.executeUpdate(OrgInfoHotelEntity.getUpdateSql(), list); + } + } + + AppDetachComInfo appDetachComInfo = new AppDetachComInfo(); + appDetachComInfo.resetAppDetachInfo(); + } + + /** + * 插入信息表数据 + * + * @param orgInfoHotelEntity 信息数据实体 + */ + private void insertSysdetachinfo(OrgInfoHotelEntity orgInfoHotelEntity) { + Integer integer = mapper.selectIdByCntitle(orgInfoHotelEntity.getCnTitle()); + if (null != integer && integer > 0) { + orgInfoHotelEntity.setInfoId(integer); + orgInfoHotelEntity.setUpdate("true"); + return; + } + boolean insertSuccess = mapper.insertSysdetachinfo(orgInfoHotelEntity.getCnTitle()); + if (insertSuccess) { // 查询最大ID - Integer infoId = mapper.selectIdByCntitle(orgInfoHotelEntity.getCnTitle()); - orgInfoHotelEntity.setInfoId(infoId); - orgInfoHotelEntity.setUpdate("false"); - } - } - - + Integer infoId = mapper.selectIdByCntitle(orgInfoHotelEntity.getCnTitle()); + orgInfoHotelEntity.setInfoId(infoId); + orgInfoHotelEntity.setUpdate("false"); + } + } + + } diff --git a/src/test/java/youhong/ai/yihong/YiHongTest.java b/src/test/java/youhong/ai/yihong/YiHongTest.java index 30e826a..3d049b3 100644 --- a/src/test/java/youhong/ai/yihong/YiHongTest.java +++ b/src/test/java/youhong/ai/yihong/YiHongTest.java @@ -3,6 +3,8 @@ package youhong.ai.yihong; import aiyh.utils.Util; import basetest.BaseTest; import com.alibaba.fastjson.JSON; +import com.api.youhong.ai.ihgzhouji.taskele.entity.IhgTaskElementConfigItem; +import com.api.youhong.ai.ihgzhouji.taskele.mapper.TaskElementMapper; import org.junit.Test; import weaver.youhong.ai.yihong.formmode.stagediagram.mapper.ModeExpandSaveActionMapper; import weaver.youhong.ai.yihong.formmode.stagediagram.pojo.StageUpdateFieldConfig; @@ -35,4 +37,12 @@ public class YiHongTest extends BaseTest { System.out.println(strings.stream().filter(item -> !item.equals("2")).collect(Collectors.toList())); } + + + @Test + public void tesetst() { + TaskElementMapper mapper = Util.getMapper(TaskElementMapper.class); + List ihgTaskElementConfigItems = mapper.selectConfig(); + System.out.println(JSON.toJSONString(ihgTaskElementConfigItems)); + } } From a0bc9c30b97707c91979e9fde95947057812043d Mon Sep 17 00:00:00 2001 From: wangxuanran <3055088966@qq.com> Date: Fri, 12 May 2023 13:42:20 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E5=BB=BA=E6=A8=A1=E7=94=9F=E6=88=90json?= =?UTF-8?q?=E7=B1=BB=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xuanran.wang/longgong/NewProductTest.js | 117 ++++++++++++++++++ .../config/service/DealWithMapping.java | 29 +++-- .../wang/shyl/dataasync/AsyncTest.java | 50 +++----- 3 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 javascript/xuanran.wang/longgong/NewProductTest.js diff --git a/javascript/xuanran.wang/longgong/NewProductTest.js b/javascript/xuanran.wang/longgong/NewProductTest.js new file mode 100644 index 0000000..b0f6285 --- /dev/null +++ b/javascript/xuanran.wang/longgong/NewProductTest.js @@ -0,0 +1,117 @@ +// 首台销售日期 +const firstSaleDateField = WfForm.convertFieldNameToId("stxsrq"); +// 跟踪时间 +const trackTimeField = WfForm.convertFieldNameToId("gzsj"); +// 跟踪时间为三个月以内 +const threeMonthIndex = 1; +// 是否提交等待节点 +const submitWaitNode = WfForm.convertFieldNameToId("sftjddjd"); +// 下次超时提醒日期 +const timeoutRemindDateFiled = WfForm.convertFieldNameToId("cstxrq"); +// 跟踪天数 +const trackingDays = WfForm.getFieldValue(trackTimeField) <= 1 ? 15 : 30; +// 跟踪触发行数 +const trackingLineField = WfForm.convertFieldNameToId("gzcfxs"); +$(() => { + let detail2LineNum = WfForm.getDetailRowCount("detail_2"); + // let firstTrack = Boolean(true); + // if (new Date(firstSaleDate) < new Date(currentDate) && dayDiff > 0) { + // firstTrack = false; + // } + // console.log('firstTrack ', firstTrack) + // 到达节点次数 + const nodeNum = getNodeNum(); + let trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); + // 如果不是则自动添加一行明细让他自己填写 + if (detail2LineNum < trackingLine && detail2LineNum < nodeNum) { + console.log('添加一行明细!'); + WfForm.addDetailRow("detail_2", {}); + } + if(detail2LineNum >= trackingLine){ + WfForm.changeFieldValue(submitWaitNode, {value: 1}); + WfForm.changeFieldValue(timeoutRemindDateFiled, {value: ''}); + return; + } + initTimeoutDate(); + WfForm.bindFieldChangeEvent(`${firstSaleDateField},${trackTimeField}`,()=>{ + initTimeoutDate(); + }); +}); + +function getNodeNum(){ + let firstSaleDate = WfForm.getFieldValue(firstSaleDateField); + console.log('首台销售日期 ', firstSaleDate); + let currentDate = getCurrentDate(); + let dayDiff = getDaysDiff(firstSaleDate, currentDate); + console.log('当前天数与首台销售日期相差天数 : ', dayDiff) + return Math.floor(dayDiff / trackingDays) + 1; +} + +function initTimeoutDate(){ + console.log('==== initTimeoutDate begin ====') + let firstSaleDate = WfForm.getFieldValue(firstSaleDateField); + const nodeNum = getNodeNum(); + console.log('到达节点次数 ', nodeNum); + console.log('跟踪天数 ', trackingDays); + let computeTimeoutDate = addDays(firstSaleDate, nodeNum * trackingDays); + console.log('计算下次超时日期 ', computeTimeoutDate); + let trackingLine = parseInt(WfForm.getFieldValue(trackingLineField)); + let detail2LineNum = WfForm.getDetailRowCount("detail_2"); + setTimeout(()=>{ + WfForm.changeFieldValue(timeoutRemindDateFiled, {value: computeTimeoutDate}); + // 判断流程提交走向 + console.log('主表跟踪触发行数 : ', trackingLine) + if (nodeNum >= trackingLine) { + console.log('nodeNum >= trackingLine'); + WfForm.changeFieldValue(submitWaitNode, {value: 1}); + WfForm.changeFieldValue(timeoutRemindDateFiled, {value: ''}); + WfForm.registerCheckEvent(WfForm.OPER_SUBMIT, function (callback) { + detail2LineNum = WfForm.getDetailRowCount("detail_2"); + if (detail2LineNum < trackingLine) { + WfForm.showMessage('请填写明细表信息!'); + detail2LineNum = WfForm.getDetailRowCount("detail_2"); + for (let i = 0; i < trackingLine - parseInt(detail2LineNum); i++) { + WfForm.addDetailRow("detail_2", {}); + } + return; + } + callback(); + }); + } else { + WfForm.changeFieldValue(submitWaitNode, {value: 0}); + } + console.log('==== initTimeoutDate end ====') + },10); +} + +function getDaysDiff(date1, date2) { + date1 = new Date(date1); + date2 = new Date(date2); + const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 + const timeDiff = Math.abs(date1.getTime() - date2.getTime()); // 两个日期对象的毫秒数差值 + // 将毫秒数差值转换为天数差值并四舍五入 + return Math.round(timeDiff / oneDay); +} + +function getCurrentDate() { + return parseDate(new Date()); +} + +function parseDate(date) { + const currentYear = date.getFullYear(); + const currentMonth = date.getMonth() + 1; // getMonth()返回0~11,需要加1 + const currentDay = date.getDate(); + return currentYear + '-' + currentMonth + '-' + currentDay; +} + +function addDays(date, days) { + const newDate = new Date(date); + newDate.setDate(newDate.getDate() + days); + console.log('newDate ', newDate) + return parseDate(newDate); +} + + + + + diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index a893b70..a9af287 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -6,6 +6,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; import weaver.conn.RecordSet; import weaver.file.ImageFileManager; import weaver.general.Util; @@ -59,12 +60,14 @@ public class DealWithMapping extends ToolUtil { private RecordSet tempRs; private DealWithMapper mapper = null; + + private final Logger logger = aiyh.utils.Util.getLogger("json-util"); { try { mapper = aiyh.utils.Util.getMapper(DealWithMapper.class); } catch (Exception e) { - this.writeErrorLog("缺少 aiyh_utils.jar依赖,初始化失败!"); + logger.error("缺少 aiyh_utils.jar依赖,初始化失败!"); } } @@ -190,7 +193,7 @@ public class DealWithMapping extends ToolUtil { * @return */ public RequestMappingConfig treeDealWithUniqueCode(String uniqueCode) { - this.writeDebuggerLog("============== 根据uniqueCode查询请求配置树形列表 treeDealWith begin ================="); + logger.info("============== 根据uniqueCode查询请求配置树形列表 treeDealWith begin ================="); RequestMappingConfig tempConfig = mappingCMD.selectByUniqueCode(uniqueCode); return this.dealWith(tempConfig); } @@ -202,7 +205,7 @@ public class DealWithMapping extends ToolUtil { * @return */ public RequestMappingConfig dealWith(RequestMappingConfig tempConfig) { - this.writeDebuggerLog("查询到的请求配置列表 query RequestMappingConfig list >>>" + JSON.toJSONString(tempConfig)); + logger.info("查询到的请求配置列表 query RequestMappingConfig list >>>" + JSON.toJSONString(tempConfig)); List mappingDetails = tempConfig.getConfigDetail(); List subMappingDetailList = new ArrayList<>(); // 过滤出指定节点的子节点,并返回除去子节点之外的节点列表 @@ -227,7 +230,7 @@ public class DealWithMapping extends ToolUtil { mappingDetailList.add(mappingDetail); } requestMappingConfig.setConfigDetail(mappingDetailList); - this.writeDebuggerLog("通过处理后得到的树形参数列表 deal with tree >>>" + JSON.toJSONString(requestMappingConfig)); + logger.info("通过处理后得到的树形参数列表 deal with tree >>>" + JSON.toJSONString(requestMappingConfig)); return requestMappingConfig; } @@ -820,7 +823,7 @@ public class DealWithMapping extends ToolUtil { Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); value = this.diyDateFortMat(date, "yyyy-MM-dd"); } catch (Exception e) { - this.writeDebuggerLog("时间处理异常:" + e); + logger.info("时间处理异常:" + e); throw new ValueDealException("时间处理异常:参数>>" + paramName); } } @@ -835,7 +838,7 @@ public class DealWithMapping extends ToolUtil { Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); value = this.diyDateFortMat(date, "yyyy-MM-dd HH:mm:ss"); } catch (Exception e) { - this.writeDebuggerLog("时间处理异常:" + e); + logger.info("时间处理异常:" + e); throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e); } } @@ -851,7 +854,7 @@ public class DealWithMapping extends ToolUtil { Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); value = this.diyDateFortMat(date, forMatString); } catch (Exception e) { - this.writeDebuggerLog("时间处理异常:" + e); + logger.info("时间处理异常:" + e); throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e.getMessage()); } } @@ -866,7 +869,7 @@ public class DealWithMapping extends ToolUtil { Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); value = date.getTime(); } catch (Exception e) { - this.writeDebuggerLog("时间处理异常:" + e); + logger.info("时间处理异常:" + e); throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e.getMessage()); } } @@ -918,7 +921,7 @@ public class DealWithMapping extends ToolUtil { FieldMessage fieldMassage = mappingDetail.getFieldMassage(); String fieldName = fieldMassage.getFieldName(); String fieldNameLower = fieldName.toLowerCase(); - this.writeDebuggerLog("fieldName:" + fieldName); + logger.info("fieldName:" + fieldName); if ("1".equals(childSource)) { value = Util.null2String(detailMap.get(fieldNameLower)); if ("".equals(value)) { @@ -1081,7 +1084,7 @@ public class DealWithMapping extends ToolUtil { multipartFile.setStream(fileInputStream); multipartFile.setFileName(docImageFile.getImageFileName()); multipartFile.setFileSize(docImageFile.getFileSize() / 1024); - this.writeDebuggerLog("multipartFile ==>" + multipartFile); + logger.info("multipartFile ==>" + multipartFile); multipartFileList.add(multipartFile); } return null; @@ -1132,7 +1135,7 @@ public class DealWithMapping extends ToolUtil { default: throw new ValueDealException("不支持的取值方式"); } - this.writeDebuggerLog("value1:" + value); + logger.info("value1:" + value); switch (typeEnum) { // String类型 case STRING: { @@ -1415,7 +1418,7 @@ public class DealWithMapping extends ToolUtil { * @return 要插入的信息 */ public Map> dealResponse(List responseMappingList, Map requestRes) { - this.writeDebuggerLog("回写信息转换处理 responseMappingList==>" + responseMappingList + " requestRes==>" + requestRes + "mainTable ==>" + mainTable); + logger.info("回写信息转换处理 responseMappingList==>" + responseMappingList + " requestRes==>" + requestRes + "mainTable ==>" + mainTable); Map> tableUpdateMap = new HashMap<>(); if (responseMappingList != null && !responseMappingList.isEmpty()) { Map mainUpdateMap = new HashMap<>(); @@ -1443,7 +1446,7 @@ public class DealWithMapping extends ToolUtil { tableUpdateMap.put(detailTableName, detailUpdateMap); } } - this.writeDebuggerLog("回写信息tableUpdateMap==> " + tableUpdateMap); + logger.info("回写信息tableUpdateMap==> " + tableUpdateMap); return tableUpdateMap; } diff --git a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java index 2db4f9b..6ec1a1e 100644 --- a/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java +++ b/src/test/java/xuanran/wang/shyl/dataasync/AsyncTest.java @@ -2,6 +2,7 @@ package xuanran.wang.shyl.dataasync; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; +import aiyh.utils.httpUtil.ResponeVo; import aiyh.utils.httpUtil.util.HttpUtils; import aiyh.utils.tool.cn.hutool.http.HttpRequest; import basetest.BaseTest; @@ -238,29 +239,13 @@ public class AsyncTest extends BaseTest { @Test public void testB() { - String json = "[{\n" + - "\t\"requestName\": \"你个沙雕32323\",\n" + - "\t\"workflowId\": \"45\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"测试20230309\"\n" + - "\t}]\n" + - "}, {\n" + - "\t\"requestName\": \"沙雕2号\",\n" + - "\t\"workflowId\": \"45\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + - "\t}]\n" + - "}, {\n" + - "\t\"requestName\": \"沙雕2号\",\n" + - "\t\"workflowId\": \"451\",\n" + - "\t\"mainData\": [{\n" + - "\t\t\"fieldName\": \"yysy\",\n" + - "\t\t\"fieldValue\": \"沙雕沙雕沙雕沙雕沙雕\"\n" + - "\t}]\n" + - "}]"; - testRestful("http://183.192.65.115:8080", "/api/wxr/shyl/workflow/batchCreate233", json); + String json = "{\"requestName\":\"教研资批量新增会议室申请流程\",\"mainData\":[{\"fieldName\":\"Address\",\"fieldValue\":192},{\"fieldName\":\"customId\",\"fieldValue\":\"500ffadfad744d5a90212f776ff13bb2\"},{\"fieldName\":\"field_1716678529\",\"fieldValue\":0},{\"fieldName\":\"MeetingType\",\"fieldValue\":0},{\"fieldName\":\"MeetingName\",\"fieldValue\":\"测试青干BB班0511-新时代中国青年的使命与担当——关于新时代中国青年,总书记怎么说-2023-05-11-授课场地预定\"},{\"fieldName\":\"description\",\"fieldValue\":\"授课场地预定\"},{\"fieldName\":\"field_1168264962\",\"fieldValue\":1},{\"fieldName\":\"BeginDate\",\"fieldValue\":\"2023-05-11\"},{\"fieldName\":\"BeginTime\",\"fieldValue\":\"18:01\"},{\"fieldName\":\"EndDate\",\"fieldValue\":\"2023-05-11\"},{\"fieldName\":\"EndTime\",\"fieldValue\":\"18:05\"}],\"detailData\":[],\"workflowId\":46}\n"; + testRestful("http://183.192.65.115:8080", "/api/workflow/paService/doCreateRequest", json); + } + + @Test + public void testA(){ + } /** @@ -348,21 +333,22 @@ public class AsyncTest extends BaseTest { // 封装请求头参数 RSA rsa = new RSA(null, spk); // 对用户信息进行加密传输,暂仅支持传输OA用户ID - String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); - List list = JSONObject.parseObject(jsonParams, List.class); + String encryptUserid = rsa.encryptBase64("54", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey); + Map list = JSONObject.parseObject(jsonParams, Map.class); HttpUtils httpUtils = new HttpUtils(); HashMap headers = new HashMap<>(); headers.put("appid", APPID); headers.put("token", token); headers.put("userid", encryptUserid); - headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); + httpUtils.getGlobalCache().header.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); log.info("请求头 = > " + headers); -// try { -// ResponeVo responeVo = httpUtils.apiPostObject(address + api, list, headers); -// log.info("reslut => " + JSONObject.toJSON(responeVo)); -// } catch (Exception e) { -// log.error("e => " + e.getMessage()); -// } + try { + log.info("list : " + list); + ResponeVo responeVo = httpUtils.apiPostObject(address + api, list, headers); + log.info("reslut => " + JSONObject.toJSON(responeVo)); + } catch (Exception e) { + log.error("e => " + e.getMessage()); + } return ""; } From ce90fa1def1da83a1a20d547c786beb48d700867 Mon Sep 17 00:00:00 2001 From: wangxuanran <3055088966@qq.com> Date: Fri, 12 May 2023 15:55:33 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89sql=E6=96=B9=E6=B3=95bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weaver/xiao/commons/config/service/DealWithMapping.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java index a9af287..e9b168e 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -5,6 +5,7 @@ import com.google.common.base.Strings; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import weaver.conn.RecordSet; @@ -670,7 +671,7 @@ public class DealWithMapping extends ToolUtil { } else { tempValue = Util.null2String(mainMap.get(fieldName)); if ("".equals(tempValue)) { - tempValue = Util.null2String(detailMap.get(fieldNameLower)); + tempValue = Util.null2String(mainMap.get(fieldNameLower)); } } } From 8b8ab744838afac3f8d93712cf2dcba075d329ae Mon Sep 17 00:00:00 2001 From: "youhong.ai" Date: Fri, 12 May 2023 21:12:06 +0800 Subject: [PATCH 6/9] =?UTF-8?q?mapper=E6=8B=BC=E6=8E=A5=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/recordset/MapperBuilderSql.java | 110 ++++++++++++ .../builderSql/impl/BuilderSqlImpl.java | 157 +++++++++--------- .../hrmNew/JobTitleMultilingualUtil.java | 10 +- 3 files changed, 202 insertions(+), 75 deletions(-) create mode 100644 src/main/java/aiyh/utils/recordset/MapperBuilderSql.java diff --git a/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java new file mode 100644 index 0000000..13fff23 --- /dev/null +++ b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java @@ -0,0 +1,110 @@ +package aiyh.utils.recordset; + +import aiyh.utils.excention.CustomerException; +import aiyh.utils.tool.cn.hutool.core.collection.CollectionUtil; +import aiyh.utils.tool.cn.hutool.core.util.StrUtil; + +import java.util.Map; + +/** + *

构建sql

+ * + *

create: 2023/5/12 20:51

+ * + * @author youHong.ai + */ +public class MapperBuilderSql { + + /** + *

构建更新sql

+ * + * @param table 表名称 + * @param param 参数 + * @return 构建的sql + */ + public static String builderUpdateSql(String table, Map param) { + if (StrUtil.isBlank(table) || CollectionUtil.isEmpty(param)) { + throw new CustomerException("tableName or param can not to be null!"); + } + StringBuilder sb = new StringBuilder(); + sb.append("update ").append(table).append(" set "); + for (Map.Entry entry : param.entrySet()) { + sb.append(" ") + .append(entry.getKey()) + .append(" = ") + .append("#{") + .append(entry.getKey()) + .append("}") + .append(","); + } + sb.deleteCharAt(sb.length() - 1); + return sb.toString(); + } + + /** + *

构建插入sql

+ * + * @param table 表名称 + * @param param 参数 + * @return 构建的sql + */ + public static String builderInsertSql(String table, Map param) { + if (StrUtil.isBlank(table) || CollectionUtil.isEmpty(param)) { + throw new CustomerException("tableName or param can not to be null!"); + } + StringBuilder sb = new StringBuilder(); + StringBuilder sbValue = new StringBuilder(); + sb.append("insert into ").append(table).append(" ("); + sbValue.append(") values ( "); + for (Map.Entry entry : param.entrySet()) { + sb.append(entry.getKey()).append(" ,"); + sbValue.append(" #{").append(entry.getKey()).append("},"); + } + sb.deleteCharAt(sb.length() - 1); + sbValue.deleteCharAt(sbValue.length() - 1); + sb.append(sbValue).append(")"); + return sb.toString(); + } + + public static String builderWhereAnd(Map param, boolean containsWhere) { + return builderWhereAnd(param, "whereParam", containsWhere); + } + + public static String builderWhereAnd(Map param) { + return builderWhereAnd(param, "whereParam", true); + } + + public static String builderNoWhereAndEn(Map param, boolean containsWhere) { + return builderWhereAnd(param, "", containsWhere); + } + + public static String builderNoWhereAndEn(Map param) { + return builderWhereAnd(param, "", false); + } + + /** + *

构建and条件

+ * + * @param param 参数 + * @param wherePrefix 条件拼接前缀 + * @param containsWhere 是否包含where + * @return 构建的where条件 + */ + public static String builderWhereAnd(Map param, String wherePrefix, boolean containsWhere) { + if (CollectionUtil.isEmpty(param)) { + throw new CustomerException("tableName or param can not to be null!"); + } + StringBuilder sb = new StringBuilder(); + if (containsWhere) { + sb.append(" where "); + } + for (Map.Entry entry : param.entrySet()) { + sb.append(entry.getKey()).append(" and ").append("#{"); + if (StrUtil.isNotBlank(wherePrefix)) { + sb.append(wherePrefix).append("."); + } + sb.append(entry.getKey()).append("}"); + } + return sb.toString(); + } +} diff --git a/src/main/java/aiyh/utils/sqlUtil/builderSql/impl/BuilderSqlImpl.java b/src/main/java/aiyh/utils/sqlUtil/builderSql/impl/BuilderSqlImpl.java index 8cf0589..82f14a0 100644 --- a/src/main/java/aiyh/utils/sqlUtil/builderSql/impl/BuilderSqlImpl.java +++ b/src/main/java/aiyh/utils/sqlUtil/builderSql/impl/BuilderSqlImpl.java @@ -5,18 +5,15 @@ import aiyh.utils.Util; import aiyh.utils.mapUtil.UtilHashMap; import aiyh.utils.mapUtil.UtilLinkedHashMap; import aiyh.utils.sqlUtil.builderSql.BuilderSql; -import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl; import aiyh.utils.sqlUtil.sqlResult.impl.BatchSqlResultImpl; +import aiyh.utils.sqlUtil.sqlResult.impl.PrepSqlResultImpl; import aiyh.utils.sqlUtil.whereUtil.Where; import aiyh.utils.sqlUtil.whereUtil.impl.WhereImpl; import weaver.conn.RecordSet; - import java.beans.BeanInfo; -import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -29,15 +26,16 @@ import java.util.stream.Collectors; public class BuilderSqlImpl implements BuilderSql { - private String DB_TYPE; - + private final String DB_TYPE; + { // 获取当前数据库的类型 this.DB_TYPE = (new RecordSet()).getDBType(); } - + /** * 构建插入语句 + * * @param tableName 数据库表名 * @param mapConfig 数据库字段和值 * @return 自定义SQL实体类 @@ -63,21 +61,22 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(" )"); return new PrepSqlResultImpl(sqlBuilder.toString(), args); } - - /** - * 通过实体类构建插入SQL - * @param tableName 数据库表名 - * @param t 实体类对象 - * @param 实体类对象泛型 - * @return SQL结果对象 - */ - public PrepSqlResultImpl insertSqlByEntity(String tableName, T t){ + + /** + * 通过实体类构建插入SQL + * + * @param tableName 数据库表名 + * @param t 实体类对象 + * @param 实体类对象泛型 + * @return SQL结果对象 + */ + public PrepSqlResultImpl insertSqlByEntity(String tableName, T t) { List args = new ArrayList<>(); StringBuilder sqlBuilder = new StringBuilder("insert into "); sqlBuilder.append(tableName); StringBuilder fieldBuilder = new StringBuilder(); StringBuilder valueBuilder = new StringBuilder(); - + BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(t.getClass(), Object.class); @@ -88,7 +87,7 @@ public class BuilderSqlImpl implements BuilderSql { Object invoke = readMethod.invoke(t); // System.out.println(name); // System.out.println(invoke); - if(invoke == null){ + if (invoke == null) { continue; } fieldBuilder.append(name); @@ -106,10 +105,11 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(" )"); return new PrepSqlResultImpl(sqlBuilder.toString(), args); } - + /** * 构建批量插入SQL - * @param tableName 表名 + * + * @param tableName 表名 * @param mapListConfig 表对应的字段和值映射list * @return 自定义批量SQL实体类 */ @@ -142,14 +142,15 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(" )"); return new BatchSqlResultImpl(sqlBuilder.toString(), args); } - - /** - * 构建批量插入SQL - * @param tableName 数据库表名 - * @param list 实体类数组 - * @param 实体类泛型 - * @return SQL对象 - */ + + /** + * 构建批量插入SQL + * + * @param tableName 数据库表名 + * @param list 实体类数组 + * @param 实体类泛型 + * @return SQL对象 + */ public BatchSqlResultImpl insertBatchSqlByEntity(String tableName, List list) { StringBuilder sqlBuilder = new StringBuilder("insert into "); sqlBuilder.append(tableName); @@ -157,11 +158,11 @@ public class BuilderSqlImpl implements BuilderSql { StringBuilder valueBuilder = new StringBuilder(); List args = new ArrayList<>(); AtomicInteger i = new AtomicInteger(); - + list.forEach(item -> { List arg = new ArrayList<>(); BeanInfo beanInfo = null; - + try { beanInfo = Introspector.getBeanInfo(item.getClass(), Object.class); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); @@ -169,7 +170,7 @@ public class BuilderSqlImpl implements BuilderSql { String name = proper.getName(); Method readMethod = proper.getReadMethod(); Object invoke = readMethod.invoke(item); - if(invoke == null){ + if (invoke == null) { continue; } if (i.get() == 0) { @@ -192,12 +193,13 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(" )"); return new BatchSqlResultImpl(sqlBuilder.toString(), args); } - + /** - * 构建更新语句 + * 构建更新语句 + * * @param tableName 表名 * @param mapConfig 表名所对应键值对 - * @param where 更新数据的条件 + * @param where 更新数据的条件 * @return 自定义SQL实体类 */ @Override @@ -222,16 +224,17 @@ public class BuilderSqlImpl implements BuilderSql { } return new PrepSqlResultImpl(sqlBuilder.toString(), args); } - - /** - * 构建更新SQL语句 - * @param tableName 数据库表名 - * @param t 实体类对象 - * @param where 更新条件对象 - * @param 实体类泛型 - * @return 构建后的SQL对象 - */ - public PrepSqlResultImpl updateSqlByEntity(String tableName, T t, Where where){ + + /** + * 构建更新SQL语句 + * + * @param tableName 数据库表名 + * @param t 实体类对象 + * @param where 更新条件对象 + * @param 实体类泛型 + * @return 构建后的SQL对象 + */ + public PrepSqlResultImpl updateSqlByEntity(String tableName, T t, Where where) { this.verifyWhere(where); StringBuilder sqlBuilder = new StringBuilder("update "); StringBuilder fieldValue = new StringBuilder(); @@ -246,7 +249,7 @@ public class BuilderSqlImpl implements BuilderSql { String name = proper.getName(); Method readMethod = proper.getReadMethod(); Object invoke = readMethod.invoke(t); - if(invoke == null){ + if (invoke == null) { continue; } fieldValue.append(name); @@ -264,12 +267,12 @@ public class BuilderSqlImpl implements BuilderSql { } return new PrepSqlResultImpl(sqlBuilder.toString(), args); } - - + + /** - * @param tableName 表名 + * @param tableName 表名 * @param mapListConfig 表名所对应的键值对数组 - * @param whereList 条件数组 + * @param whereList 条件数组 * @return 批量更新只适用于更新条件一样,但是参数不同的时候,比如更新条件都是id= ?,但是各id的数值不一样 */ @Override @@ -305,15 +308,16 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(whereList.get(0).getSql()); return new BatchSqlResultImpl(sqlBuilder.toString(), args); } - - /** - * 通过实体类构建批量更新SQL - * @param tableName 数据库表名 - * @param list 实体类集合 - * @param whereList 更新条件集合,一一对应更新数据集合 - * @param 泛型 - * @return 构建后的批量SQL对象 - */ + + /** + * 通过实体类构建批量更新SQL + * + * @param tableName 数据库表名 + * @param list 实体类集合 + * @param whereList 更新条件集合,一一对应更新数据集合 + * @param 泛型 + * @return 构建后的批量SQL对象 + */ public BatchSqlResultImpl updateBatchSqlByEntity(String tableName, List list, List whereList) { this.verifyWhereList(whereList); if (list.size() != whereList.size()) { @@ -335,7 +339,7 @@ public class BuilderSqlImpl implements BuilderSql { String name = proper.getName(); Method readMethod = proper.getReadMethod(); Object invoke = readMethod.invoke(item); - if(invoke == null){ + if (invoke == null) { continue; } if (i.get() == 0) { @@ -358,9 +362,10 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(whereList.get(0).getSql()); return new BatchSqlResultImpl(sqlBuilder.toString(), args); } - + /** * 构建插入SQL语句 + * * @param tableName 表名 * @param mapConfig 参数 * @return 拼接好的SQL @@ -387,9 +392,10 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(" )"); return sqlBuilder.toString(); } - + /** * 构建更新SQL语句 + * * @param tableName 表名 * @param mapConfig 参数 * @return 拼接好的SQL @@ -415,27 +421,27 @@ public class BuilderSqlImpl implements BuilderSql { sqlBuilder.append(where.getSql()); return sqlBuilder.toString(); } - - - - + + /** * 验证构建SQL参数的,并且过滤到为null的数据 + * * @param map 验证SQL参数map对象 * @return 验证后的UtilHashMap */ public UtilHashMap verifyMap(Map map) { UtilHashMap filterMap = Util.createUtilHashMap() - .uPutAll(map) - .filter((key, value) -> !Objects.isNull(key) && !Objects.isNull(value)); + .uPutAll(map) + .filter((key, value) -> !Objects.isNull(key) && !Objects.isNull(value)); if (Util.mapIsNullOrEmpty(filterMap)) { throw new RuntimeException("map为空或没有数据! map is null or empty!"); } return filterMap; } - + /** * 验证批量SQL构建的数据 + * * @param mapList 批量构建SQL的的工具 * @return 验证和过滤后的数据 */ @@ -444,18 +450,19 @@ public class BuilderSqlImpl implements BuilderSql { throw new RuntimeException("mapList为null!mapList is null!"); } List> collect = mapList.stream().map(item -> - Util.createUtilLinkedHashMap() - .uPutAll(item) - .filter((key, value) -> !Objects.isNull(key) && !Objects.isNull(value)) + Util.createUtilLinkedHashMap() + .uPutAll(item) + .filter((key, value) -> !Objects.isNull(key) && !Objects.isNull(value)) ).collect(Collectors.toList()); if (mapList.size() == 0) { throw new RuntimeException("mapList没有数据!mapList is empty!"); } return collect; } - + /** * 验证where条件是否符合 + * * @param where where 条件对象 */ private void verifyWhere(Where where) { @@ -463,16 +470,18 @@ public class BuilderSqlImpl implements BuilderSql { throw new RuntimeException("where为null! where is null!"); } } + /** * 验证where条件集合是否符合 + * * @param whereList where 条件对象集合 */ private void verifyWhereList(List whereList) { if (whereList == null) { throw new RuntimeException("whereList为null! whereList is null!"); } - whereList.forEach(item->{ - if(item == null){ + whereList.forEach(item -> { + if (item == null) { throw new RuntimeException("whereList中数据为null! whereDate is null in whereList!"); } }); diff --git a/src/main/youhong_ai_jitu_src/jntchina/schedule/hrmNew/JobTitleMultilingualUtil.java b/src/main/youhong_ai_jitu_src/jntchina/schedule/hrmNew/JobTitleMultilingualUtil.java index 552f87c..80def67 100644 --- a/src/main/youhong_ai_jitu_src/jntchina/schedule/hrmNew/JobTitleMultilingualUtil.java +++ b/src/main/youhong_ai_jitu_src/jntchina/schedule/hrmNew/JobTitleMultilingualUtil.java @@ -1,8 +1,10 @@ package jntchina.schedule.hrmNew; import aiyh.utils.Util; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import org.apache.log4j.Logger; import java.util.*; import java.util.function.Function; @@ -21,7 +23,8 @@ public class JobTitleMultilingualUtil { private JSONArray jsonArray = null; private Map> groupMap = null; - private final Long updateTime = 0L; + private Long updateTime = 0L; + private final Logger log = Util.getLogger(); static { extracted(); @@ -148,6 +151,7 @@ public class JobTitleMultilingualUtil { long l = System.currentTimeMillis(); if (l - updateTime >= 1_000 * 60 * 60 * 3) { extracted(); + updateTime = System.currentTimeMillis(); } StringBuilder sb = new StringBuilder(); List list = jsonArray.toJavaList(Map.class); @@ -156,6 +160,7 @@ public class JobTitleMultilingualUtil { if (!jsonArray.equals(this.jsonArray)) { this.jsonArray = jsonArray; this.groupMap = list.stream().collect(Collectors.groupingBy(getKey)); + log.info("job title group : " + JSON.toJSONString(this.groupMap)); } String active = LANGUAGE_MAP.get("active"); if (isBlank(active)) { @@ -165,9 +170,12 @@ public class JobTitleMultilingualUtil { active += ",ZHS"; String[] activeLanguageArray = active.split(","); List activeList = Arrays.stream(activeLanguageArray).distinct().collect(Collectors.toList()); + log.info("active language: " + JSON.toJSONString(activeList)); + log.info("language map: " + JSON.toJSONString(LANGUAGE_MAP)); groupMap = this.groupMap; if (!isEmpty(groupMap)) { List maps = groupMap.get(getKey.apply(JSONObject.toJavaObject(currentObj, Map.class))); + log.info("current job Maps: " + JSON.toJSONString(maps)); if (!isEmpty(maps)) { sb.append("~`"); for (Map map : maps) { From ad6c60dc9fdc56face2130973037a463881bf7ab Mon Sep 17 00:00:00 2001 From: "youhong.ai" Date: Fri, 12 May 2023 21:14:04 +0800 Subject: [PATCH 7/9] =?UTF-8?q?mapper=E6=8B=BC=E6=8E=A5=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/aiyh/utils/recordset/MapperBuilderSql.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java index 13fff23..505711c 100644 --- a/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java +++ b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java @@ -99,12 +99,13 @@ public class MapperBuilderSql { sb.append(" where "); } for (Map.Entry entry : param.entrySet()) { - sb.append(entry.getKey()).append(" and ").append("#{"); + sb.append(entry.getKey()).append(" = #{"); if (StrUtil.isNotBlank(wherePrefix)) { sb.append(wherePrefix).append("."); } - sb.append(entry.getKey()).append("}"); + sb.append(entry.getKey()).append("}").append(" and "); } + sb.deleteCharAt(sb.length() - 5); return sb.toString(); } } From 402082f03865d8c008988a54a1f15d14055b98d6 Mon Sep 17 00:00:00 2001 From: "youhong.ai" Date: Fri, 12 May 2023 21:17:28 +0800 Subject: [PATCH 8/9] =?UTF-8?q?mapper=E6=8B=BC=E6=8E=A5=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/recordset/MapperBuilderSql.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java index 505711c..6f7eb38 100644 --- a/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java +++ b/src/main/java/aiyh/utils/recordset/MapperBuilderSql.java @@ -23,6 +23,17 @@ public class MapperBuilderSql { * @return 构建的sql */ public static String builderUpdateSql(String table, Map param) { + return builderUpdateSql(table, param, ""); + } + + /** + *

构建更新sql

+ * + * @param table 表名称 + * @param param 参数 + * @return 构建的sql + */ + public static String builderUpdateSql(String table, Map param, String paramPrefix) { if (StrUtil.isBlank(table) || CollectionUtil.isEmpty(param)) { throw new CustomerException("tableName or param can not to be null!"); } @@ -32,8 +43,11 @@ public class MapperBuilderSql { sb.append(" ") .append(entry.getKey()) .append(" = ") - .append("#{") - .append(entry.getKey()) + .append("#{"); + if (StrUtil.isNotBlank(paramPrefix)) { + sb.append(paramPrefix).append("."); + } + sb.append(entry.getKey()) .append("}") .append(","); } @@ -49,6 +63,10 @@ public class MapperBuilderSql { * @return 构建的sql */ public static String builderInsertSql(String table, Map param) { + return builderInsertSql(table, param, ""); + } + + public static String builderInsertSql(String table, Map param, String paramPrefix) { if (StrUtil.isBlank(table) || CollectionUtil.isEmpty(param)) { throw new CustomerException("tableName or param can not to be null!"); } @@ -58,7 +76,11 @@ public class MapperBuilderSql { sbValue.append(") values ( "); for (Map.Entry entry : param.entrySet()) { sb.append(entry.getKey()).append(" ,"); - sbValue.append(" #{").append(entry.getKey()).append("},"); + sbValue.append(" #{"); + if (StrUtil.isNotBlank(paramPrefix)) { + sbValue.append(paramPrefix).append("."); + } + sbValue.append(entry.getKey()).append("},"); } sb.deleteCharAt(sb.length() - 1); sbValue.deleteCharAt(sbValue.length() - 1); @@ -66,6 +88,7 @@ public class MapperBuilderSql { return sb.toString(); } + public static String builderWhereAnd(Map param, boolean containsWhere) { return builderWhereAnd(param, "whereParam", containsWhere); } From 0284f4c70b7ecebdd19b72948f8f5fe1778abc06 Mon Sep 17 00:00:00 2001 From: "chaoyang.he" Date: Mon, 15 May 2023 17:58:42 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=87=E4=BB=BD---?= =?UTF-8?q?=E4=BD=95=E6=9C=9D=E9=98=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/MultiInvoiceBrowserService.java | 206 +++++ .../controller/ChangeFpytController.java | 45 + .../DeleteInvoiceNotApController.java | 73 ++ .../entity/BackupFnaDataEntity.java | 61 ++ .../mapper/DeleteInvoiceNotApMapper.java | 39 + .../service/DeleteInvoiceNotApService.java | 11 + .../impl/DeleteInvoiceNotApServiceimpl.java | 94 ++ .../DeleteInvoiceNotApServiceimpl_copy.java | 143 +++ .../mapper/ChangeFpytMapper.java | 17 + .../service/ChangeFpytService.java | 12 + .../service/impl/ChangeFpytServiceImpl.java | 33 + .../controller/ExportPDFController.java | 92 ++ .../exportpdf/mapper/ExportPDFMapper.java | 32 + .../exportpdf/service/ExportPDFService.java | 14 + .../service/impl/ExportPDFServiceImpl.java | 275 ++++++ .../DetailDataExportExcelController.java | 49 + ...TbSheetChangeDownloadStatusController.java | 280 ++++++ .../mapper/DetailDataExportExcelMapper.java | 22 + .../service/DetailDataExportExcelApi.java | 17 + .../impl/DetailDataExportExcelService.java | 403 +++++++++ .../DetailDataExportExcelService_copy.java | 497 ++++++++++ .../wflistdonestore/ExportPDF.java | 257 ++++++ .../ExportExcelAVPNApi.java | 683 ++++++++++++++ .../ExportExcelL3NSApi.java | 581 ++++++++++++ .../exportotherexcel/CheckRequestInfo.java | 90 ++ .../exportotherexcel/DemoMapper.java | 74 ++ .../exportotherexcel/DemoMapper_copy.java | 76 ++ .../exportotherexcel/ExportExcelOtherApi.java | 110 +++ .../exportotherexcel/SetCellStylePOI.java | 419 +++++++++ .../exportotherexcel/SheetCMRPOI.java | 437 +++++++++ .../exportotherexcel/SheetCostPOI.java | 452 +++++++++ .../exportotherexcel/SheetQuotationPOI.java | 450 +++++++++ .../exportotherexcel/StringEscapeUtils.java | 38 + .../controller/CheckProjectNameApi.java | 109 +++ .../controller/ExportExcelApi.java | 294 ++++++ .../controller/ExportExcelApi_copy.java | 216 +++++ .../service/ExportExcelAVPNService.java | 20 + .../service/ExportExcelL3NSService.java | 20 + .../service/ExportExcelOtherService.java | 26 + .../impl/ExportExcelAVPNServiceImpl.java | 678 ++++++++++++++ .../impl/ExportExcelL3NSServiceImpl.java | 571 ++++++++++++ .../impl/ExportExcelOtherServiceImpl.java | 113 +++ .../tayota/boshoku/action/TbSheetAction.java | 51 ++ .../djc/tayota/boshoku/dto/TbDetailData.java | 60 ++ .../tayota/boshoku/mapper/TbSheetMapper.java | 38 + .../boshoku/service/TbSheetService.java | 17 + .../service/impl/TbSheetServiceImpl.java | 111 +++ .../tbsheet/action/TBSheetAction.java | 130 +++ .../modeexpand/ChangeState.java | 21 + .../modeexpand/ModeExpandTemplate.java | 43 + .../interfaces/impl/CheckFieldTemplate.java | 70 ++ .../impl/CheckFieldTemplateMapper.java | 18 + .../impl/ExportFieldTransTemplate.java | 66 ++ .../impl/ExportFieldTransTemplate_copy.java | 64 ++ .../mapper/DeleteInvoiceNotApMapper.java | 46 + .../service/DeleteInvoiceNotApService.java | 12 + .../impl/DeleteInvoiceNotApServiceImpl.java | 75 ++ .../web/DeleteInvoiceNotApAction.java | 34 + .../action/SendFileByFTPAction.java | 196 ++++ .../action/SendFileByFTPAction_copy.java | 159 ++++ .../controller/CheckAndChangeValueAction.java | 109 +++ .../mapper/CheckAndChangeValueMapper.java | 60 ++ .../service/CheckAndChangeValueService.java | 11 + .../impl/CheckAndChangeValueServiceImpl.java | 180 ++++ .../GetDataCreateWorkflowController.java | 149 +++ .../mapper/GetWorkflowDataMapper.java | 37 + .../service/GetWorkflowDataService.java | 23 + .../impl/GetWorkflowDataServiceImpl.java | 157 ++++ .../impl/GetWorkflowDataServiceImpl_copy.java | 274 ++++++ .../acton/RollbackMoneyToWorkflowAction.java | 119 +++ .../update_lqts/action/UpdateLqtsAction.java | 83 ++ .../action/UpdatePDFNameAction.java | 132 +++ .../action/NoticeAfterSigned.java | 225 +++++ .../action/SendFieldsAction.java | 146 +++ .../action/SubmitAtoBAction.java | 116 +++ .../action/SubmitAtoBActionCopy.java | 116 +++ .../filterinvoice/FilterInvoiceService.java | 31 + .../InvoiceValuesToAccountTableAction.java | 326 +++++++ .../InvoiceValuesToAccountTableAction01.java | 246 +++++ .../InvoiceValuesToAccountTableAction02.java | 301 ++++++ .../InvoiceValuesToAccountTableAction03.java | 247 +++++ .../InvoiceValuesToAccountTableAction04.java | 264 ++++++ .../action/TbChangeTextNameAction.java | 234 +++++ .../he/shangan/common/util/CommonWFUtil.java | 273 ++++++ .../he/shangan/cornjob/MailInfoDao.java | 107 +++ .../cornjob/MailTriggerWorkflowCronJob.java | 190 ++++ .../chaoyang/he/shangan/cornjob/ReadMail.java | 520 +++++++++++ .../commons/config/dao/ConfigMappingCMD.java | 162 ++++ .../commons/config/entity/DocImageFile.java | 40 + .../commons/config/entity/FieldMessage.java | 26 + .../config/entity/ListMapIndexValue.java | 17 + .../commons/config/entity/MappingDetail.java | 48 + .../commons/config/entity/MultipartFile.java | 37 + .../config/entity/RequestMappingConfig.java | 45 + .../config/entity/ResponseMapping.java | 17 + .../config/enumtype/DataSourceEnum.java | 35 + .../config/enumtype/GetValueTypeEnum.java | 44 + .../config/enumtype/ParamTypeEnum.java | 43 + .../interfacies/CusInterfaceGetValue.java | 38 + .../interfacies/CusInterfaceListValue.java | 25 + .../config/service/DealWithMapping.java | 855 ++++++++++++++++++ .../commons/exception/RequestException.java | 21 + .../commons/exception/ValueDealException.java | 22 + .../he/xiao/commons/utils/JsonResult.java | 70 ++ .../he/xiao/commons/utils/LogUtil.java | 73 ++ .../he/xiao/commons/utils/PreMap.java | 26 + .../he/xiao/commons/utils/PropUtil.java | 57 ++ .../xiao/commons/utils/RequestBaseInfo.java | 59 ++ .../he/xiao/commons/utils/RequestUtil.java | 166 ++++ .../he/xiao/commons/utils/SqlUtil.java | 261 ++++++ .../utils/annotation/SqlFieldMapping.java | 21 + .../chaoyang/he/zwl/common/CusBaseAction.java | 104 +++ .../he/zwl/common/ThreadPoolConfig.java | 36 + .../chaoyang/he/zwl/common/ToolUtil.java | 411 +++++++++ .../chaoyang/he/zwl/common/ToolUtil_E9.java | 396 ++++++++ .../WorkflowData_To_Middle_DB_Action.java | 429 +++++++++ .../common/formmode/ExecuteSQL_Action.java | 45 + .../zwl/common/formmode/ExecuteSQL_Cron.java | 43 + .../zwl/common/formmode/ExecuteSQL_Util.java | 130 +++ .../he/zwl/common/formmode/SyncLoggerDao.java | 134 +++ .../common/formmode/SyncLoggerDetailDao.java | 70 ++ .../formmode/SyncOtherDBToModeAction.java | 41 + .../formmode/SyncOtherDBToModeCron.java | 32 + .../formmode/SyncOtherDBToModeUtil.java | 641 +++++++++++++ .../he/zwl/common/logging/Log4JLogger.java | 91 ++ .../he/zwl/common/logging/Logger.java | 78 ++ .../he/zwl/common/logging/LoggerFactory.java | 50 + .../he/zwl/common/workflow/JsonType.java | 24 + .../common/workflow/WorkflowDataToJson.java | 311 +++++++ 129 files changed, 19290 insertions(+) create mode 100644 src/main/java/com/api/chaoyang/he/browser/service/impl/MultiInvoiceBrowserService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/controller/ChangeFpytController.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/controller/DeleteInvoiceNotApController.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/entity/BackupFnaDataEntity.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl_copy.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/mapper/ChangeFpytMapper.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/ChangeFpytService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/impl/ChangeFpytServiceImpl.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/controller/ExportPDFController.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/mapper/ExportPDFMapper.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/ExportPDFService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/impl/ExportPDFServiceImpl.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/DetailDataExportExcelController.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/TbSheetChangeDownloadStatusController.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/mapper/DetailDataExportExcelMapper.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/DetailDataExportExcelApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService_copy.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/wflistdonestore/ExportPDF.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelAVPNApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelL3NSApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/CheckRequestInfo.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper_copy.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/ExportExcelOtherApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SetCellStylePOI.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCMRPOI.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCostPOI.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetQuotationPOI.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/StringEscapeUtils.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/CheckProjectNameApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi_copy.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelAVPNService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelL3NSService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelOtherService.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelAVPNServiceImpl.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelL3NSServiceImpl.java create mode 100644 src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelOtherServiceImpl.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/action/TbSheetAction.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/dto/TbDetailData.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/mapper/TbSheetMapper.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/TbSheetService.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/impl/TbSheetServiceImpl.java create mode 100644 src/main/java/weaver/chaoyang/he/fengtianfangzhi/tbsheet/action/TBSheetAction.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ChangeState.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ModeExpandTemplate.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplate.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplateMapper.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate.java create mode 100644 src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate_copy.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceImpl.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/web/DeleteInvoiceNotApAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction_copy.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/controller/CheckAndChangeValueAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/mapper/CheckAndChangeValueMapper.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/CheckAndChangeValueService.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/impl/CheckAndChangeValueServiceImpl.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/controller/GetDataCreateWorkflowController.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/mapper/GetWorkflowDataMapper.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/GetWorkflowDataService.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl_copy.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/rollbackmoneytoworkflow/acton/RollbackMoneyToWorkflowAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/update_lqts/action/UpdateLqtsAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/updatepdfname/action/UpdatePDFNameAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_pcn/noticeaftersigned/action/NoticeAfterSigned.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_pcn/sendfieldstoothersystem/action/SendFieldsAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBActionCopy.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/filterinvoice/FilterInvoiceService.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction01.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction02.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction03.java create mode 100644 src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction04.java create mode 100644 src/main/java/weaver/chaoyang/he/jiacheng/deng/toyota/boshoku/action/TbChangeTextNameAction.java create mode 100644 src/main/java/weaver/chaoyang/he/shangan/common/util/CommonWFUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/shangan/cornjob/MailInfoDao.java create mode 100644 src/main/java/weaver/chaoyang/he/shangan/cornjob/MailTriggerWorkflowCronJob.java create mode 100644 src/main/java/weaver/chaoyang/he/shangan/cornjob/ReadMail.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/dao/ConfigMappingCMD.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/DocImageFile.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/FieldMessage.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ListMapIndexValue.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MappingDetail.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MultipartFile.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/RequestMappingConfig.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ResponseMapping.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/DataSourceEnum.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/GetValueTypeEnum.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/ParamTypeEnum.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceGetValue.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceListValue.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/config/service/DealWithMapping.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/exception/RequestException.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/exception/ValueDealException.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/JsonResult.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/LogUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/PreMap.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/PropUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestBaseInfo.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/SqlUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/xiao/commons/utils/annotation/SqlFieldMapping.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/CusBaseAction.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/ThreadPoolConfig.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil_E9.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/WorkflowData_To_Middle_DB_Action.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Action.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Cron.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Util.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDao.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDetailDao.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeAction.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeCron.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeUtil.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/logging/Log4JLogger.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/logging/Logger.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/logging/LoggerFactory.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/workflow/JsonType.java create mode 100644 src/main/java/weaver/chaoyang/he/zwl/common/workflow/WorkflowDataToJson.java diff --git a/src/main/java/com/api/chaoyang/he/browser/service/impl/MultiInvoiceBrowserService.java b/src/main/java/com/api/chaoyang/he/browser/service/impl/MultiInvoiceBrowserService.java new file mode 100644 index 0000000..12a2f6e --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/browser/service/impl/MultiInvoiceBrowserService.java @@ -0,0 +1,206 @@ +/* + * + * Copyright (c) 2001-2018 泛微软件. + * 泛微协同商务系统,版权所有. + * + */ +package com.api.chaoyang.he.browser.service.impl; + +import com.api.browser.bean.ListHeadBean; +import com.api.browser.bean.SearchConditionItem; +import com.api.browser.bean.SplitTableBean; +import com.api.browser.bean.SplitTableColBean; +import com.api.browser.service.BrowserService; +import com.api.browser.util.*; +import com.cloudstore.dev.api.bean.SplitMobileDataBean; +import com.cloudstore.dev.api.bean.SplitMobileTemplateBean; +import com.cloudstore.dev.api.util.Util_MobileData; +import org.apache.commons.lang.StringEscapeUtils; +import weaver.conn.RecordSet; +import weaver.fna.e9.controller.base.FnaInvoiceLedgerController; +import weaver.fna.invoice.Constants; +import weaver.general.Util; +import weaver.systeminfo.SystemEnv; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author zhangwj + * @Description:多发票浏览按钮 + * @version 1.0 + */ +public class MultiInvoiceBrowserService extends BrowserService { + + //移动端返回数据格式的json配置 + public static final String JSON_CONFIG="[" + + " {" + + " \"key\": \"col1\"," + + " \"configs\": [" + + " {" + + " \"key\": \"col1_row1\"," + + " \"configs\": [" + + " {" + + " \"key\": \"invoiceNumber\"" + + " }," + + " {" + + " \"key\": \"invoiceCode\"," + + " \"style\": {" + + " \"float\": \"right\"" + + " }" + + " }" + + " ]" + + " }," + + " {" + + " \"key\": \"col1_row2\"," + + " \"configs\": [" + + " {" + + " \"key\": \"taxIncludedPrice\"" + + " }," + + " {" + + " \"key\": \"invoiceTypeName\"," + + " \"style\": {" + + " \"float\": \"right\"" + + " }" + + " }" + + " ]" + + " }" + + " {" + + " \"key\": \"col1_row3\"," + + " \"configs\": [" + + " {" + + " \"key\": \"billingdate\"" + + " }," + + " ]" + + " }" + + " ]" + + " }" + + "]"; + + /** + * 多发票浏览 + * @param params + * @return + */ + @Override + public Map getBrowserData(Map params) throws Exception { + Map apidatas = new HashMap(); + if(user == null){ + apidatas.put(BrowserConstant.BROWSER_RESULT_DATA, null); + return apidatas; + } + String advQry_kprq1 = Util.null2String(params.get("createdatestart")).trim(); + String advQry_kprq2 = Util.null2String(params.get("createdateend")).trim(); + String invoiceNumber = Util.null2String(params.get("invoiceNumber")); + String seller = Util.null2String(params.get("seller")); + + //发票代码,发票类型,开票日期,金额 + FnaInvoiceLedgerController fnaInvoiceLedgerController = FnaInvoiceLedgerController.getInstance(); + String sqlAppend = fnaInvoiceLedgerController.getCaseWhenSql4InvoiceTypeList("invoiceTypeName", "a.invoiceType", user.getLanguage())+" "; + //设置好搜索条件 + String backFields =" a.*, "+ + fnaInvoiceLedgerController.getCaseWhenSql4InvoiceTypeList("invoiceTypeName", "a.invoiceType", user.getLanguage())+" "; + String fromSql = " from FnaInvoiceLedger a "; + //验票为真的发票才能选择的到 + StringBuffer sqlWhere = new StringBuffer(" where 1=1 and (checkStatus = 1 or checkStatus = 2) "); + if(!"".equals(advQry_kprq2)){ + sqlWhere.append(" and a.billingDate <= '").append(StringEscapeUtils.escapeSql(advQry_kprq2)).append("' "); + } + if(!"".equals(advQry_kprq1)){ + sqlWhere.append(" and a.billingDate >= '").append(StringEscapeUtils.escapeSql(advQry_kprq1)).append("' "); + } + if(!"".equals(invoiceNumber)){ + sqlWhere.append(" and a.invoiceNumber like '%").append(StringEscapeUtils.escapeSql(invoiceNumber.trim())).append("%'"); + } + if(!"".equals(seller)){ + sqlWhere.append(" and a.seller like '%").append(StringEscapeUtils.escapeSql(seller.trim())).append("%'"); + } + sqlWhere.append(" and (a.userid_new = ").append(user.getUID()).append(" or a.id in ( select invoiceId from fnaInvoiceSharer where sharer = ").append(user.getUID()).append(") ").append(") "); + sqlWhere.append(" and a.status = '0' "); + //AP航信过滤浏览按钮中的数据-hcy +// sqlWhere.append(" and hxjksflr is null "); + String orderBy=" a.id desc "; + + //writeLog("select "+backFields+" "+fromSql+" "+sqlWhere); + List cols = new ArrayList(); + cols.add(new SplitTableColBean("true","id")); + cols.add(new SplitTableColBean("30%",SystemEnv.getHtmlLabelName(900,user.getLanguage()),"invoiceNumber","invoiceNumber",1).setIsInputCol(BoolAttr.TRUE)); + cols.add(new SplitTableColBean("30%",SystemEnv.getHtmlLabelName(17213,user.getLanguage()),"invoiceCode","invoiceCode")); + cols.add(new SplitTableColBean("30%",SystemEnv.getHtmlLabelName(17213,user.getLanguage()),"invoiceTypeName","invoiceTypeName")); + cols.add(new SplitTableColBean("30%",SystemEnv.getHtmlLabelName(17213,user.getLanguage()),"billingdate","billingdate")); + cols.add(new SplitTableColBean("30%",SystemEnv.getHtmlLabelName(17213,user.getLanguage()),"taxIncludedPrice","taxIncludedPrice")); + SplitTableBean tableBean = new SplitTableBean(backFields,fromSql,sqlWhere.toString(),orderBy,"a.id","DESC",cols); + + + //移动端返回数据 + List mobileDataBeanList=Util_MobileData.createList(JSON_CONFIG); + SplitMobileTemplateBean bean=Util_MobileData.createJsonTemplateBean("theme_default", mobileDataBeanList); + tableBean.createMobileTemplate(bean); + + apidatas.putAll(SplitTableUtil.makeListDataResult(tableBean)); + return apidatas; + } + + /** + * 高级搜索 + * @param params + * @return + */ + @Override + public Map getBrowserConditionInfo(Map params) throws Exception { + Map apidatas = new HashMap(); + List conditions = new ArrayList(); + ConditionFactory conditionFactory = new ConditionFactory(user); + conditions.add(conditionFactory.createCondition(ConditionType.INPUT, 900, "invoiceNumber").setIsQuickSearch(true)); + apidatas.put(BrowserConstant.BROWSER_RESULT_CONDITIONS, conditions); + return apidatas; + } + + /** + * 多发票(多选界面右侧选中部分) + * @param params + * @return + */ + @Override + public Map getMultBrowserDestData(Map params) throws Exception { + Map apidatas = new HashMap(); + + String selectids = Util.null2String(params.get(BrowserConstant.BROWSER_MULT_DEST_SELECTIDS)); + + List> datas = new ArrayList>(); + + StringBuffer buffer = new StringBuffer(); + buffer.append(" select a.* from FnaInvoiceLedger a "); + buffer.append(" where a.id in (").append(selectids).append(")"); + buffer.append(" order by a.id desc "); + + RecordSet rs = new RecordSet(); + rs.execute(buffer.toString()); + while(rs.next()){ + Map item = new HashMap(); + item.put("id",Util.null2String(rs.getString("id"))); + item.put("invoiceNumber",Util.null2String(rs.getString("invoiceNumber"))); + item.put("invoiceCode",Util.null2String(rs.getString("invoiceCode"))); + item.put("invoiceTypeName", Constants.INVOICETYPE.get(Util.null2String(rs.getString("invoicetype")))); + item.put("billingdate", Util.null2String(rs.getString("billingdate"))); + item.put("taxIncludedPrice", Util.null2String(rs.getString("taxIncludedPrice"))); + datas.add(item); + } + List tableHeadColumns = new ArrayList(); + tableHeadColumns.add(new ListHeadBean("id",BoolAttr.TRUE).setIsPrimarykey(BoolAttr.TRUE)); + tableHeadColumns.add(new ListHeadBean("invoiceNumber","",1,BoolAttr.TRUE)); + tableHeadColumns.add(new ListHeadBean("invoiceCode","")); + tableHeadColumns.add(new ListHeadBean("invoiceTypeName","")); + tableHeadColumns.add(new ListHeadBean("billingdate","")); + tableHeadColumns.add(new ListHeadBean("taxIncludedPrice","")); + + apidatas.put(BrowserConstant.BROWSER_RESULT_COLUMN, tableHeadColumns); + apidatas.put(BrowserConstant.BROWSER_RESULT_DATA, BrowserBaseUtil.sortDatas(datas,selectids,"id")); + apidatas.put(BrowserConstant.BROWSER_RESULT_TYPE, BrowserDataType.LIST_ALL_DATA.getTypeid()); + + return apidatas; + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/controller/ChangeFpytController.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/controller/ChangeFpytController.java new file mode 100644 index 0000000..64dc234 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/controller/ChangeFpytController.java @@ -0,0 +1,45 @@ +package com.api.chaoyang.he.hcy_aphangxin.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.chaoyang.he.hcy_aphangxin.service.ChangeFpytService; +import com.api.chaoyang.he.hcy_aphangxin.service.impl.ChangeFpytServiceImpl; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +@Path("/hcy_aphangxin") +public class ChangeFpytController { + + /** + * 用于处理修改发票用途的主要逻辑 + */ + private ChangeFpytService changeFpytService = new ChangeFpytServiceImpl(); + + /** + * 日志处理 + */ + private Logger logger = Util.getLogger(); + /** + *

AP发票库-航信台账中修改发票用途

+ * @param request,response + * @return String + * @author hcy + * @Date 2023/3/13 14:28 + */ + @POST + @Path("/change/fpyt") + @Produces(MediaType.APPLICATION_JSON) + public String checkRequestInfo(@Context HttpServletRequest request, @Context HttpServletResponse response) { + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + String s = changeFpytService.changeFpytValue(split); + return ApiResult.success(s); + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/controller/DeleteInvoiceNotApController.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/controller/DeleteInvoiceNotApController.java new file mode 100644 index 0000000..4260690 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/controller/DeleteInvoiceNotApController.java @@ -0,0 +1,73 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.DeleteInvoiceNotApService; +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.impl.DeleteInvoiceNotApServiceimpl; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Path("/hcy_aphangxin/delete") +public class DeleteInvoiceNotApController { + + /** + * 日志处理 + */ + private final Logger logger = Util.getLogger(); + + /** + * service层、用于处理主要逻辑 + */ + private final DeleteInvoiceNotApService deleteInvoiceNotApService = new DeleteInvoiceNotApServiceimpl(); + + /** + *

根据数据id删除非AP发票

+ * @param request + * @param response + * @return String + * @author hcy + * @Date 2023/3/17 15:21 + */ + @POST + @Path("/invoice/not/ap") + @Produces(MediaType.APPLICATION_JSON) + public String deleteInvoiceNotAp(@Context HttpServletRequest request, @Context HttpServletResponse response) { + //前端查询到的数据id + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + //备份数据之前,首先查询要备份和要删除的数据的发票用途字段是否为非AP,若为非AP字段则删除,若不是非AP字段则不删除,并返回前端提醒用户选择ap字段进行删除 + List fpytList = deleteInvoiceNotApService.selectFpyt(split); + List fpytCollection = fpytList.stream().filter(items -> items.equals("1")).collect(Collectors.toList()); + if (fpytList.size() != fpytCollection.size()){ + logger.info("删除数据发票用途字段不为非AP,请重新选择"); + return ApiResult.success(1,"删除数据发票用途字段不为非AP,请重新选择"); + } + //删除非AP数据之前首先备份数据 + boolean backupBoolean = deleteInvoiceNotApService.backUpAfterDelete(split); + if (backupBoolean==true){ + logger.info("数据备份成功"); + }else{ + logger.info("数据备份失败"); + } + //开始删除数据 + boolean deleteBoolean = deleteInvoiceNotApService.deleteDateById(split); + if (deleteBoolean){ + logger.info("数据删除成功"); + return ApiResult.success(0,"数据删除成功!"); + }else { + logger.info("数据删除失败"); + return ApiResult.success(1,"数据删除失败!"); + } + + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/entity/BackupFnaDataEntity.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/entity/BackupFnaDataEntity.java new file mode 100644 index 0000000..652884b --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/entity/BackupFnaDataEntity.java @@ -0,0 +1,61 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.entity; + +import lombok.Data; + +@Data +public class BackupFnaDataEntity { + + int requestId; + + int formmodeid; + + int modedatacreater; + + int modedatacreatertype; + + String modedatacreatedate; + + String modedatacreatetime; + + String MODEUUID; + + String form_biz_id; + + double taxRate; + + String billingdate; + + String invoicenumber; + + String invoicecode; + + String invoicetype; + + double taxincludedprice; + + double pricewithouttax; + + double tax; + + String purchaser; + + String purchasertaxno; + + String seller; + + String salestaxno; + + String purp; + + String hxjksflr; + + int checkStatus; + + int status; + + int authenticity; + + int fpyt; + + int check_status; +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java new file mode 100644 index 0000000..9e3ba37 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java @@ -0,0 +1,39 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.mapper; + +import aiyh.utils.annotation.recordset.*; + + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface DeleteInvoiceNotApMapper { + + + + @Select("select * from fnainvoiceledger where id in ($t{split})") + List> selectDate(@ParamMapper("split") String[] split); + + @Insert("insert into uf_apfpscsj (billingDate,invoiceCode,invoiceNumber," + + "invoiceType,seller,purchaser,invoiceServiceYype,priceWithoutTax,taxRate," + + "tax,taxIncludedPrice,authenticity,reimbursementDate,reimbursePerson,requestId,userid_new," + + "invoiceSource_new,checkcode,status,card_id_new,encrypt_code_new,openid_new,wechatstatus,imageID,purchaserTaxNo," + + "salesTaxNo,entryTime,company_seal,form_type,form_name,kind,ciphertext,category,imageDocId,checkStatus," + + "updateOperate,cloudId,codeConfirm,numberConfirm,receiptor,reviewer,issuer,province,city,travel_tax,fylx," + + "purp,iele,orf,hxjksflr,fpyt) " + + "values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + boolean backupDate(@ParamMapper("backupDataLists") List backupDataLists); + + @Delete("delete from fnainvoiceledger where id = #{id}") + boolean deleteDateById(@ParamMapper("id") String id); + + /** + *

查询发票用途字段是否为非航行

+ * @param id 数据id + * @return String + * @author hcy + * @Date 2023/3/20 13:56 + */ + @Select("select fpyt from fnainvoiceledger where id = #{id}") + String selectFpyt(String id); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java new file mode 100644 index 0000000..babe51b --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java @@ -0,0 +1,11 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service; + +import java.util.List; + +public interface DeleteInvoiceNotApService { + boolean backUpAfterDelete(String[] split); + boolean deleteDateById(String[] split); + + List selectFpyt(String[] split); + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl.java new file mode 100644 index 0000000..7a1b9ed --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl.java @@ -0,0 +1,94 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.mapper.DeleteInvoiceNotApMapper; +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.DeleteInvoiceNotApService; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class DeleteInvoiceNotApServiceimpl implements DeleteInvoiceNotApService { + + /** + * 用于sql处理 + */ + private final DeleteInvoiceNotApMapper deleteInvoiceNotApMapper = Util.getMapper(DeleteInvoiceNotApMapper.class); + + /** + * 日志 + */ + private final Logger logger = Util.getLogger(); + + /** + *

用于查询数据,查询到的数据进行数据备份

+ * @param split requestid + * @return boolean 数据备份是否成功 + * @author hcy + * @Date 2023/3/17 17:48 + */ + public boolean backUpAfterDelete(String[] split) { + RecordSet recordSet = new RecordSet(); + for (String id : split) { + String backupDataSql = "INSERT INTO fnabackup (billingdate,\t\n" + + "invoicenumber,\t\n" + + "invoicecode,\n" + + "invoicetype,\t\n" + + "taxincludedprice,pricewithouttax,\t\n" + + "tax,\n" + + "purchaser,purchasertaxno,\t\n" + + "seller,salestaxno,purp,hxjksflr,checkStatus,status,authenticity,fpyt,taxrate\n" + + ") SELECT \n" + + "billingdate,\t\n" + + "invoicenumber,\t\n" + + "invoicecode,\n" + + "invoicetype,\t\n" + + "taxincludedprice,pricewithouttax,\t\n" + + "tax,\n" + + "purchaser,purchasertaxno,\t\n" + + "seller,salestaxno,purp,hxjksflr,checkStatus,status,authenticity,fpyt,taxrate\n" + + " FROM fnainvoiceledger WHERE id = ?"; + boolean backupBool = recordSet.executeUpdate(backupDataSql, id); + if (!backupBool){ + return false; + } + } + //开始备份数据 + return true; + } + + /** + *

根据数据id、删除数据

+ * @param split id + * @return boolean 数据删除是否成功 + * @author hcy + * @Date 2023/3/17 18:00 + */ + public boolean deleteDateById(String[] split) { + List booleanList = new ArrayList<>(); + + for (String s : split) { + boolean deleteBoolean = deleteInvoiceNotApMapper.deleteDateById(s); + booleanList.add(deleteBoolean); + } + List collect = booleanList.stream().distinct().collect(Collectors.toList()); + if (collect != null && collect.size()==1){ + return true; + } + return false; + } + + @Override + public List selectFpyt(String[] split) { + List fpytLists = new ArrayList<>(); + for (String s : split) { + String fpyt = deleteInvoiceNotApMapper.selectFpyt(s); + fpytLists.add(fpyt); + } + return fpytLists; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl_copy.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl_copy.java new file mode 100644 index 0000000..a275094 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceimpl_copy.java @@ -0,0 +1,143 @@ +package com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.mapper.DeleteInvoiceNotApMapper; +import com.api.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.DeleteInvoiceNotApService; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class DeleteInvoiceNotApServiceimpl_copy implements DeleteInvoiceNotApService { + + /** + * 用于sql处理 + */ + private final DeleteInvoiceNotApMapper deleteInvoiceNotApMapper = Util.getMapper(DeleteInvoiceNotApMapper.class); + + /** + * 日志 + */ + private final Logger logger = Util.getLogger(); + + /** + *

用于查询数据,查询到的数据进行数据备份

+ * @param split requestid + * @return boolean 数据备份是否成功 + * @author hcy + * @Date 2023/3/17 17:48 + */ + public boolean backUpAfterDelete(String[] split) { + //导入数据之前先查询数据 + List> backupDate = deleteInvoiceNotApMapper.selectDate(split);//拿到需要备份的数据 + //开始备份数据 + List bool = new ArrayList<>();//存放sql语句insert动作是否成功 + for (Map map : backupDate) { + List backupDataLists = new ArrayList<>(); + backupDataLists.add(map.get("billingDate")); + backupDataLists.add(map.get("invoiceCode")); + backupDataLists.add(map.get("invoiceNumber")); + backupDataLists.add(map.get("invoiceType")); + backupDataLists.add(map.get("seller")); + backupDataLists.add(map.get("purchaser")); + backupDataLists.add(map.get("invoiceServiceYype")); + backupDataLists.add(map.get("priceWithoutTax")); + backupDataLists.add(map.get("taxRate")); + backupDataLists.add(map.get("tax")); + backupDataLists.add(map.get("taxIncludedPrice")); + backupDataLists.add(map.get("authenticity")); + backupDataLists.add(map.get("reimbursementDate")); + backupDataLists.add(map.get("reimbursePerson")); + backupDataLists.add(map.get("requestId")); + backupDataLists.add(map.get("useridNew")); + backupDataLists.add(map.get("invoiceSourceNew")); + backupDataLists.add(map.get("checkcode")); + backupDataLists.add(map.get("status")); + backupDataLists.add(map.get("cardIdNew")); + backupDataLists.add(map.get("encryptCodeNew")); + backupDataLists.add(map.get("openidNew")); + backupDataLists.add(map.get("wechatstatus")); + backupDataLists.add(map.get("imageID")); + backupDataLists.add(map.get("purchaserTaxNo")); + backupDataLists.add(map.get("salesTaxNo")); + backupDataLists.add(map.get("entryTime")); + backupDataLists.add(map.get("companySeal")); + backupDataLists.add(map.get("formType")); + backupDataLists.add(map.get("formName")); + backupDataLists.add(map.get("kind")); + backupDataLists.add(map.get("ciphertext")); + backupDataLists.add(map.get("category")); + backupDataLists.add(map.get("imageDocId")); + backupDataLists.add(map.get("checkStatus")); + backupDataLists.add(map.get("updateOperate")); + backupDataLists.add(map.get("cloudId")); + backupDataLists.add(map.get("codeConfirm")); + backupDataLists.add(map.get("numberConfirm")); + backupDataLists.add(map.get("receiptor")); + backupDataLists.add(map.get("reviewer")); + backupDataLists.add(map.get("issuer")); + backupDataLists.add(map.get("province")); + backupDataLists.add(map.get("city")); + backupDataLists.add(map.get("travelTax")); +// backupDataLists.add(map.get("fylx")); + backupDataLists.add(map.get("purp")); +// backupDataLists.add(map.get("iele")); + backupDataLists.add(map.get("orf")); + backupDataLists.add(map.get("hxjksflr")); + backupDataLists.add(map.get("fpyt")); + RecordSet recordSet = new RecordSet(); + String backupdate = "insert into fnabackup (billingDate,invoiceCode,invoiceNumber," + + "invoiceType,seller,purchaser,invoiceServiceYype,priceWithoutTax,taxRate," + + "tax,taxIncludedPrice,authenticity,reimbursementDate,reimbursePerson,requestId,userid_new," + + "invoiceSource_new,checkcode,status,card_id_new,encrypt_code_new,openid_new,wechatstatus,imageID,purchaserTaxNo," + + "salesTaxNo,entryTime,company_seal,form_type,form_name,kind,ciphertext,category,imageDocId,checkStatus," + + "updateOperate,cloudId,codeConfirm,numberConfirm,receiptor,reviewer,issuer,province,city,travel_tax," + + "purp,orf,hxjksflr,fpyt) " + + "values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + boolean insertIntoBoolean = recordSet.executeUpdate(backupdate, backupDataLists); +// boolean insertIntoBoolean = deleteInvoiceNotApMapper.backupDate(backupDataLists); + bool.add(insertIntoBoolean); + logger.info("插入语句是否成功==="+insertIntoBoolean); + } + List collect = bool.stream().distinct().collect(Collectors.toList()); + if (collect!=null && collect.size()==1){ + return true; + } + return false; + } + + /** + *

根据数据id、删除数据

+ * @param split id + * @return boolean 数据删除是否成功 + * @author hcy + * @Date 2023/3/17 18:00 + */ + public boolean deleteDateById(String[] split) { + List booleanList = new ArrayList<>(); + + for (String s : split) { + boolean deleteBoolean = deleteInvoiceNotApMapper.deleteDateById(s); + booleanList.add(deleteBoolean); + } + List collect = booleanList.stream().distinct().collect(Collectors.toList()); + if (collect != null && collect.size()==1){ + return true; + } + return false; + } + + @Override + public List selectFpyt(String[] split) { + List fpytLists = new ArrayList<>(); + for (String s : split) { + String fpyt = deleteInvoiceNotApMapper.selectFpyt(s); + fpytLists.add(fpyt); + } + return fpytLists; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/mapper/ChangeFpytMapper.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/mapper/ChangeFpytMapper.java new file mode 100644 index 0000000..26a2fed --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/mapper/ChangeFpytMapper.java @@ -0,0 +1,17 @@ +package com.api.chaoyang.he.hcy_aphangxin.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.Update; + +/** + *

根据数据id,修改发票用途字段值

+ * @Author hcy + * @Date 2023/3/13 14:41 + */ +@SqlMapper +public interface ChangeFpytMapper { + + @Update("update fnainvoiceledger set fpyt = 1 where id = #{id}") + boolean updateFpytValue(@ParamMapper("id") String id); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/ChangeFpytService.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/ChangeFpytService.java new file mode 100644 index 0000000..b0babfc --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/ChangeFpytService.java @@ -0,0 +1,12 @@ +package com.api.chaoyang.he.hcy_aphangxin.service; + +public interface ChangeFpytService { + /** + *

修改发票用途主要逻辑

+ * @param split + * @return String + * @author hcy + * @Date 2023/3/13 14:38 + */ + public String changeFpytValue(String[] split); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/impl/ChangeFpytServiceImpl.java b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/impl/ChangeFpytServiceImpl.java new file mode 100644 index 0000000..e7be351 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_aphangxin/service/impl/ChangeFpytServiceImpl.java @@ -0,0 +1,33 @@ +package com.api.chaoyang.he.hcy_aphangxin.service.impl; + +import aiyh.utils.Util; +import com.api.chaoyang.he.hcy_aphangxin.mapper.ChangeFpytMapper; +import com.api.chaoyang.he.hcy_aphangxin.service.ChangeFpytService; + + +public class ChangeFpytServiceImpl implements ChangeFpytService { + + /** + * 用于直接操作数据库的Mapper类 + */ + private final ChangeFpytMapper changeFpytMapper = Util.getMapper(ChangeFpytMapper.class); + + @Override + public String changeFpytValue(String[] split) { + int num = 0; + for (String s : split) { + if (!s.equals("")){ + boolean b = changeFpytMapper.updateFpytValue(s); + if (b){ + num++; + } + } + } + if (num == split.length){ + return "所有数据更新成功"; + }else { + return "数据更新失败"; + } + + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/controller/ExportPDFController.java b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/controller/ExportPDFController.java new file mode 100644 index 0000000..6ec18de --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/controller/ExportPDFController.java @@ -0,0 +1,92 @@ +package com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.controller; + + +import aiyh.utils.Util; +import com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.service.ExportPDFService; +import com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.service.impl.ExportPDFServiceImpl; +import org.apache.log4j.Logger; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; + +@Path("/hcy_dingxinjituan") +public class ExportPDFController { + + private final ExportPDFService exportPDFService = new ExportPDFServiceImpl(); + + private final Logger logger = Util.getLogger(); + + @GET + @Path("/export/pdf") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportPDF(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + Response build = null; + Response.ResponseBuilder header = null; + StreamingOutput output = null; + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + //第二步更新导出次+1 + exportPDFService.updateDccs(split); + + //第一步查询数据封装到List>类型的集合中 + List> dataList = exportPDFService.selectDataList(split); + User user = HrmUserVarify.getUser(request, response); + String exportUser = user.getLastname(); + //第三步同步数据 + List insertBooleanLists = exportPDFService.backupData(dataList,exportUser,this.getCurrentTime()); + for (Boolean list : insertBooleanLists) { + if (list == false){ + logger.info("备份数据失败"); + } + } + //第四步根据第一步拿到的数据导出pdf + String exportTime = getCurrentDateTime();//导出时间 + + + byte[] pdfBytes = exportPDFService.exportPDF(dataList,exportUser,exportTime); + output = outputStream -> { + outputStream.write(pdfBytes); + outputStream.close(); + }; + String fileName = "顶新集团-"+ getCurrentTime() + ".pdf"; + try { + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String(fileName.getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + return header.build(); + } + + public static String getCurrentDateTime() { + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return now.format(formatter); + } + + public static String getCurrentTime() { + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + return now.format(formatter); + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/mapper/ExportPDFMapper.java b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/mapper/ExportPDFMapper.java new file mode 100644 index 0000000..31b525d --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/mapper/ExportPDFMapper.java @@ -0,0 +1,32 @@ +package com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.Update; +import org.directwebremoting.annotations.Param; + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface ExportPDFMapper { + + + @Select("select * from uf_sapywdj where id in ($t{split})") + List> selectDataList(String[] split); + + @Update("update uf_sapywdj set dccs = #{s} where id = #{id}") + boolean updateDccs(@ParamMapper("s") String s, @ParamMapper("id") String id); + + + @Select("select dccs from uf_sapywdj where id = #{id}") + String selectDccs(String id); + + @Select("select requestname from workflow_requestbase where requestid = #{stringXglc}") + String selectRequestName(String stringXglc); + + @Select("select gysmc from uf_sapgys where id= #{gfdw} ") + String setGfdw(String gfdw); + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/ExportPDFService.java b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/ExportPDFService.java new file mode 100644 index 0000000..f338871 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/ExportPDFService.java @@ -0,0 +1,14 @@ +package com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.service; + +import java.util.List; +import java.util.Map; + +public interface ExportPDFService { + List> selectDataList(String[] split); + + void updateDccs(String[] split); + + byte[] exportPDF(List> dataList, String exportUser, String exportTime); + + List backupData(List> dataList,String exportUser,String exportTime); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/impl/ExportPDFServiceImpl.java b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/impl/ExportPDFServiceImpl.java new file mode 100644 index 0000000..53d103b --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_dingxinjituan/exportpdf/service/impl/ExportPDFServiceImpl.java @@ -0,0 +1,275 @@ +package com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.service.impl; + +import aiyh.utils.Util; + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.mapper.ExportPDFMapper; +import com.api.chaoyang.he.hcy_dingxinjituan.exportpdf.service.ExportPDFService; +import com.itextpdf.text.Document; +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.*; +import de.schlichtherle.io.File; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.general.GCONST; + + +public class ExportPDFServiceImpl implements ExportPDFService { + + private final ExportPDFMapper exportPDFMapper = Util.getMapper(ExportPDFMapper.class); + + private final Logger logger = Util.getLogger(); + @Override + public List> selectDataList(String[] split) { + return exportPDFMapper.selectDataList(split); + } + + @Override + public void updateDccs(String[] split) { + for (String s : split) { + String dccs = Util.null2String(exportPDFMapper.selectDccs(s)); + if (!"".equals(dccs) && Util.getIntValue(dccs)!=-1){ + int dccsInt = Integer.parseInt(dccs); + dccsInt++; + dccs = String.valueOf(dccsInt); + boolean updateBool = exportPDFMapper.updateDccs(dccs,s); + }else if (!"".equals(dccs) && Util.getIntValue(dccs)==-1){ + boolean updateBool = exportPDFMapper.updateDccs("1",s); + } + else{ + boolean updateBool = exportPDFMapper.updateDccs("1",s); + } + } + } + + + + @Override + public byte[] exportPDF(List> dataList, String exportUser, String exportTime) { + + // 创建PDF文档 + Document document = new Document(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + PdfWriter.getInstance(document, baos); + // 打开PDF文档 + document.open(); + + // 创建页面并设置属性 +// Rectangle pageSize = PageSize.A4; +// document.setPageSize(pageSize.rotate()); // 横向页面 +// document.setMargins(36, 36, 36, 36); // 36pt边距 + + // 创建表格 + PdfPTable table = new PdfPTable(10); + table.setWidthPercentage(100f); + table.setHorizontalAlignment(Element.ALIGN_CENTER); + table.setHeaderRows(1); + //字体 + String rootPath = GCONST.getRootPath(); +// new File(GCONST.getRootPath()+"WEB-INF"+File.separatorChar+"meeting"+File.separatorChar); +// String fontPath = rootPath + "/WEB-INF/font/simfang.ttf"; + String fontPath = "/app/ecology/WEB-INF/font/simfang.ttf"; + logger.info("fontPath==="+fontPath); +// BaseFont bfChinese = BaseFont.createFont("D:\\WEAVER\\ecology\\WEB-INF\\font\\simfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); + + + // 添加标题 + Font titleFont = new Font(bfChinese, 18, Font.BOLD); + Paragraph title = new Paragraph("SAP-业务单据数据", titleFont); + title.setAlignment(Element.ALIGN_CENTER); + document.add(title); + + + + //// 添加导出人和导出日期信息 + + Paragraph info = new Paragraph("导出人:"+exportUser+" 导出日期:"+exportTime, + new Font(bfChinese, 10f, Font.NORMAL, BaseColor.BLACK)); + info.setAlignment(Element.ALIGN_RIGHT); + document.add(info); + + // 添加表头行 + // 设置表头样式及内容 + Font headerFont = new Font(bfChinese, 10, Font.BOLD, BaseColor.WHITE); + PdfPCell headerCell = new PdfPCell(); + headerCell.setBackgroundColor(BaseColor.BLACK); + headerCell.setHorizontalAlignment(Element.ALIGN_CENTER); + headerCell.setVerticalAlignment(Element.ALIGN_MIDDLE); + headerCell.setPadding(5); + + headerCell.setPhrase(new Phrase("申请编号", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("相关流程", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("法人公司编码", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("地址号", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("给付单位", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("开户行", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("银行账号", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("金额", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("SAP凭证号", headerFont)); + table.addCell(headerCell); + headerCell.setPhrase(new Phrase("导出次数", headerFont)); + table.addCell(headerCell); + + // 添加数据行 + + Font dataFont = new Font(bfChinese, 9, Font.NORMAL, BaseColor.BLACK); + for (Map row : dataList) { + table.addCell(createCell(String.valueOf(row.get("sqbh")), dataFont, Element.ALIGN_CENTER)); + String stringXglc = Util.null2String(row.get("xglc")); + String requstName = exportPDFMapper.selectRequestName(stringXglc); + table.addCell(createCell(requstName, dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("frgsbm")), dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("dzh")), dataFont, Element.ALIGN_CENTER)); + String gfdw = Util.null2String(row.get("gfdw")); + String gfdwString = exportPDFMapper.setGfdw(gfdw); + table.addCell(createCell(gfdwString, dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("khh")), dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("yhzh")), dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("je")), dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("sappzh")), dataFont, Element.ALIGN_CENTER)); + table.addCell(createCell(String.valueOf(row.get("dccs")), dataFont, Element.ALIGN_CENTER)); + } + + // 设置表格样式和行样式 + table.setSpacingBefore(8f); + table.setSpacingAfter(8f); + table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE); + table.getDefaultCell().setPadding(4f); + + // 添加表格到页面 + document.add(table); + + // 添加导出人和导出日期信息 + + +// 关闭PDF文档 + document.close(); + +// 将PDF文档写入输出流 + return baos.toByteArray(); + } catch (Exception e) { + e.printStackTrace(); + logger.info("导出PDF文档异常原因==="+e); + } + + + return new byte[0]; + } + + + public List backupData(List> dataList,String exportuser,String exporttime) { + RecordSet recordSet = new RecordSet(); + List insertBooleanLists = new ArrayList(); + try { + for (Map map : dataList) { + //toDo: + String insertSql = "insert into uf_sapywdj_backup (requestId,formmodeid,modedatacreater,modedatacreatertype," + + "modedatacreatedate,modedatacreatetime,MODEUUID,lclx,sfmdfy,qklx,fkfs,yfklx,dx,xglc,sqr,cgbs,fhxx,sappzh,sqbm," + + "khh,yhzh,ytsm,je,frgsbm,dpmc,dpbh,qwfkrq,dzh,szgs,sqbh,cwgzrq,ph,cwjb,paystatus,completetime,fygz,jybgse,jybgwsje,jybghsje," + + "jybgfhxx1,jybgfhxx2,jybgfhxx3,jybgfhzt1,jybgfhzt2,jybgfhzt3,jybgpzh1,jybgpzh2,jybgpzh3,dh,jybglshjl,gtddh,frgs,gfdw,cbzx,ywlx,mdcwjb," + + "mdcwkzg,cwkzg,zbchbzg,zbchbzg1,mdcwkzg1,dpmc1,zhcyr,modedatamodifier,modedatamodifydatetime,dccs,exportuser,exporttime) values (?,?,?,?,?,?,?,?,?,?," + + "?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + logger.info("sql==="+insertSql); + boolean insertBool = recordSet.executeUpdate(insertSql, + Util.null2String(map.get("requestId")), + Util.null2String(map.get("formmodeid")), + Util.null2String(map.get("formmodeid")), + Util.null2String(map.get("modedatacreatertype")), + Util.null2String(map.get("modedatacreatedate")), + Util.null2String(map.get("modedatacreatetime")), + Util.null2String(map.get("MODEUUID")), + Util.null2String(map.get("lclx")), + Util.null2String(map.get("sfmdfy")), + Util.null2String(map.get("qklx")), + Util.null2String(map.get("fkfs")), + Util.null2String(map.get("yfklx")), + Util.null2String(map.get("dx")), + Util.null2String(map.get("xglc")), + Util.null2String(map.get("sqr")), + Util.null2String(map.get("cgbs")), + Util.null2String(map.get("fhxx")), + Util.null2String(map.get("sappzh")), + Util.null2String(map.get("sqbm")), + Util.null2String(map.get("khh")), + Util.null2String(map.get("yhzh")), + Util.null2String(map.get("ytsm")), + Util.null2String(map.get("je")), + Util.null2String(map.get("frgsbm")), + Util.null2String(map.get("dpmc")), + Util.null2String(map.get("dpbh")), + Util.null2String(map.get("qwfkrq")), + Util.null2String(map.get("dzh")), + Util.null2String(map.get("szgs")), + Util.null2String(map.get("sqbh")), + Util.null2String(map.get("cwgzrq")), + Util.null2String(map.get("ph")), + Util.null2String(map.get("cwjb")), + Util.null2String(map.get("paystatus")), + Util.null2String(map.get("completetime")), + Util.null2String(map.get("fygz")), + Util.null2String(map.get("jybgse")), + Util.null2String(map.get("jybgwsje")), + Util.null2String(map.get("jybghsje")), + Util.null2String(map.get("jybgfhxx1")), + Util.null2String(map.get("jybgfhxx2")), + Util.null2String(map.get("jybgfhxx3")), + Util.null2String(map.get("jybgfhzt1")), + Util.null2String(map.get("jybgfhzt2")), + Util.null2String(map.get("jybgfhzt3")), + Util.null2String(map.get("jybgpzh1")), + Util.null2String(map.get("jybgpzh2")), + Util.null2String(map.get("jybgpzh3")), + Util.null2String(map.get("dh")), + Util.null2String(map.get("jybglshjl")), + Util.null2String(map.get("gtddh")), + Util.null2String(map.get("frgs")), + Util.null2String(map.get("gfdw")), + Util.null2String(map.get("cbzx")), + Util.null2String(map.get("ywlx")), + Util.null2String(map.get("mdcwjb")), + Util.null2String(map.get("mdcwkzg")), + Util.null2String(map.get("cwkzg")), + Util.null2String(map.get("zbchbzg")), + Util.null2String(map.get("zbchbzg1")), + Util.null2String(map.get("mdcwkzg1")), + Util.null2String(map.get("dpmc1")), + Util.null2String(map.get("zhcyr")), + Util.null2String(map.get("modedatamodifier")), + Util.null2String(map.get("modedatamodifydatetime")), + Util.null2String(map.get("dccs")), + exportuser, + exporttime + ); + insertBooleanLists.add(insertBool); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("错误原因==="+e.getMessage()); + } + + + return insertBooleanLists; + } + + private PdfPCell createCell(String text, Font font, int align) { + PdfPCell cell = new PdfPCell(new Phrase(text, font)); + cell.setHorizontalAlignment(align); + cell.setVerticalAlignment(Element.ALIGN_MIDDLE); + cell.setPadding(4f); + return cell; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/DetailDataExportExcelController.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/DetailDataExportExcelController.java new file mode 100644 index 0000000..69ca6e4 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/DetailDataExportExcelController.java @@ -0,0 +1,49 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.controller; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_fengtianfangzhi.service.DetailDataExportExcelApi; +import com.api.chaoyang.he.hcy_fengtianfangzhi.service.impl.DetailDataExportExcelService; +import org.apache.log4j.Logger; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +@Path("/hcy_fengtianfangzhi") +public class DetailDataExportExcelController { + + + private DetailDataExportExcelApi detailDataExportExcelService = new DetailDataExportExcelService(); + + + private Logger logger = Util.getLogger(); + + /** + *导出AVPN Excel表格 + * @param request + * @param response + * @return + */ + @GET + @Path("/detailDataExportExcel") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response checkRequestInfo(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + String requestid = request.getParameter("requestid"); + logger.info("requestid=="+requestid); + String lsxjd = request.getParameter("lsxjd"); + logger.info("lsxjd=="+lsxjd);//lsxjd + Response response1 = detailDataExportExcelService.exportExcel(requestid,lsxjd); + return response1; + } + + + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/TbSheetChangeDownloadStatusController.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/TbSheetChangeDownloadStatusController.java new file mode 100644 index 0000000..b029f70 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/controller/TbSheetChangeDownloadStatusController.java @@ -0,0 +1,280 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.engine.workflow.biz.requestForm.WfToDocBiz; +import com.engine.workflow.biz.requestForm.WfWaterMark4WfToDocBiz; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.file.FileUpload; +import weaver.file.ImageFileManager; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; +import weaver.interfaces.workflow.action.WorkflowToDoc; +import weaver.system.SystemComInfo; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.UUID; + + +/** + *

导出状态修改

+ * @Author jiacheng.deng + * @Date 2023/1/18 14:50 + */ +//"tb/djc/changeStatus/download/requestid=" + requestId + "&workflowid=" + workflowId + "&nodeid=" + nodeId +@Path("/tb") +public class TbSheetChangeDownloadStatusController { + + + //流程保存文档源码 + private WorkflowToDoc workflowToDoc = new WorkflowToDoc(); + //流程保存文档源码 + private WfToDocBiz wfToDocBiz = new WfToDocBiz(); + //数据库链接驱动 + private RecordSet recordSet = new RecordSet(); + //日志 + private final Logger log = Util.getLogger(); + //底部签字意见列表显示数量 + private int pageSize =100; + //下载的输入流 + private ImageFileManager imageFileManager = new ImageFileManager(); + + /** + *

修改导出状态

+ * @param request,response + * @return String + * @author jiacheng.deng + */ + @GET + @Path("/changeStatus/download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response changeStatus(@Context HttpServletRequest request, + @Context HttpServletResponse response + ) { + + try { + User logInUser = HrmUserVarify.getUser(request, response); + String uid = String.valueOf(logInUser.getUID()); + log.info("用户的id===>" + uid); + String findUserRole = "select * from HrmRoleMembers where resourceid = " + uid; + boolean b = recordSet.execute(findUserRole); + log.info("查询用户数据sql===> " + findUserRole + " ===>是否执行 :" + b); + recordSet.next(); + String roleid = recordSet.getString("roleid"); + log.info("用户角色roleid===>" + roleid); + +// log.info("requsetid===>" + requestid + "workflowid===>" + workflowid + "nodeid===>" + nodeid); + + + if ("1031".equals(roleid)) { + + try { +// StreamingOutput downloadStream = download2changeStatus(uid,request,response,requestid,workflowid,nodeid); + +// InputStream is = imageFileManager.getInputStreamById(this.getImageFileId(requestid)); + + String updateDownloadStatusSQl = "update formtable_main_368 set dczt = ?" ; + + int flag = 1; + boolean b1 = recordSet.executeUpdate(updateDownloadStatusSQl, flag); + log.info("执行修改导出状态代码===>" + b1); + + +// return Response.ok(downloadStream, MediaType.APPLICATION_OCTET_STREAM).type("application/") +// .header("Content-Disposition", "attachment;filename=workflow.pdf").build(); + + } catch (Exception e) { + log.error("转换失败:" + e.toString()); + return Response.ok(ApiResult.error("出现错误,错误原因: " + e), MediaType.APPLICATION_JSON).build(); + } + + } else { + try { +// StreamingOutput downloadStream = download2changeStatus(uid,request,response,requestid,workflowid,nodeid); +// return Response.ok(downloadStream, MediaType.APPLICATION_OCTET_STREAM).type("application/pdf") +// .header("Content-Disposition", "attachment;filename=contracts.zip").build(); + } catch (Exception e) { + log.error("转换失败:" + e.toString()); + + return Response.ok(ApiResult.error("出现错误,错误原因: " + e), MediaType.APPLICATION_JSON).build(); + } + } + + }catch(Exception e){ + + } + return null; + } + + /** + *

修改导出状态

+ * @param + * @return + * @author jiacheng.deng + */ + public StreamingOutput download2changeStatus(String uid,HttpServletRequest request,HttpServletResponse response,String requestid,String workflowid,String nodeid){ + + LinkedHashMap fileids = new LinkedHashMap (); + + User user = new User(weaver.general.Util.getIntValue(uid)); + + String docFiles = getDocFiles(workflowid); + //是否签名 + int keepSign = getKeepSign(workflowid); + String filename = UUID.randomUUID().toString(); + String temppath = getFileSavePath(); + + //是否开启水印 + boolean isOpenWaterMark = WfWaterMark4WfToDocBiz.isOpenWaterMark(weaver.general.Util.getIntValue(workflowid)); + //在这里先获取到modeid 线程中获取时流程可能已经到了下个节点导致模板获取的不对 + String modeid = wfToDocBiz.getModeid(Util.getIntValue(requestid), Util.getIntValue(workflowid), Util.getIntValue(nodeid)); + + WfToDocBiz wfToDocBiz = new WfToDocBiz(user,pageSize,keepSign,docFiles,modeid,isOpenWaterMark); + wfToDocBiz.generatepdfandhtml(requestid,filename,temppath,"1"); + fileids.putAll(wfToDocBiz.getfileids("",filename,temppath)); + + StreamingOutput output = outputStream -> { + + String docID; + if (recordSet.next()){ + + docID = wfToDocBiz.getWfDocPath(workflowid, requestid); + log.info("文档生成路径=="+docID); + ImageFileManager imageFileManager = new ImageFileManager(); + int imageFileId = this.getImageFileId(requestid); + log.info("imageFileId ==" + imageFileId); + InputStream is = imageFileManager.getInputStreamById(this.getImageFileId(requestid)); + + String fileName = this.getImageFileName(requestid); + + }; + + //关闭流 + outputStream.flush(); + outputStream.close(); + }; + + return null; + } + + private String getImageFileName(String requestid) { + + return null; + } + + /** + *

获得文件保存目录

+ * @param + * @return String + * @author jiacheng.deng + */ + public String getFileSavePath() { + SystemComInfo syscominfo = new SystemComInfo(); + String createdir = FileUpload.getCreateDir(syscominfo.getFilesystem()); + return createdir; + } + + + /** + *

根据requestId返回docimagefile表中imagefileId

+ * @param requestid + * @return int + * @author jiacheng.deng + */ + public int getImageFileId(String requestid){ + RecordSet recordSet = new RecordSet(); + String get_imagefileid_sql = "select tablename \n" + + "from workflow_bill \n" + + "where id = (select formid from workflow_base where id = \n" + + "(select workflowid from workflow_requestbase where requestid = ?)\n" + + ")"; + boolean b = recordSet.executeQuery(get_imagefileid_sql, requestid); + log.info("b是否执行"+b); + boolean next = recordSet.next(); + String tablename = recordSet.getString("tablename"); + String docid_key = this.getWfDocRelateFieldName(requestid);//每一流程表单中用来存放docid的字段名称 + + String get_docid_sql = "select "+docid_key+" from "+tablename+" where requestid = ?"; + boolean b1 = recordSet.executeQuery(get_docid_sql, requestid); + log.info("b1是否执行=="+b1); + recordSet.next(); + String docid = recordSet.getString(docid_key); + if (Util.null2String(docid).equals("")){ + return -1; + } + String get_imagefileid = "select imagefileid from DocImageFile where docid = ? order by versionId"; + boolean b2 = recordSet.executeQuery(get_imagefileid, docid); + log.info("b2是否执行=="+b2); + recordSet.next(); + String imagefileid = recordSet.getString("imagefileid"); + return Integer.parseInt(imagefileid); + } + + /** + * 根据requestId反查 文档关联到的表单字段 + * @param requestid + * @return + */ + public String getWfDocRelateFieldName(String requestid){ + String get_wfdocrelatefilename_sql = "select fieldname from workflow_billfield \n" + + "where id =(select wfdocrelatefieldid from workflow_base \n" + + "where id = (select workflowid from workflow_requestbase where requestid = ?))"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(get_wfdocrelatefilename_sql, requestid); + log.info("getWfDocRelateFieldName---b是否执行=="+b); + boolean next = recordSet.next(); + String fieldname = recordSet.getString("fieldname"); + return Util.null2String(fieldname); + } + + /** + *

得到docfiles 文档附件 在线表单/离线表单(HTML)/离线表单(PDF)

+ * @param workflowid + * @return String + * @author jiacheng.deng + */ + public String getDocFiles(String workflowid){ + RecordSet rs = new RecordSet(); + String docfiles = ""; + String wfdocpath = ""; + rs.executeQuery("select docfiles,wfdocpath from workflow_base where id = ?",workflowid); + if (rs.next()){ + docfiles = weaver.general.Util.null2String(rs.getString("docfiles")); + wfdocpath = weaver.general.Util.null2String(rs.getString("wfdocpath")); + } + if ("".equals(docfiles)&&!"".equals(wfdocpath)){ + docfiles="1"; + rs.executeUpdate("update workflow_base set docfiles ='1' where id = ?",workflowid); + } + return docfiles; + } + + /** + *

得到keepsign 是否保留签字意见

+ * @param workflowid + * @return int + * @author jiacheng.deng + */ + public int getKeepSign(String workflowid){ + RecordSet rs = new RecordSet(); + int keepsign = 0; + rs.executeQuery("select keepsign from workflow_base where id = ?",workflowid); + if (rs.next()){ + keepsign = rs.getInt("keepsign"); + } + return keepsign; + } + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/mapper/DetailDataExportExcelMapper.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/mapper/DetailDataExportExcelMapper.java new file mode 100644 index 0000000..d8e1652 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/mapper/DetailDataExportExcelMapper.java @@ -0,0 +1,22 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface DetailDataExportExcelMapper{ + + @Select("select * from formtable_main_378 fm " + + "inner join formtable_main_378_dt1 fmdt " + + "on fm.id = fmdt.mainid where fm.requestid = #{requestid}") + List> selectTotalData(String requestId); + +// @Select("select * from formtable_main_35 fm " + +// "inner join formtable_main_35_dt1 fmdt " + +// "on fm.id = fmdt.mainid where fm.requestid = #{requestid}") +// List> selectTotalData(String requestId); + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/DetailDataExportExcelApi.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/DetailDataExportExcelApi.java new file mode 100644 index 0000000..8398f64 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/DetailDataExportExcelApi.java @@ -0,0 +1,17 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.service; + +import javax.ws.rs.core.Response; + +/** + * 生成excel接口文档 + */ +public interface DetailDataExportExcelApi { + + + /** + * 用于生成最终的excel表格 + */ + public Response exportExcel(String requestId,String lsxjd); + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService.java new file mode 100644 index 0000000..44a7119 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService.java @@ -0,0 +1,403 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_fengtianfangzhi.mapper.DetailDataExportExcelMapper; +import com.api.chaoyang.he.hcy_fengtianfangzhi.service.DetailDataExportExcelApi; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DetailDataExportExcelService implements DetailDataExportExcelApi { + + /** + * 日志 + */ + public Logger logger = Util.getLogger(); + + + /** + * sql + */ + private DetailDataExportExcelMapper detailDataExportExcelMapper = Util.getMapper(DetailDataExportExcelMapper.class); + + + + /** + * 用来返回生成的excel流对象 + * @param requestId requestid + */ + public Response exportExcel(String requestId,String lsxjd) { + + //创建一个工作簿 + XSSFWorkbook workbook = new XSSFWorkbook(); + //创建一个工作表sheet + XSSFSheet sheet = workbook.createSheet(); + //设置sheet表名称 + workbook.setSheetName(0, "询价单明细表单"); + //设置表单列宽 + sheet.autoSizeColumn(1, true); + + RecordSet recordSet = new RecordSet();//创建sql执行对象 + + List> totalDataList = detailDataExportExcelMapper.selectTotalData(requestId); + for (Map map : totalDataList) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + Object v = entry.getValue(); + if (key.equals("sqrxm")){//申请人姓名 + String get_sqrxm_sql = "select lastname from hrmresource where id=?"; + recordSet.executeQuery(get_sqrxm_sql,Util.null2String(v)); + recordSet.next(); + map.put("sqrxm",recordSet.getString("lastname")); + } + if (key.equals("gys")){//供应商 + String get_gys_sql = "select gysqm from uf_gyszsjxx where id=?"; + recordSet.executeQuery(get_gys_sql, Util.null2String(v)); + recordSet.next(); + map.put("gys",recordSet.getString("gysqm")); + } + if("xjr".equals(key)){//询价人 + String get_sqrxm_sql = "select lastname from hrmresource where id=?"; + recordSet.executeQuery(get_sqrxm_sql,Util.null2String(v)); + recordSet.next(); + map.put("xjr",recordSet.getString("lastname")); + } + if ("ylbm".equals(key) ||"sqrbm".equals(key) || "sqrfb".equals(key) || "xjbm".equals(key)){//依赖部门 //申请人部门 //申请人分部 //询价部门 + String getYlbm = "select departmentname from HrmDepartment where id = ? "; + recordSet.executeQuery(getYlbm,Util.null2String(v)); + recordSet.next(); + map.put(key,recordSet.getString("departmentname")); + } + + if ("lsxjd".equals(key)){//历史询价单 + String getLsxjd = "select requestname from workflow_requestbase where requestid = ? "; + recordSet.executeQuery(getLsxjd,Util.null2String(v)); + recordSet.next(); + map.put(key,recordSet.getString("requestname")); + } + +// if("sqrbm".equals(key)){//申请人部门 +// String getYlbm = "select departmentname from HrmDepartment where id = ? "; +// recordSet.executeQuery(getYlbm,Util.null2String(v)); +// recordSet.next(); +// map.put(key,recordSet.getString("departmentname")); +// } +// if ("sqrfb".equals(key)){//申请人分部 +// String getYlbm = "select departmentname from HrmDepartment where id = ? "; +// recordSet.executeQuery(getYlbm,Util.null2String(v)); +// recordSet.next(); +// map.put(key,recordSet.getString("departmentname")); +// } +// if("xjbm".equals(key)){//询价部门 +// String getYlbm = "select departmentname from HrmDepartment where id = ? "; +// recordSet.executeQuery(getYlbm,Util.null2String(v)); +// recordSet.next(); +// map.put(key,recordSet.getString("departmentname")); +// } + + } + } + + + + String getMainTableValueSql = "select id from uf_xjdmxbdczdpzbd where wybs = 'ftfz_exportExcel' "; + boolean b = recordSet.executeQuery(getMainTableValueSql); + logger.info("getMainTableValueSql是否执行=="+b); + String mainId = ""; + if (recordSet.next()){ + mainId = recordSet.getString("id"); + } + String getDetailTableValueSql = "select * from uf_xjdmxbdczdpzbd_dt1 where mainId = ?"; + boolean b1 = recordSet.executeQuery(getDetailTableValueSql, mainId); + logger.info("getDetailTableValueSql是否执行==="+b1); + List fieldNamesList = new ArrayList<>();//用于存放excel第一个行的明细表显示名 + List dBNamesList = new ArrayList<>();//用于存放明细表数据库名 + + while (recordSet.next()){ + String mxzdxsm = recordSet.getString("mxzdxsm");//字段显示名 + String mxzdsjkm = recordSet.getString("mxzdsjkm");//字段数据库名 + fieldNamesList.add(mxzdxsm); + dBNamesList.add(mxzdsjkm); + } + logger.info("fieldNamesList=="+fieldNamesList); + + + XSSFRow row = sheet.createRow(0); + + for (int colNum=0;colNum map1 = totalDataList.get(cowNum-1); + + for (int colNum=0;colNum { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String("询价单明细表单.xlsx".getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + } catch (Exception e) { + e.printStackTrace(); + logger.error("导出excel错误:" + Util.getErrString(e)); + } + build = header.build(); + logger.info("走到导出excel这一步"); + return build; + } + + + /** + * 设置字体样式,并设置字体加粗 + * + * @param workbook workbook对象 + * @return CellStyle对象 + */ + public static CellStyle setNolyWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook worKbook对象 + * @return CellStyle 字体样式 + */ + public static CellStyle setNolyWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook workbook对象 + * @return inputStream流 + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService_copy.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService_copy.java new file mode 100644 index 0000000..268b02a --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/service/impl/DetailDataExportExcelService_copy.java @@ -0,0 +1,497 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_fengtianfangzhi.service.DetailDataExportExcelApi; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DetailDataExportExcelService_copy implements DetailDataExportExcelApi { + + + public Logger logger = Util.getLogger(); + + /** + * 用来返回生成的excel流对象 + * @param requestId requestid + */ + public Response exportExcel(String requestId,String lsxjd) { + + //创建一个工作簿 + XSSFWorkbook workbook = new XSSFWorkbook(); + //创建一个工作表sheet + XSSFSheet sheet = workbook.createSheet(); + //设置sheet表名称 + workbook.setSheetName(0, "询价单明细表单"); + //设置表单列宽 + sheet.autoSizeColumn(1, true); + + RecordSet recordSet = new RecordSet();//创建sql执行对象 + String getMainIdSql = "select * from formtable_main_378 where requestId = ?"; +// String getMainIdSql = "select * from formtable_main_35 where requestId = ?"; + + boolean b2 = recordSet.executeQuery(getMainIdSql, requestId); + logger.info("getMainIdSql语句是否执行==="+b2); + String formtable_main_35_id="";//询价单流程表单id,作为明细表的mianId使用 + Map mainDataMap = new HashMap<>();//用于存放主表的数据 + if (recordSet.next()){ + formtable_main_35_id = recordSet.getString("id"); + String sqdh = recordSet.getString("sqdh");//申请单号 + mainDataMap.put("sqdh",sqdh); + String sqrxmID = recordSet.getString("sqrxm");//申请人姓名 + String get_sqrxm_sql = "select lastname from hrmresource where id=?"; + RecordSet recordSet1 = new RecordSet(); + recordSet1.executeQuery(get_sqrxm_sql, sqrxmID); + if (recordSet1.next()){ + String lastname = recordSet1.getString("lastname"); + mainDataMap.put("sqrxm",lastname); + } + String sqrbm = recordSet.getString("sqrbm");//申请人部门 + mainDataMap.put("sqrbm",sqrbm); + String sqrfb = recordSet.getString("sqrfb");//申请人分部 + mainDataMap.put("sqrfb",sqrfb); + String sqrq = recordSet.getString("sqrq");//申请日期 + mainDataMap.put("sqrq",sqrq); +// String lsxjd = recordSet.getString("lsxjd");//历史询价单 + mainDataMap.put("lsxjd",lsxjd); + String xjbm = recordSet.getString("xjbm");//询价部门 + mainDataMap.put("xjbm",xjbm); + String bz = recordSet.getString("bz");//备注 + mainDataMap.put("bz",bz); + String bjfj = recordSet.getString("bjfj");//报价附件 + mainDataMap.put("bjfj",bjfj); + String yafj = recordSet.getString("yafj");//议案附件 + mainDataMap.put("yafj",yafj); + String sysfj = recordSet.getString("sysfj");//式样书附件 + mainDataMap.put("sysfj",sysfj); + String hszje = recordSet.getString("hszje");//含税总金额 + mainDataMap.put("hszje",hszje); + String wszje = recordSet.getString("wszje");//未税总金额 + mainDataMap.put("wszje",wszje); + String fkblhj = recordSet.getString("fkblhj");//付款比例(合计) + mainDataMap.put("fkblhj",fkblhj); + String ylbmId = recordSet.getString("ylbm");//依赖部门 + String getYlbm = "select departmentname from HrmDepartment where id = ? "; + recordSet1.executeQuery(getYlbm,ylbmId); + recordSet1.next(); + String departmentname = recordSet1.getString("departmentname"); + mainDataMap.put("ylbm",departmentname); + String xjrid = recordSet.getString("xjr");//询价人 + recordSet1.executeQuery(get_sqrxm_sql,xjrid); + recordSet1.next(); + String xjr = recordSet1.getString("lastname"); + mainDataMap.put("xjr",xjr); + String gysId = recordSet.getString("gys");//供应商 + String get_gys_sql = "select gysqm from uf_gyszsjxx where id=?"; + recordSet1.executeQuery(get_gys_sql, gysId); + if (recordSet1.next()){ + String gysqm = recordSet1.getString("gysqm"); + mainDataMap.put("gys",gysqm); + } + + } + logger.info("mainDataMap主表数据==="+mainDataMap); + String getDetailDataSql = "select * from formtable_main_378_dt1 where mainId = ?"; +// String getDetailDataSql = "select * from formtable_main_35_dt1 where mainId = ?"; + boolean b3 = recordSet.executeQuery(getDetailDataSql, formtable_main_35_id); + logger.info("getDetailDataSql语句是否执行==="+b3); + List> listMap = new ArrayList<>();//用于存放明细表数据 + while (recordSet.next()){ + Map map = new HashMap<>(); + String id = recordSet.getString("id"); + map.put("id",id); + String mainId1 = recordSet.getString("mainId"); + map.put("mainId",mainId1); + String pl = Util.null2String(recordSet.getString("pl")); + String plValue = ""; + if (!"".equals(pl)){ + //消耗品 设备工事 劳保用品 IT + switch(pl){ + case "0": + plValue = "消耗品"; + break; + case "1" : + plValue = "设备工事"; + break; + case "2" : + plValue = "劳保用品"; + break; + case "3": + break; + default : + plValue = ""; + break; + } + }else{ + map.put("pl", ""); + } + map.put("pl", plValue); + String pm = recordSet.getString("pm"); + map.put("pm",pm); + String pp = recordSet.getString("pp"); + map.put("pp",pp); + String ggxh = recordSet.getString("ggxh"); + map.put("ggxh",ggxh); + String jldw = recordSet.getString("jldw"); + map.put("jldw",jldw); + String sqsl = recordSet.getString("sqsl"); + map.put("sqsl",sqsl); + String bz = recordSet.getString("bz"); + map.put("bz",bz); + String wsdj = recordSet.getString("wsdj"); + map.put("wsdj",wsdj); + String wszj = recordSet.getString("wszj"); + map.put("wszj",wszj); + String sl = recordSet.getString("sl"); + map.put("sl",sl); + String se = recordSet.getString("se"); + map.put("se",se); + String hsdj = recordSet.getString("hsdj"); + map.put("hsdj",hsdj); + String hszj = recordSet.getString("hszj"); + map.put("hszj",hszj); + String qwnq = recordSet.getString("qwnq"); + map.put("qwnq",qwnq); + String ddhfqwnqt = recordSet.getString("ddhfqwnqt"); + map.put("ddhfqwnqt",ddhfqwnqt); + String gys = recordSet.getString("gys"); + map.put("gys",gys); + String cx = recordSet.getString("cx"); + map.put("cx",cx); + String jd = recordSet.getString("jd"); + map.put("jd",jd); + String bz1 = recordSet.getString("bz1"); + map.put("bz1",bz1); + String fj = recordSet.getString("fj"); + map.put("fj",fj); + String chzx = recordSet.getString("chzx"); + map.put("chzx",chzx); + String chbm = recordSet.getString("chbm"); + map.put("chbm",chbm); + listMap.add(map); + } + logger.info("listMap明细表数据==="+listMap); + String getMainTableValueSql = "select id from uf_xjdmxbdczdpzbd where wybs = 'ftfz_exportExcel' "; + boolean b = recordSet.executeQuery(getMainTableValueSql); + logger.info("getMainTableValueSql是否执行=="+b); + String mainId = ""; + if (recordSet.next()){ + mainId = recordSet.getString("id"); + } + String getDetailTableValueSql = "select * from uf_xjdmxbdczdpzbd_dt1 where mainId = ?"; + boolean b1 = recordSet.executeQuery(getDetailTableValueSql, mainId); + logger.info("getDetailTableValueSql是否执行==="+b1); + List fieldNamesList = new ArrayList<>();//用于存放excel第一个行的明细表显示名 + List mainFieldNamesList = new ArrayList<>();//用于存放excel第一个行的主表显示名 + List detalsDBName = new ArrayList<>();//用于存放明细表数据库名 + List mainDBName = new ArrayList<>();//用于存放主表数据库字段名 + while (recordSet.next()){ + String sjly = recordSet.getString("sjly");//数据来源 + String mxzdxsm = recordSet.getString("mxzdxsm");//字段显示名 +// String mxzdlx = recordSet.getString("mxzdlx");//字段类型 + String mxzdsjkm = recordSet.getString("mxzdsjkm");//字段数据库名 + if (!"".equals(sjly)&&sjly.equals("0")){ + mainFieldNamesList.add(mxzdxsm); + mainDBName.add(mxzdsjkm); + }else if (!"".equals(sjly)&&sjly.equals("1")){ + fieldNamesList.add(mxzdxsm); + detalsDBName.add(mxzdsjkm); + } + + } + logger.info("fieldNamesList=="+fieldNamesList); + logger.info("mainFieldNamesList=="+mainFieldNamesList); + logger.info("detalsDBName=="+detalsDBName); + logger.info("mainDBName=="+mainDBName); + + XSSFRow row = sheet.createRow(0); + for (int colNum=0;colNum map1 = listMap.get(cowNum-1); + for (int colMainDataNum=0;colMainDataNum { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String("询价单明细表单.xlsx".getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + } catch (Exception e) { + e.printStackTrace(); + logger.error("导出excel错误:" + Util.getErrString(e)); + } + build = header.build(); + logger.info("走到导出excel这一步"); + return build; + } + + + /** + * 设置字体样式,并设置字体加粗 + * + * @param workbook workbook对象 + * @return CellStyle对象 + */ + public static CellStyle setNolyWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook worKbook对象 + * @return CellStyle 字体样式 + */ + public static CellStyle setNolyWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook workbook对象 + * @return inputStream流 + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/wflistdonestore/ExportPDF.java b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/wflistdonestore/ExportPDF.java new file mode 100644 index 0000000..f3f8655 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_fengtianfangzhi/wflistdonestore/ExportPDF.java @@ -0,0 +1,257 @@ +package com.api.chaoyang.he.hcy_fengtianfangzhi.wflistdonestore; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.engine.workflow.biz.requestForm.WfToDocBiz; +import org.apache.log4j.Logger; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipOutputStream; +import weaver.conn.RecordSet; +import weaver.file.ImageFileManager; +import weaver.hrm.HrmUserVarify; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +@Path("/hcy_fengtianfangzhi/wflistdonestore") +public class ExportPDF { + + private final Logger logger = Util.getLogger(); + + /** + * 源码内容 + */ + private final WfToDocBiz wfToDocBiz = new WfToDocBiz(); + + /** + *已办流程批量导出pdf + * @param request 请求 + * @param response 响应 + * @return Response 包含所有勾选的压缩包 + */ + @GET + @Path("/ExportPDF") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportPDF(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + try { + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + String getWorkflowId_sql = "select workflowid from workflow_requestbase where requestid = ?"; + RecordSet recordSet = new RecordSet(); + int amountWorkflowToDoc = this.getAmountWorkflowToDoc(split);//用来统计流程转文档的流程的数量,如果数量为0,返回文件为空 + StreamingOutput output = outputStream -> { + ZipOutputStream zipOut = new ZipOutputStream(outputStream); + for (String requestId : split) { + boolean b = recordSet.executeQuery(getWorkflowId_sql, requestId); + logger.info("b是否执行"+b); + String docID; + if (recordSet.next()){ + String workflowid = recordSet.getString("workflowid"); + docID = wfToDocBiz.getWfDocPath(workflowid, requestId); + logger.info("文档生成路径=="+docID); + int imageFileId = this.getImageFileId(requestId); + if (imageFileId==-1){ + continue; + } + InputStream is = ImageFileManager.getInputStreamById(this.getImageFileId(requestId)); + String fileName = this.getImageFileName(requestId); + if (Util.null2String(fileName).equals("")){ + break; + } + this.addToZip(is,zipOut,fileName);//向zipout对象中插入每个pdf文件 + } + } + //关闭流 + zipOut.flush(); + zipOut.close(); + outputStream.flush(); + outputStream.close(); + }; + + if (amountWorkflowToDoc == 0){ + return Response.ok(ApiResult.error("文件为空"),MediaType.TEXT_PLAIN).build(); + } + String lastname = HrmUserVarify.getUser(request, response).getLastname(); + String pdfName = lastname + "_" +getCurrentTime() + "_" + split.length; + return Response.ok(output, MediaType.APPLICATION_OCTET_STREAM).type("application/zip") + .header("Content-Disposition", "attachment;filename=\"" + + new String(pdfName.getBytes("GBK"), StandardCharsets.ISO_8859_1) + ".zip" + "\"").build(); + } catch (Exception e) { + e.printStackTrace(); + return Response.ok(ApiResult.error("出现错误,错误原因:"+e),MediaType.TEXT_PLAIN).build(); + } + } + + /** + * 当某个流程成功导出pdf时,更新导出状态字段为已导出 + * @param requestId requestid + */ + public void updateValue(String requestId){ + RecordSet recordSet = new RecordSet(); + String get_imagefileid_sql = "select tablename \n" + + "from workflow_bill \n" + + "where id = (select formid from workflow_base where id = \n" + + "(select workflowid from workflow_requestbase where requestid = ?)\n" + + ")"; + boolean b = recordSet.executeQuery(get_imagefileid_sql, requestId); + logger.info("updateValue()----b是否执行"+b); + recordSet.next(); + String tablename = recordSet.getString("tablename"); + boolean b1 = recordSet.executeUpdate("update " + tablename + " set dczt = 0,dcsj = ? where requestid = ?",getCurrentTime(), requestId); + logger.info("updatevalue()----b1是否执行==="+b1); + } + + /** + * 用来统计流程转文档的流程的数量,如果数量为0,返回文件为空, + * 并将已经流程转流程并且导出pdf的流程字段更新相关流程的导出字段为已导出 + * @param split requestid组成的数组集合 + * @return int 返回一个整型数字用于判断 + */ + public int getAmountWorkflowToDoc(String[] split){ + int amount = 0; + String getWorkflowId_sql = "select workflowid from workflow_requestbase where requestid = ?"; + RecordSet recordSet = new RecordSet(); + for (String requestId : split) { + boolean b = recordSet.executeQuery(getWorkflowId_sql, requestId); + logger.info("getAmountWorkflowToDoc----b是否执行==="+b); + if (recordSet.next()){ + int imageFileId = this.getImageFileId(requestId); + if (imageFileId==-1){ + continue; + }else { + amount++; + //用来更新更新具体哪个流程表单的导出状态为已导出 + this.updateValue(requestId); + } + } + } + return amount; + } + + /** + * 根据requestId返回docimagefile表中imagefileId + * @param requestId requestid + * @return int + */ + public int getImageFileId(String requestId){ + RecordSet recordSet = new RecordSet(); + String get_imagefileid_sql = "select tablename \n" + + "from workflow_bill \n" + + "where id = (select formid from workflow_base where id = \n" + + "(select workflowid from workflow_requestbase where requestid = ?)\n" + + ")"; + boolean b = recordSet.executeQuery(get_imagefileid_sql, requestId); + logger.info("b是否执行"+b); + recordSet.next(); + String tablename = recordSet.getString("tablename"); + String docid_key = this.getWfDocRelateFieldName(requestId);//每一流程表单中用来存放docid的字段名称 + + String get_docid_sql = "select "+docid_key+" from "+tablename+" where requestid = ?"; + boolean b1 = recordSet.executeQuery(get_docid_sql, requestId); + logger.info("b1是否执行=="+b1); + recordSet.next(); + String docid = recordSet.getString(docid_key); + if (Util.null2String(docid).equals("")){ + return -1; + } + String get_imagefileid = "select imagefileid from DocImageFile where docid = ? order by versionId"; + boolean b2 = recordSet.executeQuery(get_imagefileid, docid); + logger.info("b2是否执行=="+b2); + recordSet.next(); + String imagefileid = recordSet.getString("imagefileid"); + return Integer.parseInt(imagefileid); + } + + + /** + * 根据requestId返回docimagefile表中imagefilename + * @param requestId requestid + * @return String 返回imagefilename + */ + public String getImageFileName(String requestId){ + RecordSet recordSet = new RecordSet(); + String get_tablename_sql = "select tablename \n" + + "from workflow_bill \n" + + "where id = (select formid from workflow_base where id = \n" + + "(select workflowid from workflow_requestbase where requestid = ?)\n" + + ")"; + boolean b = recordSet.executeQuery(get_tablename_sql, requestId); + logger.info("b是否执行"+b); + recordSet.next(); + String tablename = recordSet.getString("tablename"); + String docid_key = this.getWfDocRelateFieldName(requestId);//每一流程表单中用来存放docid的字段名称 + + String get_docid_sql = "select "+docid_key+" from "+tablename+" where requestid = ?"; + boolean b1 = recordSet.executeQuery(get_docid_sql, requestId); + logger.info("b1是否执行=="+b1); + recordSet.next(); + String docid = recordSet.getString(docid_key); + String get_imagefilename = "select imagefilename from DocImageFile where docid = ? order by versionId"; + boolean b2 = recordSet.executeQuery(get_imagefilename, docid); + logger.info("b2是否执行=="+b2); + recordSet.next(); + return recordSet.getString("imagefilename"); + } + + /** + * 根据requestId反查 文档关联到的表单字段 + * @param requestid requestid + * @return String 返回filename + */ + public String getWfDocRelateFieldName(String requestid){ + String get_wfdocrelatefilename_sql = "select fieldname from workflow_billfield \n" + + "where id =(select wfdocrelatefieldid from workflow_base \n" + + "where id = (select workflowid from workflow_requestbase where requestid = ?))"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(get_wfdocrelatefilename_sql, requestid); + recordSet.next(); + logger.info("getWfDocRelateFieldName---b是否执行=="+b); + String fieldname = recordSet.getString("fieldname"); + return Util.null2String(fieldname); + } + /** + * 添加压缩文件 + * @param is 文件输入流 + * @param zipOut zipOUtPutStream + * @param fileName 文件名称 + */ + private void addToZip(InputStream is, ZipOutputStream zipOut, String fileName) { + try{ + ZipEntry entry = new ZipEntry(fileName); + zipOut.putNextEntry(entry); + int len; + byte[] buffer = new byte[1024]; + while ((len = is.read(buffer)) > 0) { + zipOut.write(buffer, 0, len); + } + zipOut.closeEntry(); + is.close(); + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + *

获取系统当前日期时间

+ * @return String + * @author hcy + * 2023/4/4 17:31 + */ + public String getCurrentTime() { + LocalDateTime now = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + return now.format(formatter); + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelAVPNApi.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelAVPNApi.java new file mode 100644 index 0000000..24d2714 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelAVPNApi.java @@ -0,0 +1,683 @@ +package com.api.chaoyang.he.hcy_xintiantongxin; + + +import aiyh.utils.Util; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.*; + +@Path("/hcy_xintiantongxin") +public class ExportExcelAVPNApi { + + private Logger logger = Util.getLogger(); + + /** + *导出AVPN Excel表格 + * @param request + * @param response + * @return + */ + @GET + @Path("/ExportExcelAVPNApi") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response checkRequestInfo(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + Response build = null; + Response.ResponseBuilder header = null; + try { + //查询到 uf_avpn_export AVPN导出表中的一条数据的ids + String ids = request.getParameter("ids"); + RecordSet rs = new RecordSet(); + StreamingOutput output = null; + + String sql_AVPN_db = "select * from uf_avpn_export where id = ?"; + rs.executeQuery(sql_AVPN_db, ids); + + //创建一个工作簿 + Workbook workbook = new XSSFWorkbook(); + String[] dbFiled = new String[10]; + String mainId = ""; + + while (rs.next()) { + //查询到uf_avpn_export表的id作为查询明细表的mainid + mainId = rs.getString("id"); + String pd_nameId = rs.getString("pd_name");//uf_pd_base_inf 得到的pd_name是字段的id + RecordSet recordSet = new RecordSet(); + String getPd_nameByIdSql = "select pd_name from uf_pd_base_inf where id =?"; + boolean b1 = recordSet.executeQuery(getPd_nameByIdSql, pd_nameId); + + logger.info("查询pd_namesql语句是否成功==" + b1); + if (recordSet.next()) { + String pd_name = recordSet.getString("pd_name");//查询到pd_name的值 + dbFiled[0] = pd_name; + } + String billing_model = rs.getString("billing_model"); + if (billing_model.equals("0")){ + billing_model = "Assignment Model Billing in China"; + } + dbFiled[1] = billing_model; + String customer_name = rs.getString("customer_name"); + dbFiled[2] = customer_name; + String ecrm_opportunity = rs.getString("ecrm_opportunity"); + dbFiled[3] = ecrm_opportunity; + String igloo = rs.getString("igloo"); + dbFiled[4] = igloo; + String terms = rs.getString("terms"); + dbFiled[5] = terms; + String att_lead_pricer = rs.getString("att_lead_pricer"); + dbFiled[6] = att_lead_pricer; + String requestjustificationoptional = rs.getString("requestjustificationoptional"); + dbFiled[7] = requestjustificationoptional; + String specialrequesttosstoptional = rs.getString("specialrequesttosstoptional"); + dbFiled[8] = specialrequesttosstoptional; + String sst_contact = rs.getString("sst_contact"); + dbFiled[9] = sst_contact; + } + //表单字段 + String[] tableFiled = new String[]{"Service Type", "Billing Model", "Customer Name", "ECRM Opportunity#", "Igloo #", "Contract Term (in months)", "AT&T Lead Pricer", "Request Justification (optional)", "Special Request to SST (Optional)", "SST Contact"}; + //明细表字段 + String[] mergerDetailTableFiled = new String[]{"Site ID", "Description", "Bandwidth", "OTC in RMB", "MRC in RMB"}; + + //创建一个工作表sheet + Sheet sheet = workbook.createSheet(); + workbook.setSheetName(0, "AVPN表单"); + sheet.autoSizeColumn(1, true); + //写入数据 //写入1-11行第一列 第二列数据 + for (int rowNum = 1; rowNum < 11; rowNum++) { + Row row = sheet.createRow(rowNum); + Cell cell0 = row.createCell(0); + cell0.setCellStyle(this.setWordStyle(workbook, true)); + cell0.setCellValue(tableFiled[rowNum - 1]); + Cell cell1 = row.createCell(1); + cell1.setCellStyle(setWordStyle(workbook, true)); + cell1.setCellValue(dbFiled[rowNum - 1]); + } + Row row12 = sheet.createRow(12);//第13行 + Cell cell12_11 = row12.createCell(11); + cell12_11.setCellStyle(setWordStyle(workbook, true)); + cell12_11.setCellValue("Default Assignment Model-Billing in China in RMB"); + Cell cell12_12 = row12.createCell(12); + cell12_12.setCellStyle(setNolyBorderStyle(workbook)); + sheet.addMergedRegion(new CellRangeAddress(12, 12, 11, 12)); + + //设置14行到15行前5列内容 + Row row13 = sheet.createRow(13); + Row row14 = sheet.createRow(14); + for (int colNum = 0; colNum < 5; colNum++) { + Cell cell = row13.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook, true)); + cell.setCellValue(mergerDetailTableFiled[colNum]); + Cell cell1 = row14.createCell(colNum); + cell1.setCellStyle(setWordStyle(workbook, true)); + cell1.setCellValue(mergerDetailTableFiled[colNum]); + sheet.addMergedRegion(new CellRangeAddress(13, 14, colNum, colNum)); + } + + + + //设置14行第六列到第13列的内容 + String[] mergerDetailTableFiled02 = new String[]{"Discount Requested (%)", "Discount SST approved (%)", "Net Price to AT&T Customer", "Royalty to SST without Tax(contra-revenue)"}; + Cell cell13_5 = row13.createCell(5); + cell13_5.setCellStyle(setWordStyle(workbook, true)); + cell13_5.setCellValue(mergerDetailTableFiled02[0]); + Cell cell113_6 = row13.createCell(6); + cell113_6.setCellStyle(setWordStyle(workbook, true)); + cell113_6.setCellValue(mergerDetailTableFiled02[0]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 5, 6)); + + + Cell cell13_7 = row13.createCell(7); + cell13_7.setCellStyle(setWordStyle(workbook, true)); + cell13_7.setCellValue(mergerDetailTableFiled02[1]); + Cell cell13_8 = row13.createCell(8); + cell13_8.setCellStyle(setWordStyle(workbook, true)); + cell13_8.setCellValue(mergerDetailTableFiled02[1]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 7, 8)); + + Cell cell13_9 = row13.createCell(9); + cell13_9.setCellStyle(setWordStyle(workbook, true)); + cell13_9.setCellValue(mergerDetailTableFiled02[2]); + Cell cell13_10 = row13.createCell(10); + cell13_10.setCellStyle(setWordStyle(workbook, true)); + cell13_10.setCellValue(mergerDetailTableFiled02[2]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 9, 10)); + + Cell cell13_11 = row13.createCell(11); + cell13_11.setCellStyle(setWordStyle(workbook, true)); + cell13_11.setCellValue(mergerDetailTableFiled02[3]); + Cell cell13_12 = row13.createCell(12); + cell13_12.setCellStyle(setWordStyle(workbook, true)); + cell13_12.setCellValue(mergerDetailTableFiled02[3]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 11, 12)); + + + //设置15行第六列到第13列的内容 + String[] mergerDetailTableFiled03 = new String[]{"OTC", "MRC", "OTC", "MRC", "OTC in RMB", "MRC in RMB", "OTC in RMB", "MRC in RMB"}; + for (int colNum = 5; colNum < 13; colNum++) { + Cell cell = row14.createCell(colNum); + for (int num = 0; num < 8; num++) { + cell.setCellStyle(setWordStyle(workbook, true)); + cell.setCellValue(mergerDetailTableFiled03[num]); + } + } + + + List> siteMap = new ArrayList<>();//用来存放site的类型和每个site的状态 + + String getSiteSql = "select site ,count(site) siteNum from uf_avpn_export_dt1 where mainId =? group by site ;"; + RecordSet rs02 = new RecordSet(); + boolean b = rs02.executeQuery(getSiteSql, mainId); + logger.info("查询site,以及site的数量的sql语句===" + b); + + while (rs02.next()) { + HashMap map = new HashMap<>(); + String site = rs02.getString("site"); + String siteNum = rs02.getString("siteNum"); + map.put(site, siteNum); + siteMap.add(map);//将site的类型和每个site的类型的个数放到siteList数组中,用来循环遍历再放入单元格中 + } + int firstCow = 15;//从第15行开始写入明细表,固定死 + int finalyCow = 0; + + + Double sum9 = 0D; + Double sum10 = 0D; + Double sum11 = 0D; + Double sum12 = 0D; + for (Map map : siteMap) { + Set siteKeySet = map.keySet(); + List> detailDateList = new ArrayList(); + int cowLength = 0;//每一个site类型的数据的长度 + for (String s1 : siteKeySet) { + cowLength = Integer.parseInt(map.get(s1));//每一个site类型的数据的长度 + String getDetailDataSql = "select * from uf_avpn_export_dt1 where mainId =? and site = ?"; + rs02.executeQuery(getDetailDataSql, mainId, s1); + while (rs02.next()) { + String site = rs02.getString("site");//Site ID + String itemId = rs02.getString("Item");//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?"; + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + + String categoryId = rs02.getString("Category");//Bandwidth + String getCategoryByIdSql = "select category from uf_pd_category_inf where id = ?"; + boolean b3 = recordSet1.executeQuery(getCategoryByIdSql, categoryId); + logger.info("查询categorySql是否执行成功==" + b3); + String category = ""; + if (recordSet1.next()) { + category = recordSet1.getString("category"); + } + String otc_price = rs02.getString("otc_price");//OTC in RMB + String mrc_price = rs02.getString("mrc_price");//MRC in RMB + String otcdiscountrequest = rs02.getString("otcdiscountrequest");//Discount Requested (%) OTC + String mrcdiscountrequest = rs02.getString("mrcdiscountrequest");//Discount Requested (%) MRC + String otcdiscountapproved = rs02.getString("otcdiscountapproved");//Discount SST approved (%) OTC + String mrcdiscountapproved = rs02.getString("mrcdiscountapproved");//Discount SST approved (%)MRC + String otc_tariff = rs02.getString("otc_tariff");//Net Price to AT&T Customer(OTC in RMB) + String mrc_tariff = rs02.getString("mrc_tariff");//Net Price to AT&T Customer(MRC in RMB) + String otc_scale = rs02.getString("otc_scale");//Royalty to SST without Tax (contra-revenue)(OTC in RMB) + String mrc_scale = rs02.getString("mrc_scale");//Royalty to SST without Tax (contra-revenue)(MRC in RMB) + ArrayList list = new ArrayList<>(); + list.add(site);//list.add(site); + list.add(item); + list.add(category); + list.add(otc_price); + list.add(mrc_price); + list.add(otcdiscountrequest); + list.add(mrcdiscountrequest); + list.add(otcdiscountapproved); + list.add(mrcdiscountapproved); + list.add(otc_tariff); + list.add(mrc_tariff); + list.add(otc_scale); + list.add(mrc_scale); + detailDateList.add(list); + } + } + Double amount9 = 0D;//用来统计每一个site种类的 Grand-Total(RMB) + Double amount10 = 0D; + Double amount11 = 0D; + Double amount12 = 0D; + //得到list类型的数据、有得到每种site类型的数据长度 + //开始向excel中导入明细表中的数据 + int i = 0;//用它来增加detailDateList的下标 + for (int cowNum = firstCow; cowNum < firstCow + cowLength; cowNum++) { + Row row = sheet.createRow(cowNum); + for (int colNum = 0; colNum < 13; colNum++) { + if (colNum == 9) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount9 = Double.valueOf(amount9) + value; + sum9 += value; + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else{ + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 10) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount10 = amount10 + value; + sum10 += value; + + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + } + } else if (colNum == 11) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount11 = amount11 + value; + sum11 += value; + + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 12) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount12 = amount12 + value; + sum12 += value; + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + + if (colNum == 5 || colNum == 6 || colNum == 7 || colNum == 8) { + Cell cell = row.createCell(colNum); + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue( (int)(value*100) + "%"); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + else if (colNum == 0||colNum==1||colNum==2){ + Cell cell = row.createCell(colNum); + String value = String.valueOf(detailDateList.get(i).get(colNum)); + if (value!=""){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum == 3||colNum==4){ + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + } + i++; + } + //合并单元格 + int lastCow = firstCow + cowLength; + + if (cowLength > 1) { + sheet.addMergedRegion(new CellRangeAddress(firstCow, lastCow - 1, 0, 0)); + } + //开始写入Sub-Total(RMB) + Row rowSubTotal = sheet.createRow(lastCow); + for (int colNum = 8; colNum < 13; colNum++) { + if (colNum == 8) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue("Sub-Total(RMB)"); + } else if (colNum == 9) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount9); + } else if (colNum == 10) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount10); + } else if (colNum == 11) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount11); + } else if (colNum == 12) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount12); + } + } + + firstCow = firstCow + cowLength + 1; + finalyCow = firstCow; + }//处理插入数据以及合并单元格 + //处理明细表最后一行的统计情况 + Row row_Grand_Total_RMB = sheet.createRow(finalyCow); + for (int colNum = 8; colNum < 13; colNum++) { + if (colNum == 8) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue("Grand-Total(RMB)"); + } else if (colNum == 9) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum9); + } else if (colNum == 10) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum10); + } else if (colNum == 11) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum11); + } else if (colNum == 12) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum12); + } + } + + //输入最下面的固定值 + String[] lastStringLeft = new String[]{ + "Notes:", + "1.This is NOT AT&T Pricing Approval. Forward this SST quote to your Lead ICB Pricer to issue the official Rate Letter", + "2.Access price must be quoted by SST, request SST as \"access provider\" in Igloo. Do NOT use quote from other access providers", + "3.Discount is only applicable to the demand set listed below, any changes in bandwidth/design/billing model, need to re-submit to SST and AT&T Pricer for approval", "" + + "4.Under in-country billing, AT&T must follow the discount% offered by SST. Do NOT deviate from the SST quoted discount.", + "5.SST can support repeatable discount for the same solution design(port/CDR/CPE) of same contract term which was approved already. Local Loop part are non-repeatable.", + "6.For ICB only - Royalty in columns L and M are contra-revenue,ICB to verify if BCRL captured these amount.", + "7.Save this SST approved quote to eCRM (without release) for record.", + "8.The quotation shall be exclusive of any applicable taxes and Customer shall pay all the taxes and charges relating to the payment if any. The VAT rate for CPE and related modules and license are 16%, the rest is 6%.", + "9.Thank you for considering SST, this engagement may be subject to a credit check, we appreciate your cooperation and look forward to doing business in the near future." + }; + int lastLineTag = finalyCow + 2;//固定值Note所在的行 + int k = 0;//用来增加lastStringLeft的下标 + for (int rowNum = lastLineTag; rowNum < lastLineTag + 10; rowNum++) { + Row row = sheet.createRow(rowNum); + Cell cell = row.createCell(0); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, 11)); + cell.setCellStyle(setTotalStyle(workbook,"微软雅黑",true,false,HorizontalAlignment.LEFT, VerticalAlignment.CENTER,false)); + cell.setCellValue(lastStringLeft[k]); + k++; + } + sheet.autoSizeColumn(0,true); + sheet.setColumnWidth(0,sheet.getColumnWidth(0)*5/10); + // 设置自动列宽 + for (int num = 1; num < 13; num++) { + sheet.autoSizeColumn(num,true); + sheet.setColumnWidth(num, (sheet.getColumnWidth(num))); + } + + + InputStream inputStream = workbookConvertorStream(workbook); + byte[] bytes = IOUtils.toByteArray(inputStream); + output = outputStream -> { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String("AVPN表单.xlsx".getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("导出excel错误:" + Util.getErrString(e)); + } + build = header.build(); + return build; + } + /** + *

设置每个单元格样式:包含字体类型,字体是否加粗,是否包含边框,元素水平方向的位置,元素垂直方向的位置,是否设置元素的数据格式,

+ * @param + * @return + * @author hcy + * @Date 2023/2/13 18:08 + */ + public static CellStyle setTotalStyle(Workbook workbook,String type,boolean setBold,boolean setBorder,HorizontalAlignment horizontalDirection,VerticalAlignment verticalAlignmentDirection ,boolean setDataFormat){ + //new一个cellStyle用于设置每一个单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName(type); + //设置字体是否加粗 + font.setBold(setBold); + //将字体样式渲染cellStyle对象中 + cellStyle.setFont(font); + if (setBorder == true){ + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + } + + //水平居中 + cellStyle.setAlignment(horizontalDirection); + //垂直居中 + cellStyle.setVerticalAlignment(verticalAlignmentDirection); + + //此处设置数据格式 + if(setDataFormat == true){ + DataFormat dataFormat = workbook.createDataFormat(); + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + } + + return cellStyle; + } + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * 只设置边框样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyBorderStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + + /** + * 设置单元格格式为数值型 + * @param workbook + * @return + */ + public static CellStyle setCellToNumber(Workbook workbook){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelL3NSApi.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelL3NSApi.java new file mode 100644 index 0000000..8dec253 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/ExportExcelL3NSApi.java @@ -0,0 +1,581 @@ +package com.api.chaoyang.he.hcy_xintiantongxin; + +import aiyh.utils.Util; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.*; + +@Path("/hcy_xintiantongxin2") +public class ExportExcelL3NSApi { + + + + private Logger logger = Util.getLogger(); + + /** + * 校验 + * @param request + * @param response + * @return + */ + @GET + @Path("/ExportExcelL3NSApi") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response checkRequestInfo(@Context HttpServletRequest request, @Context HttpServletResponse response){ + Response build = null; + Response.ResponseBuilder header = null; + try { + + + //查询到 uf_L3NS_exportt AVPN导出表中的一条数据的ids + String ids = request.getParameter("ids"); + RecordSet rs = new RecordSet(); + StreamingOutput output = null; + + + String sql_L3NS_db = "select * from uf_L3NS_exportt where id = ?"; + boolean b = rs.executeQuery(sql_L3NS_db, ids); + logger.info("是否查询uf_L3NS_exportt=="+b); + + //创建一个工作簿 + XSSFWorkbook workbook = new XSSFWorkbook(); + String[] dbFiled = new String[13]; + String[] tableFiled = new String[]{"Service Type", "Billing Model", "Customer Name", "ROME Opportunity #", "ROME WR#", "Request Type", "Original SST Order NO", "Request Justification", "Special Request to SST", "Target Service Provision date","ATT Order number:","SST Pre-Sales Contact","Date of SST Approval"}; + + String mainId = ""; + + //得到主表数据,用来写入excel中的固定值 + while (rs.next()) { + //查询到uf_avpn_export表的id作为查询明细表的mainid + mainId = rs.getString("id"); + + + String pd_nameId = rs.getString("pd_name");//uf_pd_base_inf 得到的pd_name是字段的id + RecordSet recordSet = new RecordSet(); + String getPd_nameByIdSql = "select pd_name from uf_pd_base_inf where id =?"; + boolean b1 = recordSet.executeQuery(getPd_nameByIdSql, pd_nameId); + + logger.info("查询pd_namesql语句是否成功==" + b1); + if (recordSet.next()) { + String pd_name = recordSet.getString("pd_name");//查询到pd_name的值 + dbFiled[0] = pd_name; + } + String billingmodel = rs.getString("billingmodel");//Billing Model===billingmodel + if (billingmodel.equals("0")){ + billingmodel = "Custom Subcontract"; + }else if (billingmodel == null){ + billingmodel = ""; + } + dbFiled[1] = billingmodel; + String customer_name = rs.getString("customer_name");//Customer Name===customer_name + dbFiled[2] = customer_name; + String rome_opportunity = rs.getString("rome_opportunity");//ROME Opportunity #====rome_opportunity + dbFiled[3] = rome_opportunity; + String rome_wr = rs.getString("rome_wr");//ROME WR#====rome_wr + dbFiled[4] = rome_wr; + String request_type = rs.getString("request_type");//Request Type====request_type + dbFiled[5] = request_type; + String original_sst_order_no = rs.getString("original_sst_order_no");//Original SST Order NO====original_sst_order_no + dbFiled[6] = original_sst_order_no; + String requestjustificationoptional = rs.getString("requestjustificationoptional");//Request Justification====requestjustificationoptional + dbFiled[7] = requestjustificationoptional; + String specialrequesttosstoptional = rs.getString("specialrequesttosstoptional");//Special Request to SST====specialrequesttosstoptional + dbFiled[8] = specialrequesttosstoptional; + String targetserviceprovisiondate = rs.getString("targetserviceprovisiondate");//Target Service Provision date====targetserviceprovisiondate + dbFiled[9] = targetserviceprovisiondate; + String attordernumber = rs.getString("attordernumber");//ATT Order number:====attordernumber + dbFiled[10] = attordernumber; + String sstpresalescontact = rs.getString("sstpresalescontact");//SST Pre-Sales Contact====sstpresalescontact + dbFiled[11] = sstpresalescontact; + String dateofsstapproval = rs.getString("dateofsstapproval");//Date of SST Approval====dateofsstapproval + dbFiled[12] = dateofsstapproval; + } + + //开始写入固定值 + Sheet sheet = workbook.createSheet(); + workbook.setSheetName(0, "L3NS表单"); + sheet.autoSizeColumn(1, true); + + for (int cowNum=1;cowNum<14;cowNum++){ + Row row = sheet.createRow(cowNum); + Cell cell0 = row.createCell(0); + cell0.setCellStyle(setWordStyle(workbook,true)); + cell0.setCellValue(tableFiled[cowNum-1]); + Cell cell1 = row.createCell(1); + cell1.setCellStyle(setWordStyle(workbook,true)); + cell1.setCellValue(dbFiled[cowNum-1]); + } + + Row row14 = sheet.createRow(14);//写入15行数据 + Cell cell14_0 = row14.createCell(0); + Cell cell114_1 = row14.createCell(1); + cell14_0.setCellStyle(setWordStyle(workbook,true)); + cell14_0.setCellValue("This Quote is valid for 180 days from \"Date of SST approval\""); + cell114_1.setCellStyle(setWordStyle(workbook,true)); + cell114_1.setCellValue("This Quote is valid for 180 days from \"Date of SST approval\""); + sheet.addMergedRegion(new CellRangeAddress(14, 14, 0, 1)); + + +// 写入18行,19行数据 +// Site ID Description Bandwidth OTC in RMB MRC in RMB + String[] detailFileds = new String[]{"Site ID", "Description","Bandwidth", "OTC in RMB", "MRC in RMB"}; + Row row17 = sheet.createRow(17); + Row row18 = sheet.createRow(18); + for (int colNum =0;colNum<5;colNum++){ + Cell cell = row17.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellStyle(setWordStyle(workbook,true)); + cell.setCellValue(detailFileds[colNum]); + } + for (int colNum =0;colNum<5;colNum++){ + Cell cell = row18.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellStyle(setWordStyle(workbook,true)); + cell.setCellValue(detailFileds[colNum]); + } + sheet.addMergedRegion(new CellRangeAddress(17, 18, 0, 0)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 1, 1)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 2, 2)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 3, 3)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 4, 4)); + +// Relief Requested (%) Relief SST approved (%) Tariff to SST (include VAT) 6-11列 +// OTC MRC OTC MRC OTC in RMB MRC in RMB + String[] detailFileds01 = new String[]{"Relief Requested (%)","Relief Requested (%)","Relief SST approved (%)","Relief SST approved (%)","Tariff to SST (include VAT)","Tariff to SST (include VAT)",""}; + String[] detailFileds02 = new String[]{"OTC","MRC","OTC","MRC","OTC in RMB","MRC in RMB"}; + int i=0; + int j = 0; + for(int colNum=5;colNum<11;colNum++){ + Cell cell17 = row17.createCell(colNum); + Cell cell18 = row18.createCell(colNum); + cell17.setCellValue(detailFileds01[i]); + cell17.setCellStyle(setWordStyle(workbook,true)); +// cell17.setCellStyle(setCellStyleFrame(workbook)); + + cell18.setCellValue(detailFileds02[j]); + cell18.setCellStyle(setWordStyle(workbook,true)); +// cell18.setCellStyle(setCellStyleFrame(workbook)); + i++; + j++; + } + //合并18行,19行 + sheet.addMergedRegion(new CellRangeAddress(17, 17, 5, 6)); + sheet.addMergedRegion(new CellRangeAddress(17, 17, 7, 8)); + sheet.addMergedRegion(new CellRangeAddress(17, 17, 9, 10)); + + + //开始写入20开始一直往下的动态表格中的内容 +// + + List> siteMap = new ArrayList<>();//用来存放site的类型和每个site的状态 + String getSiteSql = "select site ,count(site) siteNum from uf_L3NS_exportt_dt1 where mainId =? group by site ;"; + RecordSet rs02 = new RecordSet(); + boolean b1 = rs02.executeQuery(getSiteSql, mainId); + logger.info("查询site,以及site的数量的sql语句===" + b1); + while (rs02.next()) { + HashMap map = new HashMap<>(); + String site = rs02.getString("site"); + String siteNum = rs02.getString("siteNum"); + map.put(site, siteNum); + siteMap.add(map);//将site的类型和每个site的类型的个数放到siteList数组中,用来循环遍历再放入单元格中 + } + + int firstCow = 19;//从第15行开始写入明细表,固定死 + int finalyCow = 0; + Double sum10 = 0D;//用来统计所有site种类的Grand-Total (RMB) #REF! + Double sum9 = 0D; + for (Map map : siteMap) { + + Set siteKeySet = map.keySet(); + List> detailDateList = new ArrayList(); + int cowLength = 0;//每一个site类型的数据的长度 + for (String s1 : siteKeySet) { + cowLength = Integer.parseInt(map.get(s1));//每一个site类型的数据的长度 + String getDetailDataSql = "select * from uf_L3NS_exportt_dt1 where mainId =? and site = ?"; + rs02.executeQuery(getDetailDataSql,mainId,s1); + while(rs02.next()){ + //明细表数据 + String site = rs02.getString("site");//Site ID + String itemId = rs02.getString("Item");//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?";//uf_pd_item_inf + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + String categoryId = rs02.getString("Category");//Bandwidth + String getCategoryByIdSql = "select category from uf_pd_category_inf where id = ?";//uf_pd_category_inf + boolean b3 = recordSet1.executeQuery(getCategoryByIdSql, categoryId); + logger.info("查询categorySql是否执行成功==" + b3); + String category = ""; + if (recordSet1.next()) { + category = recordSet1.getString("category"); + } + String otc_price = rs02.getString("otc_price");//OTC in RMB + String mrc_price = rs02.getString("mrc_price");//MRC in RMB + String otc_relief_requested = rs02.getString("otc_relief_requested");//Relief Requested (%)OTC + String mrc_relief_requested = rs02.getString("mrc_relief_requested");//Relief Requested (%)MRC + String otc_relief_approved = rs02.getString("otc_relief_approved");//Relief SST approved (%)OTC + String mrc_relief_approved = rs02.getString("mrc_relief_approved");//Relief SST approved (%)MRC + String otc_tariff = rs02.getString("otc_tariff");//Tariff to SST (include VAT)(OTC in RMB) + String mrc_tariff = rs02.getString("mrc_tariff");//Tariff to SST (include VAT)(MRC in RMB) + + ArrayList list = new ArrayList<>(); + list.add(site); + list.add(item); + list.add(category); + list.add(otc_price); + list.add(mrc_price); + list.add(otc_relief_requested); + list.add(mrc_relief_requested); + list.add(otc_relief_approved); + list.add(mrc_relief_approved); + list.add(otc_tariff); + list.add(mrc_tariff); + detailDateList.add(list); + } + } + Double amount10 = 0D;//用来统计每一个site种类的 Sub-Total + Double amount9 = 0D; + + //得到list类型的数据、有得到每种site类型的数据长度 + //开始向excel中导入明细表中的数据 + int k = 0;//用它来增加detailDateList的下标 + for (int cowNum = firstCow; cowNum < firstCow + cowLength; cowNum++) { + Row row = sheet.createRow(cowNum); + for (int colNum = 0; colNum < 11; colNum++) { + if (colNum == 10) { + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != ""){ + Double value = Double.valueOf(s); + amount10 = amount10 + value; + sum10 += value; + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 9){ + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != "") { + Double value = Double.valueOf(s); + amount9 = amount9 + value; + sum9 += value; + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + if (colNum == 5 || colNum == 6 || colNum == 7 || colNum == 8) { + Cell cell = row.createCell(colNum); + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value * 100) + "%"); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 3 || colNum==4){ + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != ""){ + Double value = Double.valueOf(s); + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + else if (colNum == 0||colNum==1||colNum==2){ + Cell cell = row.createCell(colNum); + String value = String.valueOf(detailDateList.get(k).get(colNum)); + if (value!=""){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + } + } + k++; + } + //合并单元格 + int lastCow = firstCow + cowLength; + + if (cowLength > 1) { + sheet.addMergedRegion(new CellRangeAddress(firstCow, lastCow - 1, 0, 0)); + } + //开始写入Sub-Total(RMB) + Row rowSubTotal = sheet.createRow(lastCow); + Cell cellSubToTal10 = rowSubTotal.createCell(10); + cellSubToTal10.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal10.setCellValue(amount10); + + Cell cellSubToTal9 = rowSubTotal.createCell(9); + cellSubToTal9.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal9.setCellValue(amount9); + + Cell cellSubToTal8 = rowSubTotal.createCell(8); + cellSubToTal8.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal8.setCellValue("Sub-Total"); + + + firstCow = firstCow + cowLength + 1; + finalyCow = firstCow; + + } + Row rowFinalyCow = sheet.createRow(finalyCow); + Cell cellFinalyCow_10 = rowFinalyCow.createCell(10); + cellFinalyCow_10.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_10.setCellValue(sum10); + Cell cellFinalyCow_9 = rowFinalyCow.createCell(9); + cellFinalyCow_9.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_9.setCellValue(sum9); + Cell cellFinalyCow_8 = rowFinalyCow.createCell(8); + cellFinalyCow_8.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_8.setCellValue("Grand-Total (RMB)"); + + + //输入最下面的固定值 + String[] lastStringright = new String[]{ + "Notes:", + "1.This form should be submitted by Lead ICB via a ROME WR to \"AP Pricing Team\". Do NOT send this direct to SST.", + "2.Fill in full Site Address or at least provide Name of City.", + "3.Tariff relief requested should be calculated by lead ICB. Do not fill in target AVPN discount as \"Relief Requested\".", + "4.VPN Tariff is port base pricing, no charges on COS or COS profile.", + "5.AT&T GAM will place order to SST on no longer than 12 months term for Custom Subcontract, regardless of the commitment term between end customer and AT&T.", + "6.China VAT is irrecoverable cost to AT&T under custom subcontracting billing. Ttariff and Access price listed below is VAT inclusive. ICB has to cater for this cost in deal financials.", + "7.Tariff Relief is only applicable to the demand set listed below, any changes in bandwidth/design/billing model, need to re-submit to SST for approval;", + }; + int lastLineTag = finalyCow + 2;//固定值Note所在的行 + int h=0; + for (int rowNum=lastLineTag;rowNum { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String("L3NS表单.xlsx".getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + } catch (IOException e) { + logger.error("导出excel错误:" + Util.getErrString(e)); + e.printStackTrace(); + } + + + + + + build = header.build(); + return build; + } + + + + + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyBorderStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + return cellStyle; + } + + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + /** + * 设置单元格格式为数值型 + * @param workbook + * @return + */ + public static CellStyle setCellToNumber(Workbook workbook){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/CheckRequestInfo.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/CheckRequestInfo.java new file mode 100644 index 0000000..cc463ff --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/CheckRequestInfo.java @@ -0,0 +1,90 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Path("/hcy_xintiantongxin4") +public class CheckRequestInfo { + + Logger logger = Util.getLogger(); + + /** + * 校验 + * + * @param request + * @param response + * @return + */ + @POST + @Path("/checkRequestInfo") + @Produces(MediaType.APPLICATION_JSON) + public String checkRequestInfo(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + + RecordSet recordSet = new RecordSet(); + + List> lists = new ArrayList<>(); + for (String s : split) { + String getCheckData = "select customername,currencyused,contractterminmonths,contractmodel from uf_other_export where id =?"; + boolean b = recordSet.executeQuery(getCheckData, s); + logger.info("查询验证信息sql是否执行"+b); + Map map = new HashMap<>(); + if (recordSet.next()){ + String customername = recordSet.getString("customername");//系统-客户名 + String currencyused = recordSet.getString("currencyused"); + String contractterminmonths = recordSet.getString("contractterminmonths"); + String contractmodel = recordSet.getString("contractmodel"); + map.put("customername",customername); + map.put("currencyused",currencyused); + map.put("contractterminmonths",contractterminmonths); + map.put("contractmodel",contractmodel); + lists.add(map); + } + } + + String checkTag = "0"; + List> collect = lists.stream().distinct().collect(Collectors.toList());//用stream流处理相同数据,如果得到的是一条数据,那么证明满足客户条件 + if (collect.size() == 1){ + checkTag = "1"; + }else { + checkTag = "0"; + } +// Map firstMap = lists.get(0); +// String first_customername = firstMap.get("customername"); +// String first_currencyused = firstMap.get("currencyused"); +// String first_contractterminmonths = firstMap.get("contractterminmonths"); +// String first_contractmodel = firstMap.get("contractmodel"); +// +// for (Map list : lists) { +// if (first_customername.equals(list.get("customername")) & first_currencyused.equals(list.get("currencyused")) & first_contractterminmonths.equals(list.get("contractterminmonths")) & first_contractmodel.equals(list.get("contractmodel")) ){ +// checkTag = "1"; +// }else { +// checkTag = "0"; +// return ApiResult.success(checkTag); +// } +// } + String getMsgSql = "select * from uf_cus_dev_config where only_mark = ?"; + recordSet.executeQuery(getMsgSql,"prompt_after_fail"); + recordSet.next(); + String msg = recordSet.getString("param_value"); + return ApiResult.success(checkTag,msg); + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper.java new file mode 100644 index 0000000..26bcea8 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper.java @@ -0,0 +1,74 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +/** + *

mapper--sql映射类,用于查找数据库中的数据

+ * @Author hcy + * @Date 2023/2/9 13:26 + */ +@SqlMapper +public interface DemoMapper { + + /** + *

根据前端返回的id内连接查询其他产品中主表和明细表中所有的数据

+ * @param ids + * @return List> + * @author hcy + * @Date 2023/2/9 13:25 + */ + @Select("select * from \n" + + "uf_other_export main \n" + + "inner join uf_other_export_dt1 dt \n" + + "on dt.mainid = main.id where main.id in (${ids})") + List> selectAll(@ParamMapper("ids") List ids); + + + /** + *

根据前端返回的id内连接查询其他产品中主表和明细表中所有的数据

+ * @param ids + * @return List> + * @author hcy + * @Date 2023/2/9 13:25 + */ + @Select("select * from \n" + + "uf_other_export main \n" + + "inner join uf_other_export_dt1 dt \n" + + "on dt.mainid = main.id where main.id in (${ids})\n") + List> selectCMRData(@ParamMapper("ids") List ids); + + + /** + *

根据人员id在hrmresource中查询到人员姓名

+ * @param id + * @return String + * @author hcy + * @Date 2023/2/9 13:23 + */ + @Select("select lastname from hrmresource where id = #{id}") + String selectLastName(@ParamMapper("id") String id); + + /** + *

根据id向uf_pd_base表中查找pd_name

+ * @param id + * @return String + * @author hcy + * @Date 2023/2/9 13:22 + */ + @Select("select pd_name from uf_pd_base_inf where id = #{id} ") + public String getServiceTypeSql(@ParamMapper("id") String id); + + + + + + + + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper_copy.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper_copy.java new file mode 100644 index 0000000..14e31c0 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/DemoMapper_copy.java @@ -0,0 +1,76 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +/** + *

mapper--sql映射类,用于查找数据库中的数据

+ * @Author hcy + * @Date 2023/2/9 13:26 + */ +@SqlMapper +public interface DemoMapper_copy { + + /** + *

根据前端返回的id内连接查询其他产品中主表和明细表中所有的数据

+ * @param ids + * @return List> + * @author hcy + * @Date 2023/2/9 13:25 + */ + @Select("select main.id mainid,main.servicetype,main.contractterminmonths,\n" + + "dt.*\n" + + " from uf_other_export main\n" + + "inner join uf_other_export_dt1 dt on dt.mainid = main.id\n" + + "where main.id in (${ids})\n") + List> selectAll(@ParamMapper("ids") List ids); + + + /** + *

根据前端返回的id内连接查询其他产品中主表和明细表中所有的数据

+ * @param ids + * @return List> + * @author hcy + * @Date 2023/2/9 13:25 + */ + @Select("select main.id mainid,main.servicetype,main.contractterminmonths,main.channel_fee_per,main.channel_fee_type,\n" + + "dt.*\n" + + " from uf_other_export main\n" + + "inner join uf_other_export_dt1 dt on dt.mainid = main.id\n" + + "where main.id in (${ids})\n") + List> selectCMRData(@ParamMapper("ids") List ids); + + + /** + *

根据人员id在hrmresource中查询到人员姓名

+ * @param id + * @return String + * @author hcy + * @Date 2023/2/9 13:23 + */ + @Select("select lastname from hrmresource where id = #{id}") + String selectLastName(@ParamMapper("id") String id); + + /** + *

根据id向uf_pd_base表中查找pd_name

+ * @param id + * @return String + * @author hcy + * @Date 2023/2/9 13:22 + */ + @Select("select pd_name from uf_pd_base_inf where id = #{id} ") + public String getServiceTypeSql(@ParamMapper("id") String id); + + + + + + + + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/ExportExcelOtherApi.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/ExportExcelOtherApi.java new file mode 100644 index 0000000..6b5dc67 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/ExportExcelOtherApi.java @@ -0,0 +1,110 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.Util; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +@Path("/hcy_xintiantongxin1") +public class ExportExcelOtherApi { + + Logger logger = Util.getLogger(); + + /** + *获取其他产品uf_other_export表中的数据,渲染到sheet1---CMR中 + */ + private SheetCMRPOI sheetCMRPOI = new SheetCMRPOI(); + /** + * 获取其他产品uf_other_export表中的数据,渲染到sheet2---Quotation中 + */ + private SheetQuotationPOI sheetQuotationPOI = new SheetQuotationPOI(); + /** + * 获取其他产品uf_other_export表中的数据,渲染到sheet3---Cost中 + */ + private SheetCostPOI sheetCostPOI = new SheetCostPOI(); + + + /** + *

将数据库中的数据放入sheet1---Quotation中

+ * @param request,response + * @return Response + * @author hcy + * @Date 2023/2/9 14:21 + */ + @GET + @Path("/ExportExcelOtherApi") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportExcel(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + Response build = null; + Response.ResponseBuilder header = null; + StreamingOutput output = null; + String ids = request.getParameter("ids"); + String[] split = ids.split(","); + + //创建一个工作簿 + Workbook workbook = new XSSFWorkbook(); + //创建一个工作表sheet + + sheetCMRPOI.setSheetCMR(workbook,split);//创建第一个sheet1---sheet_CMR,并向sheet中渲染内容 + sheetQuotationPOI.setQuotationSheet(workbook,split);//创建第二个sheet2---sheet_Quotation,并向sheet中渲染内容 + sheetCostPOI.getSheetCost(workbook,split);//创建第三个sheet3---sheet_Cost,并向sheet中渲染内容 + try { + InputStream inputStream = workbookConvertorStream(workbook); + byte[] bytes = IOUtils.toByteArray(inputStream); + output = outputStream -> { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String("其他产品表.xlsx".getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + + } catch (IOException e) { + e.printStackTrace(); + } + + build = header.build(); + return build; + } + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SetCellStylePOI.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SetCellStylePOI.java new file mode 100644 index 0000000..d773dc5 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SetCellStylePOI.java @@ -0,0 +1,419 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import org.apache.poi.ss.usermodel.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +/** + *

poi设置单元格样式

+ * @Author hcy + * @Date 2023/2/9 14:34 + */ +public class SetCellStylePOI { + /** + *

设置每个单元格样式:包含字体类型,字体是否加粗,是否包含边框,元素水平方向的位置,元素垂直方向的位置,是否设置元素的数据格式,是否自动换行

+ * @param + * @return + * @author hcy + * @Date 2023/2/13 18:08 + */ + public static CellStyle setTotalStyle(Workbook workbook,String type,boolean setBold,boolean setBorder,HorizontalAlignment horizontalDirection,VerticalAlignment verticalAlignmentDirection ,boolean setDataFormat,boolean setWrapText){ + //new一个cellStyle用于设置每一个单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName(type); + //设置字体是否加粗 + font.setBold(setBold); + //将字体样式渲染cellStyle对象中 + cellStyle.setFont(font); + if (setBorder == true){ + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + } + + //水平居中 + cellStyle.setAlignment(horizontalDirection); + //垂直居中 + cellStyle.setVerticalAlignment(verticalAlignmentDirection); + cellStyle.setWrapText(setWrapText); + + //此处设置数据格式 + if(setDataFormat == true){ + DataFormat dataFormat = workbook.createDataFormat(); + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + } + + return cellStyle; + } + + /** + *

设置每个单元格样式:包含字体类型,字体是否加粗,是否包含边框,元素水平方向的位置,元素垂直方向的位置,是否设置元素的数据格式,

+ * @param + * @return + * @author hcy + * @Date 2023/2/13 18:08 + */ + public static CellStyle setTotalStyle(Workbook workbook,String type,boolean setBold,boolean setBorder,HorizontalAlignment horizontalDirection,VerticalAlignment verticalAlignmentDirection ,boolean setDataFormat){ + //new一个cellStyle用于设置每一个单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName(type); + //设置字体是否加粗 + font.setBold(setBold); + //将字体样式渲染cellStyle对象中 + cellStyle.setFont(font); + if (setBorder == true){ + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + } + + //水平居中 + cellStyle.setAlignment(horizontalDirection); + //垂直居中 + cellStyle.setVerticalAlignment(verticalAlignmentDirection); + + //此处设置数据格式 + if(setDataFormat == true){ + DataFormat dataFormat = workbook.createDataFormat(); + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + } + + return cellStyle; + } + + + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + /** + *

设置每个单元格的样式,并且加粗字体,设置边框,字体位置

+ * @param workbook,setBold, + * @return + * @author hcy + * @Date 2023/2/8 20:43 + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold,boolean setLocation) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + if (setLocation == true) { + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + } + + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + /** + *

设置字体颜色和边框

+ * @param workbook + * @return CellStyle + * @author hcy + * @Date 2023/2/8 17:25 + */ + public static CellStyle setWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + /** + *

仅设置字体样式

+ * @param workbook,setBold + * @return CellStyle + * @author hcy + * @Date '2023/2/8' 17:50 + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + /** + *

仅设置字体样式,并设置字体位置

+ * @param workbook,setBold + * @return CellStyle + * @author hcy + * @Date '2023/2/8' 17:50 + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold,Boolean setLocation) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + if (setLocation == true) { + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + } + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + + /** + * 只设置边框样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyBorderStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + return cellStyle; + } + + + /** + * 设置单元格格式为数值型 + * @param workbook + * @return + */ + public static CellStyle setCellToNumber(Workbook workbook){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + *

设置字体颜色,是否加粗,设置单元格格式为数值型,设置字体居中

+ * @param workbook,setBold,setLocation + * @return CellStyle + * @author hcy + * @Date 2023/2/9 13:39 + */ + public static CellStyle setCellToNumber(Workbook workbook,boolean setBold,boolean setLocation){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + if (setBold == true){ + font.setBold(setBold); + } + if (setLocation == true){ + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + } + + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + *

POI设置文字水平居中、垂直居中

+ * @param workbook + * @return CellStyle + * @author hcy + * @Date 2023/2/8 20:08 + */ + public static CellStyle setCellLocations(Workbook workbook){ + CellStyle cellStyle = workbook.createCellStyle();//创建文本单元格样式 + //水平居中 + cellStyle.setAlignment(HorizontalAlignment.CENTER); + //垂直居中 + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + return cellStyle; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCMRPOI.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCMRPOI.java new file mode 100644 index 0000000..a744f50 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCMRPOI.java @@ -0,0 +1,437 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import weaver.conn.RecordSet; + +import java.text.NumberFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

获取其他产品uf_other_export表中的数据,渲染到sheet1---CMR中

+ * hcy + * 2023/2/9 15:40 + */ +public class SheetCMRPOI extends SetCellStylePOI{ + + private final Logger logger = Util.getLogger(); + + /** + *

将数据库中的数据放入sheet1---CMR中

+ * workbook,split + * @author hcy + 2023/2/9 14:19 + */ + public void setSheetCMR(Workbook workbook, String[] split){ + logger.info("SheetCMRPOI----开始执行"); + Sheet sheet_CMR = workbook.createSheet(); + workbook.setSheetName(0,"CMR"); + +// 将第一行数据放入CMR-sheet_0中 + Row row0 = sheet_CMR.createRow(0); + sheet_CMR.autoSizeColumn(0); + Cell cell0_0 = row0.createCell(0); + cell0_0.setCellValue("CMR Analysis Form"); + cell0_0.setCellStyle(setNolyWordStyle(workbook,true,true)); + sheet_CMR.addMergedRegion(new CellRangeAddress(0,0,0,7)); +// 将第二行数据放入CMR-sheet_0中 + Row row1 = sheet_CMR.createRow(1); + sheet_CMR.autoSizeColumn(1); + Cell cell1_0 = row1.createCell(0); + cell1_0.setCellValue("General Information"); + cell1_0.setCellStyle(setWordStyle(workbook,true,false)); + Cell cell1_1 = row1.createCell(1); + cell1_1.setCellValue("General Information"); + cell1_1.setCellStyle(setWordStyle(workbook,true,false)); + for (int colNum = 1;colNum<8;colNum++){ + Cell cell = row1.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + sheet_CMR.addMergedRegion(new CellRangeAddress(1,1,0,7)); + String[] value_row3_9 = new String[] + {"Customer Name", + "Sales Name", + "Presales Name", + "Service Delivery Date", + "Contract Period (Months)", + "Customer Requirements", + "Service Description"}; + +// 从其他产品表单数据库表中导出主表中3-9行所需数据 + + String getValue3_9FromDB = "select * from uf_other_export where id = ?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(getValue3_9FromDB,split[0]); + logger.info("b是否执行=="+b); + List value3_9FromDB = new ArrayList<>(); + String contractterminmonths = ""; + if (recordSet.next()){ + String customerName = recordSet.getString("customername");//Customer Name 系统-客户名 + value3_9FromDB.add(customerName); + value3_9FromDB.add("");//Sales Name---手工(导出后填写) 这里设置为空 + String cjr = recordSet.getString("cjr");//Presales Name---报价单创建人 + DemoMapper getLastNameMapper = Util.getMapper(DemoMapper.class); + String getCreaterName = getLastNameMapper.selectLastName(cjr);//根据id在hrmsource表中查到LastName 姓名 + value3_9FromDB.add(getCreaterName); + value3_9FromDB.add("");//Service Delivery Date---手工(导出后填写)---这里设置为空 + contractterminmonths = recordSet.getString("contractterminmonths");//Contract Period (Months)---系统- Contract Term(in months)(contractterminmonths) + value3_9FromDB.add(contractterminmonths); + value3_9FromDB.add("");//Customer Requirements---手工(导出后填写) 这里设置为空 + value3_9FromDB.add("");////Service Description---手工(导出后填写) 这里设置为空 + } + + for (int rowNum = 2;rowNum<9;rowNum++){ + Row row = sheet_CMR.createRow(rowNum); + sheet_CMR.autoSizeColumn(rowNum); + Cell cell0 = row.createCell(0); + Cell cell1 = row.createCell(1); + cell0.setCellValue(value_row3_9[rowNum-2]);//将3-9行第一列固定数据放入sheet0中 + cell0.setCellStyle(setWordStyle(workbook,true)); + cell1.setCellValue(value3_9FromDB.get(rowNum-2));//将3-9行第二列数据库中查到的数据放入sheet0中 + cell1.setCellStyle(setWordStyle(workbook,false)); + for (int colNum =2;colNum<8;colNum++){ + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + sheet_CMR.addMergedRegion(new CellRangeAddress(rowNum,rowNum,1,7)); + } + + + + +// 开始写入11-12行固定值数据 + String[] valueRow11 = new String[] + {"Revenue Information(RMB) VAT Exclusive", + "", + "Quotation", + "Quotation", + "COST", + "COST", + "Agent fee", + "Agent fee" + }; + String[] valueRow12 = new String[] + {"Revenue Information(RMB) VAT Exclusive", + "Revenue Information(RMB) VAT Exclusive", + "One Time Charge", + "Recurring Monthly Charge", + "One Time Charge", + "Recurring Monthly Charge", + "One Time Charge", + "Recurring Monthly Charge" + }; + List list11 = Arrays.asList(valueRow11); + List list12 = Arrays.asList(valueRow12); + List> list11_12 = new ArrayList<>();//new 一个list对象用于存放12-13行所有的元素 + list11_12.add(list11); + list11_12.add(list12); + + for (int rowNum = 10;rowNum<12;rowNum++){ + Row row = sheet_CMR.createRow(rowNum); + sheet_CMR.autoSizeColumn(rowNum); + List list = list11_12.get(rowNum - 10);//将list11_12中数据放入list中 + for (int cowNum = 0;cowNum<8;cowNum++){ + Cell cell = row.createCell(cowNum); + cell.setCellStyle(setWordStyle(workbook,true)); + cell.setCellValue(list.get(cowNum));//开始写入数据 + } + } + //开始合并12-13行数据 + sheet_CMR.addMergedRegion(new CellRangeAddress(10,11,0,1)); + sheet_CMR.addMergedRegion(new CellRangeAddress(10,10,2,3)); + sheet_CMR.addMergedRegion(new CellRangeAddress(10,10,4,5)); + sheet_CMR.addMergedRegion(new CellRangeAddress(10,10,6,7)); + + //开始处理14行及其14行一下的其他产品明细表中的数据 + List splitList = Arrays.asList(split); + DemoMapper mapper = Util.getMapper(DemoMapper.class);//获得mapper对象 + List> dynamicData = mapper.selectCMRData(splitList);//13行及其13行一下的动态数据获取到dynamicData对象中 + logger.info("dynamicData==="+dynamicData); + + Map>> newMap = dynamicData.stream() + .collect(Collectors.groupingBy(map1 -> map1.get("servicetype"))); + List> result = new ArrayList<>();//明细表中动态表格最终的数据来源 + for (Map.Entry>> e : newMap.entrySet()) { + Object key = e.getKey(); + List> maps = e.getValue(); + Map resultMap = new HashMap<>(); + for (Map map1 : maps) { + for (Map.Entry entry : map1.entrySet()) { + String k = entry.getKey(); + Object v = entry.getValue(); + if ("priceexcludingtaxotc".equals(k) || "priceexcludingtaxmrc".equals(k) || k.equals("costexcludingtaxotc") || k.equals("costexcludingtaxmrc") ) { + if ("".equals(Util.null2String(v))) { + v = 0; + } + resultMap.merge(k, v, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + } + + if ("xxfylx".equals(k)){ //代理费用类型(xxfylx)== 0.项目百分比 1.固定金额 2.月租百分比 + String channeltype = Util.null2String(v); + if ("0".equals(channeltype)){//项目百分比 = 0时 One Time Charge = agentfee + Object agent_fee = map1.get("agentfee");//代理费用(不含税) + String price = Util.null2String(agent_fee); + logger.info("最后一次需求变更----price===="+price); +// Object channelfeeper = map1.get("channelFeePer"); +// String percent = Util.null2String(channelfeeper);//代理费用占比 + double Agent_fee_One_Time_Charge; + if (!"".equals(price)){ + Agent_fee_One_Time_Charge = Double.parseDouble(price); + resultMap.merge("OneTimeCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + }else{ + Agent_fee_One_Time_Charge = 0; + resultMap.merge("OneTimeCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + } + }else if ("1".equals(channeltype)) {//固定金额 + Object agent_fee = map1.get("agentfee"); + String price = Util.null2String(agent_fee); + logger.info("最后一次需求变更----price===="+price); + double Agent_fee_One_Time_Charge; + if (!"".equals(price)){ + Agent_fee_One_Time_Charge = Double.parseDouble(price); + resultMap.merge("OneTimeCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + }else{ + Agent_fee_One_Time_Charge = 0; + resultMap.merge("OneTimeCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + } + }else if ("2".equals(channeltype)){//月租百分比 +// Object xxfyzb = map1.get("xxfyzb");//代理费用占比 +// String percent = Util.null2String(xxfyzb); + Object agent_fee = map1.get("agentfee"); + String price = Util.null2String(agent_fee); + logger.info("最后一次需求变更----price===="+price); + int terms = Util.getIntValue(Util.null2String(map1.get("terms"))); + logger.info("最后一次需求变更----terms===="+terms); + double Agent_fee_One_Time_Charge; + if (!"".equals(price)){ + double priceDouble = Double.parseDouble(price); +// double percentDouble = Double.parseDouble(percent); + Agent_fee_One_Time_Charge = priceDouble / terms; + logger.info("最后一次需求变更----Agent_fee_One_Time_Charge===="+Agent_fee_One_Time_Charge); + resultMap.merge("RecurringMonthlyCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + }else{ + Agent_fee_One_Time_Charge = 0; + resultMap.merge("RecurringMonthlyCharge", Agent_fee_One_Time_Charge, (v1, v2) -> Double.parseDouble(Util.null2String(v1)) + Double.parseDouble(Util.null2String(v2))); + } + } + } + } + } + resultMap.put("servicetype", key); + result.add(resultMap); + } + //-------新的业务逻辑--------- + int tag = 0; + double totalColumn3 = 0; + double totalColumn4 = 0; + double totalColumn5 = 0; + double totalColumn6 = 0; + double totalColumn7 = 0; + double totalColumn8 = 0; + + for (int cowNum=12;cowNum < result.size()+12;cowNum++ ){ + Row row = sheet_CMR.createRow(cowNum); + sheet_CMR.autoSizeColumn(cowNum); + Map map = result.get(cowNum - 12); + for (int colNum = 0;colNum < 8;colNum++){ + if (colNum==0){ + Cell cell = row.createCell(colNum); + tag++; + cell.setCellValue(tag); + cell.setCellStyle(setWordStyle(workbook,false,true)); + }else if (colNum == 1){ //servicetype + Cell cell = row.createCell(colNum); + Object servicetype = map.get("servicetype"); + String string = Util.null2String(servicetype); + if (!"".equals(string) && (int)Double.parseDouble(string)!=-1) { + DemoMapper getServicetyeMapper = Util.getMapper(DemoMapper.class); + String serviceTypeSql = getServicetyeMapper.getServiceTypeSql(string); + cell.setCellValue(serviceTypeSql); + cell.setCellStyle(setWordStyle(workbook,false,true)); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum == 2) { //priceexcludingtaxotc + Cell cell = row.createCell(colNum); + Object priceexcludingtaxotc = map.get("priceexcludingtaxotc"); + String string = Util.null2String(priceexcludingtaxotc); + if (!"".equals(string)){ + if ((int)Double.parseDouble(string)!=-1){ + double stringToDouble = Double.parseDouble(string); + totalColumn3 += stringToDouble;//统计第三列数据的和 + cell.setCellStyle(setCellToNumber(workbook,false,true));//设置为数值型 + cell.setCellValue(stringToDouble); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else{ + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum == 3) {//priceexcludingtaxmrc + Cell cell = row.createCell(colNum); + Object priceexcludingtaxmrc = map.get("priceexcludingtaxmrc"); + String string = Util.null2String(priceexcludingtaxmrc); + if (!"".equals(string)){ + if ((int)Double.parseDouble(string)!=-1){ + double stringToDouble = Double.parseDouble(string); + totalColumn4 += stringToDouble; + cell.setCellStyle(setCellToNumber(workbook,false,true));//设置为数值型 + cell.setCellValue(stringToDouble); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 4) {//costexcludingtaxotc + Cell cell = row.createCell(colNum); + Object costexcludingtaxotc = map.get("costexcludingtaxotc"); + String string = Util.null2String(costexcludingtaxotc); + if (!"".equals(string)){ + if ((int)Double.parseDouble(string)!=-1){ + double stringToDouble = Double.parseDouble(string); + totalColumn5 += stringToDouble; + cell.setCellStyle(setCellToNumber(workbook,false,true));//设置为数值型 + cell.setCellValue(stringToDouble); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 5) {//costexcludingtaxmrc + Cell cell = row.createCell(colNum); + Object costexcludingtaxmrc = map.get("costexcludingtaxmrc"); + String string = Util.null2String(costexcludingtaxmrc); + if (!"".equals(string)){ + if ((int)Double.parseDouble(string)!=-1){ + double stringToDouble = Double.parseDouble(string); + totalColumn6 += stringToDouble; + cell.setCellStyle(setCellToNumber(workbook,false,true));//设置为数值型 + cell.setCellValue(stringToDouble); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 6) {//channel_fee_type channelfeetype channel_fee_per channelfeeper + Cell cell = row.createCell(colNum); + Object oneTimeCharge = map.get("OneTimeCharge"); + String oneTimeChargeValue = Util.null2String(oneTimeCharge); + if (!"".equals(oneTimeChargeValue)){ + double oneTimeChargeDouble = Double.parseDouble(oneTimeChargeValue); + cell.setCellStyle(setCellToNumber(workbook,false,true)); + cell.setCellValue(oneTimeChargeDouble); + totalColumn7 += oneTimeChargeDouble; + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else{//channel_fee_per channelfeeper + Cell cell = row.createCell(colNum); + Object recurringMonthlyCharge = map.get("RecurringMonthlyCharge"); + String recurringMonthlyChargeValue = Util.null2String(recurringMonthlyCharge); + if (!"".equals(recurringMonthlyChargeValue)){ + double recurringMonthlyChargeDouble= Double.parseDouble(recurringMonthlyChargeValue); + cell.setCellStyle(setCellToNumber(workbook,false,true)); + cell.setCellValue(recurringMonthlyChargeDouble); + totalColumn8 += recurringMonthlyChargeDouble; + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + } + } + //开始写入Total一行,用来统计第三列到第八列明细表中数据的和 + int cowNumTotal = 12 + result.size(); + Row row_cowNumTotal = sheet_CMR.createRow(cowNumTotal); + sheet_CMR.autoSizeColumn(cowNumTotal); + Cell cell_cowNumTotal_0 = row_cowNumTotal.createCell(0); + cell_cowNumTotal_0.setCellValue("Total"); + cell_cowNumTotal_0.setCellStyle(setWordStyle(workbook,true,true)); + sheet_CMR.addMergedRegion(new CellRangeAddress(cowNumTotal,cowNumTotal,0,1)); + + //开始写入数据和具体数值 第三列到第八列 + Cell cell_cowNumTotal_2 = row_cowNumTotal.createCell(2); + cell_cowNumTotal_2.setCellValue(totalColumn3);//写入第三列总和 + cell_cowNumTotal_2.setCellStyle(setCellToNumber(workbook,true,true)); + Cell cell_cowNumTotal_3 = row_cowNumTotal.createCell(3); + cell_cowNumTotal_3.setCellValue(totalColumn4);//写入第4列总和 + cell_cowNumTotal_3.setCellStyle(setCellToNumber(workbook,true,true)); + Cell cell_cowNumTotal_4 = row_cowNumTotal.createCell(4); + cell_cowNumTotal_4.setCellValue(totalColumn5);//写入第5列总和 + cell_cowNumTotal_4.setCellStyle(setCellToNumber(workbook,true,true)); + Cell cell_cowNumTotal_5 = row_cowNumTotal.createCell(5); + cell_cowNumTotal_5.setCellValue(totalColumn6);//写入第6列总和 + cell_cowNumTotal_5.setCellStyle(setCellToNumber(workbook,true,true)); + Cell cell_cowNumTotal_6 = row_cowNumTotal.createCell(6); + cell_cowNumTotal_6.setCellValue(totalColumn7);//写入第7列总和 + cell_cowNumTotal_6.setCellStyle(setCellToNumber(workbook,true,true)); + Cell cell_cowNumTotal_7 = row_cowNumTotal.createCell(7); + cell_cowNumTotal_7.setCellValue(totalColumn8);//写入第4列总和 + cell_cowNumTotal_7.setCellStyle(setCellToNumber(workbook,true,true)); + +// 开始写入最后一行数据 + Row finalRow = sheet_CMR.createRow(cowNumTotal + 1); + sheet_CMR.autoSizeColumn(cowNumTotal +1); + Cell cell_final_0 = finalRow.createCell(0); + cell_final_0.setCellValue("Contribution Margin"); + cell_final_0.setCellStyle(setWordStyle(workbook,true,true)); + Cell cell_final_1 = finalRow.createCell(1); + cell_final_1.setCellValue("CMR(%)"); + cell_final_1.setCellStyle(setWordStyle(workbook,true,true)); + + //开始计算最后一行的公式:="【D20+E20*C8-F20-G20*C8-H20-I20*C8】/【D20+E20*C8】" + double month =0; + if (!contractterminmonths.equals("") ){ + month = Double.parseDouble(contractterminmonths); + if ((int)month == -1){ + month = 0; + } + } +// -36 / (120+120*12) + double expressions = ( totalColumn3 + totalColumn4 * month - totalColumn5 - totalColumn6 * month - totalColumn7 - totalColumn8 * month) / ( totalColumn3 + totalColumn4 * month); + Cell cell_final_2 = finalRow.createCell(2); + + cell_final_2.setCellType(CellType.NUMERIC); + cell_final_2.setCellValue(getPercentFormat(expressions,2,2)); + cell_final_2.setCellStyle(setWordStyle(workbook,true,true)); + for (int colNmu = 3 ;colNmu < 8 ;colNmu++){ + Cell cell = finalRow.createCell(colNmu); + cell.setCellStyle(setCellToNumber(workbook,true,true)); + } + sheet_CMR.addMergedRegion(new CellRangeAddress(cowNumTotal+1,cowNumTotal+1,2,7)); + + sheet_CMR.setColumnWidth(10,sheet_CMR.getColumnWidth(10)*17/10); + // 设置自动列宽 + for (int num = 0; num < 8; num++) { + sheet_CMR.autoSizeColumn(num); + sheet_CMR.setColumnWidth(num, (sheet_CMR.getColumnWidth(num))); + } + sheet_CMR.setColumnWidth(1, 20*256); + + } + + /** + *

Double转化成百分数

+ * @param d 要转换的内容 + * @param IntegerDigits 整数部分 + * @param FractionDigits 小数部分 + * @return String + * @author hcy + 2023/2/21 17:50 + */ + public static String getPercentFormat(double d,int IntegerDigits,int FractionDigits) { + NumberFormat nf = NumberFormat.getPercentInstance(); + nf.setMaximumIntegerDigits(IntegerDigits);//小数点前保留几位 + nf.setMinimumFractionDigits(FractionDigits);// 小数点后保留几位 + return nf.format(d); + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCostPOI.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCostPOI.java new file mode 100644 index 0000000..561e1ea --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/exportotherexcel/SheetCostPOI.java @@ -0,0 +1,452 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSON; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import weaver.conn.RecordSet; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +/** + *

获取其他产品uf_other_export表中的数据,渲染到sheet3---Cost中

+ * @Author hcy + * @Date 2023/2/9 14:27 + */ +public class SheetCostPOI extends SetCellStylePOI{ + + private final Logger logger = Util.getLogger(); + + + + /** + *

将数据库中的数据渲染到sheet3---Cost中

+ * @param workbook:poi workbook对象用来操作excel表, split:前端传来的数据的id组成的数组 + * @return + * @author hcy + * @Date 2023/2/9 14:35 + */ + public void getSheetCost(Workbook workbook,String[] split){ + try { + Sheet sheet_Cost = workbook.createSheet(); + workbook.setSheetName(2,"Cost"); + + String[] tableFiled = new String[]{"Customer Name", "Service Provider", "Contract Term(in months)", "Currency Used", "Issueing Date", "Expiration Date"}; + List systemFiled = new ArrayList<>(); + String sql_other_export_db = "select * from uf_other_export where id = ?"; + RecordSet rs = new RecordSet(); + rs.executeQuery(sql_other_export_db,split[0]); + while (rs.next()){ + String customername = rs.getString("customername"); + systemFiled.add(customername);//Customer Name + systemFiled.add("SST");//Service Provider + systemFiled.add(rs.getString("contractterminmonths"));//Contract Term(in months) + systemFiled.add("RMB");//Currency Used + //系统当前时间 + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Date date = new Date(System.currentTimeMillis()); + systemFiled.add(formatter.format(date));//Issueing Date + //系统当前时间再往后推30天 + Calendar currentdate = Calendar.getInstance(); + //在这里进行加30天(ps:周六周日也算在里边了) + currentdate.add(Calendar.DATE, 30); + //得到最后的时间 + Date finalday = currentdate.getTime(); + + systemFiled.add(formatter.format(finalday));//Expiration Date + } + //将1-6行固定值数据放入excel中 + for (int cowNum = 0; cowNum < 6; cowNum++) { + Row row = sheet_Cost.createRow(cowNum); + Cell cell0col = row.createCell(0); + Cell cell1col = row.createCell(1); + cell0col.setCellStyle(setNolyWordStyle(workbook,true)); + cell0col.setCellValue(tableFiled[cowNum]); + cell1col.setCellStyle(setNolyWordStyle(workbook,true)); + cell1col.setCellValue(systemFiled.get(cowNum)); + } + //将8行数据放入excel中 + //Quotation Breakdown: + Row row7 = sheet_Cost.createRow(7); + Cell cell7_0 = row7.createCell(0); + cell7_0.setCellStyle(setNolyWordStyle(workbook,true)); + cell7_0.setCellValue("Quotation Breakdown:"); + Cell cell7_1 = row7.createCell(1); + cell7_1.setCellStyle(setNolyWordStyle(workbook,true)); + cell7_1.setCellValue("Quotation Breakdown:"); + sheet_Cost.addMergedRegion(new CellRangeAddress(7,7,0,1)); + + //将第九行第十行前四列放入excel中并合并单元格 + //1Service Type 2.Site 3.Item 4.Service Description + String[] string8_4 = new String[]{"Service Type","Site","Item","Service Description"}; + Row row8 = sheet_Cost.createRow(8); + Row row9 = sheet_Cost.createRow(9); + for (int colNum = 0;colNum<4;colNum++){ + Cell cell8 = row8.createCell(colNum); + cell8.setCellStyle(setWordStyle(workbook,true)); + cell8.setCellValue(string8_4[colNum]); + Cell cell9 = row9.createCell(colNum); + cell9.setCellStyle(setWordStyle(workbook,true)); + cell9.setCellValue(""); + sheet_Cost.addMergedRegion(new CellRangeAddress(8,9,colNum,colNum)); + } + //Price Plus tax VAT rate % Price Excluding tax + //第九行三个字段并合并字段 5-10列 + Cell cell8_4 = row8.createCell(4); + cell8_4.setCellValue("Cost Plus tax"); + cell8_4.setCellStyle(setWordStyle(workbook,true)); + Cell cell8_5 = row8.createCell(5); + cell8_5.setCellStyle(setWordStyle(workbook,true)); + sheet_Cost.addMergedRegion(new CellRangeAddress(8,8,4,5)); + Cell cell8_6 = row8.createCell(6); + cell8_6.setCellValue("VAT rate %"); + cell8_6.setCellStyle(setWordStyle(workbook,true)); + Cell cell8_7 = row8.createCell(7); + cell8_7.setCellStyle(setWordStyle(workbook,true)); + sheet_Cost.addMergedRegionUnsafe(new CellRangeAddress(8,8,6,7)); + Cell cell8_8 = row8.createCell(8); + cell8_8.setCellStyle(setWordStyle(workbook,true)); + cell8_8.setCellValue("Cost Excluding tax"); + Cell cell8_9 = row8.createCell(9); + cell8_9.setCellStyle(setWordStyle(workbook,true)); + sheet_Cost.addMergedRegionUnsafe(new CellRangeAddress(8,8,8,9)); + + //OTC MRC OTC MRC OTC MRC + //写入10行第5列到第10列的内容 + Cell cell9_4 = row9.createCell(4); + cell9_4.setCellStyle(setWordStyle(workbook,true)); + cell9_4.setCellValue("OTC"); + Cell cell9_5 = row9.createCell(5); + cell9_5.setCellStyle(setWordStyle(workbook,true)); + cell9_5.setCellValue("MRC"); + Cell cell9_6 = row9.createCell(6); + cell9_6.setCellStyle(setWordStyle(workbook,true)); + cell9_6.setCellValue("OTC"); + Cell cell9_7 = row9.createCell(7); + cell9_7.setCellStyle(setWordStyle(workbook,true)); + cell9_7.setCellValue("MRC"); + Cell cell9_8 = row9.createCell(8); + cell9_8.setCellStyle(setWordStyle(workbook,true)); + cell9_8.setCellValue("OTC"); + Cell cell9_9 = row9.createCell(9); + cell9_9.setCellStyle(setWordStyle(workbook,true)); + cell9_9.setCellValue("MRC"); + //写入remark 9行11列 并合并9行10行 + Cell cell8_10 = row8.createCell(10); + cell8_10.setCellStyle(setWordStyle(workbook,true)); + cell8_10.setCellValue("Remark"); + Cell cell9_10 = row9.createCell(10); + cell9_10.setCellStyle(setWordStyle(workbook,true)); + cell9_10.setCellValue(""); + sheet_Cost.addMergedRegion(new CellRangeAddress(8,9,10,10)); + + //开始写入动态表格中的内容 + DemoMapper mapper = Util.getMapper(DemoMapper.class); + List idList = Arrays.asList(split); + + List> maps = mapper.selectAll(idList); + Map>> servicetype = maps.stream() + .collect(Collectors.groupingBy(item -> item.get("servicetype")));//servicetype的种类,以及每个种类的数量 +// System.out.println("servicetype===="+JSON.toJSONString(servicetype)); +// servicetype.forEach((key,value)->{ +// System.out.println(key + " : " + value.size()); +// }); + Map>>> result = new HashMap<>(); + servicetype.forEach((key,value)->{ + Map>> site = value.stream().collect(Collectors.groupingBy(item -> item.get("site"))); + result.put(key,site); + }); + + + List> list = new ArrayList<>(); + System.out.println("result===="+ JSON.toJSONString(result)); + result.forEach((key,value)->{ + AtomicInteger serviceSize = new AtomicInteger(); + value.forEach((itemKey,itemValue)->{ + serviceSize.addAndGet(itemValue.size()); + list.addAll(itemValue); + }); + // System.out.println(key + " : " + serviceSize.get()); + // value.forEach((itemKey,itemValue)->{ + // System.out.println("\t\t" + itemKey + " : " + itemValue.size()); + // }); + }); +// System.out.println(JSON.toJSONString(list)); + + + //从第11行开始插入明细表中的数据 + int fisrtCowCol_0 = 10; + int lastCowCol_1; + double sum4 = 0d; + double sum5 = 0d; + double sum8 = 0d; + double sum9 = 0d; + + int i = 0; + for (int cowNum=10;cowNum<10+ list.size();cowNum++){ + Row row = sheet_Cost.createRow(cowNum); + Map map = list.get(i); + for (int colNum=0;colNum<11;colNum++){ + Cell cell = row.createCell(colNum); + if (colNum==0){ + cell.setCellStyle(setWordStyle(workbook)); + String servicetypeId = String.valueOf(map.get("servicetype")); + String getServiceTypeSql = "select pd_name from uf_pd_base_inf where id = ?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(getServiceTypeSql, servicetypeId); + logger.info("查询serviceType在数据库中的值的sql语句是否查询成功=="+b); + if (recordSet.next()){ + String pd_name = recordSet.getString("pd_name"); + cell.setCellValue(pd_name); + } + }else if (colNum==1){ + String value = String.valueOf(map.get("site")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(String.valueOf(map.get("site"))); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum ==2){ + String itemId = String.valueOf(map.get("item"));//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?";//uf_pd_item_inf + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + if (!itemId.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(item); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 3){ + String value = String.valueOf(map.get("servicedescription")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); +// String valueHtml = stringEscapeUtils.escapeHtml(value);//此处完成国际特殊字符转译 + String newValue = value.replace(" ", " "); + cell.setCellValue(newValue); + + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum== 4){ + try { + String value = String.valueOf(map.get("costplustaxotc"));//costplustaxotc + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1){ + double newValue = Double.parseDouble(value); + sum4 += newValue; + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + }else{ + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + }else if (colNum==5){ + String value = String.valueOf(map.get("costplustaxmrc"));//costplustaxmrc + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1){ + double newValue = Double.parseDouble(value); + sum5 += newValue; + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + }else{ + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum ==6){ + String vatrateotc = String.valueOf(map.get("vatrateotc"));//vatrateotc + double value; + if (!vatrateotc.equals("")){ + if ((int)Double.parseDouble(vatrateotc)!=-1) { + value = Double.parseDouble(vatrateotc); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value*100)+"%"); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum==7){ + String vatratemrc = String.valueOf(map.get("vatratemrc"));//vatratemrc + double value; + if (!vatratemrc.equals("")){ + if ((int)Double.parseDouble(vatratemrc)!=-1) { + value = Double.parseDouble(vatratemrc); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value*100)+"%"); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 8){ + + String value = String.valueOf(map.get("costexcludingtaxotc"));//costexcludingtaxotc + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1) { + double newValue = Double.parseDouble(value); + sum8 += newValue; + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum ==9){ + String value = String.valueOf(map.get("costexcludingtaxmrc"));//costexcludingtaxmrc + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1) { + double newValue = Double.parseDouble(value); + sum9 += newValue; + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else{ + String value = String.valueOf(map.get("remark")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + } + } + i++; + } + + //合并第一列单元格 + for (Map.Entry>> entry : servicetype.entrySet()) { + Object key = entry.getKey(); + List> value = entry.getValue(); + System.out.println(key + " : " + value.size()); + int size = value.size(); + lastCowCol_1 = fisrtCowCol_0 + size; + if (size>1){ + sheet_Cost.addMergedRegion(new CellRangeAddress(fisrtCowCol_0, lastCowCol_1-1, 0, 0)); + } + fisrtCowCol_0 = lastCowCol_1; + } + + //合并明细表里面第二列单元格 + + int firstRowCol_1 = 10; + int lastRowCol_1; + for (Map.Entry>>> entry : result.entrySet()) { + Object key = entry.getKey(); + Map>> value = entry.getValue(); + AtomicInteger serviceSize = new AtomicInteger(); + value.forEach((itemKey, itemValue) -> { + serviceSize.addAndGet(itemValue.size()); + list.addAll(itemValue); + }); + System.out.println(key + " : " + serviceSize.get()); + for (Map.Entry>> e : value.entrySet()) { + Object itemKey = e.getKey(); + List> itemValue = e.getValue(); + System.out.println("\t\t" + itemKey + " : " + itemValue.size()); + int size = itemValue.size(); + lastRowCol_1 = size + firstRowCol_1; + if (size>1){ + sheet_Cost.addMergedRegion(new CellRangeAddress(firstRowCol_1, lastRowCol_1-1, 1, 1)); + } + firstRowCol_1 = lastRowCol_1; + } + } + + //写入统计第四列内容 Grand Total + Row row = sheet_Cost.createRow(fisrtCowCol_0); + Cell cellGrandToTal_3 = row.createCell(3); + cellGrandToTal_3.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_3.setCellValue("Grand Total"); + + Cell cellGrandToTal_4 = row.createCell(4); + Cell cellGrandToTal_5 = row.createCell(5); + Cell cellGrandToTal_8 = row.createCell(8); + Cell cellGrandToTal_9 = row.createCell(9); + + cellGrandToTal_4.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_5.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_8.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_9.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_4.setCellValue(sum4); + cellGrandToTal_5.setCellValue(sum5); + cellGrandToTal_8.setCellValue(sum8); + cellGrandToTal_9.setCellValue(sum9); + + + String[] finalyString = new String[]{ + "Note:", + "1.This price is for budgetary use only and subject to SST's final confirmation;", + "2.OTC stands for one time charge and MRC stands for monthly recurring charge.", + "3. The price is exclusive of any in-house wiring charge which may be needed in customer's building.", + "4. In case the resources of the local telecom operator at the customer premises can not meet the requirement of the Service in such spot, customer will assume the additional engineering cost.", + "5.A PSTN line should be provided by the customer at each location for out-of-band access to the managed CPE;", + "6.Managed CPE contains router installation, configuring, on-going MA (subject to the actual site addresses) and helpdesk support;", + "7. There is no SLA for the performance of Internet access;", + "8. The early termination penalty is 100% of the monthly charges of remaining contract period.", + "9. Customer acknowledges and agrees that SST is entitled to withdraw, revoke or terminate this quotation for convenience at any time upon written notice to Customer due to applicable policy " + + "adjustment which is relevant to SST’s cost led by the authority or any other government agencies, such as tariff increase, even if Customer had received or confirmed this quotation. SST will reissue the quotation with updated OTC and MRC to Customer at its request.", + }; + + int finalyCow = fisrtCowCol_0+2; + int j=0; + for (int cowNum = finalyCow;cowNum获取其他产品uf_other_export表中的数据,渲染到sheet2---Quotation中 + * @Author hcy + * @Date 2023/2/9 15:49 + */ +public class SheetQuotationPOI extends SetCellStylePOI{ + + Logger logger = Util.getLogger(); + + + /** + *

将数据库中的数据放入sheet2---Quotation中

+ * @param workbook,split + * @return void + * @author hcy + * @Date 2023/2/9 15:50 + */ + public void setQuotationSheet(Workbook workbook, String[] split){ + + try { + Sheet sheet_Quotation = workbook.createSheet(); + workbook.setSheetName(1,"Quotation"); + + + String[] tableFiled = new String[]{"Customer Name", "Service Provider", "Contract Term(in months)", "Currency Used", "Issueing Date", "Expiration Date"}; + List systemFiled = new ArrayList<>(); + String sql_other_export_db = "select * from uf_other_export where id = ?"; + RecordSet rs = new RecordSet(); + rs.executeQuery(sql_other_export_db,split[0]); + while (rs.next()){ + String customername = rs.getString("customername"); + systemFiled.add(customername);//Customer Name + systemFiled.add("SST");//Service Provider + systemFiled.add(rs.getString("contractterminmonths"));//Contract Term(in months) + systemFiled.add("RMB");//Currency Used + //系统当前时间 + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Date date = new Date(System.currentTimeMillis()); + systemFiled.add(formatter.format(date));//Issueing Date + //系统当前时间再往后推30天 + Calendar currentdate = Calendar.getInstance(); + //在这里进行加30天(ps:周六周日也算在里边了) + currentdate.add(Calendar.DATE, 30); + //得到最后的时间 + Date finalday = currentdate.getTime(); + systemFiled.add(formatter.format(finalday));//Expiration Date + } + //将1-6行固定值数据放入excel中 + for (int cowNum = 0; cowNum < 6; cowNum++) { + Row row = sheet_Quotation.createRow(cowNum); + Cell cell0col = row.createCell(0); + Cell cell1col = row.createCell(1); + cell0col.setCellStyle(setNolyWordStyle(workbook,true)); + cell0col.setCellValue(tableFiled[cowNum]); + cell1col.setCellStyle(setNolyWordStyle(workbook,true)); + cell1col.setCellValue(systemFiled.get(cowNum)); + } + //将8行数据放入excel中 + //Quotation Breakdown: + Row row7 = sheet_Quotation.createRow(7); + Cell cell7_0 = row7.createCell(0); + cell7_0.setCellStyle(setNolyWordStyle(workbook,true)); + cell7_0.setCellValue("Quotation Breakdown:"); + Cell cell7_1 = row7.createCell(1); + cell7_1.setCellStyle(setNolyWordStyle(workbook,true)); + cell7_1.setCellValue("Quotation Breakdown:"); + sheet_Quotation.addMergedRegion(new CellRangeAddress(7,7,0,1)); + + //将第九行第十行前四列放入excel中并合并单元格 + //1Service Type 2.Site 3.Item 4.Service Description + String[] string8_4 = new String[]{"Service Type","Site","Item","Service Description"}; + Row row8 = sheet_Quotation.createRow(8); + Row row9 = sheet_Quotation.createRow(9); + for (int colNum = 0;colNum<4;colNum++){ + Cell cell8 = row8.createCell(colNum); + cell8.setCellStyle(setWordStyle(workbook,true)); + cell8.setCellValue(string8_4[colNum]); + Cell cell9 = row9.createCell(colNum); + cell9.setCellStyle(setWordStyle(workbook,true)); + cell9.setCellValue(""); + sheet_Quotation.addMergedRegion(new CellRangeAddress(8,9,colNum,colNum)); + } + //Price Plus tax VAT rate % Price Excluding tax + //第九行三个字段并合并字段 5-10列 + Cell cell8_4 = row8.createCell(4); + cell8_4.setCellValue("Price Plus tax"); + cell8_4.setCellStyle(setWordStyle(workbook,true)); + Cell cell8_5 = row8.createCell(5); + cell8_5.setCellStyle(setWordStyle(workbook,true)); + sheet_Quotation.addMergedRegion(new CellRangeAddress(8,8,4,5)); + Cell cell8_6 = row8.createCell(6); + cell8_6.setCellValue("VAT rate %"); + cell8_6.setCellStyle(setWordStyle(workbook,true)); + Cell cell8_7 = row8.createCell(7); + cell8_7.setCellStyle(setWordStyle(workbook,true)); + sheet_Quotation.addMergedRegionUnsafe(new CellRangeAddress(8,8,6,7)); + Cell cell8_8 = row8.createCell(8); + cell8_8.setCellStyle(setWordStyle(workbook,true)); + cell8_8.setCellValue("Price Excluding tax"); + Cell cell8_9 = row8.createCell(9); + cell8_9.setCellStyle(setWordStyle(workbook,true)); + sheet_Quotation.addMergedRegionUnsafe(new CellRangeAddress(8,8,8,9)); + + //OTC MRC OTC MRC OTC MRC + //写入10行第5列到第10列的内容 + Cell cell9_4 = row9.createCell(4); + cell9_4.setCellStyle(setWordStyle(workbook,true)); + cell9_4.setCellValue("OTC"); + Cell cell9_5 = row9.createCell(5); + cell9_5.setCellStyle(setWordStyle(workbook,true)); + cell9_5.setCellValue("MRC"); + Cell cell9_6 = row9.createCell(6); + cell9_6.setCellStyle(setWordStyle(workbook,true)); + cell9_6.setCellValue("OTC"); + Cell cell9_7 = row9.createCell(7); + cell9_7.setCellStyle(setWordStyle(workbook,true)); + cell9_7.setCellValue("MRC"); + Cell cell9_8 = row9.createCell(8); + cell9_8.setCellStyle(setWordStyle(workbook,true)); + cell9_8.setCellValue("OTC"); + Cell cell9_9 = row9.createCell(9); + cell9_9.setCellStyle(setWordStyle(workbook,true)); + cell9_9.setCellValue("MRC"); + //写入remark 9行11列 并合并9行10行 + Cell cell8_10 = row8.createCell(10); + cell8_10.setCellStyle(setWordStyle(workbook,true)); + cell8_10.setCellValue("Remark"); + Cell cell9_10 = row9.createCell(10); + cell9_10.setCellStyle(setWordStyle(workbook,true)); + cell9_10.setCellValue(""); + sheet_Quotation.addMergedRegion(new CellRangeAddress(8,9,10,10)); + + //开始写入动态表格中的内容 + DemoMapper mapper = Util.getMapper(DemoMapper.class); + List idList = Arrays.asList(split); + + List> maps = mapper.selectAll(idList); + Map>> servicetype = maps.stream() + .collect(Collectors.groupingBy(item -> item.get("servicetype")));//servicetype的种类,以及每个种类的数量 +// System.out.println("servicetype===="+JSON.toJSONString(servicetype)); +// servicetype.forEach((key,value)->{ +// System.out.println(key + " : " + value.size()); +// }); + Map>>> result = new HashMap<>(); + servicetype.forEach((key,value)->{ + Map>> site = value.stream().collect(Collectors.groupingBy(item -> item.get("site"))); + result.put(key,site); + }); + + + List> list = new ArrayList<>(); + System.out.println("result===="+ JSON.toJSONString(result)); + result.forEach((key,value)->{ + AtomicInteger serviceSize = new AtomicInteger(); + value.forEach((itemKey,itemValue)->{ + serviceSize.addAndGet(itemValue.size()); + list.addAll(itemValue); + }); + // System.out.println(key + " : " + serviceSize.get()); + // value.forEach((itemKey,itemValue)->{ + // System.out.println("\t\t" + itemKey + " : " + itemValue.size()); + // }); + }); +// System.out.println(JSON.toJSONString(list)); + + + //从第11行开始插入明细表中的数据 + int fisrtCowCol_0 = 10; + int lastCowCol_1; + double sum4 = 0d; + double sum5 = 0d; + double sum8 = 0d; + double sum9 = 0d; + + int i = 0; + for (int cowNum=10;cowNum<10+ list.size();cowNum++){ + Row row = sheet_Quotation.createRow(cowNum); + Map map = list.get(i); + for (int colNum=0;colNum<11;colNum++){ + Cell cell = row.createCell(colNum); + if (colNum==0){ + cell.setCellStyle(setWordStyle(workbook)); + String servicetypeId = String.valueOf(map.get("servicetype")); + String getServiceTypeSql = "select pd_name from uf_pd_base_inf where id = ?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(getServiceTypeSql, servicetypeId); + logger.info("查询serviceType在数据库中的值的sql语句是否查询成功=="+b); + if (recordSet.next()){ + String pd_name = recordSet.getString("pd_name"); + cell.setCellValue(pd_name); + } + }else if (colNum==1){ + String value = String.valueOf(map.get("site")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(String.valueOf(map.get("site"))); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum ==2){ + String itemId = String.valueOf(map.get("item"));//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?";//uf_pd_item_inf + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + if (!itemId.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(item); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 3){ + String value = String.valueOf(map.get("servicedescription")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); +// String valueHtml = stringEscapeUtils.escapeHtml(value);//此处完成国际特殊字符转译 + String newValue = value.replace(" ", " "); + cell.setCellValue(newValue); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum== 4){ + try { + String value = String.valueOf(map.get("priceplustaxotc")); + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1){ + double newValue = Double.parseDouble(value); + sum4 += newValue; + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + }else{ + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + } + }else if (colNum==5){ + String value = String.valueOf(map.get("priceplustaxmrc")); + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1){ + double newValue = Double.parseDouble(value); + sum5 += newValue; + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + }else{ + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum ==6){ + String vatrateotc = String.valueOf(map.get("vatrateotc")); + double value; + if (!vatrateotc.equals("")){ + if ((int)Double.parseDouble(vatrateotc)!=-1) { + value = Double.parseDouble(vatrateotc); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value*100)+"%"); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum==7){ + String vatratemrc = String.valueOf(map.get("vatratemrc")); + double value; + if (!vatratemrc.equals("")){ + if ((int)Double.parseDouble(vatratemrc)!=-1) { + value = Double.parseDouble(vatratemrc); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value*100)+"%"); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 8){ + + String value = String.valueOf(map.get("priceexcludingtaxotc")); + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1) { + double newValue = Double.parseDouble(value); + sum8 += newValue; + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum ==9){ + String value = String.valueOf(map.get("priceexcludingtaxmrc")); + if (!value.equals("")){ + if ((int)Double.parseDouble(value)!=-1) { + double newValue = Double.parseDouble(value); + sum9 += newValue; + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(newValue); + } else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else{ + String value = String.valueOf(map.get("remark")); + if (!value.equals("")){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + } + } + i++; + } + + //合并第一列单元格 + for (Map.Entry>> entry : servicetype.entrySet()) { + Object key = entry.getKey(); + List> value = entry.getValue(); + System.out.println(key + " : " + value.size()); + int size = value.size(); + lastCowCol_1 = fisrtCowCol_0 + size; + if (size>1){ + sheet_Quotation.addMergedRegion(new CellRangeAddress(fisrtCowCol_0, lastCowCol_1-1, 0, 0)); + } + fisrtCowCol_0 = lastCowCol_1; + } + + //合并明细表里面第二列单元格 + + int firstRowCol_1 = 10; + int lastRowCol_1; + for (Map.Entry>>> entry : result.entrySet()) { + Object key = entry.getKey(); + Map>> value = entry.getValue(); + AtomicInteger serviceSize = new AtomicInteger(); + value.forEach((itemKey, itemValue) -> { + serviceSize.addAndGet(itemValue.size()); + list.addAll(itemValue); + }); + System.out.println(key + " : " + serviceSize.get()); + for (Map.Entry>> e : value.entrySet()) { + Object itemKey = e.getKey(); + List> itemValue = e.getValue(); + System.out.println("\t\t" + itemKey + " : " + itemValue.size()); + int size = itemValue.size(); + lastRowCol_1 = size + firstRowCol_1; + if (size>1){ + sheet_Quotation.addMergedRegion(new CellRangeAddress(firstRowCol_1, lastRowCol_1-1, 1, 1)); + } + firstRowCol_1 = lastRowCol_1; + } + } + + //写入统计第四列内容 Grand Total + Row row = sheet_Quotation.createRow(fisrtCowCol_0); + Cell cellGrandToTal_3 = row.createCell(3); + cellGrandToTal_3.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_3.setCellValue("Grand Total"); + + Cell cellGrandToTal_4 = row.createCell(4); + Cell cellGrandToTal_5 = row.createCell(5); + Cell cellGrandToTal_8 = row.createCell(8); + Cell cellGrandToTal_9 = row.createCell(9); + + cellGrandToTal_4.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_5.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_8.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_9.setCellStyle(setNolyWordStyle(workbook,true)); + cellGrandToTal_4.setCellValue(sum4); + cellGrandToTal_5.setCellValue(sum5); + cellGrandToTal_8.setCellValue(sum8); + cellGrandToTal_9.setCellValue(sum9); + + + String[] finalyString = new String[]{ + "Note:", + "1.This price is for budgetary use only and subject to SST's final confirmation;", + "2.OTC stands for one time charge and MRC stands for monthly recurring charge.", + "3. The price is exclusive of any in-house wiring charge which may be needed in customer's building.", + "4. In case the resources of the local telecom operator at the customer premises can not meet the requirement of the Service in such spot, customer will assume the additional engineering cost.", + "5.A PSTN line should be provided by the customer at each location for out-of-band access to the managed CPE;", + "6.Managed CPE contains router installation, configuring, on-going MA (subject to the actual site addresses) and helpdesk support;", + "7. There is no SLA for the performance of Internet access;", + "8. The early termination penalty is 100% of the monthly charges of remaining contract period.", + "9. Customer acknowledges and agrees that SST is entitled to withdraw, revoke or terminate this quotation for convenience at any time upon written notice to Customer due to applicable policy adjustment which is relevant to SST’s cost led by the authority or any other government agencies, such as tariff increase, even if Customer had received or confirmed this quotation. SST will reissue the quotation with updated OTC and MRC to Customer at its request.", + }; + + int finalyCow = fisrtCowCol_0+2; + int j=0; + for (int cowNum = finalyCow;cowNum escapeMap = new HashMap<>(); + + static { + escapeMap.put("&", "&"); + escapeMap.put("<", "<"); + escapeMap.put(">", ">"); + escapeMap.put("\"", """); + escapeMap.put("'", "'"); + escapeMap.put("/", "/"); + escapeMap.put(" "," ");//空格 + } + + public static String escapeHtml(String input) { + if (input == null) { + return null; + } + StringBuilder output = new StringBuilder(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + String escape = escapeMap.get(Character.toString(c)); + if (escape != null) { + output.append(escape); + } else { + output.append(c); + } + } + return output.toString(); + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/CheckProjectNameApi.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/CheckProjectNameApi.java new file mode 100644 index 0000000..7330989 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/CheckProjectNameApi.java @@ -0,0 +1,109 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.wechat.util.Utils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

校验项目报价记录查询中,项目名称是否是同一个

+ * @Author hcy + * @Date 2023/2/17 14:55 + */ +@Path("/projectorder") +public class CheckProjectNameApi { + + private final Logger logger = Util.getLogger(); + /** + *

接收前端传过来的主表id

+ * @param request,response + * @return String + * @author hcy + * @Date 2023/2/17 15:36 + */ + @POST + @Path("/checkProjectNameApi") + @Produces(MediaType.APPLICATION_JSON) + public String checkProjectNameApi(@Context HttpServletRequest request, @Context HttpServletResponse response) { + try { + String ids = request.getParameter("ids"); + RecordSet recordSet = new RecordSet(); + String[] split = ids.split(","); + List> projectLists = new ArrayList<>(); + for (String s : split) { + Map map = new HashMap<>(); + String getDataSql = "select project_name,order_record,servicetype from uf_project_order where id = ?"; + if (recordSet.executeQuery(getDataSql,s)){ + while (recordSet.next()){ + String project_name = recordSet.getString("project_name");//项目名称 + map.put("project_name",project_name); + String order_record = recordSet.getString("order_record");//报价记录 + map.put("order_record",order_record); + String servicetype = Utils.null2String(recordSet.getString("servicetype"));//服务类型 + map.put("servicetype",servicetype); + projectLists.add(map); + } + } + } + + List> lists = new ArrayList<>();//用于存放其他产品中customername,currencyused,contractterminmonths,contractmodel + for (Map projectList : projectLists) { + String project_name = Util.null2String(projectList.get("project_name")); + String order_record = Util.null2String(projectList.get("order_record")); + String servicetype = Utils.null2String(projectList.get("servicetype")); + String getCheckData = "select customername,currencyused,contractterminmonths,contractmodel from uf_other_export where lcid =?"; + boolean b = recordSet.executeQuery(getCheckData, order_record); + logger.info("查询验证信息sql是否执行"+b); + if ((!servicetype.equals("373")) && (!servicetype.equals("384"))){ + Map map = new HashMap<>(); + String customername = recordSet.getString("customername");//系统-客户名 + String currencyused = recordSet.getString("currencyused"); + String contractterminmonths = recordSet.getString("contractterminmonths"); + String contractmodel = recordSet.getString("contractmodel"); + map.put("customername",customername); + map.put("currencyused",currencyused); + map.put("contractterminmonths",contractterminmonths); + map.put("contractmodel",contractmodel); + map.put("project_name",project_name); + lists.add(map); + } + } + logger.info("lists==="+lists); + List> collect1 = lists.stream().distinct().collect(Collectors.toList()); + String checkTag; + String getMsgSql = "select * from uf_cus_dev_config where only_mark = ?"; + recordSet.executeQuery(getMsgSql,"exportProject"); + recordSet.next(); + String msg = recordSet.getString("param_value"); + //校验项目名称是否一致 + if (collect1.size()==1) { + checkTag = "1"; + return ApiResult.success(checkTag); + }else { + checkTag = "0"; + return ApiResult.success(checkTag,msg); + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("异常==="+e); + return ApiResult.success(0,"代码异常"); + } + + + } + +} \ No newline at end of file diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi.java new file mode 100644 index 0000000..a821163 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi.java @@ -0,0 +1,294 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelAVPNService; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelL3NSService; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelOtherService; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl.ExportExcelAVPNServiceImpl; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl.ExportExcelL3NSServiceImpl; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl.ExportExcelOtherServiceImpl; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.wechat.util.Utils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.text.SimpleDateFormat; +import java.util.*; + +@Path("/export") +public class ExportExcelApi { + + /** + * 用于处理AVPN的excel导出的业务处理 + */ + private final ExportExcelAVPNService exportExcelAVPNService = new ExportExcelAVPNServiceImpl(); + /** + * 用于处理L3NS的excel导出的业务处理 + */ + private final ExportExcelL3NSService exportExcelL3NSService = new ExportExcelL3NSServiceImpl(); + + /** + * 用于处理other的excel导出的业务处理 + */ + private final ExportExcelOtherService exportExcelOtherService = new ExportExcelOtherServiceImpl(); + + /** + * 日志处理 + */ + private final Logger logger = Util.getLogger(); + + + + + @GET + @Path("/exportProjectExcel") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportProjectExcel(@Context HttpServletRequest request, @Context HttpServletResponse response) { + + String ids = request.getParameter("ids"); + RecordSet recordSet = new RecordSet(); + String[] split = ids.split(","); + List datas = Arrays.asList(split); + List> listMapData = new ArrayList<>();//用于存放每一条数据的报价记录、serviceType + + for (String data : datas) { + Map map = new HashMap<>(); + String getDataSql = "select * from uf_project_order where id = ?"; + if (recordSet.executeQuery(getDataSql,data)){ + while (recordSet.next()){ + String id = Utils.null2String(recordSet.getString("id"));//id + map.put("id",id); + String servicetype = Utils.null2String(recordSet.getString("servicetype"));//Service Type + map.put("servicetype",servicetype); + String order_record = Utils.null2String(recordSet.getString("order_record"));//报价记录 + map.put("order_record",order_record); + listMapData.add(map); + } + } + + } + String otherIds = ""; + String projectId = ""; + for (Map map : listMapData) { + int servicetype = Integer.parseInt(String.valueOf(map.get("servicetype"))); + //AVPN=373 L3NS=384 + if (servicetype == 373){ + String AVPNIds = String.valueOf(map.get("id")); + String AVPNFileName = getAVPNFileName(AVPNIds); + //表名:uf_avpn_export + //uf_project_order.order_record = uf_avpn_export.lcid + String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); + String get_uf_avpn_export_id = "select id from uf_avpn_export where lcid = ?"; + if (recordSet.executeQuery(get_uf_avpn_export_id,order_record)){ + recordSet.next(); + String id = recordSet.getString("id"); + Response response1 = exportExcelAVPNService.exportExcelAVPN(id,AVPNFileName); + return response1; + } + }else if (servicetype == 384){ + //数据库表名:uf_L3NS_exportt + String L3NSIds = Utils.null2String(map.get("id")); + String L3NSFileName = getL3NSFileName(L3NSIds); + String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); + String get_uf_L3NS_exportt_id = "select id from uf_L3NS_exportt where lcid = ?"; + if (recordSet.executeQuery(get_uf_L3NS_exportt_id,order_record)){ + recordSet.next(); + String id = recordSet.getString("id"); + Response response1 = exportExcelL3NSService.exportExcelL3NSService(id,L3NSFileName); + return response1; + } + }else { //servicetype == other + //数据库表名:uf_other_export + String projectOrderId = Utils.null2String(map.get("id")); + projectId += projectOrderId + ","; + String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); + String get_uf_other_export = "select id from uf_other_export where lcid = ?"; + if (recordSet.executeQuery(get_uf_other_export,order_record)&&recordSet.next()){ + String id = Utils.null2String(recordSet.getString("id")); + if(!id.equals("")){ + otherIds += id +","; + } + } + + } + } + //处理导出other-excel的业务 + if (!otherIds.equals("")){{ + String otherFileName = getOtherFileName(projectId); + Response response1 = exportExcelOtherService.exportExcelOther(otherIds,otherFileName); + return response1; + }} + + return Response.ok(ApiResult.error("出现错误,错误原因: " ), MediaType.TEXT_PLAIN).build(); + + } + + /** + *

获取导出AVPN类型的excel的文件名称

+ * @param AVPNIds:数据id + * @return String + * @author hcy + * @Date 2023/2/28 12:20 + */ + public String getAVPNFileName(String AVPNIds) { + + //“CMR” + customer_name + (select uf_project_inf .project_name from uf_project_inf where id = 导出数据表.project_name) + project_code + 日期(导出的日期) + //CMR + //project_name + String fileName = "SST Discount Request Form"; + RecordSet rs = new RecordSet(); + String getDBFrom_uf_project_order = "select order_record,project_name from uf_project_order where id = ?"; + Map map = new HashMap<>(); + if (rs.executeQuery(getDBFrom_uf_project_order,AVPNIds) && rs.next()){ + String order_record = Utils.null2String(rs.getString("order_record")); + map.put("order_record",order_record); + String project_name = Utils.null2String(rs.getString("project_name"));//项目名称 + map.put("project_name",project_name); + } + String get_customer_name = "select * from uf_avpn_export where lcid = ?"; + if (rs.executeQuery(get_customer_name,map.get("order_record")) && rs.next()){ + String customer_name = Utils.null2String(rs.getString("customer_name")); + if (!customer_name.equals("")){ + fileName += "-"+customer_name;//拼接customer_name + } + } + + String get_project_name = "select project_name,project_code from uf_project_inf where id = ?"; + if (rs.executeQuery(get_project_name,map.get("project_name")) && rs.next()){ + String project_name = Utils.null2String(rs.getString("project_name")); + String project_code = Utils.null2String(rs.getString("project_code")); + if (!project_name.equals("")){ + fileName += "-"+project_name; + } + if (!project_code.equals("")){ + fileName += "-"+project_code; + } + } + + //获取系统当前时间 + String currentTime = this.getCurrentTime(); + fileName += "-"+currentTime+".xlsx"; + //拼接后缀名 + + + return fileName; + } + /** + *

获取导出L3NS类型的excel的文件名称

+ * @param L3NSIds:数据id + * @return String:文件名称 + * @author hcy + * @Date 2023/2/28 12:22 + */ + public String getL3NSFileName(String L3NSIds) { + + //“CMR” + customer_name + (select uf_project_inf .project_name from uf_project_inf where id = 导出数据表.project_name) + project_code + 日期(导出的日期) + //CMR + //project_name + String fileName = "SST Discount Request Form"; + RecordSet rs = new RecordSet(); + String getDBFrom_uf_project_order = "select order_record,project_name from uf_project_order where id = ?"; + Map map = new HashMap<>(); + if (rs.executeQuery(getDBFrom_uf_project_order,L3NSIds) && rs.next()){ + String order_record = Utils.null2String(rs.getString("order_record")); + map.put("order_record",order_record); + String project_name = Utils.null2String(rs.getString("project_name"));//项目名称 + map.put("project_name",project_name); + } + String get_customer_name = "select * from uf_L3NS_exportt where lcid = ?"; + if (rs.executeQuery(get_customer_name,map.get("order_record")) && rs.next()){ + String customer_name = Utils.null2String(rs.getString("customer_name")); + if (!customer_name.equals("")){ + fileName += "-"+customer_name;//拼接customer_name + } + } + + String get_project_name = "select project_name,project_code from uf_project_inf where id = ?"; + if (rs.executeQuery(get_project_name,map.get("project_name")) && rs.next()){ + String project_name = Utils.null2String(rs.getString("project_name")); + String project_code = Utils.null2String(rs.getString("project_code")); + if (!project_name.equals("")){ + fileName += "-"+project_name; + } + if (!project_code.equals("")){ + fileName += "-"+project_code; + } + } + + //获取系统当前时间 + String currentTime = this.getCurrentTime(); + fileName += "-"+currentTime+".xlsx"; + + return fileName; + } + /** + *

获取导出OtherIds类型的excel的文件名称

+ * @param OtherIds:数据id + * @return String:文件名称 + * @author hcy + * @Date 2023/2/28 12:23 + */ + public String getOtherFileName(String OtherIds) { + + //“CMR” + customer_name + (select uf_project_inf .project_name from uf_project_inf where id = 导出数据表.project_name) + project_code + 日期(导出的日期) + //CMR + //project_name + String[] split = OtherIds.split(","); + String fileName = "CMR"; + RecordSet rs = new RecordSet(); + String getDBFrom_uf_project_order = "select order_record,project_name from uf_project_order where id = ?"; + Map map = new HashMap<>(); + if (rs.executeQuery(getDBFrom_uf_project_order,split[0]) && rs.next()){ + String order_record = Utils.null2String(rs.getString("order_record")); + map.put("order_record",order_record); + String project_name = Utils.null2String(rs.getString("project_name"));//项目名称 + map.put("project_name",project_name); + } + String get_customer_name = "select * from uf_other_export where lcid = ?"; + if (rs.executeQuery(get_customer_name,map.get("order_record")) && rs.next()){ + String customer_name = Utils.null2String(rs.getString("customername")); + if (!customer_name.equals("")){ + fileName += "-"+customer_name;//拼接customer_name + } + } + + String get_project_name = "select project_name,project_code from uf_project_inf where id = ?"; + if (rs.executeQuery(get_project_name,map.get("project_name")) && rs.next()){ + String project_name = Utils.null2String(rs.getString("project_name")); + String project_code = Utils.null2String(rs.getString("project_code")); + if (!project_name.equals("")){ + fileName += "-"+project_name; + } + if (!project_code.equals("")){ + fileName += "-"+project_code; + } + } + + //获取系统当前时间 + String currentTime = this.getCurrentTime(); + fileName += "-"+currentTime+".xlsx"; + + return fileName; + } + /** + *

返回系统当前日期时间

+ * @param + * @return String 当前日期 + * @author hcy + */ + public String getCurrentTime(){ + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi_copy.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi_copy.java new file mode 100644 index 0000000..025617d --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/controller/ExportExcelApi_copy.java @@ -0,0 +1,216 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.controller;//package com.api.hcy_xintiantongxin.projectorder.controller; +// +//import aiyh.utils.ApiResult; +//import aiyh.utils.Util; +//import com.api.hcy_xintiantongxin.projectorder.service.ExportExcelAVPNService; +//import com.api.hcy_xintiantongxin.projectorder.service.ExportExcelL3NSService; +//import com.api.hcy_xintiantongxin.projectorder.service.ExportExcelOtherService; +//import com.api.hcy_xintiantongxin.projectorder.service.impl.ExportExcelAVPNServiceImpl; +//import com.api.hcy_xintiantongxin.projectorder.service.impl.ExportExcelL3NSServiceImpl; +//import com.api.hcy_xintiantongxin.projectorder.service.impl.ExportExcelOtherServiceImpl; +//import org.apache.log4j.Logger; +//import weaver.conn.RecordSet; +//import weaver.wechat.util.Utils; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import javax.ws.rs.GET; +//import javax.ws.rs.Path; +//import javax.ws.rs.Produces; +//import javax.ws.rs.core.Context; +//import javax.ws.rs.core.MediaType; +//import javax.ws.rs.core.Response; +//import javax.ws.rs.core.StreamingOutput; +//import java.io.FileInputStream; +//import java.io.IOException; +//import java.io.InputStream; +//import java.io.UnsupportedEncodingException; +//import java.nio.charset.StandardCharsets; +//import java.util.*; +//import java.util.zip.ZipEntry; +//import java.util.zip.ZipOutputStream; +// +//import static com.caucho.server.log.AccessLog.BUFFER_SIZE; +// +//@Path("/export") +//public class ExportExcelApi_copy { +// +//* +// * 用于处理AVPN的excel导出的业务处理 +// +// +// private final ExportExcelAVPNService exportExcelAVPNService = new ExportExcelAVPNServiceImpl(); +//* +// * 用于处理L3NS的excel导出的业务处理 +// +// +// private final ExportExcelL3NSService exportExcelL3NSService = new ExportExcelL3NSServiceImpl(); +// +//* +// * 用于处理other的excel导出的业务处理 +// +// +// private final ExportExcelOtherService exportExcelOtherService = new ExportExcelOtherServiceImpl(); +// +//* +// * 日志处理 +// +// +// private final Logger logger = Util.getLogger(); +// +// +// +// +// @GET +// @Path("/exportProjectExcel") +// @Produces(MediaType.APPLICATION_OCTET_STREAM) +// public Response exportProjectExcel(@Context HttpServletRequest request, @Context HttpServletResponse response) { +// +// String ids = request.getParameter("ids"); +// RecordSet recordSet = new RecordSet(); +// String[] split = ids.split(","); +// List datas = Arrays.asList(split); +// List> listMapData = new ArrayList<>();//用于存放每一条数据的报价记录、serviceType +// +// for (String data : datas) { +// Map map = new HashMap<>(); +// String getDataSql = "select * from uf_project_order where id = ?"; +// if (recordSet.executeQuery(getDataSql,data)){ +// while (recordSet.next()){ +// String servicetype = Utils.null2String(recordSet.getString("servicetype"));//Service Type +// map.put("servicetype",servicetype); +// String order_record = Utils.null2String(recordSet.getString("order_record"));//报价记录 +// map.put("order_record",order_record); +// listMapData.add(map); +// } +// } +// +// } +// +// logger.info("listMapData==="+listMapData); +// StreamingOutput output = outputStream -> { +// ZipOutputStream zipOut = new ZipOutputStream(outputStream); +// String otherIds = ""; +// for (Map map : listMapData) { +// int servicetype = Integer.parseInt(String.valueOf(map.get("servicetype"))); +// //AVPN=373 L3NS=384 +// if (servicetype == 373){ +// //表名:uf_avpn_export +// //uf_project_order.order_record = uf_avpn_export.lcid +// String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); +// String get_uf_avpn_export_id = "select id from uf_avpn_export where lcid = ?"; +// if (recordSet.executeQuery(get_uf_avpn_export_id,order_record)){ +// recordSet.next(); +// String id = recordSet.getString("id"); +// InputStream inputStream = exportExcelAVPNService.exportExcelAVPN(id); +// //文件名称的获取规则为:“CMR” + customer_name + (select uf_project_inf .project_name from uf_project_inf where id = 导出数据表.project_name) + project_code + 日期(导出的日期) +// String filename = exportExcelAVPNService.getFilename(id); +// toZip(inputStream,zipOut,filename); +// } +// }else if (servicetype == 384){ +// //数据库表名:uf_L3NS_exportt +// String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); +// String get_uf_L3NS_exportt_id = "select id from uf_L3NS_exportt where lcid = ?"; +// if (recordSet.executeQuery(get_uf_L3NS_exportt_id,order_record)){ +// recordSet.next(); +// String id = recordSet.getString("id"); +// InputStream inputStream = exportExcelL3NSService.exportExcelL3NSService(id); +// String filename = exportExcelL3NSService.getFilename(id); +// toZip(inputStream,zipOut,filename); +// } +// }else { //servicetype == other +// //数据库表名:uf_other_export +// String order_record = Utils.null2String(String.valueOf(map.get("order_record"))); +// String get_uf_other_export = "select id from uf_other_export where lcid = ?"; +// if (recordSet.executeQuery(get_uf_other_export,order_record)&&recordSet.next()){ +// String id = Utils.null2String(recordSet.getString("id")); +// if(!id.equals("")){ +// otherIds += id +","; +// } +// } +// } +// } +// //处理导出other-excel的业务 +// if (!otherIds.equals("")){{ +// InputStream inputStream = exportExcelOtherService.exportExcelOther(otherIds); +// String filename = exportExcelOtherService.getFilename(otherIds); +// toZip(inputStream,zipOut,filename); +// }} +// //关闭流 +// zipOut.flush(); +// zipOut.close(); +// outputStream.flush(); +// outputStream.close(); +// }; +// +// try { +// return Response.ok(output, MediaType.APPLICATION_OCTET_STREAM).type("application/zip") +// .header("Content-Disposition", "attachment;filename=\"" + +// new String("项目报价记录".getBytes("GBK"), StandardCharsets.ISO_8859_1) + ".zip" + "\"").build(); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// return Response.ok(ApiResult.error("出现错误,错误原因:"+e),MediaType.TEXT_PLAIN).build(); +// } +// } +//* +// *

添加压缩文件

+// * @param is,zipOut,fileName +// * @return +// * @author hcy +// * @Date 2023/2/18 16:59 +// +// +// private static void addToZip(InputStream is, ZipOutputStream zipOut, String fileName) { +// try{ +// ZipEntry entry = new ZipEntry(fileName); +// zipOut.putNextEntry(entry); +// int len; +// byte[] buffer = new byte[1024]; +// while ((len = is.read(buffer)) > 0) { +// zipOut.write(buffer, 0, len); +// } +// zipOut.closeEntry(); +// is.close(); +// }catch (Exception e){ +// e.printStackTrace(); +// } +// } +// +// +//* +// *

压缩成ZIP

+// * @param is,out,filename +// * @return +// * @author hcy +// * @Date 2023/2/23 18:29 +// +// +// public static void toZip(InputStream is, ZipOutputStream zos,String fileName) throws RuntimeException { +// long start = System.currentTimeMillis(); +// try { +// byte[] buf = new byte[BUFFER_SIZE]; +// zos.putNextEntry(new ZipEntry(fileName)); +// int len; +// FileInputStream is1 = (FileInputStream) is; +// while ((len = is1.read(buf)) != -1) { +// zos.write(buf, 0, len); +// } +// zos.finish(); +// zos.closeEntry(); +// is1.close(); +// +// long end = System.currentTimeMillis(); +// System.out.println("压缩完成,耗时:" + (end - start) + " ms"); +// } catch (Exception e) { +// throw new RuntimeException("zip error from ZipUtils", e); +// } finally { +// if (zos != null) { +// try { +// zos.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// } +//} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelAVPNService.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelAVPNService.java new file mode 100644 index 0000000..aa2a8df --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelAVPNService.java @@ -0,0 +1,20 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service; + +import javax.ws.rs.core.Response; + +/** + *

用于导出AVPN--excel

+ * @Author hcy + * @Date 2023/2/18 14:59 + */ +public interface ExportExcelAVPNService { + + /** + *

传入数据id,查询当前数据id对应的数据库数据,然后插入到excel表单中,返回response

+ * @param ids :数据id,用逗号分割 + * @return Response + * @author hcy + * @Date 2023/2/18 15:04 + */ + public Response exportExcelAVPN(String ids,String AVPNFileName); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelL3NSService.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelL3NSService.java new file mode 100644 index 0000000..2331eb7 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelL3NSService.java @@ -0,0 +1,20 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service; + +import javax.ws.rs.core.Response; + +/** + *

用于处理导出L3NS.xlsx业务处理

+ * @Author hcy + * @Date 2023/2/18 15:11 + */ +public interface ExportExcelL3NSService { + + /** + *

传入数据id,查询当前数据id对应的数据库数据,然后插入到excel表单中,返回response

+ * @param ids :数据id,用逗号隔开 + * @return Response + * @author hcy + * @Date 2023/2/18 15:13 + */ + public Response exportExcelL3NSService(String ids,String L3NSFileName); +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelOtherService.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelOtherService.java new file mode 100644 index 0000000..3fc526c --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/ExportExcelOtherService.java @@ -0,0 +1,26 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service; + +import javax.ws.rs.core.Response; + +/** + *

用于导出other--excel业务处理

+ * @Author hcy + * @Date 2023/2/18 14:59 + */ +public interface ExportExcelOtherService { + + /** + *

传入数据id,查询当前数据id对应的数据库数据,然后插入到excel表单中,返回InputStream

+ * @param ids :数据id,用逗号分割 + * @return InputStream + * @author hcy + * @Date 2023/2/18 15:04 + */ + public Response exportExcelOther(String ids,String otherFileName); + + + + + + +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelAVPNServiceImpl.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelAVPNServiceImpl.java new file mode 100644 index 0000000..8ad13b8 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelAVPNServiceImpl.java @@ -0,0 +1,678 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelAVPNService; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.*; + +public class ExportExcelAVPNServiceImpl implements ExportExcelAVPNService { + + private final Logger logger = Util.getLogger(); + + public Response exportExcelAVPN(String ids,String AVPNName) { + logger.info("ExportExcelAVPNServiceImpl-----开始"); + Response build = null; + Response.ResponseBuilder header = null; + try { + //查询到 uf_avpn_export AVPN导出表中的一条数据的ids + RecordSet rs = new RecordSet(); + StreamingOutput output = null; + + String sql_AVPN_db = "select * from uf_avpn_export where id = ?"; + rs.executeQuery(sql_AVPN_db, ids); + + //创建一个工作簿 + Workbook workbook = new XSSFWorkbook(); + String[] dbFiled = new String[10]; + String mainId = ""; + + while (rs.next()) { + //查询到uf_avpn_export表的id作为查询明细表的mainid + mainId = rs.getString("id"); + String pd_nameId = rs.getString("pd_name");//uf_pd_base_inf 得到的pd_name是字段的id + RecordSet recordSet = new RecordSet(); + String getPd_nameByIdSql = "select pd_name from uf_pd_base_inf where id =?"; + boolean b1 = recordSet.executeQuery(getPd_nameByIdSql, pd_nameId); + + logger.info("查询pd_namesql语句是否成功==" + b1); + if (recordSet.next()) { + String pd_name = recordSet.getString("pd_name");//查询到pd_name的值 + dbFiled[0] = pd_name; + } + String billing_model = rs.getString("billing_model"); + if (billing_model.equals("0")){ + billing_model = "Assignment Model Billing in China"; + } + dbFiled[1] = billing_model; + String customer_name = rs.getString("customer_name"); + dbFiled[2] = customer_name; + String ecrm_opportunity = rs.getString("ecrm_opportunity"); + dbFiled[3] = ecrm_opportunity; + String igloo = rs.getString("igloo"); + dbFiled[4] = igloo; + String terms = rs.getString("terms"); + dbFiled[5] = terms; + String att_lead_pricer = rs.getString("att_lead_pricer"); + dbFiled[6] = att_lead_pricer; + String requestjustificationoptional = rs.getString("requestjustificationoptional"); + dbFiled[7] = requestjustificationoptional; + String specialrequesttosstoptional = rs.getString("specialrequesttosstoptional"); + dbFiled[8] = specialrequesttosstoptional; + String sst_contact = rs.getString("sst_contact"); + dbFiled[9] = sst_contact; + } + //表单字段 + String[] tableFiled = new String[]{"Service Type", "Billing Model", "Customer Name", "ECRM Opportunity#", "Igloo #", "Contract Term (in months)", "AT&T Lead Pricer", "Request Justification (optional)", "Special Request to SST (Optional)", "SST Contact"}; + //明细表字段 + String[] mergerDetailTableFiled = new String[]{"Site ID", "Description", "Bandwidth", "OTC in RMB", "MRC in RMB"}; + + //创建一个工作表sheet + Sheet sheet = workbook.createSheet(); + workbook.setSheetName(0, "AVPN表单"); + sheet.autoSizeColumn(1, true); + //写入数据 //写入1-11行第一列 第二列数据 + for (int rowNum = 1; rowNum < 11; rowNum++) { + Row row = sheet.createRow(rowNum); + Cell cell0 = row.createCell(0); + cell0.setCellStyle(this.setWordStyle(workbook, true)); + cell0.setCellValue(tableFiled[rowNum - 1]); + Cell cell1 = row.createCell(1); + cell1.setCellStyle(setWordStyle(workbook, true)); + cell1.setCellValue(dbFiled[rowNum - 1]); + } + Row row12 = sheet.createRow(12);//第13行 + Cell cell12_11 = row12.createCell(11); + cell12_11.setCellStyle(setWordStyle(workbook, true)); + cell12_11.setCellValue("Default Assignment Model-Billing in China in RMB"); + Cell cell12_12 = row12.createCell(12); + cell12_12.setCellStyle(setNolyBorderStyle(workbook)); + sheet.addMergedRegion(new CellRangeAddress(12, 12, 11, 12)); + + //设置14行到15行前5列内容 + Row row13 = sheet.createRow(13); + Row row14 = sheet.createRow(14); + for (int colNum = 0; colNum < 5; colNum++) { + Cell cell = row13.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook, true)); + cell.setCellValue(mergerDetailTableFiled[colNum]); + Cell cell1 = row14.createCell(colNum); + cell1.setCellStyle(setWordStyle(workbook, true)); + cell1.setCellValue(mergerDetailTableFiled[colNum]); + sheet.addMergedRegion(new CellRangeAddress(13, 14, colNum, colNum)); + } + + + + //设置14行第六列到第13列的内容 + String[] mergerDetailTableFiled02 = new String[]{"Discount Requested (%)", "Discount SST approved (%)", "Net Price to AT&T Customer", "Royalty to SST without Tax(contra-revenue)"}; + Cell cell13_5 = row13.createCell(5); + cell13_5.setCellStyle(setWordStyle(workbook, true)); + cell13_5.setCellValue(mergerDetailTableFiled02[0]); + Cell cell113_6 = row13.createCell(6); + cell113_6.setCellStyle(setWordStyle(workbook, true)); + cell113_6.setCellValue(mergerDetailTableFiled02[0]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 5, 6)); + + + Cell cell13_7 = row13.createCell(7); + cell13_7.setCellStyle(setWordStyle(workbook, true)); + cell13_7.setCellValue(mergerDetailTableFiled02[1]); + Cell cell13_8 = row13.createCell(8); + cell13_8.setCellStyle(setWordStyle(workbook, true)); + cell13_8.setCellValue(mergerDetailTableFiled02[1]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 7, 8)); + + Cell cell13_9 = row13.createCell(9); + cell13_9.setCellStyle(setWordStyle(workbook, true)); + cell13_9.setCellValue(mergerDetailTableFiled02[2]); + Cell cell13_10 = row13.createCell(10); + cell13_10.setCellStyle(setWordStyle(workbook, true)); + cell13_10.setCellValue(mergerDetailTableFiled02[2]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 9, 10)); + + Cell cell13_11 = row13.createCell(11); + cell13_11.setCellStyle(setWordStyle(workbook, true)); + cell13_11.setCellValue(mergerDetailTableFiled02[3]); + Cell cell13_12 = row13.createCell(12); + cell13_12.setCellStyle(setWordStyle(workbook, true)); + cell13_12.setCellValue(mergerDetailTableFiled02[3]); + sheet.addMergedRegion(new CellRangeAddress(13, 13, 11, 12)); + + + //设置15行第六列到第13列的内容 + String[] mergerDetailTableFiled03 = new String[]{"OTC", "MRC", "OTC", "MRC", "OTC in RMB", "MRC in RMB", "OTC in RMB", "MRC in RMB"}; + for (int colNum = 5; colNum < 13; colNum++) { + Cell cell = row14.createCell(colNum); + for (int num = 0; num < 8; num++) { + cell.setCellStyle(setWordStyle(workbook, true)); + cell.setCellValue(mergerDetailTableFiled03[num]); + } + } + + + List> siteMap = new ArrayList<>();//用来存放site的类型和每个site的状态 + + String getSiteSql = "select site ,count(site) siteNum from uf_avpn_export_dt1 where mainId =? group by site ;"; + RecordSet rs02 = new RecordSet(); + boolean b = rs02.executeQuery(getSiteSql, mainId); + logger.info("查询site,以及site的数量的sql语句===" + b); + + while (rs02.next()) { + HashMap map = new HashMap<>(); + String site = rs02.getString("site"); + String siteNum = rs02.getString("siteNum"); + map.put(site, siteNum); + siteMap.add(map);//将site的类型和每个site的类型的个数放到siteList数组中,用来循环遍历再放入单元格中 + } + int firstCow = 15;//从第15行开始写入明细表,固定死 + int finalyCow = 0; + + + Double sum9 = 0D; + Double sum10 = 0D; + Double sum11 = 0D; + Double sum12 = 0D; + for (Map map : siteMap) { + Set siteKeySet = map.keySet(); + List> detailDateList = new ArrayList(); + int cowLength = 0;//每一个site类型的数据的长度 + for (String s1 : siteKeySet) { + cowLength = Integer.parseInt(map.get(s1));//每一个site类型的数据的长度 + String getDetailDataSql = "select * from uf_avpn_export_dt1 where mainId =? and site = ?"; + rs02.executeQuery(getDetailDataSql, mainId, s1); + while (rs02.next()) { + String site = rs02.getString("site");//Site ID + String itemId = rs02.getString("Item");//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?"; + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + + String categoryId = rs02.getString("Category");//Bandwidth + String getCategoryByIdSql = "select category from uf_pd_category_inf where id = ?"; + boolean b3 = recordSet1.executeQuery(getCategoryByIdSql, categoryId); + logger.info("查询categorySql是否执行成功==" + b3); + String category = ""; + if (recordSet1.next()) { + category = recordSet1.getString("category"); + } + String otc_price = rs02.getString("otc_price");//OTC in RMB + String mrc_price = rs02.getString("mrc_price");//MRC in RMB + String otcdiscountrequest = rs02.getString("otcdiscountrequest");//Discount Requested (%) OTC + String mrcdiscountrequest = rs02.getString("mrcdiscountrequest");//Discount Requested (%) MRC + String otcdiscountapproved = rs02.getString("otcdiscountapproved");//Discount SST approved (%) OTC + String mrcdiscountapproved = rs02.getString("mrcdiscountapproved");//Discount SST approved (%)MRC + String otc_tariff = rs02.getString("otc_tariff");//Net Price to AT&T Customer(OTC in RMB) + String mrc_tariff = rs02.getString("mrc_tariff");//Net Price to AT&T Customer(MRC in RMB) + String otc_scale = rs02.getString("otc_scale");//Royalty to SST without Tax (contra-revenue)(OTC in RMB) + String mrc_scale = rs02.getString("mrc_scale");//Royalty to SST without Tax (contra-revenue)(MRC in RMB) + ArrayList list = new ArrayList<>(); + list.add(site);//list.add(site); + list.add(item); + list.add(category); + list.add(otc_price); + list.add(mrc_price); + list.add(otcdiscountrequest); + list.add(mrcdiscountrequest); + list.add(otcdiscountapproved); + list.add(mrcdiscountapproved); + list.add(otc_tariff); + list.add(mrc_tariff); + list.add(otc_scale); + list.add(mrc_scale); + detailDateList.add(list); + } + } + Double amount9 = 0D;//用来统计每一个site种类的 Grand-Total(RMB) + Double amount10 = 0D; + Double amount11 = 0D; + Double amount12 = 0D; + //得到list类型的数据、有得到每种site类型的数据长度 + //开始向excel中导入明细表中的数据 + int i = 0;//用它来增加detailDateList的下标 + for (int cowNum = firstCow; cowNum < firstCow + cowLength; cowNum++) { + Row row = sheet.createRow(cowNum); + for (int colNum = 0; colNum < 13; colNum++) { + if (colNum == 9) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount9 = Double.valueOf(amount9) + value; + sum9 += value; + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else{ + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 10) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount10 = amount10 + value; + sum10 += value; + + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + } + } else if (colNum == 11) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount11 = amount11 + value; + sum11 += value; + + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 12) { + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + amount12 = amount12 + value; + sum12 += value; + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + + if (colNum == 5 || colNum == 6 || colNum == 7 || colNum == 8) { + Cell cell = row.createCell(colNum); + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue( (int)(value*100) + "%"); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + else if (colNum == 0||colNum==1||colNum==2){ + Cell cell = row.createCell(colNum); + String value = String.valueOf(detailDateList.get(i).get(colNum)); + if (value!=""){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + }else if (colNum == 3||colNum==4){ + String s = String.valueOf(detailDateList.get(i).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + Cell cell = row.createCell(colNum); + cell.setCellType(CellType.NUMERIC); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + } + i++; + } + //合并单元格 + int lastCow = firstCow + cowLength; + + if (cowLength > 1) { + sheet.addMergedRegion(new CellRangeAddress(firstCow, lastCow - 1, 0, 0)); + } + //开始写入Sub-Total(RMB) + Row rowSubTotal = sheet.createRow(lastCow); + for (int colNum = 8; colNum < 13; colNum++) { + if (colNum == 8) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue("Sub-Total(RMB)"); + } else if (colNum == 9) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount9); + } else if (colNum == 10) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount10); + } else if (colNum == 11) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount11); + } else if (colNum == 12) { + Cell cellSubToTal = rowSubTotal.createCell(colNum); + cellSubToTal.setCellStyle(setNolyWordStyle(workbook, true)); + cellSubToTal.setCellValue(amount12); + } + } + + firstCow = firstCow + cowLength + 1; + finalyCow = firstCow; + }//处理插入数据以及合并单元格 + //处理明细表最后一行的统计情况 + Row row_Grand_Total_RMB = sheet.createRow(finalyCow); + for (int colNum = 8; colNum < 13; colNum++) { + if (colNum == 8) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue("Grand-Total(RMB)"); + } else if (colNum == 9) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum9); + } else if (colNum == 10) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum10); + } else if (colNum == 11) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum11); + } else if (colNum == 12) { + Cell cell = row_Grand_Total_RMB.createCell(colNum); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + cell.setCellValue(sum12); + } + } + + //输入最下面的固定值 + String[] lastStringLeft = new String[]{ + "Notes:", + "1.This is NOT AT&T Pricing Approval. Forward this SST quote to your Lead ICB Pricer to issue the official Rate Letter", + "2.Access price must be quoted by SST, request SST as \"access provider\" in Igloo. Do NOT use quote from other access providers", + "3.Discount is only applicable to the demand set listed below, any changes in bandwidth/design/billing model, need to re-submit to SST and AT&T Pricer for approval", "" + + "4.Under in-country billing, AT&T must follow the discount% offered by SST. Do NOT deviate from the SST quoted discount.", + "5.SST can support repeatable discount for the same solution design(port/CDR/CPE) of same contract term which was approved already. Local Loop part are non-repeatable.", + "6.For ICB only - Royalty in columns L and M are contra-revenue,ICB to verify if BCRL captured these amount.", + "7.Save this SST approved quote to eCRM (without release) for record.", + "8.The quotation shall be exclusive of any applicable taxes and Customer shall pay all the taxes and charges relating to the payment if any. The VAT rate for CPE and related modules and license are 16%, the rest is 6%.", + "9.Thank you for considering SST, this engagement may be subject to a credit check, we appreciate your cooperation and look forward to doing business in the near future." + }; + int lastLineTag = finalyCow + 2;//固定值Note所在的行 + int k = 0;//用来增加lastStringLeft的下标 + for (int rowNum = lastLineTag; rowNum < lastLineTag + 10; rowNum++) { + Row row = sheet.createRow(rowNum); + Cell cell = row.createCell(0); + cell.setCellStyle(setNolyWordStyle(workbook,true)); + sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, 11)); + cell.setCellStyle(setTotalStyle(workbook,"微软雅黑",true,false,HorizontalAlignment.LEFT, VerticalAlignment.CENTER,false)); + cell.setCellValue(lastStringLeft[k]); + k++; + } + sheet.autoSizeColumn(0,true); + sheet.setColumnWidth(0,sheet.getColumnWidth(0)*8/10); + // 设置自动列宽 + for (int num = 1; num < 13; num++) { + sheet.autoSizeColumn(num,true); + sheet.setColumnWidth(num, (sheet.getColumnWidth(num))); + } + + + InputStream inputStream = workbookConvertorStream(workbook); + byte[] bytes = IOUtils.toByteArray(inputStream); + output = outputStream -> { + outputStream.write(bytes); + outputStream.close(); + }; + header = Response.ok(output,MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String(AVPNName.getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + + } catch (Exception e) { + e.printStackTrace(); + logger.error("导出excel错误:" + Util.getErrString(e)); + } + build = header.build(); + return build; + } + + /** + *

设置每个单元格样式:包含字体类型,字体是否加粗,是否包含边框,元素水平方向的位置,元素垂直方向的位置,是否设置元素的数据格式,

+ * @param + * @return + * @author hcy + * @Date 2023/2/13 18:08 + */ + public static CellStyle setTotalStyle(Workbook workbook,String type,boolean setBold,boolean setBorder,HorizontalAlignment horizontalDirection,VerticalAlignment verticalAlignmentDirection ,boolean setDataFormat){ + //new一个cellStyle用于设置每一个单元格样式 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName(type); + //设置字体是否加粗 + font.setBold(setBold); + //将字体样式渲染cellStyle对象中 + cellStyle.setFont(font); + if (setBorder == true){ + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + } + + //水平居中 + cellStyle.setAlignment(horizontalDirection); + //垂直居中 + cellStyle.setVerticalAlignment(verticalAlignmentDirection); + + //此处设置数据格式 + if(setDataFormat == true){ + DataFormat dataFormat = workbook.createDataFormat(); + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + } + + return cellStyle; + } + /** + *

返回系统当前日期时间

+ * @param + * @return String 当前日期 + * @author hcy + */ + public String getCurrentTime(){ + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + String currentTime = dateFormat.format(date); + return currentTime; + } + + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyBorderStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + return cellStyle; + } + + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + /** + * 设置单元格格式为数值型 + * @param workbook + * @return + */ + public static CellStyle setCellToNumber(Workbook workbook){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelL3NSServiceImpl.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelL3NSServiceImpl.java new file mode 100644 index 0000000..6ff06c2 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelL3NSServiceImpl.java @@ -0,0 +1,571 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelL3NSService; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import weaver.conn.RecordSet; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.*; + +public class ExportExcelL3NSServiceImpl implements ExportExcelL3NSService { + + private final Logger logger = Util.getLogger(); + + public Response exportExcelL3NSService(String ids,String L3NSFileName) { + Response build = null; + Response.ResponseBuilder header = null; + try { + //查询到 uf_L3NS_exportt AVPN导出表中的一条数据的ids + RecordSet rs = new RecordSet(); + StreamingOutput output = null; + + + String sql_L3NS_db = "select * from uf_L3NS_exportt where id = ?"; + boolean b = rs.executeQuery(sql_L3NS_db, ids); + logger.info("是否查询uf_L3NS_exportt=="+b); + + //创建一个工作簿 + XSSFWorkbook workbook = new XSSFWorkbook(); + String[] dbFiled = new String[13]; + String[] tableFiled = new String[]{"Service Type", "Billing Model", "Customer Name", "ROME Opportunity #", "ROME WR#", "Request Type", "Original SST Order NO", "Request Justification", "Special Request to SST", "Target Service Provision date","ATT Order number:","SST Pre-Sales Contact","Date of SST Approval"}; + + String mainId = ""; + + //得到主表数据,用来写入excel中的固定值 + while (rs.next()) { + //查询到uf_avpn_export表的id作为查询明细表的mainid + mainId = rs.getString("id"); + + + String pd_nameId = rs.getString("pd_name");//uf_pd_base_inf 得到的pd_name是字段的id + RecordSet recordSet = new RecordSet(); + String getPd_nameByIdSql = "select pd_name from uf_pd_base_inf where id =?"; + boolean b1 = recordSet.executeQuery(getPd_nameByIdSql, pd_nameId); + + logger.info("查询pd_namesql语句是否成功==" + b1); + if (recordSet.next()) { + String pd_name = recordSet.getString("pd_name");//查询到pd_name的值 + dbFiled[0] = pd_name; + } + String billingmodel = rs.getString("billingmodel");//Billing Model===billingmodel + if (billingmodel.equals("0")){ + billingmodel = "Custom Subcontract"; + }else if (billingmodel == null){ + billingmodel = ""; + } + dbFiled[1] = billingmodel; + String customer_name = rs.getString("customer_name");//Customer Name===customer_name + dbFiled[2] = customer_name; + String rome_opportunity = rs.getString("rome_opportunity");//ROME Opportunity #====rome_opportunity + dbFiled[3] = rome_opportunity; + String rome_wr = rs.getString("rome_wr");//ROME WR#====rome_wr + dbFiled[4] = rome_wr; + String request_type = rs.getString("request_type");//Request Type====request_type + dbFiled[5] = request_type; + String original_sst_order_no = rs.getString("original_sst_order_no");//Original SST Order NO====original_sst_order_no + dbFiled[6] = original_sst_order_no; + String requestjustificationoptional = rs.getString("requestjustificationoptional");//Request Justification====requestjustificationoptional + dbFiled[7] = requestjustificationoptional; + String specialrequesttosstoptional = rs.getString("specialrequesttosstoptional");//Special Request to SST====specialrequesttosstoptional + dbFiled[8] = specialrequesttosstoptional; + String targetserviceprovisiondate = rs.getString("targetserviceprovisiondate");//Target Service Provision date====targetserviceprovisiondate + dbFiled[9] = targetserviceprovisiondate; + String attordernumber = rs.getString("attordernumber");//ATT Order number:====attordernumber + dbFiled[10] = attordernumber; + String sstpresalescontact = rs.getString("sstpresalescontact");//SST Pre-Sales Contact====sstpresalescontact + dbFiled[11] = sstpresalescontact; + String dateofsstapproval = rs.getString("dateofsstapproval");//Date of SST Approval====dateofsstapproval + dbFiled[12] = dateofsstapproval; + } + + //开始写入固定值 + Sheet sheet = workbook.createSheet(); + workbook.setSheetName(0, "L3NS表单"); + sheet.autoSizeColumn(1, true); + + for (int cowNum=1;cowNum<14;cowNum++){ + Row row = sheet.createRow(cowNum); + Cell cell0 = row.createCell(0); + cell0.setCellStyle(setWordStyle(workbook,true)); + cell0.setCellValue(tableFiled[cowNum-1]); + Cell cell1 = row.createCell(1); + cell1.setCellStyle(setWordStyle(workbook,true)); + cell1.setCellValue(dbFiled[cowNum-1]); + } + + Row row14 = sheet.createRow(14);//写入15行数据 + Cell cell14_0 = row14.createCell(0); + Cell cell114_1 = row14.createCell(1); + cell14_0.setCellStyle(setWordStyle(workbook,true)); + cell14_0.setCellValue("This Quote is valid for 180 days from \"Date of SST approval\""); + cell114_1.setCellStyle(setWordStyle(workbook,true)); + cell114_1.setCellValue("This Quote is valid for 180 days from \"Date of SST approval\""); + sheet.addMergedRegion(new CellRangeAddress(14, 14, 0, 1)); + + +// 写入18行,19行数据 +// Site ID Description Bandwidth OTC in RMB MRC in RMB + String[] detailFileds = new String[]{"Site ID", "Description","Bandwidth", "OTC in RMB", "MRC in RMB"}; + Row row17 = sheet.createRow(17); + Row row18 = sheet.createRow(18); + for (int colNum =0;colNum<5;colNum++){ + Cell cell = row17.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellStyle(setWordStyle(workbook,true)); + cell.setCellValue(detailFileds[colNum]); + } + for (int colNum =0;colNum<5;colNum++){ + Cell cell = row18.createCell(colNum); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellStyle(setWordStyle(workbook,true)); + cell.setCellValue(detailFileds[colNum]); + } + sheet.addMergedRegion(new CellRangeAddress(17, 18, 0, 0)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 1, 1)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 2, 2)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 3, 3)); + sheet.addMergedRegion(new CellRangeAddress(17, 18, 4, 4)); + +// Relief Requested (%) Relief SST approved (%) Tariff to SST (include VAT) 6-11列 +// OTC MRC OTC MRC OTC in RMB MRC in RMB + String[] detailFileds01 = new String[]{"Relief Requested (%)","Relief Requested (%)","Relief SST approved (%)","Relief SST approved (%)","Tariff to SST (include VAT)","Tariff to SST (include VAT)",""}; + String[] detailFileds02 = new String[]{"OTC","MRC","OTC","MRC","OTC in RMB","MRC in RMB"}; + int i=0; + int j = 0; + for(int colNum=5;colNum<11;colNum++){ + Cell cell17 = row17.createCell(colNum); + Cell cell18 = row18.createCell(colNum); + cell17.setCellValue(detailFileds01[i]); + cell17.setCellStyle(setWordStyle(workbook,true)); +// cell17.setCellStyle(setCellStyleFrame(workbook)); + + cell18.setCellValue(detailFileds02[j]); + cell18.setCellStyle(setWordStyle(workbook,true)); +// cell18.setCellStyle(setCellStyleFrame(workbook)); + i++; + j++; + } + //合并18行,19行 + sheet.addMergedRegion(new CellRangeAddress(17, 17, 5, 6)); + sheet.addMergedRegion(new CellRangeAddress(17, 17, 7, 8)); + sheet.addMergedRegion(new CellRangeAddress(17, 17, 9, 10)); + + + //开始写入20开始一直往下的动态表格中的内容 +// + + List> siteMap = new ArrayList<>();//用来存放site的类型和每个site的状态 + String getSiteSql = "select site ,count(site) siteNum from uf_L3NS_exportt_dt1 where mainId =? group by site ;"; + RecordSet rs02 = new RecordSet(); + boolean b1 = rs02.executeQuery(getSiteSql, mainId); + logger.info("查询site,以及site的数量的sql语句===" + b1); + while (rs02.next()) { + HashMap map = new HashMap<>(); + String site = rs02.getString("site"); + String siteNum = rs02.getString("siteNum"); + map.put(site, siteNum); + siteMap.add(map);//将site的类型和每个site的类型的个数放到siteList数组中,用来循环遍历再放入单元格中 + } + + int firstCow = 19;//从第15行开始写入明细表,固定死 + int finalyCow = 0; + Double sum10 = 0D;//用来统计所有site种类的Grand-Total (RMB) #REF! + Double sum9 = 0D; + for (Map map : siteMap) { + + Set siteKeySet = map.keySet(); + List> detailDateList = new ArrayList(); + int cowLength = 0;//每一个site类型的数据的长度 + for (String s1 : siteKeySet) { + cowLength = Integer.parseInt(map.get(s1));//每一个site类型的数据的长度 + String getDetailDataSql = "select * from uf_L3NS_exportt_dt1 where mainId =? and site = ?"; + rs02.executeQuery(getDetailDataSql,mainId,s1); + while(rs02.next()){ + //明细表数据 + String site = rs02.getString("site");//Site ID + String itemId = rs02.getString("Item");//Description + String getItemValueSql = "select item from uf_pd_item_inf where id =?";//uf_pd_item_inf + RecordSet recordSet1 = new RecordSet(); + boolean b2 = recordSet1.executeQuery(getItemValueSql, itemId); + logger.info("查询item值sql是否执行成功=" + b2); + String item = "";//从数据库中查询到item的值 + if (recordSet1.next()) { + item = recordSet1.getString("Item"); + } + String categoryId = rs02.getString("Category");//Bandwidth + String getCategoryByIdSql = "select category from uf_pd_category_inf where id = ?";//uf_pd_category_inf + boolean b3 = recordSet1.executeQuery(getCategoryByIdSql, categoryId); + logger.info("查询categorySql是否执行成功==" + b3); + String category = ""; + if (recordSet1.next()) { + category = recordSet1.getString("category"); + } + String otc_price = rs02.getString("otc_price");//OTC in RMB + String mrc_price = rs02.getString("mrc_price");//MRC in RMB + String otc_relief_requested = rs02.getString("otc_relief_requested");//Relief Requested (%)OTC + String mrc_relief_requested = rs02.getString("mrc_relief_requested");//Relief Requested (%)MRC + String otc_relief_approved = rs02.getString("otc_relief_approved");//Relief SST approved (%)OTC + String mrc_relief_approved = rs02.getString("mrc_relief_approved");//Relief SST approved (%)MRC + String otc_tariff = rs02.getString("otc_tariff");//Tariff to SST (include VAT)(OTC in RMB) + String mrc_tariff = rs02.getString("mrc_tariff");//Tariff to SST (include VAT)(MRC in RMB) + + ArrayList list = new ArrayList<>(); + list.add(site); + list.add(item); + list.add(category); + list.add(otc_price); + list.add(mrc_price); + list.add(otc_relief_requested); + list.add(mrc_relief_requested); + list.add(otc_relief_approved); + list.add(mrc_relief_approved); + list.add(otc_tariff); + list.add(mrc_tariff); + detailDateList.add(list); + } + } + Double amount10 = 0D;//用来统计每一个site种类的 Sub-Total + Double amount9 = 0D; + + //得到list类型的数据、有得到每种site类型的数据长度 + //开始向excel中导入明细表中的数据 + int k = 0;//用它来增加detailDateList的下标 + for (int cowNum = firstCow; cowNum < firstCow + cowLength; cowNum++) { + Row row = sheet.createRow(cowNum); + for (int colNum = 0; colNum < 11; colNum++) { + if (colNum == 10) { + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != ""){ + Double value = Double.valueOf(s); + amount10 = amount10 + value; + sum10 += value; + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + }else if (colNum == 9){ + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != "") { + Double value = Double.valueOf(s); + amount9 = amount9 + value; + sum9 += value; + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + if (colNum == 5 || colNum == 6 || colNum == 7 || colNum == 8) { + Cell cell = row.createCell(colNum); + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s!=""){ + Double value = Double.valueOf(s); + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue((int)(value * 100) + "%"); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } else if (colNum == 3 || colNum==4){ + String s = String.valueOf(detailDateList.get(k).get(colNum)); + if (s != ""){ + Double value = Double.valueOf(s); + Cell cell = row.createCell(colNum); + cell.setCellStyle(setCellToNumber(workbook)); + cell.setCellValue(value); + }else { + Cell cell = row.createCell(colNum); + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + } + else if (colNum == 0||colNum==1||colNum==2){ + Cell cell = row.createCell(colNum); + String value = String.valueOf(detailDateList.get(k).get(colNum)); + if (value!=""){ + cell.setCellStyle(setWordStyle(workbook)); + cell.setCellValue(value); + }else { + cell.setCellStyle(setNolyBorderStyle(workbook)); + } + + } + } + k++; + } + //合并单元格 + int lastCow = firstCow + cowLength; + + if (cowLength > 1) { + sheet.addMergedRegion(new CellRangeAddress(firstCow, lastCow - 1, 0, 0)); + } + //开始写入Sub-Total(RMB) + Row rowSubTotal = sheet.createRow(lastCow); + Cell cellSubToTal10 = rowSubTotal.createCell(10); + cellSubToTal10.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal10.setCellValue(amount10); + + Cell cellSubToTal9 = rowSubTotal.createCell(9); + cellSubToTal9.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal9.setCellValue(amount9); + + Cell cellSubToTal8 = rowSubTotal.createCell(8); + cellSubToTal8.setCellStyle(setNolyWordStyle(workbook,true)); + cellSubToTal8.setCellValue("Sub-Total"); + + + firstCow = firstCow + cowLength + 1; + finalyCow = firstCow; + + } + Row rowFinalyCow = sheet.createRow(finalyCow); + Cell cellFinalyCow_10 = rowFinalyCow.createCell(10); + cellFinalyCow_10.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_10.setCellValue(sum10); + Cell cellFinalyCow_9 = rowFinalyCow.createCell(9); + cellFinalyCow_9.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_9.setCellValue(sum9); + Cell cellFinalyCow_8 = rowFinalyCow.createCell(8); + cellFinalyCow_8.setCellStyle(setNolyWordStyle(workbook,true)); + cellFinalyCow_8.setCellValue("Grand-Total (RMB)"); + + + //输入最下面的固定值 + String[] lastStringright = new String[]{ + "Notes:", + "1.This form should be submitted by Lead ICB via a ROME WR to \"AP Pricing Team\". Do NOT send this direct to SST.", + "2.Fill in full Site Address or at least provide Name of City.", + "3.Tariff relief requested should be calculated by lead ICB. Do not fill in target AVPN discount as \"Relief Requested\".", + "4.VPN Tariff is port base pricing, no charges on COS or COS profile.", + "5.AT&T GAM will place order to SST on no longer than 12 months term for Custom Subcontract, regardless of the commitment term between end customer and AT&T.", + "6.China VAT is irrecoverable cost to AT&T under custom subcontracting billing. Ttariff and Access price listed below is VAT inclusive. ICB has to cater for this cost in deal financials.", + "7.Tariff Relief is only applicable to the demand set listed below, any changes in bandwidth/design/billing model, need to re-submit to SST for approval;", + }; + int lastLineTag = finalyCow + 2;//固定值Note所在的行 + int h=0; + for (int rowNum=lastLineTag;rowNum { + outputStream.write(bytes); + outputStream.close(); + }; + + header = Response.ok(output, MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String(L3NSFileName.getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + } catch (IOException e) { + logger.error("导出excel错误:" + Util.getErrString(e)); + e.printStackTrace(); + } + build = header.build(); + return build; + } + + + + + /** + *

返回系统当前日期时间

+ * @param + * @return String 当前日期 + * @author hcy + */ + public String getCurrentTime(){ + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + String currentTime = dateFormat.format(date); + return currentTime; + } + /** + * 设置每个单元格的样式,并且加粗字体,设置边框 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook, Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + + //设置样式对象,这里仅设置了边框属性 + + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setWordStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + return cellStyle; + } + + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyWordStyle(Workbook workbook,Boolean setBold) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + font.setBold(setBold); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } + + /** + * 只设置字体样式 + * + * @param workbook + * @return + */ + public static CellStyle setNolyBorderStyle(Workbook workbook) { + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + + return cellStyle; + } + + + + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + + /** + * 设置单元格格式为数值型 + * @param workbook + * @return + */ + public static CellStyle setCellToNumber(Workbook workbook){ + // 设置字体 + CellStyle cellStyle = workbook.createCellStyle(); + //设置样式对象,这里仅设置了边框属性 + cellStyle.setBorderBottom(BorderStyle.THIN); //下边框 + + cellStyle.setBorderLeft(BorderStyle.THIN);//左边框 + + cellStyle.setBorderTop(BorderStyle.THIN);//上边框 + + cellStyle.setBorderRight(BorderStyle.THIN);//右边框 + Font font = workbook.createFont(); + //颜色 + font.setColor(Font.COLOR_NORMAL); + //设置字体大小 + font.setFontHeightInPoints((short) 10); + //字体 + font.setFontName("微软雅黑"); + cellStyle.setFont(font); + DataFormat dataFormat = workbook.createDataFormat();//此处设置数据格式 + cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); + return cellStyle; + } +} diff --git a/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelOtherServiceImpl.java b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelOtherServiceImpl.java new file mode 100644 index 0000000..a5d0d02 --- /dev/null +++ b/src/main/java/com/api/chaoyang/he/hcy_xintiantongxin/projectorder/service/impl/ExportExcelOtherServiceImpl.java @@ -0,0 +1,113 @@ +package com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.impl; + +import aiyh.utils.Util; + +import com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel.SheetCMRPOI; +import com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel.SheetCostPOI; +import com.api.chaoyang.he.hcy_xintiantongxin.exportotherexcel.SheetQuotationPOI; +import com.api.chaoyang.he.hcy_xintiantongxin.projectorder.service.ExportExcelOtherService; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ExportExcelOtherServiceImpl implements ExportExcelOtherService { + + /** + *获取其他产品uf_other_export表中的数据,渲染到sheet1---CMR中 + */ + private final SheetCMRPOI sheetCMRPOI = new SheetCMRPOI(); + /** + * 获取其他产品uf_other_export表中的数据,渲染到sheet2---Quotation中 + */ + private final SheetQuotationPOI sheetQuotationPOI = new SheetQuotationPOI(); + /** + * 获取其他产品uf_other_export表中的数据,渲染到sheet3---Cost中 + */ + private final SheetCostPOI sheetCostPOI = new SheetCostPOI(); + + /** + * 日志 + */ + private final Logger logger = Util.getLogger(); + + public Response exportExcelOther(String ids,String otherFileName) { + logger.info("ExportExcelOtherServiceImpl----开始"); + Response build = null; + Response.ResponseBuilder header = null; + StreamingOutput output = null; + String[] split = ids.split(","); + + //创建一个工作簿 + Workbook workbook = new XSSFWorkbook(); + //创建一个工作表sheet + + sheetCMRPOI.setSheetCMR(workbook,split);//创建第一个sheet1---sheet_CMR,并向sheet中渲染内容 + sheetQuotationPOI.setQuotationSheet(workbook,split);//创建第二个sheet2---sheet_Quotation,并向sheet中渲染内容 + sheetCostPOI.getSheetCost(workbook,split);//创建第三个sheet3---sheet_Cost,并向sheet中渲染内容 + try { + InputStream inputStream = workbookConvertorStream(workbook); + byte[] bytes = IOUtils.toByteArray(inputStream); + output = outputStream -> { + outputStream.write(bytes); + outputStream.close(); + }; + header = Response.ok(output, MediaType.APPLICATION_OCTET_STREAM) + .type("application/xlsx") + .header("Content-Disposition", + "attachment; filename=\""+ new String(otherFileName.getBytes("GBK"), StandardCharsets.ISO_8859_1)+"\""); + + } catch (IOException e) { + e.printStackTrace(); + } + + build = header.build(); + return build; + } + + + + /** + *

返回系统当前日期时间

+ * @param + * @return String 当前日期 + * @author hcy + */ + public String getCurrentTime(){ + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + return dateFormat.format(date); + } + /** + * SXSSFWorkbook 转 InputStream + * @param workbook + * @return + */ + public static InputStream workbookConvertorStream(Workbook workbook) { + InputStream in = null; + try{ + //临时缓冲区 + ByteArrayOutputStream out = new ByteArrayOutputStream(); + //创建临时文件 + workbook.write(out); + byte [] bookByteAry = out.toByteArray(); + in = new ByteArrayInputStream(bookByteAry); + } + catch (Exception e){ + e.printStackTrace(); + } + return in; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/action/TbSheetAction.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/action/TbSheetAction.java new file mode 100644 index 0000000..65b70e5 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/action/TbSheetAction.java @@ -0,0 +1,51 @@ +package weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.action; + + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.service.TbSheetService; +import weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.service.impl.TbSheetServiceImpl; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.DetailTable; +import weaver.soa.workflow.request.DetailTableInfo; +import weaver.soa.workflow.request.RequestInfo; + +import java.util.List; +import java.util.Map; + +/** + *

询价单调达担当节点后附加操作

+ * @Author jiacheng.deng + * @Date 2022/12/27 14:41 + */ +public class TbSheetAction implements Action { + + private static TbSheetService tbSheetService = new TbSheetServiceImpl(); + private final Logger log = Util.getLogger(); + + /** + *

重写execute,获取明细数据

+ * @param requestInfo + * @return null + * @author jiacheng.deng + */ + @Override + public String execute(RequestInfo requestInfo) { + + try { + DetailTableInfo detailTableInfo = requestInfo.getDetailTableInfo(); + DetailTable[] detailTable = detailTableInfo.getDetailTable(); + List> detailData = tbSheetService.getDetailData(requestInfo); + for (Map stringObjectMap : detailData) { + String chbm = (String) stringObjectMap.get("chbm"); + if("".equals(chbm)){ + tbSheetService.insertTbDetailDataToLedger(stringObjectMap,requestInfo); + } + } + }catch (Exception e){ + log.error(Util.getErrString(e)); + } + + return null; + } +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/dto/TbDetailData.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/dto/TbDetailData.java new file mode 100644 index 0000000..6f8f8d6 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/dto/TbDetailData.java @@ -0,0 +1,60 @@ +package weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.dto; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class TbDetailData { + + + /** 存货编码 */ + public String chbm; + + /** 控制明细只读字段 */ + public int kzmxzdzd; + + /** 品类 */ + public int pl; + + /** 品名 */ + public String pm; + + /** 品牌 */ + public String pp; + + /** 规格型号 */ + public String ggxh; + + /** 计量单位 */ + public String jldw; + + /** 存货属性 */ + public int chzx; + + /** 未税单价*/ + public float wsdj; + + /** 税率 */ + public int sl; + + /** 含税单价 */ + public float hsdj; + + /** 供应商 */ + public String gys; + + /** 纳期 */ + public int ddhfqwnqt; + + /** 说明 */ + public String bz1; + + /** 附件*/ + public String fj; + + + +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/mapper/TbSheetMapper.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/mapper/TbSheetMapper.java new file mode 100644 index 0000000..afd13b8 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/mapper/TbSheetMapper.java @@ -0,0 +1,38 @@ +package weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.mapper; + +import aiyh.utils.annotation.recordset.Insert; +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + + +@SqlMapper +public interface TbSheetMapper { + + @Select("select id,chbm,kzmxzdzd,pl,pm,pp,ggxh,jldw,chzx,wsdj,sl,hsdj,ddhfqwnqt,bz1,fj from formtable_main_35_dt1 where mainid = #{mainid}") + List> getDetailDatas(@ParamMapper("mainid") String mainId); + + @Insert("insert into uf_chtz_tbtj(chbm,kzmxzdzd,pl,pm,pp,ggxh,jldw,chzx,wsdj,sl,hsdj,gys,ddhfqwnqt,bz1,fj) values(#{chbm},#{kzmxzdzd},#{pl},#{pm},#{pp},#{ggxh},#{jldw},#{chzx},#{wsdj},#{sl},#{hsdj},#{gys},#{ddhfqwnqt},#{bz1},#{fj})") + void insertDetailData(@ParamMapper("chbm") String chbm, + @ParamMapper("kzmxzdzd") int kzmxzdzd, + @ParamMapper("pl") int pl, + @ParamMapper("pm") String pm, + @ParamMapper("pp") String pp, + @ParamMapper("ggxh") String ggxh, + @ParamMapper("jldw") String jldw, + @ParamMapper("chzx") int chzx, + @ParamMapper("wsdj") float wsdj, + @ParamMapper("sl") int sl, + @ParamMapper("hsdj") float hsdj, + @ParamMapper("gys") String gys, + @ParamMapper("ddhfqwnqt") int ddhfqwnqt, + @ParamMapper("bz1") String bz1, + @ParamMapper("fj") String fj); + + @Select("select id from formtable_main_35 where requestid = #{requestid}") + String getMainTableId(@ParamMapper("requestid") String requestId); + +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/TbSheetService.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/TbSheetService.java new file mode 100644 index 0000000..8a26db6 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/TbSheetService.java @@ -0,0 +1,17 @@ +package weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.service; + +import weaver.soa.workflow.request.RequestInfo; + +import java.util.List; +import java.util.Map; + +public interface TbSheetService { + + + List> getDetailData(RequestInfo requestInfo); + + void insertTbDetailDataToLedger(Map stringObjectMap,RequestInfo requestInfo); + + String getMainTableId(String requestId); + +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/impl/TbSheetServiceImpl.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/impl/TbSheetServiceImpl.java new file mode 100644 index 0000000..33688ae --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/djc/tayota/boshoku/service/impl/TbSheetServiceImpl.java @@ -0,0 +1,111 @@ +package weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.service.impl; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSON; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.mapper.TbSheetMapper; +import weaver.chaoyang.he.fengtianfangzhi.djc.tayota.boshoku.service.TbSheetService; +import weaver.conn.RecordSet; +import weaver.soa.workflow.request.Property; +import weaver.soa.workflow.request.RequestInfo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

Action逻辑处理

+ * @Author jiacheng.deng + * @Date 2022/12/27 14:42 + */ +public class TbSheetServiceImpl implements TbSheetService { + private final Logger log = Util.getLogger(); + + TbSheetMapper tbSheetMapper = Util.getMapper(TbSheetMapper.class); + + /** + *

获取明细数据

+ * @param requestInfo + * @return list + * @author jiacheng.deng + */ + @Override + public List> getDetailData(RequestInfo requestInfo) { + + String mainId = this.getMainTableId(requestInfo.getRequestid()); + log.info("main table id is :" + mainId); + List> detailDatas = tbSheetMapper.getDetailDatas(mainId); + log.info(JSON.toJSONString(detailDatas)); + return detailDatas; + } + + + /** + *

将明细数据插入台账

+ * @param stringObjectMap,requestInfo + * @return void + * @author jiacheng.deng + */ + @Override + public void insertTbDetailDataToLedger(Map stringObjectMap,RequestInfo requestInfo) { + + List list = new ArrayList<>(); + + Map wfMainTableInfo = this.getWfMainTableInfo(requestInfo); + String gys = wfMainTableInfo.get("gys"); + log.info("main table gys is :" + gys); + + String chbm = "12345"; + + list.add(chbm); + list.add(stringObjectMap.get("kzmxzdzd")); + list.add(stringObjectMap.get("pl")); + list.add(stringObjectMap.get("pm")); + list.add(stringObjectMap.get("pp")); + list.add(stringObjectMap.get("ggxh")); + list.add(stringObjectMap.get("jldw")); + list.add(stringObjectMap.get("chzx")); + list.add(stringObjectMap.get("wsdj")); + list.add(stringObjectMap.get("sl")); + list.add(stringObjectMap.get("hsdj")); + list.add(gys); + list.add(stringObjectMap.get("ddhfqwnqt")); + list.add(stringObjectMap.get("bz1")); + list.add(stringObjectMap.get("fj")); + + String stringsql = "insert into uf_chtz_tbtj(chbm,kzmxzdzd,pl,pm,pp,ggxh,jldw,chzx,wsdj,sl,hsdj,gys,ddhfqwnqt,bz1,fj) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + RecordSet recordSet = new RecordSet(); + + boolean b = recordSet.executeUpdate(stringsql, list); + + log.info("recordSet是否执行:" + b); + + } + + /** + *

获取主表id

+ * @param requestId + * @return mainTableId + * @author jiacheng.deng + */ + @Override + public String getMainTableId(String requestId) { + String mainTableId = tbSheetMapper.getMainTableId(requestId); + return mainTableId; + } + + /** + * 获取流程主表数据 + * + * @param requestInfo 流程信息对象 + * @return Map key 字段名 value 字段值 + */ + public Map getWfMainTableInfo(RequestInfo requestInfo) { + Map map = new HashMap<>(); + for (Property property : requestInfo.getMainTableInfo().getProperty()) { + map.put(property.getName(), property.getValue()); + } + return map; + } +} diff --git a/src/main/java/weaver/chaoyang/he/fengtianfangzhi/tbsheet/action/TBSheetAction.java b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/tbsheet/action/TBSheetAction.java new file mode 100644 index 0000000..5cae4eb --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/fengtianfangzhi/tbsheet/action/TBSheetAction.java @@ -0,0 +1,130 @@ +package weaver.chaoyang.he.fengtianfangzhi.tbsheet.action; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TBSheetAction implements Action { + public Logger logger = Util.getLogger(); + @Override + public String execute(RequestInfo requestInfo) { + String requestid = requestInfo.getRequestid(); + String sql = "select id,gys from formtable_main_35 where requestId = ?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(sql, requestid); + logger.info("sql是否执行=="+b); + String mainId = ""; + String gys = ""; + if (recordSet.next()){ + mainId = recordSet.getString("id"); + gys = recordSet.getString("gys"); + } + + String detailSql = "select * from formtable_main_35_dt1 where mainId = ?"; + boolean b1 = recordSet.executeQuery(detailSql, mainId); + logger.info("b1是否执行=="+b1); + + List> listMap = new ArrayList<>(); + while (recordSet.next()){ + Map map = new HashMap<>(); + /** 存货编码 */ + String chbm = recordSet.getString("chbm"); + map.put("chbm",chbm); + /** 控制明细只读字段 */ + String kzmxzdzd = recordSet.getString("kzmxzdzd"); + map.put("kzmxzdzd",kzmxzdzd); + /** 品类 */ + String pl = recordSet.getString("pl"); + map.put("pl",pl); + /** 品名 */ + String pm = recordSet.getString("pm"); + map.put("pm",pm); + /** 品牌 */ + String pp = recordSet.getString("pp"); + map.put("pp",pp); + /** 规格型号 */ + String ggxh = recordSet.getString("ggxh"); + map.put("ggxh",ggxh); + /** 计量单位 */ + String jldw = recordSet.getString("jldw"); + map.put("jldw",jldw); + /** 存货属性 */ + String chzx = recordSet.getString("chzx"); + map.put("chzx",chzx); + /** 未税单价*/ + String wsdj = recordSet.getString("wsdj"); + map.put("wsdj",wsdj); + /** 税率 */ + String sl = recordSet.getString("sl"); + map.put("sl",sl); + /** 含税单价 */ + String hsdj = recordSet.getString("hsdj"); + map.put("hsdj",hsdj); +// /** 供应商 */ +// String gys = recordSet.getString("gys"); +// map.put("gys",gys); + /** 纳期 */ + String ddhfqwnqt = recordSet.getString("ddhfqwnqt"); + map.put("ddhfqwnqt",ddhfqwnqt); + /** 说明 */ + String bz11 = recordSet.getString("bz1"); + map.put("bz11",bz11); + /**附件*/ + String fj = recordSet.getString("fj"); + map.put("fj",fj); + /** + * id + */ + String id = recordSet.getString("id"); + map.put("gys",gys); + map.put("id",id); + + listMap.add(map); + } + + + + for (Map map : listMap) { + String chbm = String.valueOf(map.get("chbm")); + if (chbm.equals("")){ + List list = new ArrayList<>(); + String stringsql = "insert into uf_chtz_tbtj(chbm,pl,pm,pp,ggxh,jldw,chzx,wsdj,sl,hsdj,nqt,gys,sm,fj) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + chbm = "12345"; + list.add(chbm);//chbm-chbm + list.add(map.get("pl"));//pl-pl + list.add(map.get("pm"));//pm-pm + list.add(map.get("pp"));//pp-pp + list.add(map.get("ggxh"));//ggxh-ggxh + list.add(map.get("jldw"));//jldw-jldw + list.add(map.get("chzx"));//chzx-chzx + list.add(map.get("wsdj"));//wsdj-wsdj + list.add(map.get("sl"));//sl-sl + list.add(map.get("hsdj"));//hsdj-hsdj + list.add(map.get("qwnq"));//nqt-qwnq + list.add(map.get("gys"));//gys-gys + list.add(map.get("bz1"));//sm-bz1 + list.add(map.get("fj"));//fj-fj + + boolean b2 = recordSet.executeUpdate(stringsql, list); + logger.info("b2是否执行=="+b2); + String id = String.valueOf(map.get("id")); + if (b2){ + String afterSuccessInsertSql = "insert into formtable_main_35_dt1 (chbm) values (?) where id = ?"; + boolean b3 = recordSet.executeUpdate(afterSuccessInsertSql, chbm, id); + logger.info("b3是否执行=="+b3); + } + + } + } + + return Action.FAILURE_AND_CONTINUE; + } +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ChangeState.java b/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ChangeState.java new file mode 100644 index 0000000..ef8960f --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ChangeState.java @@ -0,0 +1,21 @@ +package weaver.chaoyang.he.formmode.customjavacode.modeexpand; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew; + +import java.util.Map; + +public class ChangeState extends AbstractModeExpandJavaCodeNew { + private Logger logger = Util.getLogger(); + @Override + public Map doModeExpand(Map map) { + + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + logger.info(key+":"+value); + } + return null; + } +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ModeExpandTemplate.java b/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ModeExpandTemplate.java new file mode 100644 index 0000000..6630187 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/customjavacode/modeexpand/ModeExpandTemplate.java @@ -0,0 +1,43 @@ +package weaver.chaoyang.he.formmode.customjavacode.modeexpand; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.formmode.customjavacode.AbstractModeExpandJavaCodeNew; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; + +import java.util.HashMap; +import java.util.Map; + +public class ModeExpandTemplate extends AbstractModeExpandJavaCodeNew { + private Logger logger = Util.getLogger(); + @Override + public Map doModeExpand(Map param) { + +// for (Map.Entry entry : map.entrySet()) { +// String key = entry.getKey(); +// Object value = entry.getValue(); +// logger.info(key+":"+value); +// } +// return null; + + Map result = new HashMap(); + try { + User user = (User)param.get("user"); + int billid = -1;//数据id + int modeid = -1;//模块id + RequestInfo requestInfo = (RequestInfo)param.get("RequestInfo"); + if(requestInfo!=null){ + billid = weaver.general.Util.getIntValue(requestInfo.getRequestid()); + modeid = weaver.general.Util.getIntValue(requestInfo.getWorkflowid()); + if(billid>0&&modeid>0){ + //------请在下面编写业务逻辑代码------ + } + } + } catch (Exception e) { + result.put("errmsg","自定义出错信息"); + result.put("flag", "false"); + } + return result; + } +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplate.java b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplate.java new file mode 100644 index 0000000..8a07e92 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplate.java @@ -0,0 +1,70 @@ +package weaver.chaoyang.he.formmode.interfaces.impl; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.file.ExcelParseForPOI; +import weaver.formmode.interfaces.ImportPreInterfaceForPOIAction; +import weaver.hrm.User; +import java.util.List; +import java.util.Map; + +/** + *

在excel导入前校验字段是否符合要求

+ * hcy + * 2023/4/13 8:50 + */ +public class CheckFieldTemplate implements ImportPreInterfaceForPOIAction { + + //日志 + private final Logger logger = Util.getLogger(); + //sql + private final CheckFieldTemplateMapper checkFieldTemplateMap = Util.getMapper(CheckFieldTemplateMapper.class); + + @Override + public String checkImportData(Map param, User user, ExcelParseForPOI excelParse) { + + + //从配置表中查询到数据 + List> configData = checkFieldTemplateMap.getConfigurationTable(); + logger.info("configData===="+configData); + int rowSum = excelParse.getRowSum("1", 2,Util.getIntValue(Util.null2String(configData.get(0).get("bgjtnyl")))); + logger.info("rowSum==="+rowSum); + //获取建模表单里面所有的数据 + List> dbDataMapList = checkFieldTemplateMap.getDBDataMapList(); + logger.info("dbDataMapList===="+dbDataMapList); + + logger.info("dbDataMapList===="+dbDataMapList); + for (Map configDatum : configData) { + int colNum = Util.getIntValue(Util.null2String(configDatum.get("bgjtnyl")));//具体那一列 + logger.info("colNum==="+colNum); + String targetValue = Util.null2String(configDatum.get("dyjmbdjtzdsjkm"));//建模表单中具体哪个字段名称 + logger.info("targetValue==="+targetValue); +// int rowSum = excelParse.getRowSum("1", 100,colNum); + + for (int i = 2; i < 2+rowSum; i++) { + //获取第 sheetindex 个sheet的第row行第col列的单元格的值 (下标都是从1开始) + String value = excelParse.getValue("1", i, colNum); + logger.info("value==="+value); + //开始比较数据是否正确 + boolean compareBool = compareValue(dbDataMapList,value,targetValue); + logger.info("compareBool==="+compareBool); + if (!compareBool) { + //书写校验逻辑 返回空则表示校验通过,否则验证不通过,不允许导入 + return "第"+i+"行第"+(colNum) + "列的数据不符合要求"; + } + } + } + + return ""; + } + + private Boolean compareValue(List> dbDataMapList, String value,String targetValue) { + for (Map map : dbDataMapList) { + String targetValueString = Util.null2String(map.get(targetValue)); + if (targetValueString.equals(value)){ + return true; + } + } + return false; + } +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplateMapper.java b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplateMapper.java new file mode 100644 index 0000000..81419e3 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/CheckFieldTemplateMapper.java @@ -0,0 +1,18 @@ +package weaver.chaoyang.he.formmode.interfaces.impl; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface CheckFieldTemplateMapper { + + @Select("select * from uf_dept") + List> getDBDataMapList(); + + + @Select("select * from uf_exceldrzddypzb_dt1 where mainid in (select id from uf_exceldrzddypzb where wybs = 'fw001') ") + List> getConfigurationTable(); +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate.java b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate.java new file mode 100644 index 0000000..3668697 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate.java @@ -0,0 +1,66 @@ +package weaver.chaoyang.he.formmode.interfaces.impl; + +import com.alibaba.fastjson.JSON; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.formmode.interfaces.ExportFieldTransAction; +import weaver.general.BaseBean; +import weaver.general.Util; +import weaver.hrm.User; + +import java.util.Map; + +/** + *

TBTJ-询价单明细台账更新到处状态

+ * @Author hcy + * @Date 2023/1/31 13:09 + */ +public class ExportFieldTransTemplate implements ExportFieldTransAction{ + + private Logger logger = aiyh.utils.Util.getLogger(); + + @Override + public String getTransValue(Map param,User user) { + // 获取当前登录人员ID + Integer userId = user.getUID(); + logger.info(JSON.toJSONString(param)); + // 获取模块ID + Integer modeId = Util.getIntValue(param.get("modeid").toString()); + //表单id + Integer formId = Util.getIntValue(param.get("formid").toString()); + //当前字段id + String fieldid = Util.null2String(param.get("fieldid")); + //查询列表id + String customid = Util.null2String(param.get("customid")); + //当前列名称(明细表会有d_前缀) + String columnname = Util.null2String(param.get("columnname")); + //当前列数据 + String value = Util.null2String(param.get("value")); + + Map data1 = (Map) param.get("data"); + String mxid = String.valueOf(data1.get("d_mxid")); + String mainId = String.valueOf(data1.get("id")); + this.updateValueIntoDB(mainId,mxid); + //当前行数据 + Map data = (Map) param.get("data"); + + new BaseBean().writeLog(userId+" "+modeId+" "+formId+" "+fieldid+" "+customid+" "+columnname+" "+value); + + return value; + } + + /** + *

update导出状态为已导出

+ * @param mainId,id + * @return + * @author hcy + */ + public void updateValueIntoDB(String mainId,String mxid){ +// String updateSql = "update formtable_main_99_dt1 set dczt = ? where mainId = ? and mxid = ?"; + String updateSql = "update uf_xjdmx_dt1 set dczt = ? where mainId = ? and mxid = ?"; + + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeUpdate(updateSql, "0", mainId,mxid); + logger.info("updateSql是否导出=="+b); + } +} diff --git a/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate_copy.java b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate_copy.java new file mode 100644 index 0000000..1ff0d6e --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/formmode/interfaces/impl/ExportFieldTransTemplate_copy.java @@ -0,0 +1,64 @@ +package weaver.chaoyang.he.formmode.interfaces.impl; + +import com.alibaba.fastjson.JSON; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.formmode.interfaces.ExportFieldTransAction; +import weaver.general.BaseBean; +import weaver.general.Util; +import weaver.hrm.User; + +import java.util.Map; + +/** + *

TBTJ-询价单明细台账更新到处状态

+ * @Author hcy + * @Date 2023/1/31 13:09 + */ +public class ExportFieldTransTemplate_copy implements ExportFieldTransAction{ + + private Logger logger = aiyh.utils.Util.getLogger(); + + @Override + public String getTransValue(Map param,User user) { + // 获取当前登录人员ID + Integer userId = user.getUID(); + logger.info(JSON.toJSONString(param)); + // 获取模块ID + Integer modeId = Util.getIntValue(param.get("modeid").toString()); + //表单id + Integer formId = Util.getIntValue(param.get("formid").toString()); + //当前字段id + String fieldid = Util.null2String(param.get("fieldid")); + //查询列表id + String customid = Util.null2String(param.get("customid")); + //当前列名称(明细表会有d_前缀) + String columnname = Util.null2String(param.get("columnname")); + //当前列数据 + String value = Util.null2String(param.get("value")); + + Map data1 = (Map) param.get("data"); + String mxid = String.valueOf(data1.get("d_mxid")); + String mainId = String.valueOf(data1.get("id")); + this.updateValueIntoDB(mainId,mxid); + //当前行数据 + Map data = (Map) param.get("data"); + + new BaseBean().writeLog(userId+" "+modeId+" "+formId+" "+fieldid+" "+customid+" "+columnname+" "+value); + + return value; + } + + /** + *

update导出状态为已导出

+ * @param mainId,id + * @return + * @author hcy + */ + public void updateValueIntoDB(String mainId,String mxid){ + String updateSql = "update formtable_main_99_dt1 set dczt = ? where mainId = ? and mxid = ?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeUpdate(updateSql, "0", mainId,mxid); + logger.info("updateSql是否导出=="+b); + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java new file mode 100644 index 0000000..83cb1f7 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/mapper/DeleteInvoiceNotApMapper.java @@ -0,0 +1,46 @@ +package weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.mapper; + +import aiyh.utils.annotation.recordset.Delete; +import aiyh.utils.annotation.recordset.Insert; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface DeleteInvoiceNotApMapper { + + /** + *

查询到发票用途为非AP的数据id

+ * @return List 包含数据id的list集合 + * @author hcy + 2023/3/21 10:09 + */ + @Select("select id from fnainvoiceledger where fpyt = 1") + List selectIdByNotAP(); + + /** + *

根据数据id查询到数据

+ * @param idNotAPList id组成的List集合 + * @return List> data + * @author hcy + * 2023/3/21 10:19 + */ + @Select("select * from fnainvoiceledger where id in ($t{idNotAPList})") + List> selectDataById(List idNotAPList); + + @Insert("insert into fnabackup (billingDate,invoiceCode,invoiceNumber," + + "invoiceType,seller,purchaser,invoiceServiceYype,priceWithoutTax,taxRate," + + "tax,taxIncludedPrice,authenticity,reimbursementDate,reimbursePerson,requestId,userid_new," + + "invoiceSource_new,checkcode,status,card_id_new,encrypt_code_new,openid_new,wechatstatus,imageID,purchaserTaxNo," + + "salesTaxNo,entryTime,company_seal,form_type,form_name,kind,ciphertext,category,imageDocId,checkStatus," + + "updateOperate,cloudId,codeConfirm,numberConfirm,receiptor,reviewer,issuer,province,city,travel_tax,fylx," + + "purp,iele,orf,hxjksflr,fpyt) " + + "values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + boolean backupData(List dataList); + + @Delete("delete from fnainvoiceledger where id = #{id}") + boolean deleteDataById(String id); + +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java new file mode 100644 index 0000000..11499cc --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/DeleteInvoiceNotApService.java @@ -0,0 +1,12 @@ +package weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service; + +import java.util.List; + +public interface DeleteInvoiceNotApService { + + List selectIdByNotAP(); + + boolean backupdate(List idNotAPList); + + boolean deleteDataById(List idNotAPList); +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceImpl.java b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceImpl.java new file mode 100644 index 0000000..3a2e369 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/service/impl/DeleteInvoiceNotApServiceImpl.java @@ -0,0 +1,75 @@ +package weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.impl; + +import aiyh.utils.Util; +import weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.mapper.DeleteInvoiceNotApMapper; +import weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.DeleteInvoiceNotApService; +import weaver.conn.RecordSet; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class DeleteInvoiceNotApServiceImpl implements DeleteInvoiceNotApService { + + + private final DeleteInvoiceNotApMapper deleteInvoiceNotApMapper = Util.getMapper(DeleteInvoiceNotApMapper.class); + @Override + public List selectIdByNotAP() { + return deleteInvoiceNotApMapper.selectIdByNotAP(); + } + + /** + *

备份数据

+ * @param idNotAPList 需要备份数据的id + * @return boolean + * @author hcy + * 2023/3/21 10:15 + */ + public boolean backupdate(List idNotAPList) { + RecordSet recordSet = new RecordSet(); + for (String id : idNotAPList) { + String backupDataSql = "INSERT INTO fnabackup (billingdate,\t\n" + + "invoicenumber,\t\n" + + "invoicecode,\n" + + "invoicetype,\t\n" + + "taxincludedprice,pricewithouttax,\t\n" + + "tax,\n" + + "purchaser,purchasertaxno,\t\n" + + "seller,salestaxno,purp,hxjksflr,checkStatus,status,authenticity,fpyt,taxrate\n" + + ") SELECT \n" + + "billingdate,\t\n" + + "invoicenumber,\t\n" + + "invoicecode,\n" + + "invoicetype,\t\n" + + "taxincludedprice,pricewithouttax,\t\n" + + "tax,\n" + + "purchaser,purchasertaxno,\t\n" + + "seller,salestaxno,purp,hxjksflr,checkStatus,status,authenticity,fpyt,taxrate\n" + + " FROM fnainvoiceledger WHERE id = ?"; + boolean backupBool = recordSet.executeUpdate(backupDataSql, id); + if (!backupBool){ + return false; + } + } + //开始备份数据 + return true; + } + + /** + *

根据数据id删除数据

+ * @param idNotAPList 数据id + * @return boolean 是否删除成功 + * @author hcy + * 2023/3/21 10:31 + */ + public boolean deleteDataById(List idNotAPList) { + for (String id : idNotAPList) { + boolean deleteBool = deleteInvoiceNotApMapper.deleteDataById(id); + if (!deleteBool){ + return false; + } + } + return true; + + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/web/DeleteInvoiceNotApAction.java b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/web/DeleteInvoiceNotApAction.java new file mode 100644 index 0000000..ae63675 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_aphangxin/deleteinvoicenotap/web/DeleteInvoiceNotApAction.java @@ -0,0 +1,34 @@ +package weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.web; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.DeleteInvoiceNotApService; +import weaver.chaoyang.he.hcy_aphangxin.deleteinvoicenotap.service.impl.DeleteInvoiceNotApServiceImpl; +import weaver.interfaces.schedule.BaseCronJob; + +import java.util.List; + +public class DeleteInvoiceNotApAction extends BaseCronJob { + + private final DeleteInvoiceNotApService deleteInvoiceNotAPservice = new DeleteInvoiceNotApServiceImpl(); + + private final Logger logger = Util.getLogger(); + public void execute() { + //第一步查询fnainvoiceledger中每一条数据中发票用途是否为非AP + List idNotAPList = deleteInvoiceNotAPservice.selectIdByNotAP(); + //第二步:根据第一步查询到的数据id,将想要删除的数据备份到fnabackup表中 + boolean backupBool = deleteInvoiceNotAPservice.backupdate(idNotAPList); + logger.info("数据备份是否成功==="+backupBool); + if (backupBool){ + //第三步:开始删除数据 + boolean deleteBool = deleteInvoiceNotAPservice.deleteDataById(idNotAPList); + if (deleteBool){ + logger.info("数据删除成功"); + }else { + logger.info("数据删除失败"); + } + }else{ + logger.info("数据备份失败,请重新操作"); + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction.java b/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction.java new file mode 100644 index 0000000..b1e18a4 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction.java @@ -0,0 +1,196 @@ +package weaver.chaoyang.he.hcy_dingxinjituan.sendfilebyftp.action; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.file.ImageFileManager; +import weaver.integration.util.FTPUtil; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Property; +import weaver.soa.workflow.request.RequestInfo; +import weaver.workflow.request.RequestManager; + + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +public class SendFileByFTPAction implements Action { + //ip + private String SERVER; + + //端口号 + private String PORT; + + //用户名 + private String USERNAME; + + //密码 + private String PASSWORD; + + //上传的指定路径 + private String REMOTEDIRAPTH; + + //日志 + private final Logger logger = Util.getLogger(); + + + + public String execute(RequestInfo requestInfo) { + + RequestManager requestManager = requestInfo.getRequestManager(); + //获取当前流程附件的附件流 + Map wfMainTableInfo = this.getWfMainTableInfo(requestInfo); + String fj = wfMainTableInfo.get("fj"); + RecordSet recordSet = new RecordSet(); + String get_imageFiledId = "select imagefileid,imagefilename from DocImageFile where docid = ? order by versionId"; +// Util.selectImageInfoByDocId() + boolean b = recordSet.executeQuery(get_imageFiledId, fj); + logger.info("get_imageFiledId是否执行===" + b); + recordSet.next(); + String imagefileid = Util.null2String(recordSet.getString("imagefileid")); + String imagefilename = Util.null2String(recordSet.getString("imagefilename")); + logger.info("文件imagefileid为==="+imagefileid+" 文件名称为==="+imagefilename); + int imagefileidInt; + if (!"".equals(imagefileid)) { + imagefileidInt = Integer.parseInt(imagefileid); + } else { + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("附件上传ftp系统失败"); + return Action.FAILURE_AND_CONTINUE; + } + InputStream is = ImageFileManager.getInputStreamById(imagefileidInt); + if (is==null){ + logger.info("文件输入流为空"); + }else{ + logger.info("文件输入流不为空"); + } + + try { + if (is!=null){ + this.uploadFile(is, imagefilename); + }else { + logger.info("附件内容为空"); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("附件内容为空"); + return Action.FAILURE_AND_CONTINUE; + } + } catch (IOException e) { + e.printStackTrace(); + logger.info("附件上传失败,失败原因==="+e); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("附件上传ftp系统失败"); + return Action.FAILURE_AND_CONTINUE; + } + return Action.SUCCESS; + } + + //上传文件到指定的ftp + public void uploadFile(InputStream inputStream, String fileName) throws IOException { + // FTPFileUtil fileUtil = new FTPFileUtil(SERVER,Util.getIntValue(PORT,21),USERNAME,PASSWORD); + FTPUtil ftpUtil = new FTPUtil(SERVER,Util.getIntValue(PORT,21),USERNAME,PASSWORD); + + if(!ftpUtil.isConnected()){ + ftpUtil.login(); + } + + boolean isSuccess = ftpUtil.uploadFile(inputStream,fileName,REMOTEDIRAPTH); + + if (isSuccess) { + logger.info("文件上传成功"); + }else{ + logger.info("文件上传失败"); + } + ftpUtil.logout(); +/* + FTPClient ftpClient = new FTPClient(); + ftpClient.setControlEncoding("GBK"); + + try { + ftpClient.connect(SERVER, Integer.parseInt(PORT)); + ftpClient.login(USERNAME, PASSWORD); + ftpClient.enterLocalPassiveMode(); + ftpClient.setFileType(FTP.BINARY_FILE_TYPE); + + ftpClient.changeWorkingDirectory("/"+REMOTEDIRAPTH); + boolean success = ftpClient.storeFile(fileName, inputStream); + logger.info("文件上传是否成功==="+success); + if (success) { + logger.info("文件上传成功"); + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("文件上传失败的原因==="+e); + } finally { + if (inputStream != null) { + inputStream.close(); + } + if (ftpClient.isConnected()) { + ftpClient.logout(); + ftpClient.disconnect(); + } + }*/ + } + + + + + public String getSERVER() { + return SERVER; + } + + public void setSERVER(String SERVER) { + this.SERVER = SERVER; + } + + + public String getUSERNAME() { + return USERNAME; + } + + public void setUSERNAME(String USERNAME) { + this.USERNAME = USERNAME; + } + + public String getPASSWORD() { + return PASSWORD; + } + + public void setPASSWORD(String PASSWORD) { + this.PASSWORD = PASSWORD; + } + + public String getREMOTEDIRAPTH() { + return REMOTEDIRAPTH; + } + + public void setREMOTEDIRAPTH(String REMOTEDIRAPTH) { + this.REMOTEDIRAPTH = REMOTEDIRAPTH; + } + + public String getPORT() { + return PORT; + } + + public void setPORT(String PORT) { + this.PORT = PORT; + } + + /** + * 获取流程主表数据 + * + * @param requestInfo 流程信息对象 + * @return Map key 字段名 value 字段值 + */ + public Map getWfMainTableInfo(RequestInfo requestInfo) { + Map map = new HashMap<>(); + for (Property property : requestInfo.getMainTableInfo().getProperty()) { + map.put(property.getName(), property.getValue()); + } + return map; + } + +} + + diff --git a/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction_copy.java b/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction_copy.java new file mode 100644 index 0000000..822e181 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_dingxinjituan/sendfilebyftp/action/SendFileByFTPAction_copy.java @@ -0,0 +1,159 @@ +package weaver.chaoyang.he.hcy_dingxinjituan.sendfilebyftp.action; + +import aiyh.utils.Util; +import org.apache.commons.net.ftp.FTP; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.file.ImageFileManager; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Property; +import weaver.soa.workflow.request.RequestInfo; +import weaver.workflow.request.RequestManager; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +public class SendFileByFTPAction_copy implements Action { + //ip + private String SERVER; + + //端口号 + private String PORT; + + //用户名 + private String USERNAME; + + //密码 + private String PASSWORD; + + //上传的指定路径 + private String REMOTEDIRAPTH; + + //日志 + private final Logger logger = Util.getLogger(); + + + + public String execute(RequestInfo requestInfo) { + RequestManager requestManager = requestInfo.getRequestManager(); + + FTPClient ftp = new FTPClient(); + + try { + //连接ftp + if (!"".equals(PORT)){ + ftp.connect(SERVER, Integer.parseInt(PORT)); + } + //登录 + ftp.login(USERNAME, PASSWORD); + ftp.enterLocalPassiveMode(); + ftp.setFileType(FTP.BINARY_FILE_TYPE); + + //获取当前流程附件的附件流 + Map wfMainTableInfo = this.getWfMainTableInfo(requestInfo); + String fj = wfMainTableInfo.get("fj"); + RecordSet recordSet = new RecordSet(); + String get_imageFiledId = "select imagefileid from DocImageFile where docid = ? order by versionId"; + boolean b = recordSet.executeQuery(get_imageFiledId, fj); + logger.info("get_imageFiledId是否执行==="+b); + recordSet.next(); + String imagefileid = Util.null2String(recordSet.getString("imagefileid")); + int imagefileidInt ; + if (!"".equals(imagefileid)){ + imagefileidInt = Integer.parseInt(imagefileid); + }else { + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("附件上传ftp系统失败"); + return Action.FAILURE_AND_CONTINUE; + } + InputStream is = ImageFileManager.getInputStreamById(imagefileidInt); + String remoteFilePath = REMOTEDIRAPTH;//上传路径 + boolean uploaded = ftp.storeFile(remoteFilePath, is);//文件导入 + if (uploaded) { + logger.info("File uploaded successfully"); + } else { + logger.info("File uploaded fail!"); + } + } catch (IOException ex) { + System.out.println("Error: " + ex.getMessage()); + logger.info("Error:"+ex.getMessage()); + ex.printStackTrace(); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("附件上传ftp系统失败"); + return Action.FAILURE_AND_CONTINUE; + } finally { + try { + ftp.logout(); + ftp.disconnect(); + } catch (IOException ex) { + ex.printStackTrace(); + logger.info("Error:"+ex.getMessage()); + } + } + return Action.SUCCESS; + } + + + + + public String getSERVER() { + return SERVER; + } + + public void setSERVER(String SERVER) { + this.SERVER = SERVER; + } + + + public String getUSERNAME() { + return USERNAME; + } + + public void setUSERNAME(String USERNAME) { + this.USERNAME = USERNAME; + } + + public String getPASSWORD() { + return PASSWORD; + } + + public void setPASSWORD(String PASSWORD) { + this.PASSWORD = PASSWORD; + } + + public String getREMOTEDIRAPTH() { + return REMOTEDIRAPTH; + } + + public void setREMOTEDIRAPTH(String REMOTEDIRAPTH) { + this.REMOTEDIRAPTH = REMOTEDIRAPTH; + } + + public String getPORT() { + return PORT; + } + + public void setPORT(String PORT) { + this.PORT = PORT; + } + + /** + * 获取流程主表数据 + * + * @param requestInfo 流程信息对象 + * @return Map key 字段名 value 字段值 + */ + public Map getWfMainTableInfo(RequestInfo requestInfo) { + Map map = new HashMap<>(); + for (Property property : requestInfo.getMainTableInfo().getProperty()) { + map.put(property.getName(), property.getValue()); + } + return map; + } + +} + + diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/controller/CheckAndChangeValueAction.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/controller/CheckAndChangeValueAction.java new file mode 100644 index 0000000..3f7bd8c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/controller/CheckAndChangeValueAction.java @@ -0,0 +1,109 @@ +package weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.controller; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.service.CheckAndChangeValueService; +import weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.service.impl.CheckAndChangeValueServiceImpl; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Cell; +import weaver.soa.workflow.request.DetailTable; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.Row; +import weaver.workflow.request.RequestManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CheckAndChangeValueAction implements Action { + /** + * 校验字段、取uf_OfficeInventory表数据以及进行加减计算 + */ + private final CheckAndChangeValueService checkAndChangeValueService = new CheckAndChangeValueServiceImpl(); + /** + * 日志 + */ + private final Logger logger = Util.getLogger(); + @Override + public String execute(RequestInfo requestInfo) { + RequestManager requestManager = requestInfo.getRequestManager(); + Map>> detailTableValue = getDetailTableValue(requestInfo); + List> detailLists = detailTableValue.get("1"); + logger.info("detailLists==="+detailLists); + Map> checkMaps = checkAndChangeValueService.checkfield(detailLists); + logger.info("checkMaps==="+checkMaps); + if (checkMaps==null || checkMaps.size()==0){ + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("后端代码异常"); + return Action.FAILURE_AND_CONTINUE; + } + //开始校验字段是否符合要求 + for (Map.Entry> entry : checkMaps.entrySet()) { + String key = entry.getKey(); + List values = entry.getValue(); + if (!"".equals(key) && key.equals("lingyong")){ + for (String value : values) { + if (value.equals("false")){ + logger.error("requestid:" + requestInfo.getRequestid() ); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("领用数量超过库存数量,请核对信息!"); + return Action.FAILURE_AND_CONTINUE; + } + } + }else if (!"".equals(key) && key.equals("tuihuan")){ + for (String value : values) { + if (value.equals("false")){ + logger.error("requestid:" + requestInfo.getRequestid() ); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("退货数量超过实收数量,请核对信息!"); + return Action.FAILURE_AND_CONTINUE; + } + } + } + + } + //开始更新台账数据 + checkAndChangeValueService.changeDBValue(detailLists); + return Action.SUCCESS; + + } + + + /** + *

获取所有明细数据

+ * + * @return 以明细表需要为键,以明细表数据为值的键值对明细数据信息 + */ + protected Map>> getDetailTableValue(RequestInfo requestInfo) { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 0.75)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + /** + *

根据明细表信息获取明细表数据

+ * + * @param detailTable 明细表对象 + * @return 明细表数据 + */ + private List> getDetailValue(DetailTable detailTable) { + Row[] rowArr = detailTable.getRow(); + List> detailData = new ArrayList<>(rowArr.length); + for (Row row : rowArr) { + Cell[] cellArr = row.getCell(); + Map rowData = new HashMap<>((int) Math.ceil(cellArr.length * 0.75)); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/mapper/CheckAndChangeValueMapper.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/mapper/CheckAndChangeValueMapper.java new file mode 100644 index 0000000..6bb6825 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/mapper/CheckAndChangeValueMapper.java @@ -0,0 +1,60 @@ +package weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.Update; + + +@SqlMapper +public interface CheckAndChangeValueMapper { + + /** + *

根据产品编号查询领用数量

+ * @param id 产品编号 + * @return String 查询到的领用数量 + * @author hcy + * @Date 2023/3/17 10:36 + */ + @Select("select lysl from uf_OfficeInventory where id = #{id}") + String selectLysl(@ParamMapper("id") String id); + + /** + *

更新领用数量

+ * @param lysl 领用数量 + * @param id id + * @return boolean update是否更新成功 + * @author hcy + * @Date 2023/3/17 10:30 + */ + @Update("update uf_OfficeInventory set lysl = #{lysl} where id = #{id}") + boolean updateLysl(@ParamMapper("lysl") String lysl, + @ParamMapper("id") String id); + + + /** + *

根据产品编号查询退还数量

+ * @param id id + * @return String 查询到的退还数量 + * @author hcy + * @Date 2023/3/17 10:36 + */ + @Select("select thsl from uf_OfficeInventory where id = #{id}") + String selectThsl(@ParamMapper("id") String id); + + + /** + *

更新退还数量

+ * @param thsl 退还数量 + * @param id id + * @return boolean update是否更新成功 + * @author hcy + * @Date 2023/3/17 10:30 + */ + @Update("update uf_OfficeInventory set thsl = #{thsl} where id = #{id}") + boolean updaThsl(@ParamMapper("thsl") String thsl, + @ParamMapper("id") String id); + + + +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/CheckAndChangeValueService.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/CheckAndChangeValueService.java new file mode 100644 index 0000000..8d22684 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/CheckAndChangeValueService.java @@ -0,0 +1,11 @@ +package weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.service; + +import java.util.List; +import java.util.Map; + +public interface CheckAndChangeValueService { + + public Map> checkfield(List> detailLists); + + public void changeDBValue(List> detailLists); +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/impl/CheckAndChangeValueServiceImpl.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/impl/CheckAndChangeValueServiceImpl.java new file mode 100644 index 0000000..fa7d258 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/checkandchangevalue/action/service/impl/CheckAndChangeValueServiceImpl.java @@ -0,0 +1,180 @@ +package weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.service.impl; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.mapper.CheckAndChangeValueMapper; +import weaver.chaoyang.he.hcy_esteelauder.checkandchangevalue.action.service.CheckAndChangeValueService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class CheckAndChangeValueServiceImpl implements CheckAndChangeValueService { + + + private final CheckAndChangeValueMapper checkAndChangeValueMapper = Util.getMapper(CheckAndChangeValueMapper.class); + private final Logger logger = Util.getLogger(); + /** + *

校验字段是否符合流程流转的需求

+ * @param detailLists 明细表所有数据 + * @return boolean 不符合返回false + * @author hcy + * 2023/3/16 15:22 + */ + public Map> checkfield(List> detailLists) { + try { + Map>> detailMap = detailLists.stream().collect(Collectors.groupingBy(items -> items.get("ywlx"))); + List booleanLingYong = new ArrayList<>();//用来存放 false 和 true 校验字段是否属于符合标准 + List booleanTuiHuan = new ArrayList<>();//用来存放 false 和 true 校验字段是否属于符合标准 + + for (Map.Entry>> entry : detailMap.entrySet()) { + String key = Util.null2String(entry.getKey()); + List> value = entry.getValue(); + if (key.equals("0")){ + Map>> cpbh = value.stream().collect(Collectors.groupingBy(items -> items.get("cpbh")));//产品编号 + for (Map.Entry>> cpbhentry : cpbh.entrySet()) { +// String cpbhkey = Util.null2String(cpbhentry.getKey()); + List> cpbhvalue = cpbhentry.getValue(); + double total = 0; + for (Map stringStringMap : cpbhvalue) { + String lythsl = Util.null2String(stringStringMap.get("lythsl"));//领用/退还数量 + if (!"".equals(lythsl)){ + total += Double.parseDouble(lythsl); + } + } + String kcyesl = Util.null2String(value.get(0).get("kcyesl")); + double kcyeslDouble = 0; + if (!"".equals(kcyesl)){ + kcyeslDouble = Double.parseDouble(kcyesl); + } + if (total <= kcyeslDouble){ + booleanLingYong.add("true"); + }else { + booleanLingYong.add("false"); + } + } + }else if (key.equals("1")){ + Map>> cpbh = value.stream().collect(Collectors.groupingBy(items -> items.get("cpbh")));//产品编号 + for (Map.Entry>> cpbhentry : cpbh.entrySet()) { +// String cpbhkey = Util.null2String(cpbhentry.getKey()); + List> cpbhvalue = cpbhentry.getValue(); + double total = 0; + for (Map stringStringMap : cpbhvalue) { + String lythsl = Util.null2String(stringStringMap.get("lythsl"));//领用/退还数量 + if (!lythsl.equals("")){ + total += Double.parseDouble(lythsl); + } + } + String sssl = Util.null2String(cpbhvalue.get(0).get("sssl"));//实收数量 + String kcyesl = Util.null2String(cpbhvalue.get(0).get("kcyesl"));//剩余库存数量 + double ssslDouble = 0; + double kcyeslDouble = 0; + if (!"".equals(sssl)&&!"".equals(kcyesl)){ + ssslDouble = Double.parseDouble(sssl); + kcyeslDouble = Double.parseDouble(kcyesl); + } + double subtractionValue = ssslDouble - kcyeslDouble; + logger.info("subtractionValue==="+subtractionValue); + logger.info("total==="+total); + if (total <= subtractionValue){ + booleanTuiHuan.add("true"); + }else { + booleanTuiHuan.add("false"); + } + } + } + } + Map> booleanMap = new HashMap<>(); + booleanMap.put("lingyong",booleanLingYong); + booleanMap.put("tuihuan", booleanTuiHuan); + return booleanMap; + } catch (NumberFormatException e) { + e.printStackTrace(); + logger.info("checkfield方法异常==="+e); + return null; + } + } + + /** + *

修改uf_OfficeInventory表数据以及进行加减计算

+ * @param detailLists 明细表所有数据 + * @author hcy + * 2023/3/16 15:23 + */ + public void changeDBValue(List> detailLists) { + try { + + Map>> detailMap = detailLists.stream().collect(Collectors.groupingBy(items -> items.get("ywlx"))); + Map lingYongMap = new HashMap<>();//用于存放领用类型的数据 + Map tuiHuanMap = new HashMap<>();//用于存放退还类型的数据 + for (Map.Entry>> entry : detailMap.entrySet()) { + String key = Util.null2String(entry.getKey()); + List> value = entry.getValue(); + if (!("".equals(key)) && key.equals("0")){ + Map>> cpbh = value.stream().collect(Collectors.groupingBy(items -> items.get("cpbh")));//产品编号 + for (Map.Entry>> cpbhentry : cpbh.entrySet()) { + String cpbhkey = Util.null2String(cpbhentry.getKey()); + List> cpbhvalue = cpbhentry.getValue(); + int total = 0; + for (Map stringStringMap : cpbhvalue) { + String lythsl = Util.null2String(stringStringMap.get("lythsl"));//领用/退还数量 + if (!lythsl.equals("")){ + total += Integer.parseInt(lythsl); + } + } + lingYongMap.put(cpbhkey,total); + } + }else if (!("".equals(key)) && key.equals("1")){ + Map>> cpbh = value.stream().collect(Collectors.groupingBy(items -> items.get("cpbh")));//产品编号 + for (Map.Entry>> cpbhentry : cpbh.entrySet()) { + String cpbhkey = Util.null2String(cpbhentry.getKey()); + List> cpbhvalue = cpbhentry.getValue(); + int total = 0; + for (Map stringStringMap : cpbhvalue) { + String lythsl = Util.null2String(stringStringMap.get("lythsl"));//领用/退还数量 + if (!lythsl.equals("")){ + total += Integer.parseInt(lythsl); + } + } + tuiHuanMap.put(cpbhkey,total); + } + } + } + + //开始updte数据库 + for (Map.Entry entry : lingYongMap.entrySet()) { + String key = entry.getKey(); + Integer value = entry.getValue(); + String selectLysl = checkAndChangeValueMapper.selectLysl(key); + int lyslDB = 0; + if (!selectLysl.equals("")){ + lyslDB = Integer.parseInt(selectLysl); + } + //减库存 + boolean updateLysl = checkAndChangeValueMapper.updateLysl(String.valueOf(lyslDB + value),key); + logger.info("减库存是否成功==="+updateLysl); + } + + for (Map.Entry entry : tuiHuanMap.entrySet()) { + String key = entry.getKey(); + Integer value = entry.getValue(); + String selectThsl = checkAndChangeValueMapper.selectThsl(key); + int thslDB = 0; + if (!selectThsl.equals("")){ + thslDB = Integer.parseInt(selectThsl); + } + //增加库存 + String finalThsl = String.valueOf(thslDB + value); + boolean updateThsl = checkAndChangeValueMapper.updaThsl(finalThsl,key); + logger.info("增加库存是否成功"+updateThsl); + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("changeDBValue异常为==="+e); + } + + + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/controller/GetDataCreateWorkflowController.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/controller/GetDataCreateWorkflowController.java new file mode 100644 index 0000000..16d7e91 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/controller/GetDataCreateWorkflowController.java @@ -0,0 +1,149 @@ +package weaver.chaoyang.he.hcy_esteelauder.createworkflow.controller; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.hcy_esteelauder.createworkflow.mapper.GetWorkflowDataMapper; +import weaver.chaoyang.he.hcy_esteelauder.createworkflow.service.GetWorkflowDataService; +import weaver.chaoyang.he.hcy_esteelauder.createworkflow.service.impl.GetWorkflowDataServiceImpl; +import weaver.hrm.User; +import weaver.interfaces.schedule.BaseCronJob; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

计划任务一段时间收集《office库存领用/退还登记》流程中的数据,用收集到的数据创建《office库存领用/退还汇总签批》流程

+ * @Author hcy + * @Date 2023/3/15 11:45 + */ +public class GetDataCreateWorkflowController extends BaseCronJob { + //获取数据主表的名称 + private String getDataMainTableName; + //获取数据的和主表数据对应的明细表的名称 + private String getDataDetailTableName; + //流程id + private String workflowId; + //配置表的唯一标识 + private String wybs; + //校验日志 + private String datetime; + + + + /** + * 获取《office库存领用/退还申请》流程中的数据 + */ + private final GetWorkflowDataService getWorkflowDataService = (GetWorkflowDataService) new GetWorkflowDataServiceImpl(); + + private final GetWorkflowDataMapper getWorkflowDataMapper = Util.getMapper(GetWorkflowDataMapper.class); + /** + * 日志 + */ + private final Logger logger = Util.getLogger(); + + /** + *

获取流程数据,创建新的流程

+ * @param + * @return + * @author hcy + * @Date 2023/3/15 13:54 + */ + public void execute() { + + try { + String month = this.getlastdayDate(); + //第一步拿到数据 + List> totalData = new ArrayList<>(); + + if (!"".equals(Util.null2String(datetime))){ + totalData = getWorkflowDataService.getTotalData(getDataMainTableName, getDataDetailTableName,datetime); + }else { + totalData = getWorkflowDataService.getTotalData(getDataMainTableName, getDataDetailTableName,month); + } + + logger.info("===totalData==="+totalData); + //这一步是获取权限区分字段名称 + String distinctField = getWorkflowDataMapper.getDistincteField(wybs); + Map>> datas = totalData.stream().collect(Collectors.groupingBy(items -> items.get(distinctField)));//单个流程,过滤数据 + logger.info("===datas===="+datas); + User user = new User(); + //第二步创建流程 + datas.forEach((key,value)->{ + //拿到数据创建流程 + String s = getWorkflowDataService.startWorkflow(workflowId, value, user, "1",wybs,distinctField); + logger.info("============"+s+"============"); + }); + } catch (Exception e) { + e.printStackTrace(); + logger.info("controller层出现问题---问题为:"+e); + } + + + } + + + + /** + *

获取系统当前时间的前一天日期

+ * @param + * @return String + * @author hcy + * @Date 2023/3/16 10:50 + */ + public String getlastdayDate(){ + SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd"); + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.DAY_OF_MONTH, -1); + date = calendar.getTime(); + System.out.println(sdf.format(date)); + return sdf.format(date); + } + + public String getGetDataMainTableName() { + return getDataMainTableName; + } + + public void setGetDataMainTableName(String getDataMainTableName) { + this.getDataMainTableName = getDataMainTableName; + } + + public String getGetDataDetailTableName() { + return getDataDetailTableName; + } + + public void setGetDataDetailTableName(String getDataDetailTableName) { + this.getDataDetailTableName = getDataDetailTableName; + } + + + public String getWorkflowId() { + return workflowId; + } + + public void setWorkflowId(String workflowId) { + this.workflowId = workflowId; + } + + public GetWorkflowDataService getGetWorkflowDataService() { + return getWorkflowDataService; + } + + public String getWybs() { + return wybs; + } + + public void setWybs(String wybs) { + this.wybs = wybs; + } + + public String getDatetime() { + return datetime; + } + + public void setDatetime(String datetime) { + this.datetime = datetime; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/mapper/GetWorkflowDataMapper.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/mapper/GetWorkflowDataMapper.java new file mode 100644 index 0000000..05dbadb --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/mapper/GetWorkflowDataMapper.java @@ -0,0 +1,37 @@ +package weaver.chaoyang.he.hcy_esteelauder.createworkflow.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; +import java.util.Map; + +@SqlMapper +public interface GetWorkflowDataMapper { + + /** + *

内连接主表以及明细表查询出来放入List中

+ * @param mainTableName,detailTableName + * @return List> + * @author hcy + * @Date 2023/3/15 14:47 + */ + + @Select("select * from $t{mainTableName} m inner join $t{detailTableName} d on m.id = d.mainid where LEFT(sqrq,7) = LEFT(#{month},7)") + List> selectTotalData(@ParamMapper("mainTableName") String mainTableName, + @ParamMapper("detailTableName") String detailTableName, + @ParamMapper("month") String month + ); + @Select("select bmmc from uf_dept where id = #{ppbm}") + String selectPpName(@ParamMapper("ppbm")String ppbm); + + @Select("select * from uf_xjlcbdzddypzb uf inner join uf_xjlcbdzddypzb_dt1 ufdt1 on uf.id = ufdt1.mainid where uf.wybs = #{wybs}") + List> selectfromCustomizeTable(@ParamMapper("wybs") String wybs); + + @Select("select qxqfzdsjkmc from uf_xjlcbdzddypzb where wybs = #{wybs}") + String getDistincteField(String wybs); + + @Select("select bmmc from uf_dept where id= #{ppbm}") + String getPpbmValue(String ppbm); +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/GetWorkflowDataService.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/GetWorkflowDataService.java new file mode 100644 index 0000000..c5615d7 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/GetWorkflowDataService.java @@ -0,0 +1,23 @@ +package weaver.chaoyang.he.hcy_esteelauder.createworkflow.service; + +import weaver.hrm.User; + +import java.util.List; +import java.util.Map; + +public interface GetWorkflowDataService { + + public List> getTotalData(String mainTableName,String detailTableName,String month); + + /** + *

创建一个流程

+ * @param workflowId 流程id + * @param totalDatas:主表数据,明细表数据:数据形式:key:value + * @param user 当前用户信息 + * @param isNextFlow 是否自动提交至下一个节点 0:否 1:是 + * @return String:流程创建是否成功 + * @author hcy + * @Date 2023/3/15 16:42 + */ + public String startWorkflow(String workflowId,List> totalDatas,User user, String isNextFlow,String wybs,String distinctField); +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl.java new file mode 100644 index 0000000..b9b4cdb --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl.java @@ -0,0 +1,157 @@ +package weaver.chaoyang.he.hcy_esteelauder.createworkflow.service.impl; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.chaoyang.he.hcy_esteelauder.createworkflow.mapper.GetWorkflowDataMapper; +import weaver.chaoyang.he.hcy_esteelauder.createworkflow.service.GetWorkflowDataService; +import weaver.hrm.User; +import weaver.workflow.webservices.*; + +import java.text.SimpleDateFormat; +import java.util.*; + +public class GetWorkflowDataServiceImpl implements GetWorkflowDataService { + + private final Logger logger = Util.getLogger(); + private final GetWorkflowDataMapper getWorkflowDataMapper = Util.getMapper(GetWorkflowDataMapper.class); + + @Override + public List> getTotalData(String mainTableName, String detailTableName,String month) { + return getWorkflowDataMapper.selectTotalData(mainTableName, detailTableName,month); + } + + /** + *

创建流程

+ * @param workflowId:流程id + * @return String:流程创建成功与否 + * @author hcy + * 2023/3/15 22:45 + */ + public String startWorkflow(String workflowId, List> totalDatas, User user, String isNextFlow,String wybs,String distinctField) { + + + try { + List> customizeDataList = getWorkflowDataMapper.selectfromCustomizeTable(wybs); + List> mailTableDatas = new ArrayList<>(); + List> detailDataDatas = new ArrayList<>(); + + for (Map map : customizeDataList) { + if (Util.null2String(map.get("sjly")).equals("0")&&Util.null2String(map.get("mbzdsjly")).equals("0")){ + mailTableDatas.add(map); + } + if (Util.null2String(map.get("sjly")).equals("0")&&Util.null2String(map.get("mbzdsjly")).equals("1")){ + detailDataDatas.add(map); + } + if (Util.null2String(map.get("sjly")).equals("1")&&Util.null2String(map.get("mbzdsjly")).equals("1")){ + detailDataDatas.add(map); + } + } + WorkflowRequestTableField[] wrti = new WorkflowRequestTableField[mailTableDatas.size()]; + + //配置表动态处理主表字段 + for (int i = 0; i dataMap = mailTableDatas.get(i); + wrti[i] = new WorkflowRequestTableField(); + String targetField = Util.null2String(dataMap.get("mblczdsjkm")); + wrti[i].setFieldName(targetField); + Object ylczdsjkm = dataMap.get("ylczdsjkm"); + Object sourceField = totalDatas.get(i).get(ylczdsjkm); + wrti[i].setFieldValue(Util.null2String(sourceField)); + wrti[i].setView(true); + wrti[i].setEdit(true); + + } + + WorkflowRequestTableRecord[] wrtri = new WorkflowRequestTableRecord[1];//主字段只有一行数据 + wrtri[0] = new WorkflowRequestTableRecord(); + wrtri[0].setWorkflowRequestTableFields(wrti); + WorkflowMainTableInfo wmi = new WorkflowMainTableInfo(); + wmi.setRequestRecords(wrtri); + //主表end + int detailrows = totalDatas.size();//添加指定条数明细 + + // 添加明细数据 + wrtri = new WorkflowRequestTableRecord[totalDatas.size()];//添加指定条数行明细数据 + //每行明细对应的字段 + + for (int i = 0; i < detailrows; i++) { + //字段信息 + wrti = new WorkflowRequestTableField[detailDataDatas.size()]; + int j=0; + for (Map detailDataData : detailDataDatas) { + wrti[j] = new WorkflowRequestTableField(); + String targetField = Util.null2String(detailDataData.get("mblczdsjkm"));//目标字段,字段名 + wrti[j].setFieldName(targetField);//服务类型 + Object ylczdsjkm = detailDataData.get("ylczdsjkm"); + Object sourceField = totalDatas.get(i).get(ylczdsjkm); + String sourceFieldString = Util.null2String(sourceField); + if (Util.null2String(totalDatas.get(i).get("ywlx")).equals("0")&&Util.null2String(ylczdsjkm).equals("lythsl")){ + sourceFieldString = "-"+sourceFieldString; + } + wrti[j].setFieldValue(sourceFieldString); + wrti[j].setView(true);//字段是否可见 + wrti[j].setEdit(true);//字段是否可编辑 + j++; + } + wrtri[i] = new WorkflowRequestTableRecord(); + wrtri[i].setWorkflowRequestTableFields(wrti); + } + //添加到明细表中 + WorkflowDetailTableInfo WorkflowDetailTableInfo[] = new WorkflowDetailTableInfo[1];//指定明细表的个数,多个明细表指定多个,顺序按照明细的顺序 + WorkflowDetailTableInfo[0] = new WorkflowDetailTableInfo(); + WorkflowDetailTableInfo[0].setWorkflowRequestTableRecords(wrtri); + //添加工作流id + WorkflowBaseInfo wbi = new WorkflowBaseInfo(); + wbi.setWorkflowId(workflowId);//workflowid 流程接口演示流程2016==38 + WorkflowRequestInfo wri = new WorkflowRequestInfo();//流程基本信息 + wri.setCreatorId("1");//创建人id ToDo:这里先写死,稍后再做改写 + wri.setRequestLevel("0");//0 正常,1重要,2紧急 + String ppbmValue = getWorkflowDataMapper.getPpbmValue(Util.null2String(totalDatas.get(0).get(distinctField))); + String workflowTitle = this.getWorkflowTitle(ppbmValue); + wri.setRequestName(workflowTitle);//流程标题 + wri.setWorkflowMainTableInfo(wmi);//添加主字段数据 + wri.setWorkflowDetailTableInfos(WorkflowDetailTableInfo);//添加明细数据 + wri.setWorkflowBaseInfo(wbi); +// wri.setIsnextflow(isNextFlow);//是否提交下一个节点 + WorkflowService workflowService = new WorkflowServiceImpl(); + String requestid =workflowService.doCreateWorkflowRequest(wri,1); + logger.info("===requestid==="+requestid); + if (!requestid.equals("")){ + return "流程创建成功"; + }else { + return "流程创建失败"; + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("流程创建异常===异常信息===="+e); + return "流程创建异常===异常信息===="+e; + } + + + } + + /** + *

获取流程标题

+ * @param pp 品牌名称 + * @return String + * @author hcy + * 2023/3/16 11:27 + */ + public String getWorkflowTitle(String pp){ + + String workflowName = pp + "-" + getSystemDate() + "-" + "office库存领用/退还明细"; + logger.info("workflowName==="+workflowName); + return workflowName; + } + /** + *

获取系统当年份

+ * @return String + * @author hcy + * 2023/3/15 13:52 + */ + public String getSystemDate(){ + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return dateFormat.format(date); + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl_copy.java b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl_copy.java new file mode 100644 index 0000000..ec0c4e0 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_esteelauder/createworkflow/service/impl/GetWorkflowDataServiceImpl_copy.java @@ -0,0 +1,274 @@ +package weaver.chaoyang.he.hcy_esteelauder.createworkflow.service.impl;//package weaver.hcy_esteelauder.createworkflow.service.impl; +// +//import aiyh.utils.Util; +//import org.apache.log4j.Logger; +//import weaver.hcy_esteelauder.createworkflow.mapper.GetWorkflowDataMapper; +//import weaver.hcy_esteelauder.createworkflow.service.GetWorkflowDataService; +//import weaver.hrm.User; +//import weaver.workflow.webservices.*; +// +//import java.text.SimpleDateFormat; +//import java.util.Date; +//import java.util.List; +//import java.util.Map; +// +//public class GetWorkflowDataServiceImpl_copy implements GetWorkflowDataService { +// +// private final Logger logger = Util.getLogger(); +// private final GetWorkflowDataMapper getWorkflowDataMapper = Util.getMapper(GetWorkflowDataMapper.class); +// +// @Override +// public List> getTotalData(String mainTableName, String detailTableName,String month) { +// return getWorkflowDataMapper.selectTotalData(mainTableName, detailTableName,month); +// } +// +// /** +// *

创建流程

+// * @param workflowId:流程id +// * @param workflowId:流程id +// * @param workflowId:流程id +// * @return String:流程创建成功与否 +// * @author hcy +// * @Date 2023/3/15 22:45 +// */ +// public String startWorkflow(String workflowId, List> totalDatas, User user, String isNextFlow,String wybs) { +// +// +// try { +//// List> customizeDataList = getWorkflowDataMapper.selectfromCustomizeTable(wybs); +// +// WorkflowRequestTableField[] wrti = new WorkflowRequestTableField[4]; +// +// //字段信息 +// wrti[0] = new WorkflowRequestTableField(); +// wrti[0].setFieldName("sqr"); +// wrti[0].setFieldValue(Util.null2String(String.valueOf(totalDatas.get(0).get("sqr")))); +// wrti[0].setView(true); +// wrti[0].setEdit(true); +// +// wrti[1] = new WorkflowRequestTableField(); +// wrti[1].setFieldName("sqrbm"); +// wrti[1].setFieldValue(Util.null2String(String.valueOf(totalDatas.get(0).get("sqrbm")))); +// wrti[1].setView(true); +// wrti[1].setEdit(true); +// +// wrti[2] = new WorkflowRequestTableField(); +// wrti[2].setFieldName("sqrq"); +// wrti[2].setFieldValue(Util.null2String(String.valueOf(totalDatas.get(0).get("sqrq")))); +// wrti[2].setView(true); +// wrti[2].setEdit(true); +// +// wrti[3] = new WorkflowRequestTableField(); +// wrti[3].setFieldName("ppbm"); +// String ppbmValue = Util.null2String(String.valueOf(totalDatas.get(0).get("ppbm"))); +// if (!ppbmValue.equals("")){ +// wrti[3].setFieldValue(ppbmValue); +// } +// wrti[3].setView(true); +// wrti[3].setEdit(true); +// +// +// WorkflowRequestTableRecord[] wrtri = new WorkflowRequestTableRecord[1];//主字段只有一行数据 +// wrtri[0] = new WorkflowRequestTableRecord(); +// wrtri[0].setWorkflowRequestTableFields(wrti); +// WorkflowMainTableInfo wmi = new WorkflowMainTableInfo(); +// wmi.setRequestRecords(wrtri); +// //主表end +// int detailrows = totalDatas.size();//添加指定条数明细 +// // 添加明细数据 +// wrtri = new WorkflowRequestTableRecord[totalDatas.size()];//添加指定条数行明细数据 +// for (int i = 0; i < detailrows; i++) { +// //每行明细对应的字段 +// wrti = new WorkflowRequestTableField[20]; +// //字段信息 +// //0 +// wrti[0] = new WorkflowRequestTableField(); +// wrti[0].setFieldName("ywlx");//服务类型 +// wrti[0].setFieldValue(String.valueOf(totalDatas.get(i).get("ywlx"))); +// wrti[0].setView(true);//字段是否可见 +// wrti[0].setEdit(true);//字段是否可编辑 +// +// wrti[1] = new WorkflowRequestTableField(); +// wrti[1].setFieldName("pp");//品牌 +// wrti[1].setFieldValue(String.valueOf(totalDatas.get(i).get("ppbm"))); +// wrti[1].setView(true);//字段是否可见 +// wrti[1].setEdit(true);//字段是否可编辑 +// +// wrti[2] = new WorkflowRequestTableField(); +// wrti[2].setFieldName("bm");//部门 +// wrti[2].setFieldValue(String.valueOf(totalDatas.get(i).get("sqrbm"))); +// wrti[2].setView(true);//字段是否可见 +// wrti[2].setEdit(true);//字段是否可编辑 +// +// +// wrti[3] = new WorkflowRequestTableField(); +// wrti[3].setFieldName("stockowner");//stockowner +// wrti[3].setFieldValue(String.valueOf(totalDatas.get(i).get("stockowner"))); +// wrti[3].setView(true);//字段是否可见 +// wrti[3].setEdit(true);//字段是否可编辑 +// +// wrti[4] = new WorkflowRequestTableField(); +// wrti[4].setFieldName("sqr");//申请人 +// wrti[4].setFieldValue(String.valueOf(totalDatas.get(i).get("sqr"))); +// wrti[4].setView(true);//字段是否可见 +// wrti[4].setEdit(true);//字段是否可编辑 +// +// wrti[5] = new WorkflowRequestTableField(); +// wrti[5].setFieldName("cs");//城市 +// wrti[5].setFieldValue(String.valueOf(totalDatas.get(i).get("cs"))); +// wrti[5].setView(true);//字段是否可见 +// wrti[5].setEdit(true);//字段是否可编辑 +// +// wrti[6] = new WorkflowRequestTableField(); +// wrti[6].setFieldName("stocklocation");//stocklocation +// wrti[6].setFieldValue(String.valueOf(totalDatas.get(i).get("stocklocation"))); +// wrti[6].setView(true);//字段是否可见 +// wrti[6].setEdit(true);//字段是否可编辑 +// +// wrti[7] = new WorkflowRequestTableField(); +// wrti[7].setFieldName("hgbh");//货柜编号 +// wrti[7].setFieldValue(String.valueOf(totalDatas.get(i).get("hgbh"))); +// wrti[7].setView(true);//字段是否可见 +// wrti[7].setEdit(true);//字段是否可编辑 +// +// wrti[8] = new WorkflowRequestTableField(); +// wrti[8].setFieldName("cpbh");//产品编号 +// wrti[8].setFieldValue(String.valueOf(totalDatas.get(i).get("cpbh"))); +// wrti[8].setView(true);//字段是否可见 +// wrti[8].setEdit(true);//字段是否可编辑 +// +// wrti[9] = new WorkflowRequestTableField(); +// wrti[9].setFieldName("ddbh");//订单编号 +// wrti[9].setFieldValue(String.valueOf(totalDatas.get(i).get("ddbh"))); +// wrti[9].setView(true);//字段是否可见 +// wrti[9].setEdit(true);//字段是否可编辑 +// +// wrti[10] = new WorkflowRequestTableField(); +// wrti[10].setFieldName("zwms");//中文描述 +// wrti[10].setFieldValue(String.valueOf(totalDatas.get(i).get("zwms"))); +// wrti[10].setView(true);//字段是否可见 +// wrti[10].setEdit(true);//字段是否可编辑 +// +// wrti[11] = new WorkflowRequestTableField(); +// wrti[11].setFieldName("kcyesl");//剩余库存 +// wrti[11].setFieldValue(String.valueOf(totalDatas.get(i).get("kcyesl"))); +// wrti[11].setView(true);//字段是否可见 +// wrti[11].setEdit(true);//字段是否可编辑 +// +// wrti[12] = new WorkflowRequestTableField(); +// wrti[12].setFieldName("lythrq");//领用/退还日期 +// wrti[12].setFieldValue(String.valueOf(totalDatas.get(i).get("lythrq"))); +// wrti[12].setView(true);//字段是否可见 +// wrti[12].setEdit(true);//字段是否可编辑 +// +// wrti[13] = new WorkflowRequestTableField(); +// wrti[13].setFieldName("dqrq");//到期日期 +// wrti[13].setFieldValue(String.valueOf(totalDatas.get(i).get("dqrq"))); +// wrti[13].setView(true);//字段是否可见 +// wrti[13].setEdit(true);//字段是否可编辑 +// +// wrti[14] = new WorkflowRequestTableField(); +// wrti[14].setFieldName("lythsl");//领用退还数量 +// if (Util.null2String(totalDatas.get(i).get("ywlx")).equals("1")){ +// wrti[14].setFieldValue(String.valueOf("-"+totalDatas.get(i).get("lythsl"))); +// }else if (Util.null2String(totalDatas.get(i).get("ywlx")).equals("0")){ +// wrti[14].setFieldValue(String.valueOf(totalDatas.get(i).get("lythsl"))); +// } +// wrti[14].setView(true);//字段是否可见 +// wrti[14].setEdit(true);//字段是否可编辑 +// +// +// wrti[15] = new WorkflowRequestTableField(); +// wrti[15].setFieldName("cplx");//产品类型 +// wrti[15].setFieldValue(String.valueOf(totalDatas.get(i).get("cplx"))); +// wrti[15].setView(true);//字段是否可见 +// wrti[15].setEdit(true);//字段是否可编辑 +// +// wrti[16] = new WorkflowRequestTableField(); +// wrti[16].setFieldName("kdzjxx");//快递/转交信息 +// wrti[16].setFieldValue(String.valueOf(totalDatas.get(i).get("kdzjxx"))); +// wrti[16].setView(true);//字段是否可见 +// wrti[16].setEdit(true);//字段是否可编辑 +// +// wrti[17] = new WorkflowRequestTableField(); +// wrti[17].setFieldName("cpyt");//产品用途 +// wrti[17].setFieldValue(String.valueOf(totalDatas.get(i).get("cpyt"))); +// wrti[17].setView(true);//字段是否可见 +// wrti[17].setEdit(true);//字段是否可编辑 +// +// wrti[18] = new WorkflowRequestTableField(); +// wrti[18].setFieldName("sssl");//实收数量 +// wrti[18].setFieldValue(String.valueOf(totalDatas.get(i).get("sssl"))); +// wrti[18].setView(true);//字段是否可见 +// wrti[18].setEdit(true);//字段是否可编辑 +// +// wrti[19] = new WorkflowRequestTableField(); +// wrti[19].setFieldName("bz");//备注 +// wrti[19].setFieldValue(String.valueOf(totalDatas.get(i).get("bz"))); +// wrti[19].setView(true);//字段是否可见 +// wrti[19].setEdit(true);//字段是否可编辑 +// +// wrtri[i] = new WorkflowRequestTableRecord(); +// wrtri[i].setWorkflowRequestTableFields(wrti); +// } +// //添加到明细表中 +// WorkflowDetailTableInfo WorkflowDetailTableInfo[] = new WorkflowDetailTableInfo[1];//指定明细表的个数,多个明细表指定多个,顺序按照明细的顺序 +// WorkflowDetailTableInfo[0] = new WorkflowDetailTableInfo(); +// WorkflowDetailTableInfo[0].setWorkflowRequestTableRecords(wrtri); +// //添加工作流id +// WorkflowBaseInfo wbi = new WorkflowBaseInfo(); +// wbi.setWorkflowId(workflowId);//workflowid 流程接口演示流程2016==38 +// WorkflowRequestInfo wri = new WorkflowRequestInfo();//流程基本信息 +// wri.setCreatorId("1");//创建人id ToDo:这里先写死,稍后再做改写 +// wri.setRequestLevel("0");//0 正常,1重要,2紧急 +// String workflowTitle = this.getWorkflowTitle(Util.null2String(String.valueOf(totalDatas.get(0).get("ppbm")))); +// wri.setRequestName(workflowTitle);//流程标题 +// wri.setWorkflowMainTableInfo(wmi);//添加主字段数据 +// wri.setWorkflowDetailTableInfos(WorkflowDetailTableInfo);//添加明细数据 +// wri.setWorkflowBaseInfo(wbi); +//// wri.setIsnextflow(isNextFlow);//是否提交下一个节点 +// WorkflowService workflowService = new WorkflowServiceImpl(); +// String requestid =workflowService.doCreateWorkflowRequest(wri,1); +// logger.info("===requestid==="+requestid); +// if (!requestid.equals("")){ +// return "流程创建成功"; +// }else { +// return "流程创建失败"; +// } +// } catch (Exception e) { +// e.printStackTrace(); +// logger.info("流程创建异常===异常信息===="+e); +// return "流程创建异常===异常信息===="+e; +// } +// +// +// } +// +// /** +// *

获取流程标题

+// * @param pp 品牌名称 +// * @return String +// * @author hcy +// * @Date 2023/3/16 11:27 +// */ +// public String getWorkflowTitle(String pp){ +// String ppName = getWorkflowDataMapper.selectPpName(pp); +// String workflowName = ppName + "-" + getSystemDate() + "-" + "office库存领用/退还明细"; +// logger.info("workflowName==="+workflowName); +// return workflowName; +// } +// /** +// *

获取系统当年份

+// * @param +// * @return String +// * @author hcy +// * @Date 2023/3/15 13:52 +// */ +// public String getSystemDate(){ +// Date date = new Date(); +// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); +// return dateFormat.format(date); +// } +// +// +//} diff --git a/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/rollbackmoneytoworkflow/acton/RollbackMoneyToWorkflowAction.java b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/rollbackmoneytoworkflow/acton/RollbackMoneyToWorkflowAction.java new file mode 100644 index 0000000..5b6c2e7 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/rollbackmoneytoworkflow/acton/RollbackMoneyToWorkflowAction.java @@ -0,0 +1,119 @@ +package weaver.chaoyang.he.hcy_fengtianfangzhi.rollbackmoneytoworkflow.acton; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Cell; +import weaver.soa.workflow.request.DetailTable; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.Row; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

对公付款申请(一般采购)明细表二:验收入库单中的已申请金额/未申请金额计算后需要反填到验收入库单中

+ * @Author hcy + * @Date 2023/1/30 19:57 + */ +public class RollbackMoneyToWorkflowAction implements Action { + + private Logger logger = Util.getLogger(); + + @Override + public String execute(RequestInfo requestInfo) { + try { + Map>> detailTableValue = this.getDetailTableValue(requestInfo); + + List> lists = detailTableValue.get("2");//获取到明细表2中的所有数据 + logger.info("lists=="+ lists); + for (Map list : lists) { + String ysrkdh = Util.null2String(list.get("ysrkdh"));//验收入库单号字段 + logger.info("验收入库单号==="+ysrkdh); + String bcfkjehs = Util.null2String(list.get("bcfkjehs"));//本次付款金额(含税) + logger.info("本次付款金额(含税)---bcfkjehs==="+bcfkjehs); + String selectValueSql = "select hszje,ysqje from uf_ysrkd where id=?"; + RecordSet recordSet = new RecordSet(); + boolean b = recordSet.executeQuery(selectValueSql, ysrkdh); + logger.info("b是否执行==="+b); + Double hszjeTotal = 0.0;//wszje 含税总金额 + Double ysqjeTotal = 0.0;//ysqje 已申请金额 + Double wsqjeTotal = 0.0;//wsqje 未申请金额 + if (recordSet.next()) { + String hszje = Util.null2String(recordSet.getString("hszje"));//hszje 含税总金额 + String ysqje = Util.null2String(recordSet.getString("ysqje"));// ysqje 已申请金额 + + logger.info("含税总金额---hszje==="+ysqje); + if (!"".equals(ysqje) && !"".equals(bcfkjehs)){ + Double ysqjeDouble = Double.parseDouble(ysqje); + Double bcfkjehsDouble = Double.parseDouble(bcfkjehs); + ysqjeTotal = ysqjeDouble + bcfkjehsDouble; + } + if (!"".equals(hszje)) { + hszjeTotal = Double.parseDouble(hszje); + } + + } + logger.info("hszjeTotal==="+ysqjeTotal); + + String updateYsqje_Sql = "update uf_ysrkd set ysqje = ? where id = ?"; + boolean b1 = recordSet.executeUpdate(updateYsqje_Sql, ysqjeTotal, ysrkdh); + logger.info("b1是否执行==="+b1); + + //开始更新未申请金额 = 含税总金额 - 已申请金额 :wsqje = hszje - ysqje + wsqjeTotal = hszjeTotal - ysqjeTotal; + String updateWsqje_sql = "update uf_ysrkd set wsqje = ? where id = ?"; + boolean b2 = recordSet.executeUpdate(updateWsqje_sql, wsqjeTotal, ysrkdh); + logger.info("b2是否执行==="+b2); + } + } catch (NumberFormatException e) { + e.printStackTrace(); + logger.info("NumberFormatException==="+e); + } + return Action.SUCCESS; + } + + + + /** + *

获取所有明细数据

+ * + * @return 以明细表需要为键,以明细表数据为值的键值对明细数据信息 + */ + protected Map>> getDetailTableValue(RequestInfo requestInfo) { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 0.75)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + /** + *

根据明细表信息获取明细表数据

+ * + * @param detailTable 明细表对象 + * @return 明细表数据 + */ + @NotNull + private List> getDetailValue(DetailTable detailTable) { + Row[] rowArr = detailTable.getRow(); + List> detailData = new ArrayList<>(rowArr.length); + for (Row row : rowArr) { + Cell[] cellArr = row.getCell(); + Map rowData = new HashMap<>((int) Math.ceil(cellArr.length * 0.75)); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/update_lqts/action/UpdateLqtsAction.java b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/update_lqts/action/UpdateLqtsAction.java new file mode 100644 index 0000000..e43a010 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/update_lqts/action/UpdateLqtsAction.java @@ -0,0 +1,83 @@ +package weaver.chaoyang.he.hcy_fengtianfangzhi.update_lqts.action; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + + +/** + *

调用进项发票信息获取接口,将返回值回写到发票台账

+ * @Author hcy + * @Date 2023/1/30 15:49 + */ +public class UpdateLqtsAction extends BaseCronJob { + + private Logger logger = Util.getLogger(); + @Override + public void execute() { + try { + RecordSet recordSet = new RecordSet(); + String getDB_Sql = "select * from uf_clgm_dt1"; + boolean b = recordSet.executeQuery(getDB_Sql); + logger.info("getDB_Sql---b---是否执行==="+b); + + while (recordSet.next()){ + String sjnq = recordSet.getString("sjnq");//实际纳期 + String id = recordSet.getString("id"); + logger.info("实际纳期==="+sjnq); + String currentTime = this.getCurrentTime();//系统当前日期 + long daySub = getDaySub(currentTime, sjnq); + RecordSet recordSet1 = new RecordSet(); + String update_lqts_Sql ="update uf_clgm_dt1 set lqts = ? where id = ?"; + boolean b1 = recordSet1.executeUpdate(update_lqts_Sql, daySub, id); + logger.info("b1是否执行=="+b1); + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("Exception==="+e); + } + } + + /** + *

日期相减得到的天数

+ * @param beginDateStr,endDateStr + * @return long + * @author hcy + */ + public static long getDaySub(String beginDateStr, String endDateStr) { + + long day = 0; + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date beginDate; + Date endDate; + try { + beginDate = format.parse(beginDateStr); + endDate = format.parse(endDateStr); + day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000); + } catch (ParseException e) { + e.printStackTrace(); + } + System.out.println("day:" + day); + + return day; + } + + /** + *

返回系统当前日期时间

+ * @param + * @return String 当前日期 + * @author hcy + */ + public String getCurrentTime(){ + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(); + String currentTime = dateFormat.format(date); + return currentTime; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/updatepdfname/action/UpdatePDFNameAction.java b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/updatepdfname/action/UpdatePDFNameAction.java new file mode 100644 index 0000000..3a995ad --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_fengtianfangzhi/updatepdfname/action/UpdatePDFNameAction.java @@ -0,0 +1,132 @@ +package weaver.chaoyang.he.hcy_fengtianfangzhi.updatepdfname.action; + +import aiyh.utils.Util; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.*; + +import java.text.SimpleDateFormat; +import java.util.*; + + +/** + *

配置节点后附加操作,用于修改流程存为文档pdf的名称

+ * @Author hcy + * @Date 2023/4/8 0:23 + */ +public class UpdatePDFNameAction implements Action { + /** + * 日志 + */ + private Logger logger = Util.getLogger(); + + public String execute(RequestInfo requestInfo) { + Map mainTableMap = this.getMainTableValue(requestInfo);//yczwzd + String docid = mainTableMap.get("yczwzd");//隐藏正文字段 ---用于存放主文书(定期品)和注文书(临期品)的pdf字段 是DocImageFile中的docid + logger.info("docid=="+docid); + String imagefilename = this.getImagefilename(mainTableMap); + logger.info("修改的文件名称==="+imagefilename); + RecordSet recordSet = new RecordSet(); + String selectpdfSql = "select imagefilename from DocImageFile where docid = ?"; + recordSet.executeQuery(selectpdfSql, docid); + recordSet.next(); + String imagefilename1 = Util.null2String(recordSet.getString("imagefilename")); + logger.info("修改前的文件名称为==="+imagefilename1); + if (!"".equals(imagefilename1)&&imagefilename1.endsWith(".pdf")){ + String updatePdfNameSql = "update DocImageFile set imagefilename = ? where docid = ?"; + boolean updateFileName = recordSet.executeUpdate(updatePdfNameSql, imagefilename, docid); + logger.info("修改文件名称是否成功"+updateFileName); + } + return Action.SUCCESS; + } + + private String getImagefilename(Map mainTableDataMap) { + + //订单编号 :sqdh + //供应商 : gys + //申请人部门 : sqrbm + String sqdh = mainTableDataMap.get("sqdh");//订单编号 + String gys = mainTableDataMap.get("gys");//供应商 + String sqrbm = mainTableDataMap.get("sqrbm");//申请人部门 + RecordSet recordSet1 = new RecordSet(); + String getGysValueSql = "select gysqm from uf_gyszsjxx where id=?"; + recordSet1.executeQuery(getGysValueSql,gys); + recordSet1.next(); + String gysValue = recordSet1.getString("gysqm");//供应商的值 + String getSqrbmSql = "select departmentname from hrmdepartment where id = ?"; + recordSet1.executeQuery(getSqrbmSql,sqrbm); + recordSet1.next(); + String departmentname = recordSet1.getString("departmentname");//申请人部门 + return sqdh+"_"+gysValue+"_"+departmentname+"_"+this.getSystemDate()+".pdf"; + } + + + /** + *

获取系统当年份

+ * @return String + * @author hcy + * 2023/3/15 13:52 + */ + public String getSystemDate(){ + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + return dateFormat.format(date); + } + + /** + *

获取流程主表数据

+ * + * @return 流程主表数据 + */ + protected Map getMainTableValue(RequestInfo requestInfo) { +// 获取主表数据 + Property[] propertyArr = requestInfo.getMainTableInfo().getProperty(); + if (null == propertyArr) { + return Collections.emptyMap(); + } + Map mainTable = new HashMap<>((int) Math.ceil(propertyArr.length * 1.4)); + for (Property property : propertyArr) { + String fieldName = property.getName(); + String value = property.getValue(); + mainTable.put(fieldName, value); + } + return mainTable; + } + /** + *

获取所有明细数据

+ * + * @return 以明细表需要为键,以明细表数据为值的键值对明细数据信息 + */ + protected Map>> getDetailTableValue(RequestInfo requestInfo) { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 0.75)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + /** + *

根据明细表信息获取明细表数据

+ * + * @param detailTable 明细表对象 + * @return 明细表数据 + */ + private List> getDetailValue(DetailTable detailTable) { + Row[] rowArr = detailTable.getRow(); + List> detailData = new ArrayList<>(rowArr.length); + for (Row row : rowArr) { + Cell[] cellArr = row.getCell(); + Map rowData = new HashMap<>((int) Math.ceil(cellArr.length * 0.75)); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_pcn/noticeaftersigned/action/NoticeAfterSigned.java b/src/main/java/weaver/chaoyang/he/hcy_pcn/noticeaftersigned/action/NoticeAfterSigned.java new file mode 100644 index 0000000..51e8384 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_pcn/noticeaftersigned/action/NoticeAfterSigned.java @@ -0,0 +1,225 @@ +package weaver.chaoyang.he.hcy_pcn.noticeaftersigned.action; + +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Cell; +import weaver.soa.workflow.request.DetailTable; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.Row; +import weaver.workflow.request.RequestManager; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.service.DealWithMapping; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class NoticeAfterSigned implements Action { + + + private String uniqueCode;//唯一标识 + private String apikey; + private String accountMessageTableName; //台账数据表名 + private String statusName; //状态名 + private String updateFieldName; //更新标识字段 + private String valueUpdateFiledName;//明细字段名 + private String detailkey;//哪个明细表 + + private final Logger log = aiyh.utils.Util.getLogger(); + private final DealWithMapping dealWithMapping = new DealWithMapping(); + + @Override + public String execute(RequestInfo requestInfo) { + log.info("NoticeAfterSigned begin;requestid:" + requestInfo.getRequestid()); + RequestManager requestManager = requestInfo.getRequestManager(); + try{ + + String tableName = requestManager.getBillTableName(); + String requestid = requestInfo.getRequestid(); + RecordSet rs = new RecordSet(); + String sql = "select * from " + tableName + " where requestid = ?"; + Map params = new HashMap<>();//请求体 + dealWithMapping.setMainTable(tableName); + if (rs.executeQuery(sql,requestid) && rs.next()) { + RequestMappingConfig conf = dealWithMapping.treeDealWithUniqueCode(uniqueCode); + String requestUrl = conf.getRequestUrl();//目标url + log.info("获取到的url为:"+requestUrl); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("Accept", MediaType.APPLICATION_JSON); + headers.put("Content-Type", "application/json"); + headers.put("apikey", apikey); + HttpUtils httpUtils = new HttpUtils(); + + //请求体 + List> li = new ArrayList<>(); //定义一个map元素的List集合用来存放 + List requestListParam = dealWithMapping.getRequestListParam(rs, conf); + for (Object requestParam : requestListParam) { + params = (Map) requestParam; + log.info("得到的请求体内容为:"+params); + try { + ResponeVo responeVo = httpUtils.apiPost(requestUrl, params, headers); + log.info("接口返回值===="+responeVo); + int code = responeVo.getCode(); + log.info("状态码为:code===="+code); + Map m = new HashMap<>(); + m.put("status",""); + + if (code == 200){ + Map entityMap = responeVo.getEntityMap(); + int errcode = (int)entityMap.get("errcode"); + int status = 4; + //根据状态码更新台账合同状态 + if (errcode==200){ + status = 0; + }else if (errcode==1000089){ + status = 1; + }else if (errcode==1000090){ + status = 2; + }else if (errcode==1000091){ + status = 3; + } + m.put("status",status); + li.add(m); + + }else { + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("对方接口链接超时"); + return Action.FAILURE_AND_CONTINUE; + } + } catch (IOException e) { + log.info("调用接口异常报错==="+e); + e.printStackTrace(); + } + } + try { + Map>> detailTableValue = this.getDetailTableValue(requestInfo); + + List> values = detailTableValue.get(detailkey); + for(int i = 0;i < values.size();i ++){ + Map m = values.get(i); + String value = m.get(valueUpdateFiledName); + int status = (int) li.get(i).get("status"); + log.info("li===="+li); + String updateSql = "update "+accountMessageTableName+" set "+statusName+"= ? where "+updateFieldName+"= ?"; + log.info("updateSql更新的sql语句"+updateSql); + boolean b = rs.executeUpdate(updateSql, status, value); + log.info("更新合同台账信息===="+b); + } + } catch (Exception e) { + log.info("台账状态更新异常:"+e); + e.printStackTrace(); + } + } + log.info("action done;requestid:" + requestid); + return Action.SUCCESS; + }catch (Exception e1){ + log.error("requestid:" + requestInfo.getRequestid() + ";mesage:" + e1.getMessage() + ";e:" + e1); + requestManager.setMessageid(String.valueOf(System.currentTimeMillis())); + requestManager.setMessagecontent("action 异常,请联系管理员!"); + return Action.FAILURE_AND_CONTINUE; + } + } + + public String getUniqueCode() { + return uniqueCode; + } + + public void setUniqueCode(String uniqueCode) { + this.uniqueCode = uniqueCode; + } + + public String getApikey() { + return apikey; + } + + public void setApikey(String apikey) { + this.apikey = apikey; + } + + public String getAccountMessageTableName() { + return accountMessageTableName; + } + + public void setAccountMessageTableName(String accountMessageTableName) { + this.accountMessageTableName = accountMessageTableName; + } + + public String getStatusName() { + return statusName; + } + + public void setStatusName(String statusName) { + this.statusName = statusName; + } + + public String getUpdateFieldName() { + return updateFieldName; + } + + public void setUpdateFieldName(String updateFieldName) { + this.updateFieldName = updateFieldName; + } + + public String getValueUpdateFiledName() { + return valueUpdateFiledName; + } + + public void setValueUpdateFiledName(String valueUpdateFiledName) { + this.valueUpdateFiledName = valueUpdateFiledName; + } + + public String getDetailkey() { + return detailkey; + } + + public void setDetailkey(String detailkey) { + this.detailkey = detailkey; + } + + /** + *

获取所有明细数据

+ * + * @return 以明细表需要为键,以明细表数据为值的键值对明细数据信息 + */ + protected Map>> getDetailTableValue(RequestInfo requestInfo) { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 0.75)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + /** + *

根据明细表信息获取明细表数据

+ * + * @param detailTable 明细表对象 + * @return 明细表数据 + */ + private List> getDetailValue(DetailTable detailTable) { + Row[] rowArr = detailTable.getRow(); + List> detailData = new ArrayList<>(rowArr.length); + for (Row row : rowArr) { + Cell[] cellArr = row.getCell(); + Map rowData = new HashMap<>((int) Math.ceil(cellArr.length * 0.75)); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } + + +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_pcn/sendfieldstoothersystem/action/SendFieldsAction.java b/src/main/java/weaver/chaoyang/he/hcy_pcn/sendfieldstoothersystem/action/SendFieldsAction.java new file mode 100644 index 0000000..804c837 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_pcn/sendfieldstoothersystem/action/SendFieldsAction.java @@ -0,0 +1,146 @@ +package weaver.chaoyang.he.hcy_pcn.sendfieldstoothersystem.action; + +import aiyh.utils.httpUtil.HttpMultipartFile; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import cn.hutool.crypto.SecureUtil; +import org.apache.commons.codec.binary.Hex; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.general.Util; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; +import weaver.xiao.commons.config.entity.MultipartFile; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.service.DealWithMapping; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SendFieldsAction implements Action { + + private String clientId; //由SBS提供clientId + private String clientSecret; //由SBS提供clientSecret + private final DealWithMapping dealWithMapping = new DealWithMapping(); + private String onlyMark;//用于查询配置表的唯一标识 + private final Logger log = aiyh.utils.Util.getLogger(); + + public String execute(RequestInfo requestInfo) { + String tableName = requestInfo.getRequestManager().getBillTableName(); + String requestId = requestInfo.getRequestid(); + RecordSet rs = new RecordSet(); + String sql = "select * from " + tableName + " where requestid = ?"; + log.info("sql======>" + sql); + String response = ""; + int code; + String data = ""; + dealWithMapping.setMainTable(tableName); + try { + if (rs.executeQuery(sql, requestId) && rs.next()) { + RequestMappingConfig config = dealWithMapping.treeDealWithUniqueCode(onlyMark); + String post_url = config.getRequestUrl(); + // 生成的map数据 + Map mapBodyParam = dealWithMapping.getRequestParam(rs, config); + // 获取多文件数据信息 + List multipartFileList = dealWithMapping.getMultipartFileList(); + List multipartFiles = new ArrayList<>(); + for (MultipartFile multipartFile : multipartFileList) { + HttpMultipartFile multipart + = new HttpMultipartFile(); + multipart.setFileKey(multipartFile.getFileKey()); + multipart.setFileName(multipartFile.getFileName()); + multipart.setFileSize(multipartFile.getFileSize()); + multipart.setStream(multipartFile.getStream()); + multipartFiles.add(multipart); + } + // 请求头 + String timestamp = String.valueOf(System.currentTimeMillis()); + String nonce = this.getRandomNumber(); + HashMap headers = new HashMap<>(); + headers.put("Content-Type", MediaType.MULTIPART_FORM_DATA); + headers.put("X-Timestamp", timestamp); + headers.put("X-Client-Id", clientId); + headers.put("X-Nonce", nonce); + headers.put("user-agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"); + headers.put("X-Sign", this.sign(timestamp, nonce)); + HttpUtils httpUtils = new HttpUtils(); + try { +// httpUtils.uploadFileByInputStream();//调用文件上传的接口 + ResponeVo responeVo = httpUtils.apiPutUploadFiles(post_url, multipartFiles, mapBodyParam, headers); + response = Util.null2String(responeVo.getEntityString()); + code = responeVo.getCode(); + if (code == 200) { + Map entityMap = responeVo.getEntityMap(); + data = String.valueOf(entityMap.get("data")); + if (data.equals("true")) { + return Action.SUCCESS; + } else { + return Action.FAILURE_AND_CONTINUE; + } + } else { + log.info("状态请求失败,对方相应code不为200"); + return Action.FAILURE_AND_CONTINUE; + } + } catch (IOException e) { + log.info("fetch " + post_url + " error!"); + throw e; + } + } + } catch (Exception e) { + log.error("action execute fail! error msg : \n" + aiyh.utils.Util.getErrString(e)); + } + return Action.FAILURE_AND_CONTINUE; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getOnlyMark() { + return onlyMark; + } + + public void setOnlyMark(String onlyMark) { + this.onlyMark = onlyMark; + } + + /** + * 随机码 + */ + private String getRandomNumber() { + byte[] result = new byte[16]; + SecureRandom secRandom = new SecureRandom(); + secRandom.nextBytes(result); + return Hex.encodeHexString(result); + } + + + /** + * POST签名 + */ + private String sign(String timestamp, String nonce) { + StringBuilder sb = new StringBuilder(); + sb.append(timestamp).append(nonce).append(clientSecret); + log.info("body签名字符串:{},timestamp:{},nonce:{}"); + System.out.println("签名:" + SecureUtil.md5(sb.toString())); + return SecureUtil.md5(sb.toString()); + } + +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBAction.java b/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBAction.java new file mode 100644 index 0000000..8103b5a --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBAction.java @@ -0,0 +1,116 @@ +package weaver.chaoyang.he.hcy_pcn.workflowsetvalue.action; + +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.general.Util; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Property; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.RequestService; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 业务需求在A流程归档前增加aciton, + * 将A中的部分字段信息(包括附件), + * 根据requestid更新到B流程中, + * 并且将B流程提交到下一节点。 + */ +public class SubmitAtoBAction implements Action { + + /** + * 目标请求参数字段 + */ + private String targetRequestField; + + /** + * 配置文件唯一标识 + */ + private String uniqueFieldId; + + private final Logger log = aiyh.utils.Util.getLogger(); + + + public String execute(RequestInfo requestInfo) { + + String sql = "select * from uf_lczdzdypzb where wybs = '" + uniqueFieldId +"'"; //查询uf_lczdzdypzb流程字段值对应配置表的数据 + RecordSet rs = new RecordSet(); //创建sql对象 + RecordSet rs02 = new RecordSet();//创建sql02对象 + rs.executeQuery(sql);//执行sql语句 + + Map tableInfo = this.getWfMainTableInfo(requestInfo);//原流程数据 + + String mainId = "";//查询主表中id,用于对应明细表中mainid + String mbzd="";//目标字段 + String yzd = "";//原字段 + String setRule = "";//update中set条件 + Map mapKey = new HashMap<>(); + + if (rs.next()){ + mainId = rs.getString("id");//查询主表中id,用于对应明细表中mainid + log.info("查询主表中id,用于对应明细表中mainid---mainid==="+mainId); + //todo 通过workflowid查数据库表获取表名 + String sql_dt1 = "select ck1.fieldname mbzd, ck.fieldname yzd from uf_lczdzdypzb_dt1 dt left join workflow_field_table_view ck on dt.yzd = ck.id left join workflow_field_table_view ck1 on dt.mbzd = ck1.id where mainid = ?";//查询明细表 + rs02.executeQuery(sql_dt1,mainId);//执行明细表sql语句 + while (rs02.next()){ + mbzd = rs02.getString("mbzd");//目标字段 + yzd = rs02.getString("yzd");//原字段 + mapKey.put(mbzd,yzd); + log.info("明细表执行结果>>>>>>>>>>"+"目标字段="+mbzd+"-----原字段="+yzd); + } + RequestService requestService=new RequestService(); + //todo 获取表名 + String targetRequestId = tableInfo.get(targetRequestField); + String tableName = requestService.getRequest(Util.getIntValue(targetRequestId)).getRequestManager().getBillTableName(); + Set keySet = mapKey.keySet(); + for (String s : keySet) { + String valueYzd = tableInfo.get(mapKey.get(s)); + setRule += s + "= " + "'" + valueYzd + "'" +" ,"; + } + setRule = setRule.substring(0,setRule.length()-1); + log.info("update中set条件,setRule==="+setRule); + + String sqlmbLc = "update "+tableName+" set " + setRule + " where requestid = ?";//update 目标流程 set 目标字段 = 原字段 where requestid = ? ; + rs.executeUpdate(sqlmbLc,targetRequestId); + log.info("更新语句update>>>>>>"+ sqlmbLc +"===requestid="+targetRequestId); + log.info("B流程开始提交"); + boolean b = requestService.nextNodeBySubmit(requestService.getRequest(Util.getIntValue(targetRequestId)), Util.getIntValue(targetRequestId), 1, "action自动提交流程(流程字段赋值)"); + + log.info("B流程提交结束"); + } + return Action.SUCCESS; + } + + + public String getTargetRequestField() { + return targetRequestField; + } + + public void setTargetRequestField(String targetRequestField) { + this.targetRequestField = targetRequestField; + } + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + /** + * 获取流程主表数据 + * + * @param requestInfo 流程信息对象 + * @return Map key 字段名 value 字段值 + */ + public Map getWfMainTableInfo(RequestInfo requestInfo) { + Map map = new HashMap<>(); + for (Property property : requestInfo.getMainTableInfo().getProperty()) { + map.put(property.getName(), property.getValue()); + } + return map; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBActionCopy.java b/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBActionCopy.java new file mode 100644 index 0000000..dc1f8af --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_pcn/workflowsetvalue/action/SubmitAtoBActionCopy.java @@ -0,0 +1,116 @@ +package weaver.chaoyang.he.hcy_pcn.workflowsetvalue.action; + +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.general.Util; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.Property; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.RequestService; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * 业务需求在A流程归档前增加aciton, + * 将A中的部分字段信息(包括附件), + * 根据requestid更新到B流程中, + * 并且将B流程提交到下一节点。 + */ +public class SubmitAtoBActionCopy implements Action { + + /** + * 目标请求参数字段 + */ + private String targetRequestField; + + /** + * 配置文件唯一标识 + */ + private String uniqueFieldId; + + private final Logger log = aiyh.utils.Util.getLogger(); + + + public String execute(RequestInfo requestInfo) { + + String sql = "select * from uf_lczdzdypzb where wybs = '" + uniqueFieldId +"'"; //查询uf_lczdzdypzb流程字段值对应配置表的数据 + RecordSet rs = new RecordSet(); //创建sql对象 + RecordSet rs02 = new RecordSet();//创建sql02对象 + rs.executeQuery(sql);//执行sql语句 + + Map tableInfo = this.getWfMainTableInfo(requestInfo);//原流程数据 + + String mainId = "";//查询主表中id,用于对应明细表中mainid + String mbzd="";//目标字段 + String yzd = "";//原字段 + String setRule = "";//update中set条件 + Map mapKey = new HashMap<>(); + + if (rs.next()){ + mainId = rs.getString("id");//查询主表中id,用于对应明细表中mainid + log.info("查询主表中id,用于对应明细表中mainid---mainid==="+mainId); + //todo 通过workflowid查数据库表获取表名 + String sql_dt1 = "select ck1.fieldname mbzd, ck.fieldname yzd from uf_lczdzdypzb_dt1 dt left join workflow_field_table_view ck on dt.yzd = ck.id left join workflow_field_table_view ck1 on dt.mbzd = ck1.id where mainid = ?";//查询明细表 + rs02.executeQuery(sql_dt1,mainId);//执行明细表sql语句 + while (rs02.next()){ + mbzd = rs02.getString("mbzd");//目标字段 + yzd = rs02.getString("yzd");//原字段 + mapKey.put(mbzd,yzd); + log.info("明细表执行结果>>>>>>>>>>"+"目标字段="+mbzd+"-----原字段="+yzd); + } + RequestService requestService=new RequestService(); + //todo 获取表名 + String targetRequestId = tableInfo.get(targetRequestField); + String tableName = requestService.getRequest(Util.getIntValue(targetRequestId)).getRequestManager().getBillTableName(); + Set keySet = mapKey.keySet(); + for (String s : keySet) { + String valueYzd = tableInfo.get(mapKey.get(s)); + setRule += s + "= " + "'" + valueYzd + "'" +" ,"; + } + setRule = setRule.substring(0,setRule.length()-1); + log.info("update中set条件,setRule==="+setRule); + + String sqlmbLc = "update "+tableName+" set " + setRule + " where requestid = ?";//update 目标流程 set 目标字段 = 原字段 where requestid = ? ; + rs.executeUpdate(sqlmbLc,targetRequestId); + log.info("更新语句update>>>>>>"+ sqlmbLc +"===requestid="+targetRequestId); + log.info("B流程开始提交"); + boolean b = requestService.nextNodeBySubmit(requestService.getRequest(Util.getIntValue(targetRequestId)), Util.getIntValue(targetRequestId), 1, "action自动提交流程(流程字段赋值)"); + + log.info("B流程提交结束"); + } + return Action.SUCCESS; + } + + + public String getTargetRequestField() { + return targetRequestField; + } + + public void setTargetRequestField(String targetRequestField) { + this.targetRequestField = targetRequestField; + } + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + /** + * 获取流程主表数据 + * + * @param requestInfo 流程信息对象 + * @return Map key 字段名 value 字段值 + */ + public Map getWfMainTableInfo(RequestInfo requestInfo) { + Map map = new HashMap<>(); + for (Property property : requestInfo.getMainTableInfo().getProperty()) { + map.put(property.getName(), property.getValue()); + } + return map; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/filterinvoice/FilterInvoiceService.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/filterinvoice/FilterInvoiceService.java new file mode 100644 index 0000000..5c6425e --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/filterinvoice/FilterInvoiceService.java @@ -0,0 +1,31 @@ +package weaver.chaoyang.he.hcy_yihong.filterinvoice; + +import aiyh.utils.Util; +import com.engine.common.service.BrowserTabService; +import com.engine.common.service.impl.BrowserTabServiceImpl; +import com.engine.core.cfg.annotation.ServiceDynamicProxy; +import com.engine.core.cfg.annotation.ServiceMethodDynamicProxy; +import com.engine.core.impl.aop.AbstractServiceProxy; +import org.apache.log4j.Logger; + +import java.util.Map; + +@ServiceDynamicProxy(target = BrowserTabServiceImpl.class, desc="实现BrowserTabService对象用于过滤除去航信的数据") +public class FilterInvoiceService extends AbstractServiceProxy implements BrowserTabService { + private final Logger logger = Util.getLogger(); + @Override + @ServiceMethodDynamicProxy(desc="过滤除去AP航信的数据") + public Map list(Map map) { + Map result = (Map)executeMethod(map); + logger.info("result==="+result); + return null; + } + + @Override + public Map update(Map map) { + return null; + } + + + //api/common/browsetab/list?type=293&__random__=1677073032544 +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction.java new file mode 100644 index 0000000..162e652 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction.java @@ -0,0 +1,326 @@ +package weaver.chaoyang.he.hcy_yihong.sendinvoicevaluestoaccounttable.action; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import lombok.SneakyThrows; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; +import weaver.wechat.util.Utils; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceValuesToAccountTableAction extends BaseCronJob { + + + private Logger logger = Util.getLogger(); + + private String uniqueFieldId; + + private String url;//请求的接口的url + + @SneakyThrows + @Override + public void execute() { + try { + String sql1 = "select taxNo,belongTo from uf_TaxNo_Config"; + RecordSet rs1 = new RecordSet(); + rs1.executeQuery(sql1); + + //获取上一次操作的日期 + String startDay = Util.getCusConfigValue("getDataTime"); + + //获取当前的日期 + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String endDay = dateFormat.format(date); + + while(rs1.next()){ + + String taxNo = Util.null2String(rs1.getString("taxNo")); + String belongTo = Util.null2String(rs1.getString("belongTo")); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("User-Agent", "Apifox/1.0.0 (https://www.apifox.cn)"); + headers.put("Content-Type", "application/json"); + + String dateAddday3 = dateAdd3(startDay); + logger.info("开始时间往前推3天--dateAddday3==="+dateAddday3); + //设置请求体 + Map body = new HashMap<>(); + body.put("identity",taxNo); + body.put("startDay",dateAddday3); + body.put("endDay",endDay); + HttpUtils httpUtils = new HttpUtils(); + + ResponeVo responeVo = httpUtils.apiPost(url, body, headers); + int code = responeVo.getCode(); + if (code != 200){ + logger.info("对方接口状态码为:"+code+" 程序执行错误"); + continue; + } + Map entityMap = responeVo.getEntityMap(); + List datas = (List)entityMap.get("data"); + if (datas==null ||datas.isEmpty()){ + logger.info("接口返回主表参数为空,请查询税号是否准确"); + continue; + } + Map totalDataMap = new HashMap(); + String invoice_detail_Mainid = "";//用来判断台账表中是否含有相同记录 + for (Object data : datas){ + totalDataMap = (Map)data;//主表数据 + logger.info("主表数据==="+totalDataMap); + //第五步:查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + Object invoiceCode = totalDataMap.get("invoiceCode");//发票代码 + Object invoiceNum = totalDataMap.get("invoiceNum");//发票号码 + + //需求更新:需要在主表数据中选出卖方税号,这里的卖方税号=供应商库uf_gysxx里面的供应商税号 + RecordSet recordSet = new RecordSet(); + String serllerTaxNo = Utils.null2String(totalDataMap.get("sellerTaxNo"));//销方税号 + String sellerName = Utils.null2String(totalDataMap.get("sellerName"));//销方名称 + logger.info("销方税号--serllerTaxNo==="+serllerTaxNo+"--销方名称---sellerName==="+sellerName); + String getuf_gysxx_countId = "select count(id) countId from uf_gysxx where gyssh = ?"; + boolean getuf_gysxx_countId_boolean = recordSet.executeQuery(getuf_gysxx_countId, serllerTaxNo); + logger.info("getuf_gysxx_countId_boolean是否执行"+getuf_gysxx_countId_boolean); + if (getuf_gysxx_countId_boolean&&recordSet.next()) { + String countId = Utils.null2String(recordSet.getString("countId"));//查询到的数据的条数 + int countIdInt=0; + if (!"".equals(countId)){ + countIdInt = Integer.parseInt(countId); + logger.info("数据一共有几条==="+countId); + } + if (countIdInt==0){ + continue; + } +// if ((!countId.equals("1"))){ +// continue; +// } + RecordSet recordSet1 = new RecordSet(); + String getdataFrom_uf_gysxx = "select qfzd,hkyfjkgs from uf_gysxx where gyssh = ? and gysmc = ?"; + boolean getdataFrom_uf_gysxx_boolean = recordSet1.executeQuery(getdataFrom_uf_gysxx, serllerTaxNo, sellerName); + logger.info("getdataFrom_uf_gysxx_boolean是否执行==="+getdataFrom_uf_gysxx_boolean); + if (getdataFrom_uf_gysxx_boolean && recordSet1.next()){ + String qfzd = Utils.null2String(recordSet1.getString("qfzd"));//区分字段 +// String hkyfjkgs = Utils.null2String(recordSet1.getString("hkyfjkgs"));//货款/运费/进口关税 + if ((!qfzd.equals("0"))){ + continue; + } + } + } + + + //查询发票类型对应配置表:将想要转换的发票类型提前转换 + String queryInvoiceType = "select oaTypeValue from uf_InvoiceType_Mapping where interfaceTypeValue = ?";//改一下 + RecordSet rs2 = new RecordSet(); + rs2.executeQuery(queryInvoiceType,totalDataMap.get("invoiceType")); + if (rs2.next()){ + String oaTypeValue = Util.null2String(rs2.getString("oaTypeValue")); + totalDataMap.put("invoiceType",oaTypeValue);//转换发票类型 + logger.info("转换发票类型==="+oaTypeValue); + }else { + continue; +// totalDataMap.put("invoiceType","-1");//如果接口中的发票类型 + } + + //将时间戳转换成yyyy-MM-dd + String invoiceDate = (String)totalDataMap.get("invoiceDate"); + String new_invoiceDate = this.stampToDate(invoiceDate); + totalDataMap.put("invoiceDate",new_invoiceDate); + logger.info("转换后的时间戳====="+new_invoiceDate); + + //查询台账表中是否包含这个数据 + String sql2 = "select id from fnaInvoiceLedger where invoicecode = ? and invoicenumber = ?"; + + rs2.executeQuery(sql2,invoiceCode,invoiceNum); + if (rs2.next()) { + invoice_detail_Mainid = rs2.getString("id"); + logger.info("===invoice_detail_Mainid==="+invoice_detail_Mainid); + }else{ + invoice_detail_Mainid = ""; + } + + String mainId = ""; + String detailID = ""; + String updateSetkey = "";//当台账表中存在一条一样的数据的时候,我们需要设置更新条件 + List updateSetVaule = new ArrayList<>();//用来处理update条件下,?的赋值 + String insertSetKey = "(";//向台账中插入的key + String insertSetValue = "(";//向台账中插入的value + //第四步:通过配置的配置表获得到客户传的参数和台账字段的对应关系 + String sql3 = "select * from uf_fptzdypzbd where wybs = ?";//查询台账配置表 + if (rs2.executeQuery(sql3,uniqueFieldId)&&rs2.next()) { + mainId = rs2.getString("id");//查询发票台账对应配置表的id对应查询明细表的mainid + String sqlDetail1 = "select * from uf_fptzdypzbd_dt1 where mainid = ?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlDetail1,mainId); + + while(rs3.next()){ + String jkhqcs = rs3.getString("jkhqcs");//接口获取主表参数 + String sjkzcs = rs3.getString("sjkzcs");//数据库中主表参数 + String zhlx = rs3.getString("zhlx");//转换类型 + String zdyz = rs3.getString("zdyz");//自定义值 + if (zhlx!=""&&zhlx.equals("0")){ + updateSetkey += sjkzcs + "=" + "?,"; + insertSetKey += sjkzcs + ","; + insertSetValue += "?"+","; + updateSetVaule.add(totalDataMap.get(jkhqcs)); + }else if (zhlx!=""&&zhlx.equals("1")){ + updateSetkey += sjkzcs + "=" + "?,"; + insertSetKey += sjkzcs + ","; + insertSetValue += "?"+","; + updateSetVaule.add(zdyz); + } + } + //拼接 发票归属人 + updateSetkey = updateSetkey + "userid_new=?"; + updateSetVaule.add(Integer.parseInt(belongTo)); + insertSetKey = insertSetKey+"userid_new)"; + insertSetValue = insertSetValue+"?)"; + + + + logger.info("updateSetKey====="+updateSetkey); + logger.info("updateSetVaule====="+updateSetVaule); + logger.info("insertSetKey====="+insertSetKey); + logger.info("insertSetValue====="+insertSetValue); + } + //查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + logger.info("主表数据id---invoice_detail_Mainid==="+invoice_detail_Mainid); + if (!"".equals(Util.null2String(invoice_detail_Mainid))){//执行更新语句 + RecordSet recordSet4 = new RecordSet(); + String getHxjksflrSql = "select * from fnaInvoiceLedger where id = ?"; + boolean getHxjksflrBool = recordSet4.executeQuery(getHxjksflrSql, invoice_detail_Mainid); + logger.info("getHxjksflrBool是否执行==="+getHxjksflrBool); + String isApInvoice = ""; + if (getHxjksflrBool && recordSet4.next()){ + isApInvoice = Util.null2String(recordSet4.getString("hxjksflr"));// 判断这条数据是不是航信接口导入的数据 + logger.info("isApInvoice==="+isApInvoice); + } + + if ("Y".equals(isApInvoice)){ + updateSetVaule.add(invoiceCode); + updateSetVaule.add(invoiceNum); + String sqlUpdate = "update fnaInvoiceLedger set "+updateSetkey +" where invoicecode = ? and invoicenumber = ? "; + Object[] objects = updateSetVaule.toArray(); + logger.info("sqlUpdate更新的update语句====="+sqlUpdate); + boolean b = rs2.executeUpdate(sqlUpdate, objects); + logger.info("主表的更新语句是否更新=="+b); + } + }else{ + Object[] objects = updateSetVaule.toArray(); + String sqlInsert = "insert into fnaInvoiceLedger "+insertSetKey+" values "+insertSetValue; + logger.info("sqlInsert插入的insert语句======"+sqlInsert); + boolean b = rs2.executeUpdate(sqlInsert, objects); + logger.info("主表的插入语句是否插入=="+b); + } + //查询到刚插入的数据的id作为明细表的mainid + String sqlSelectId = "select id from fnaInvoiceLedger where invoicecode=? and invoicenumber=?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlSelectId,invoiceCode,invoiceNum); + if (rs3.next()){ + detailID= Util.null2String(rs3.getString("id")); + logger.info("detailID==="+detailID); + } + //向台账明细表中插入数据操作 + List details = (List)totalDataMap.get("detail");//明细表数据 + logger.info("明细表数据"+details); + String invoiceDetailSql = "delete from fnainvoiceledgerdetail where mainid = ?";//不管明细表中有没有内容一律删掉 + logger.info("不管明细表中有没有内容一律删掉sql语句==="+invoiceDetailSql); + boolean b1 = rs3.executeUpdate(invoiceDetailSql, detailID); + logger.info("删除操作是否成功b1===="+b1); + Map detailsMap = new HashMap<>(); + if (details ==null || details.isEmpty()){ + logger.info("明细表内容为空!跳出明细表出入循环"); + continue; + } + //开始查询配置表获得到客户传的明细表中参数和台账明细表中字段的对应关系 + for (Object detail : details) { + detailsMap = (Map)detail; + String sqlDetail2 = "select * from uf_fptzdypzbd_dt2 where mainid = ?"; + rs3.executeQuery(sqlDetail2,mainId); + String insertDetailSetKey = "(";//insert条件的拼接字符串1 + String insertDetailSetValue = "(";//insert条件的拼接字符串2 + List listDetail = new ArrayList<>();//用来将?赋值 + while (rs3.next()){ + String jkhqmxbzcs = Util.null2String(rs3.getString("jkhqmxbzcs"));//接口获取明细表中参数 + String jkhqmxbzcslx = Util.null2String(rs3.getString("jkhqmxbzcslx"));//接口获取明细表中参数类型 + String sjkzmxbcs = Util.null2String(rs3.getString("sjkzmxbcs"));//数据库中明细表参数 + String sjkzmxbcslx = Util.null2String(rs3.getString("sjkzmxbcslx"));//数据库中明细表参数类型 + insertDetailSetKey += sjkzmxbcs + ","; + insertDetailSetValue += "?,"; + listDetail.add(detailsMap.get(jkhqmxbzcs)); + + } + insertDetailSetKey = insertDetailSetKey + "mainid)"; + insertDetailSetValue = insertDetailSetValue+"?)"; + listDetail.add(detailID); + logger.info("明细表中用来插入的setkey---insertDetailSetKey==="+insertDetailSetKey); + logger.info("明细表中用来插入的setvalue---insertDetailSetValue==="+insertDetailSetValue); + logger.info("用来拼接?的listDetail"+listDetail); + + String insertIntoDetailSql = "insert into fnainvoiceledgerdetail "+insertDetailSetKey+ "values "+insertDetailSetValue ; + logger.info("insertIntoDetailSql明细表的插入语句==="+insertIntoDetailSql); + boolean b = rs3.executeUpdate(insertIntoDetailSql, listDetail); + logger.info("明细表数据插入是否成功===="+b); + } + } + } + //将当前时间设置到配置表中,作为下一次的开始时间 + logger.info("最后更新到配置表中的时间endDay==="+endDay); + Util.insertOrUpdateConfigValue("getDataTime",endDay,"更新同步时间"); + } catch (IOException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + /* + * 将时间戳转换为时间 + */ + public static String stampToDate(String s){ + String res; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long lt = new Long(s); + Date date = new Date(lt); + res = simpleDateFormat.format(date); + return res; + } + + public static String dateAdd3(String dateString){ + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //定义日期格式化的格式 + Date classDate = null;//把字符串转化成指定格式的日期 + try { + classDate = format.parse(dateString); + } catch (ParseException e) { + e.printStackTrace(); + } + Calendar calendar = Calendar.getInstance(); //使用Calendar日历类对日期进行加减 + calendar.setTime(classDate); + calendar.add(Calendar.DAY_OF_MONTH, -3); + classDate = calendar.getTime();//获取加减以后的Date类型日期 + String lastDate = format.format(classDate); + return lastDate; + } + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} \ No newline at end of file diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction01.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction01.java new file mode 100644 index 0000000..2f2f210 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction01.java @@ -0,0 +1,246 @@ +package weaver.chaoyang.he.hcy_yihong.sendinvoicevaluestoaccounttable.action; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import lombok.SneakyThrows; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceValuesToAccountTableAction01 extends BaseCronJob { + + + private Logger logger = Util.getLogger(); + + private String uniqueFieldId; + + private String url;//请求的接口的url + + + @SneakyThrows + @Override + public void execute() { + try { + String sql1 = "select taxNo,belongTo from uf_TaxNo_Config"; + RecordSet rs1 = new RecordSet(); + rs1.executeQuery(sql1); + + //获取上一次操作的日期 + String startDay = Util.getCusConfigValue("getDataTime"); + + //获取当前的日期 + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String endDay = dateFormat.format(date); + + while(rs1.next()){ + + String taxNo = rs1.getString("taxNo"); + String belongTo = rs1.getString("belongTo"); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("User-Agent", "Apifox/1.0.0 (https://www.apifox.cn)"); + headers.put("Content-Type", "application/json"); + + + //设置请求体 + Map body = new HashMap<>(); + body.put("identity",taxNo); + body.put("startDay",startDay); + body.put("endDay",endDay); + HttpUtils httpUtils = new HttpUtils(); + + ResponeVo responeVo = httpUtils.apiPost(url, body, headers); + int code = responeVo.getCode(); + if (code != 200){ + logger.info("对方接口状态码为:"+code+" 程序执行错误"); + continue; + } + Map entityMap = responeVo.getEntityMap(); + List datas = (List)entityMap.get("data"); + if (datas==null ||datas.isEmpty()){ + logger.info("接口返回主表参数为空,请查询税号是否准确"); + continue; + } + Map totalDataMap = new HashMap(); + String invoice_detail_Mainid = "";//用来判断台账表中是否含有相同记录 + for (Object data : datas){ + totalDataMap = (Map)data;//主表数据 + logger.info("主表数据==="+totalDataMap); + //第五步:查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + Object invoiceCode = totalDataMap.get("invoiceCode");//发票代码 + Object invoiceNum = totalDataMap.get("invoiceNum");//发票号码 + + //查询发票类型对应配置表:将想要转换的发票类型提前转换 + String queryInvoiceType = "select oaTypeValue from uf_InvoiceType_Mapping where interfaceTypeValue = ?";//改一下 + RecordSet rs2 = new RecordSet(); + rs2.executeQuery(queryInvoiceType,totalDataMap.get("invoiceType")); + if (rs2.next()){ + String oaTypeValue = rs2.getString("oaTypeValue"); + totalDataMap.put("invoiceType",oaTypeValue);//转换发票类型 + logger.info("转换发票类型==="+oaTypeValue); + }else { + totalDataMap.put("invoiceType","-1");//如果接口中的发票类型 + } + + //将时间戳转换成yyyy-MM-dd + String invoiceDate = (String)totalDataMap.get("invoiceDate"); + String new_invoiceDate = this.stampToDate(invoiceDate); + totalDataMap.put("invoiceDate",new_invoiceDate); + logger.info("转换后的时间戳====="+new_invoiceDate); + + //查询台账表中是否包含这个数据 + String sql2 = "select id from fnaInvoiceLedger where invoicecode = ? and invoicenumber = ?"; + + rs2.executeQuery(sql2,invoiceCode,invoiceNum); + if (rs2.next()) { + invoice_detail_Mainid = rs2.getString("id"); + } + + String mainId = ""; + String detailID = ""; + String updateSetkey = "";//当台账表中存在一条一样的数据的时候,我们需要设置更新条件 + List updateSetVaule = new ArrayList<>();//用来处理update条件下,?的赋值 + String insertSetKey = "(";//向台账中插入的key + String insertSetValue = "(";//向台账中插入的value + //第四步:通过配置的配置表获得到客户传的参数和台账字段的对应关系 + String sql3 = "select * from uf_fptzdypzbd where wybs = ?";//查询台账配置表 + if (rs2.executeQuery(sql3,uniqueFieldId)&&rs2.next()) { + mainId = rs2.getString("id");//查询发票台账对应配置表的id对应查询明细表的mainid + String sqlDetail1 = "select * from uf_fptzdypzbd_dt1 where mainid = ?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlDetail1,mainId); + while(rs3.next()){ + String jkhqcs = rs3.getString("jkhqcs");//接口获取主表参数 + String jkhqzbcslx = rs3.getString("jkhqzbcslx");//接口获取主表参数类型 + String sjkzcs = rs3.getString("sjkzcs");//数据库中主表参数 + String sjkzzbcslx = rs3.getString("sjkzzbcslx");//数据库中主表参数类型 + updateSetkey += sjkzcs + "=" + "?,"; + insertSetKey += sjkzcs + ","; + insertSetValue += "?"+","; + updateSetVaule.add(totalDataMap.get(jkhqcs)); + } + //拼接 发票归属人 + updateSetkey = updateSetkey + "userid_new=?"; + updateSetVaule.add(Integer.parseInt(belongTo)); + insertSetKey = insertSetKey+"userid_new)"; + insertSetValue = insertSetValue+"?)"; + + logger.info("updateSetKey====="+updateSetkey); + logger.info("updateSetVaule====="+updateSetVaule); + logger.info("insertSetKey====="+insertSetKey); + logger.info("insertSetValue====="+insertSetValue); + } + //查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + if (!"".equals(invoice_detail_Mainid)){//执行更新语句 + updateSetVaule.add(invoiceCode); + updateSetVaule.add(invoiceNum); + String sqlUpdate = "update fnaInvoiceLedger set "+updateSetkey +" where invoicecode = ? and invoicenumber = ? "; + Object[] objects = updateSetVaule.toArray(); + logger.info("sqlUpdate更新的update语句====="+sqlUpdate); + boolean b = rs2.executeUpdate(sqlUpdate, objects); + logger.info("主表的更新语句是否更新=="+b); + }else{ + Object[] objects = updateSetVaule.toArray(); + String sqlInsert = "insert into fnaInvoiceLedger "+insertSetKey+" values "+insertSetValue; + logger.info("sqlInsert插入的insert语句======"+sqlInsert); + boolean b = rs2.executeUpdate(sqlInsert, objects); + logger.info("主表的插入语句是否插入=="+b); + } + //查询到刚插入的数据的id作为明细表的mainid + String sqlSelectId = "select id from fnaInvoiceLedger where invoicecode=? and invoicenumber=?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlSelectId,invoiceCode,invoiceNum); + if (rs3.next()){ + detailID= rs3.getString("id"); + logger.info("detailID==="+detailID); + } + //向台账明细表中插入数据操作 + List details = (List)totalDataMap.get("detail");//明细表数据 + logger.info("明细表数据"+details); + String invoiceDetailSql = "delete from fnainvoiceledgerdetail where mainid = ?";//不管明细表中有没有内容一律删掉 + logger.info("不管明细表中有没有内容一律删掉sql语句==="+invoiceDetailSql); + boolean b1 = rs3.executeUpdate(invoiceDetailSql, detailID); + logger.info("删除操作是否成功b1===="+b1); + Map detailsMap = new HashMap<>(); + if (details ==null || details.isEmpty()){ + logger.info("明细表内容为空!跳出明细表出入循环"); + continue; + } + //开始查询配置表获得到客户传的明细表中参数和台账明细表中字段的对应关系 + for (Object detail : details) { + detailsMap = (Map)detail; + String sqlDetail2 = "select * from uf_fptzdypzbd_dt2 where mainid = ?"; + rs3.executeQuery(sqlDetail2,mainId); + String insertDetailSetKey = "(";//insert条件的拼接字符串1 + String insertDetailSetValue = "(";//insert条件的拼接字符串2 + List listDetail = new ArrayList<>();//用来将?赋值 + while (rs3.next()){ + String jkhqmxbzcs = rs3.getString("jkhqmxbzcs");//接口获取明细表中参数 + String jkhqmxbzcslx = rs3.getString("jkhqmxbzcslx");//接口获取明细表中参数类型 + String sjkzmxbcs = rs3.getString("sjkzmxbcs");//数据库中明细表参数 + String sjkzmxbcslx = rs3.getString("sjkzmxbcslx");//数据库中明细表参数类型 + insertDetailSetKey += sjkzmxbcs + ","; + insertDetailSetValue += "?,"; + listDetail.add(detailsMap.get(jkhqmxbzcs)); + + } + insertDetailSetKey = insertDetailSetKey + "mainid)"; + insertDetailSetValue = insertDetailSetValue+"?)"; + listDetail.add(detailID); + logger.info("明细表中用来插入的setkey---insertDetailSetKey==="+insertDetailSetKey); + logger.info("明细表中用来插入的setvalue---insertDetailSetValue==="+insertDetailSetValue); + logger.info("用来拼接?的listDetail"+listDetail); + + String insertIntoDetailSql = "insert into fnainvoiceledgerdetail "+insertDetailSetKey+ "values "+insertDetailSetValue ; + logger.info("insertIntoDetailSql明细表的插入语句==="+insertIntoDetailSql); + boolean b = rs3.executeUpdate(insertIntoDetailSql, listDetail); + logger.info("明细表数据插入是否成功===="+b); + } + } + } + //将当前时间设置到配置表中,作为下一次的开始时间 + logger.info("最后更新到配置表中的时间endDay==="+endDay); + Util.insertOrUpdateConfigValue("getDataTime",endDay,"更新同步时间"); + } catch (IOException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + /* + * 将时间戳转换为时间 + */ + public static String stampToDate(String s){ + String res; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long lt = new Long(s); + Date date = new Date(lt); + res = simpleDateFormat.format(date); + return res; + } + + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} \ No newline at end of file diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction02.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction02.java new file mode 100644 index 0000000..317432b --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction02.java @@ -0,0 +1,301 @@ +package weaver.chaoyang.he.hcy_yihong.sendinvoicevaluestoaccounttable.action; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import lombok.SneakyThrows; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceValuesToAccountTableAction02 extends BaseCronJob { + + + private Logger logger = Util.getLogger(); + + private String uniqueFieldId; + + private String url;//请求的接口的url + + + @SneakyThrows + @Override + public void execute() { + + //第一步首先获取税号 + //第二步获取开票开始时间 格式:yyyy-MM-dd 开票结束时间 格式:yyyy-MM-dd + + try { + String sql1 = "select taxNo,belongTo from uf_TaxNo_Config"; + RecordSet rs1 = new RecordSet(); + rs1.executeQuery(sql1); + while (rs1.next()){ + //第三步:new一个okhttp这个对象然后获取到客户给我们传的参数 + String taxNo = rs1.getString("taxNo"); + String belongTo = rs1.getString("belongTo"); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("User-Agent", "Apifox/1.0.0 (https://www.apifox.cn)"); + headers.put("Content-Type", "application/json"); + + + //获取上一次操作的日期 + String startDay = Util.getCusConfigValue("getDataTime"); + + //获取当前的日期 + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String endDay = dateFormat.format(date); + + //设置请求体 + Map body = new HashMap<>(); + body.put("identity",taxNo); + // body.put("startDay",startDay); + body.put("startDay",startDay); + // body.put("endDay",endDay); + body.put("endDay",endDay); + HttpUtils httpUtils = new HttpUtils(); + ResponeVo responeVo = httpUtils.apiPost(url, body, headers); + int code = responeVo.getCode(); + if (code != 200){ + logger.info("对方接口状态码为:"+code+" 程序执行错误"); + continue; + } + Map entityMap = responeVo.getEntityMap(); + logger.info(entityMap); + List datas = (List)entityMap.get("data"); + Map totalDataMap = new HashMap(); + if (datas == null || datas.isEmpty()){ + continue; + } + String invoice_detail_Mainid = "";//用来判断台账表中是否含有相同记录 + for (Object data : datas) { //主循环,数据都在里面 + totalDataMap = (Map)data;//主表数据 + //第五步:查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + Object invoiceCode = totalDataMap.get("invoiceCode");//发票代码 + Object invoiceNum = totalDataMap.get("invoiceNum");//发票号码 + + //查询发票类型对应配置表:将想要转换的发票类型提前转换 + String queryInvoiceType = "select oaTypeValue from uf_InvoiceType_Mapping where interfaceTypeValue = ?";//改一下 + RecordSet rs9 = new RecordSet(); + rs9.executeQuery(queryInvoiceType,totalDataMap.get("invoiceType")); + if (rs9.next()){ + String oaTypeValue = rs9.getString("oaTypeValue"); + totalDataMap.put("invoiceType",oaTypeValue);//转换发票类型 + } + + //将时间戳转换成yyyy-hh-dd + String invoiceDate = (String)totalDataMap.get("invoiceDate"); + String new_invoiceDate = this.stampToDate(invoiceDate); + totalDataMap.put("invoiceDate",new_invoiceDate); + + + RecordSet rs2 = new RecordSet(); + String sql2 = "select id from fnaInvoiceLedger where invoicecode = ? and invoicenumber = ?";//查询台账表中是否包含这个数据 + + rs2.executeQuery(sql2,invoiceCode,invoiceNum); + if (rs2.next()) { + invoice_detail_Mainid = rs2.getString("id"); + } + + String mainId = ""; + String detailID = ""; + //第四步:通过配置的配置表获得到客户传的参数和台账字段的对应关系 + String sql3 = "select * from uf_fptzdypzbd where wybs = ?";//查询台账配置表 + String insertSetKey1 = "(";//insert条件的拼接字符串1 + String insertSetKey2 = "(";//insert条件的拼接字符串2 + String updateSetkey = "";//update条件的拼接字符串 + Map updateMap = new HashMap<>();//update条件的拼接的map + Map updateIntMap = new HashMap<>();//update条件并且字段类型为int的拼接的map + Map updataDoubleMap = new HashMap<>();//update条件并且字段类型为double的拼接的map + RecordSet rs3 = new RecordSet(); + RecordSet rs4 = new RecordSet(); + if (rs3.executeQuery(sql3,uniqueFieldId)&&rs3.next()){ + mainId = rs3.getString("id"); + String sqlDetail1 = "select * from uf_fptzdypzbd_dt1 where mainid = ?"; + rs4.executeQuery(sqlDetail1,mainId); + while (rs4.next()){ + String jkhqcs = rs4.getString("jkhqcs");//接口获取主表参数 + String jkhqzbcslx = rs4.getString("jkhqzbcslx");//接口获取主表参数类型 + String sjkzcs = rs4.getString("sjkzcs");//数据库中主表参数 + String sjkzzbcslx = rs4.getString("sjkzzbcslx");//数据库中主表参数类型 + totalDataMap.put(jkhqcs,String.valueOf(totalDataMap.get(jkhqcs))); + + + if (Integer.valueOf(sjkzzbcslx)==0){ + updateMap.put(sjkzcs,String.valueOf(totalDataMap.get(jkhqcs))); + } else if (Integer.valueOf(sjkzzbcslx)==1){ + if (Integer.valueOf(jkhqzbcslx)==2){ + updateIntMap.put(sjkzcs,Double.valueOf(String.valueOf(totalDataMap.get(jkhqcs))).intValue()); + }else if (Integer.valueOf(jkhqzbcslx)==0){ + updateIntMap.put(sjkzcs, Integer.parseInt(String.valueOf(totalDataMap.get(jkhqcs)))); + } + } else if (Integer.valueOf(sjkzzbcslx)==2){ + updataDoubleMap.put(sjkzcs, Double.valueOf(String.valueOf(totalDataMap.get(jkhqcs)))); + }else if (Integer.valueOf(sjkzzbcslx)==3){ + updateMap.put(sjkzcs,String.valueOf(totalDataMap.get(jkhqcs))); + } + } + + } + updateIntMap.put("userid_new",Integer.parseInt(belongTo)); + //拼接update的set语句 + Set splicingUpdate = updateMap.keySet(); + for (String s : splicingUpdate) { + updateSetkey += s + "= " + "'" + updateMap.get(s) + "'" +" ,"; + insertSetKey1 += s+","; + insertSetKey2 += "'"+updateMap.get(s)+"',"; + } + Set splicingIntUpdate = updateIntMap.keySet(); + for (String s : splicingIntUpdate) { + updateSetkey += s + "= " + updateIntMap.get(s) +" ,"; + insertSetKey1 += s+","; + insertSetKey2 += updateIntMap.get(s)+","; + } + Set splicingDoubleUpdate = updataDoubleMap.keySet(); + for (String s : splicingDoubleUpdate) { + updateSetkey += s + "= " + updataDoubleMap.get(s) +" ,"; + insertSetKey1 += s+","; + insertSetKey2 += updataDoubleMap.get(s)+","; + } + updateSetkey = updateSetkey.substring(0, updateSetkey.length()-1); + insertSetKey1 = insertSetKey1.substring(0,insertSetKey1.length()-1)+")"; + insertSetKey2 = insertSetKey2.substring(0,insertSetKey2.length()-1)+")"; + logger.info("updateSetkey条件的查询结果:"+updateSetkey); + logger.info("insertSetKey1条件的查询结果:"+insertSetKey1); + logger.info("insertSetKey2条件的查询结果:"+insertSetKey2); + //查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + if (!"".equals(invoice_detail_Mainid)){//执行更新语句 + String sqlUpdate = "update fnaInvoiceLedger set "+updateSetkey +" where invoicecode = ? and invoicenumber = ? "; + RecordSet rs5 = new RecordSet(); + rs5.executeUpdate(sqlUpdate,invoiceCode,invoiceNum); + }else{ + String sqlInsert = "insert into fnaInvoiceLedger "+insertSetKey1+" values "+insertSetKey2; + logger.info("主表的查询语句sql====="+sqlInsert); + RecordSet rs6 = new RecordSet(); + rs6.executeUpdate(sqlInsert); + } + + //查询到刚插入的数据的id作为明细表的mainid + String sqlSelectId = "select id from fnaInvoiceLedger where invoicecode=? and invoicenumber=?"; + RecordSet rs10 = new RecordSet(); + rs10.executeQuery(sqlSelectId,invoiceCode,invoiceNum); + if (rs10.next()){ + detailID= rs10.getString("id"); + logger.info("查询到刚插入的数据的id作为明细表的detailID====="+detailID); + } + + //向台账明细表中插入数据操作 + List details = (List)totalDataMap.get("detail");//明细表数据 + String invoiceDetailSql = "delete from fnainvoiceledgerdetail where mainid = ?";//不管明细表中有没有内容一律删掉 + RecordSet rs6 = new RecordSet(); + rs6.executeUpdate(invoiceDetailSql,detailID); + Map detailsMap = new HashMap<>(); + if (details == null || details.isEmpty()){ + continue; + } + for (Object detail : details) { + detailsMap = (Map)detail; + logger.info("查询到的明细表的数据detailsMap"+detailsMap); + String sqlDetail2 = "select * from uf_fptzdypzbd_dt2 where mainid = ?"; + RecordSet rs7 = new RecordSet(); + rs7.executeQuery(sqlDetail2,mainId); + Map updateDetailMap = new HashMap<>();//update条件的拼接的明细表中的map + Map updateDetailIntMap = new HashMap<>();//update条件并且字段类型为int的明细表中拼接的map + Map updateDetailDoubleMap = new HashMap<>();//update条件并且字段类型为double的明细表中拼接的map + String insertDetailSetKey1 = "(";//insert条件的拼接字符串1 + String insertDetailSetKey2 = "(";//insert条件的拼接字符串2 + while(rs7.next()){ + String jkhqmxbzcs = rs7.getString("jkhqmxbzcs");//接口获取明细表中参数 + String jkhqmxbzcslx = rs7.getString("jkhqmxbzcslx");//接口获取明细表中参数类型 + String sjkzmxbcs = rs7.getString("sjkzmxbcs");//数据库中明细表参数 + String sjkzmxbcslx = rs7.getString("sjkzmxbcslx");//数据库中明细表参数类型 + detailsMap.put(jkhqmxbzcs,String.valueOf(detailsMap.get(jkhqmxbzcs))); + + if (Integer.valueOf(sjkzmxbcslx)==0){ + updateDetailMap.put(sjkzmxbcs,detailsMap.get(jkhqmxbzcs)); + }else if (Integer.valueOf(sjkzmxbcslx)==1){ + if(Integer.valueOf(jkhqmxbzcslx)==2){ + updateDetailIntMap.put(sjkzmxbcs,Double.valueOf(detailsMap.get(jkhqmxbzcs)).intValue()); + }else if (Integer.valueOf(jkhqmxbzcslx)==1){ + updateDetailIntMap.put(sjkzmxbcs,Integer.parseInt(detailsMap.get(jkhqmxbzcs))); + } + }else if (Integer.valueOf(sjkzmxbcslx)==2){ + updateDetailDoubleMap.put(sjkzmxbcs,Double.valueOf(detailsMap.get(jkhqmxbzcs))); + } + } + updateDetailIntMap.put("mainid",Integer.parseInt(detailID));//将明细表需要的id给他 + for (Map.Entry entry : updateDetailMap.entrySet()) { + String k = entry.getKey(); + String v = entry.getValue(); + insertDetailSetKey1 += k + ","; + insertDetailSetKey2 += "'"+v+"'"+","; + } + for (Map.Entry entry : updateDetailIntMap.entrySet()) { + String k = entry.getKey(); + Integer v = entry.getValue(); + insertDetailSetKey1 += k + ","; + insertDetailSetKey2 += v + ","; + } + for (Map.Entry entry : updateDetailDoubleMap.entrySet()) { + String k = entry.getKey(); + Double v = entry.getValue(); + insertDetailSetKey1 += k + ","; + insertDetailSetKey2 += v + ","; + } + + insertDetailSetKey1 = insertDetailSetKey1.substring(0,insertDetailSetKey1.length()-1)+")"; + insertDetailSetKey2 = insertDetailSetKey2.substring(0,insertDetailSetKey2.length()-1)+")"; + String insertIntoDetailSql = "insert into fnainvoiceledgerdetail "+insertDetailSetKey1 + "values "+insertDetailSetKey2 ; + RecordSet rs8 = new RecordSet(); + rs8.executeUpdate(insertIntoDetailSql); + } + } + //将当前时间设置到配置表中,作为下一次的开始时间 + Util.insertOrUpdateConfigValue("getDataTime",endDay,"更新同步时间"); + + } + } catch (IOException e) { + e.printStackTrace(); + logger.info("异常类型说明====="+e); + } catch (NumberFormatException e) { + e.printStackTrace(); + logger.info("异常类型说明====="+e); + } + + + } + + /* + * 将时间戳转换为时间 + */ + public static String stampToDate(String s){ + String res; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long lt = new Long(s); + Date date = new Date(lt); + res = simpleDateFormat.format(date); + return res; + } + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction03.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction03.java new file mode 100644 index 0000000..7c6e925 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction03.java @@ -0,0 +1,247 @@ +package weaver.chaoyang.he.hcy_yihong.sendinvoicevaluestoaccounttable.action; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import lombok.SneakyThrows; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceValuesToAccountTableAction03 extends BaseCronJob { + + + private Logger logger = Util.getLogger(); + + private String uniqueFieldId; + + private String url;//请求的接口的url + + + @SneakyThrows + @Override + public void execute() { + try { + String sql1 = "select taxNo,belongTo from uf_TaxNo_Config"; + RecordSet rs1 = new RecordSet(); + rs1.executeQuery(sql1); + + //获取上一次操作的日期 + String startDay = Util.getCusConfigValue("getDataTime"); + + //获取当前的日期 + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String endDay = dateFormat.format(date); + + while(rs1.next()){ + + String taxNo = rs1.getString("taxNo"); + String belongTo = rs1.getString("belongTo"); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("User-Agent", "Apifox/1.0.0 (https://www.apifox.cn)"); + headers.put("Content-Type", "application/json"); + + + //设置请求体 + Map body = new HashMap<>(); + body.put("identity",taxNo); + body.put("startDay",startDay); + body.put("endDay",endDay); + HttpUtils httpUtils = new HttpUtils(); + + ResponeVo responeVo = httpUtils.apiPost(url, body, headers); + int code = responeVo.getCode(); + if (code != 200){ + logger.info("对方接口状态码为:"+code+" 程序执行错误"); + continue; + } + Map entityMap = responeVo.getEntityMap(); + List datas = (List)entityMap.get("data"); + if (datas==null ||datas.isEmpty()){ + logger.info("接口返回主表参数为空,请查询税号是否准确"); + continue; + } + Map totalDataMap = new HashMap(); + String invoice_detail_Mainid = "";//用来判断台账表中是否含有相同记录 + for (Object data : datas){ + totalDataMap = (Map)data;//主表数据 + logger.info("主表数据==="+totalDataMap); + //第五步:查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + Object invoiceCode = totalDataMap.get("invoiceCode");//发票代码 + Object invoiceNum = totalDataMap.get("invoiceNum");//发票号码 + + //查询发票类型对应配置表:将想要转换的发票类型提前转换 + String queryInvoiceType = "select oaTypeValue from uf_InvoiceType_Mapping where interfaceTypeValue = ?";//改一下 + RecordSet rs2 = new RecordSet(); + rs2.executeQuery(queryInvoiceType,totalDataMap.get("invoiceType")); + if (rs2.next()){ + String oaTypeValue = rs2.getString("oaTypeValue"); + totalDataMap.put("invoiceType",oaTypeValue);//转换发票类型 + logger.info("转换发票类型==="+oaTypeValue); + }else { + break; +// totalDataMap.put("invoiceType","-1");//如果接口中的发票类型 + } + + //将时间戳转换成yyyy-MM-dd + String invoiceDate = (String)totalDataMap.get("invoiceDate"); + String new_invoiceDate = this.stampToDate(invoiceDate); + totalDataMap.put("invoiceDate",new_invoiceDate); + logger.info("转换后的时间戳====="+new_invoiceDate); + + //查询台账表中是否包含这个数据 + String sql2 = "select id from fnaInvoiceLedger where invoicecode = ? and invoicenumber = ?"; + + rs2.executeQuery(sql2,invoiceCode,invoiceNum); + if (rs2.next()) { + invoice_detail_Mainid = rs2.getString("id"); + } + + String mainId = ""; + String detailID = ""; + String updateSetkey = "";//当台账表中存在一条一样的数据的时候,我们需要设置更新条件 + List updateSetVaule = new ArrayList<>();//用来处理update条件下,?的赋值 + String insertSetKey = "(";//向台账中插入的key + String insertSetValue = "(";//向台账中插入的value + //第四步:通过配置的配置表获得到客户传的参数和台账字段的对应关系 + String sql3 = "select * from uf_fptzdypzbd where wybs = ?";//查询台账配置表 + if (rs2.executeQuery(sql3,uniqueFieldId)&&rs2.next()) { + mainId = rs2.getString("id");//查询发票台账对应配置表的id对应查询明细表的mainid + String sqlDetail1 = "select * from uf_fptzdypzbd_dt1 where mainid = ?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlDetail1,mainId); + while(rs3.next()){ + String jkhqcs = rs3.getString("jkhqcs");//接口获取主表参数 + String jkhqzbcslx = rs3.getString("jkhqzbcslx");//接口获取主表参数类型 + String sjkzcs = rs3.getString("sjkzcs");//数据库中主表参数 + String sjkzzbcslx = rs3.getString("sjkzzbcslx");//数据库中主表参数类型 + updateSetkey += sjkzcs + "=" + "?,"; + insertSetKey += sjkzcs + ","; + insertSetValue += "?"+","; + updateSetVaule.add(totalDataMap.get(jkhqcs)); + } + //拼接 发票归属人 + updateSetkey = updateSetkey + "userid_new=?"; + updateSetVaule.add(Integer.parseInt(belongTo)); + insertSetKey = insertSetKey+"userid_new)"; + insertSetValue = insertSetValue+"?)"; + + logger.info("updateSetKey====="+updateSetkey); + logger.info("updateSetVaule====="+updateSetVaule); + logger.info("insertSetKey====="+insertSetKey); + logger.info("insertSetValue====="+insertSetValue); + } + //查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + if (!"".equals(invoice_detail_Mainid)){//执行更新语句 + updateSetVaule.add(invoiceCode); + updateSetVaule.add(invoiceNum); + String sqlUpdate = "update fnaInvoiceLedger set "+updateSetkey +" where invoicecode = ? and invoicenumber = ? "; + Object[] objects = updateSetVaule.toArray(); + logger.info("sqlUpdate更新的update语句====="+sqlUpdate); + boolean b = rs2.executeUpdate(sqlUpdate, objects); + logger.info("主表的更新语句是否更新=="+b); + }else{ + Object[] objects = updateSetVaule.toArray(); + String sqlInsert = "insert into fnaInvoiceLedger "+insertSetKey+" values "+insertSetValue; + logger.info("sqlInsert插入的insert语句======"+sqlInsert); + boolean b = rs2.executeUpdate(sqlInsert, objects); + logger.info("主表的插入语句是否插入=="+b); + } + //查询到刚插入的数据的id作为明细表的mainid + String sqlSelectId = "select id from fnaInvoiceLedger where invoicecode=? and invoicenumber=?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlSelectId,invoiceCode,invoiceNum); + if (rs3.next()){ + detailID= rs3.getString("id"); + logger.info("detailID==="+detailID); + } + //向台账明细表中插入数据操作 + List details = (List)totalDataMap.get("detail");//明细表数据 + logger.info("明细表数据"+details); + String invoiceDetailSql = "delete from fnainvoiceledgerdetail where mainid = ?";//不管明细表中有没有内容一律删掉 + logger.info("不管明细表中有没有内容一律删掉sql语句==="+invoiceDetailSql); + boolean b1 = rs3.executeUpdate(invoiceDetailSql, detailID); + logger.info("删除操作是否成功b1===="+b1); + Map detailsMap = new HashMap<>(); + if (details ==null || details.isEmpty()){ + logger.info("明细表内容为空!跳出明细表出入循环"); + continue; + } + //开始查询配置表获得到客户传的明细表中参数和台账明细表中字段的对应关系 + for (Object detail : details) { + detailsMap = (Map)detail; + String sqlDetail2 = "select * from uf_fptzdypzbd_dt2 where mainid = ?"; + rs3.executeQuery(sqlDetail2,mainId); + String insertDetailSetKey = "(";//insert条件的拼接字符串1 + String insertDetailSetValue = "(";//insert条件的拼接字符串2 + List listDetail = new ArrayList<>();//用来将?赋值 + while (rs3.next()){ + String jkhqmxbzcs = rs3.getString("jkhqmxbzcs");//接口获取明细表中参数 + String jkhqmxbzcslx = rs3.getString("jkhqmxbzcslx");//接口获取明细表中参数类型 + String sjkzmxbcs = rs3.getString("sjkzmxbcs");//数据库中明细表参数 + String sjkzmxbcslx = rs3.getString("sjkzmxbcslx");//数据库中明细表参数类型 + insertDetailSetKey += sjkzmxbcs + ","; + insertDetailSetValue += "?,"; + listDetail.add(detailsMap.get(jkhqmxbzcs)); + + } + insertDetailSetKey = insertDetailSetKey + "mainid)"; + insertDetailSetValue = insertDetailSetValue+"?)"; + listDetail.add(detailID); + logger.info("明细表中用来插入的setkey---insertDetailSetKey==="+insertDetailSetKey); + logger.info("明细表中用来插入的setvalue---insertDetailSetValue==="+insertDetailSetValue); + logger.info("用来拼接?的listDetail"+listDetail); + + String insertIntoDetailSql = "insert into fnainvoiceledgerdetail "+insertDetailSetKey+ "values "+insertDetailSetValue ; + logger.info("insertIntoDetailSql明细表的插入语句==="+insertIntoDetailSql); + boolean b = rs3.executeUpdate(insertIntoDetailSql, listDetail); + logger.info("明细表数据插入是否成功===="+b); + } + } + } + //将当前时间设置到配置表中,作为下一次的开始时间 + logger.info("最后更新到配置表中的时间endDay==="+endDay); + Util.insertOrUpdateConfigValue("getDataTime",endDay,"更新同步时间"); + } catch (IOException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + /* + * 将时间戳转换为时间 + */ + public static String stampToDate(String s){ + String res; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long lt = new Long(s); + Date date = new Date(lt); + res = simpleDateFormat.format(date); + return res; + } + + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} \ No newline at end of file diff --git a/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction04.java b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction04.java new file mode 100644 index 0000000..7f202b9 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/hcy_yihong/sendinvoicevaluestoaccounttable/action/InvoiceValuesToAccountTableAction04.java @@ -0,0 +1,264 @@ +package weaver.chaoyang.he.hcy_yihong.sendinvoicevaluestoaccounttable.action; + +import aiyh.utils.Util; +import aiyh.utils.httpUtil.ResponeVo; +import aiyh.utils.httpUtil.util.HttpUtils; +import lombok.SneakyThrows; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.schedule.BaseCronJob; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class InvoiceValuesToAccountTableAction04 extends BaseCronJob { + + + private Logger logger = Util.getLogger(); + + private String uniqueFieldId; + + private String url;//请求的接口的url + + + @SneakyThrows + @Override + public void execute() { + try { + String sql1 = "select taxNo,belongTo from uf_TaxNo_Config"; + RecordSet rs1 = new RecordSet(); + rs1.executeQuery(sql1); + + //获取上一次操作的日期 + String startDay = Util.getCusConfigValue("getDataTime"); + + //获取当前的日期 + Date date = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + String endDay = dateFormat.format(date); + + while(rs1.next()){ + + String taxNo = rs1.getString("taxNo"); + String belongTo = rs1.getString("belongTo"); + + //请求头 + HashMap headers = new HashMap<>(); + headers.put("User-Agent", "Apifox/1.0.0 (https://www.apifox.cn)"); + headers.put("Content-Type", "application/json"); + + + //设置请求体 + Map body = new HashMap<>(); + body.put("identity",taxNo); + body.put("startDay",startDay); + body.put("endDay",endDay); + HttpUtils httpUtils = new HttpUtils(); + + ResponeVo responeVo = httpUtils.apiPost(url, body, headers); + int code = responeVo.getCode(); + if (code != 200){ + logger.info("对方接口状态码为:"+code+" 程序执行错误"); + continue; + } + Map entityMap = responeVo.getEntityMap(); + List datas = (List)entityMap.get("data"); + if (datas==null ||datas.isEmpty()){ + logger.info("接口返回主表参数为空,请查询税号是否准确"); + continue; + } + Map totalDataMap = new HashMap(); + String invoice_detail_Mainid = "";//用来判断台账表中是否含有相同记录 + for (Object data : datas){ + totalDataMap = (Map)data;//主表数据 + logger.info("主表数据==="+totalDataMap); + //第五步:查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + Object invoiceCode = totalDataMap.get("invoiceCode");//发票代码 + Object invoiceNum = totalDataMap.get("invoiceNum");//发票号码 + + //查询发票类型对应配置表:将想要转换的发票类型提前转换 + String queryInvoiceType = "select oaTypeValue from uf_InvoiceType_Mapping where interfaceTypeValue = ?";//改一下 + RecordSet rs2 = new RecordSet(); + rs2.executeQuery(queryInvoiceType,totalDataMap.get("invoiceType")); + if (rs2.next()){ + String oaTypeValue = rs2.getString("oaTypeValue"); + totalDataMap.put("invoiceType",oaTypeValue);//转换发票类型 + logger.info("转换发票类型==="+oaTypeValue); + }else { + continue; +// totalDataMap.put("invoiceType","-1");//如果接口中的发票类型 + } + + //将时间戳转换成yyyy-MM-dd + String invoiceDate = (String)totalDataMap.get("invoiceDate"); + String new_invoiceDate = this.stampToDate(invoiceDate); + totalDataMap.put("invoiceDate",new_invoiceDate); + logger.info("转换后的时间戳====="+new_invoiceDate); + + //查询台账表中是否包含这个数据 + String sql2 = "select id from fnaInvoiceLedger where invoicecode = ? and invoicenumber = ?"; + + rs2.executeQuery(sql2,invoiceCode,invoiceNum); + if (rs2.next()) { + invoice_detail_Mainid = rs2.getString("id"); + } + + String mainId = ""; + String detailID = ""; + String updateSetkey = "";//当台账表中存在一条一样的数据的时候,我们需要设置更新条件 + List updateSetVaule = new ArrayList<>();//用来处理update条件下,?的赋值 + String insertSetKey = "(";//向台账中插入的key + String insertSetValue = "(";//向台账中插入的value + //第四步:通过配置的配置表获得到客户传的参数和台账字段的对应关系 + String sql3 = "select * from uf_fptzdypzbd where wybs = ?";//查询台账配置表 + if (rs2.executeQuery(sql3,uniqueFieldId)&&rs2.next()) { + mainId = rs2.getString("id");//查询发票台账对应配置表的id对应查询明细表的mainid + String sqlDetail1 = "select * from uf_fptzdypzbd_dt1 where mainid = ?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlDetail1,mainId); + + + String defaultValue = ""; + while(rs3.next()){ + String jkhqcs = rs3.getString("jkhqcs");//接口获取主表参数 + String sjkzcs = rs3.getString("sjkzcs");//数据库中主表参数 + String zhlx = rs3.getString("zhlx");//转换类型 + String zdyz = rs3.getString("zdyz");//自定义值 + if (zhlx!=""&&zhlx.equals("0")){ + updateSetkey += sjkzcs + "=" + "?,"; + insertSetKey += sjkzcs + ","; + insertSetValue += "?"+","; + updateSetVaule.add(totalDataMap.get(jkhqcs)); + }else if (zhlx!=""&&zhlx.equals("1")){ + defaultValue = zdyz; + } + + } + //拼接 发票归属人 + updateSetkey = updateSetkey + "userid_new=?,"; + updateSetVaule.add(Integer.parseInt(belongTo)); + insertSetKey = insertSetKey+"userid_new,"; + insertSetValue = insertSetValue+"?,"; + + + //拼接固定值中的类型 + updateSetkey = updateSetkey + "hxjksflr=?"; + updateSetVaule.add(defaultValue); + insertSetKey = insertSetKey+"hxjksflr)"; + insertSetValue = insertSetValue+"?)"; + + + + logger.info("updateSetKey====="+updateSetkey); + logger.info("updateSetVaule====="+updateSetVaule); + logger.info("insertSetKey====="+insertSetKey); + logger.info("insertSetValue====="+insertSetValue); + } + //查询每一个参数在台账主表中是否包含记录,如果包含执行update操作,如果不包含,执行insert操作。 + if (!"".equals(invoice_detail_Mainid)){//执行更新语句 + updateSetVaule.add(invoiceCode); + updateSetVaule.add(invoiceNum); + String sqlUpdate = "update fnaInvoiceLedger set "+updateSetkey +" where invoicecode = ? and invoicenumber = ? "; + Object[] objects = updateSetVaule.toArray(); + logger.info("sqlUpdate更新的update语句====="+sqlUpdate); + boolean b = rs2.executeUpdate(sqlUpdate, objects); + logger.info("主表的更新语句是否更新=="+b); + }else{ + Object[] objects = updateSetVaule.toArray(); + String sqlInsert = "insert into fnaInvoiceLedger "+insertSetKey+" values "+insertSetValue; + logger.info("sqlInsert插入的insert语句======"+sqlInsert); + boolean b = rs2.executeUpdate(sqlInsert, objects); + logger.info("主表的插入语句是否插入=="+b); + } + //查询到刚插入的数据的id作为明细表的mainid + String sqlSelectId = "select id from fnaInvoiceLedger where invoicecode=? and invoicenumber=?"; + RecordSet rs3 = new RecordSet(); + rs3.executeQuery(sqlSelectId,invoiceCode,invoiceNum); + if (rs3.next()){ + detailID= rs3.getString("id"); + logger.info("detailID==="+detailID); + } + //向台账明细表中插入数据操作 + List details = (List)totalDataMap.get("detail");//明细表数据 + logger.info("明细表数据"+details); + String invoiceDetailSql = "delete from fnainvoiceledgerdetail where mainid = ?";//不管明细表中有没有内容一律删掉 + logger.info("不管明细表中有没有内容一律删掉sql语句==="+invoiceDetailSql); + boolean b1 = rs3.executeUpdate(invoiceDetailSql, detailID); + logger.info("删除操作是否成功b1===="+b1); + Map detailsMap = new HashMap<>(); + if (details ==null || details.isEmpty()){ + logger.info("明细表内容为空!跳出明细表出入循环"); + continue; + } + //开始查询配置表获得到客户传的明细表中参数和台账明细表中字段的对应关系 + for (Object detail : details) { + detailsMap = (Map)detail; + String sqlDetail2 = "select * from uf_fptzdypzbd_dt2 where mainid = ?"; + rs3.executeQuery(sqlDetail2,mainId); + String insertDetailSetKey = "(";//insert条件的拼接字符串1 + String insertDetailSetValue = "(";//insert条件的拼接字符串2 + List listDetail = new ArrayList<>();//用来将?赋值 + while (rs3.next()){ + String jkhqmxbzcs = rs3.getString("jkhqmxbzcs");//接口获取明细表中参数 + String jkhqmxbzcslx = rs3.getString("jkhqmxbzcslx");//接口获取明细表中参数类型 + String sjkzmxbcs = rs3.getString("sjkzmxbcs");//数据库中明细表参数 + String sjkzmxbcslx = rs3.getString("sjkzmxbcslx");//数据库中明细表参数类型 + insertDetailSetKey += sjkzmxbcs + ","; + insertDetailSetValue += "?,"; + listDetail.add(detailsMap.get(jkhqmxbzcs)); + + } + insertDetailSetKey = insertDetailSetKey + "mainid)"; + insertDetailSetValue = insertDetailSetValue+"?)"; + listDetail.add(detailID); + logger.info("明细表中用来插入的setkey---insertDetailSetKey==="+insertDetailSetKey); + logger.info("明细表中用来插入的setvalue---insertDetailSetValue==="+insertDetailSetValue); + logger.info("用来拼接?的listDetail"+listDetail); + + String insertIntoDetailSql = "insert into fnainvoiceledgerdetail "+insertDetailSetKey+ "values "+insertDetailSetValue ; + logger.info("insertIntoDetailSql明细表的插入语句==="+insertIntoDetailSql); + boolean b = rs3.executeUpdate(insertIntoDetailSql, listDetail); + logger.info("明细表数据插入是否成功===="+b); + } + } + } + //将当前时间设置到配置表中,作为下一次的开始时间 + logger.info("最后更新到配置表中的时间endDay==="+endDay); + Util.insertOrUpdateConfigValue("getDataTime",endDay,"更新同步时间"); + } catch (IOException e) { + e.printStackTrace(); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + + /* + * 将时间戳转换为时间 + */ + public static String stampToDate(String s){ + String res; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long lt = new Long(s); + Date date = new Date(lt); + res = simpleDateFormat.format(date); + return res; + } + + + public String getUniqueFieldId() { + return uniqueFieldId; + } + + public void setUniqueFieldId(String uniqueFieldId) { + this.uniqueFieldId = uniqueFieldId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} \ No newline at end of file diff --git a/src/main/java/weaver/chaoyang/he/jiacheng/deng/toyota/boshoku/action/TbChangeTextNameAction.java b/src/main/java/weaver/chaoyang/he/jiacheng/deng/toyota/boshoku/action/TbChangeTextNameAction.java new file mode 100644 index 0000000..09af6f9 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/jiacheng/deng/toyota/boshoku/action/TbChangeTextNameAction.java @@ -0,0 +1,234 @@ +package weaver.chaoyang.he.jiacheng.deng.toyota.boshoku.action; + +import aiyh.utils.Util; +import com.sun.istack.internal.NotNull; +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +/** + *

附件上传后修改名称保存到目录

+ * @Author jiacheng.deng + * @Date 2023/2/13 10:41 + */ +public class TbChangeTextNameAction implements Action { + + //日志打印 + private final Logger log = Util.getLogger(); + + /** + *

附件上传后修改名称

+ * @param requestInfo + * @return Action.SUCCESS + * @author jiacheng.deng + */ + @Override + public String execute(RequestInfo requestInfo) { + + Property[] property = requestInfo.getMainTableInfo().getProperty(); + + List> detailData = new ArrayList<>(); + + Map mainMap = new HashMap<>(); + for (Property property1 : property) { + String name = property1.getName(); + String value = property1.getValue(); + + mainMap.put(name,value); + } + + log.info("main table name and value is : " + mainMap); + + DetailTable detailTable = requestInfo.getDetailTableInfo().getDetailTable(0); + + Row[] row2 = detailTable.getRow(); + + for (Row row : row2) { + Cell[] cell = row.getCell(); + Map detailMap = new HashMap<>(); + for (Cell cell1 : cell) { + String name = cell1.getName(); + String value = cell1.getValue(); + detailMap.put(name,value); + } + detailData.add(detailMap); + } + + for (Map detailDatum : detailData) { + log.info("detail table name and value is : " + detailDatum ); + } + + String workflowid = requestInfo.getWorkflowid(); + RecordSet refindFieldType = new RecordSet(); + String findFieldhtmltypeSQL = "select w3.billid,w3.showtablename,w3.fieldhtmltype,w3.fieldname from workflow_base w1 join workflow_bill w2 on w1.formid = w2.id \n " + + " join workflow_field_table_view w3 on w3.billid = w2.id\n " + + " where w1.id = ? and w3.fieldhtmltype='附件上传'"; + boolean findFieldhtmltype = refindFieldType.executeQuery(findFieldhtmltypeSQL, workflowid); + log.info("查询表单字段类型sql是否执行:" + findFieldhtmltype); + + String findMainParamValueSQL = "select paramvalue from uf_systemconfig where uuid = 'main_upload'"; + String findDetailParamValueSQL = "select paramvalue from uf_systemconfig where uuid = 'detail_upload'"; + + RecordSet refindMainParam = new RecordSet(); + boolean findMainParamValue = refindMainParam.executeQuery(findMainParamValueSQL); + refindMainParam.next(); + String mainParamvalue = refindMainParam.getString("paramvalue"); + log.info("查询配置列表配置主表参数sql是否执行:" + findMainParamValue + "and 主表配置的附件参数为:" + mainParamvalue); + + RecordSet refindDetailParam = new RecordSet(); + boolean findDetailParamValue = refindDetailParam.executeQuery(findDetailParamValueSQL); + refindDetailParam.next(); + String detailParamvalue = refindDetailParam.getString("paramvalue"); + log.info("查询配置列表配置明细表参数sql是否执行:" + findDetailParamValue + "and 明细表配置的附件参数为:" + detailParamvalue); + + List showtablenameList = new ArrayList(); + List fieldnameList = new ArrayList(); + String fieldname ; + String showtablename; + + while (refindFieldType.next()){ + showtablename = refindFieldType.getString("showtablename"); + fieldname = refindFieldType.getString("fieldname"); + showtablenameList.add(showtablename); + fieldnameList.add(fieldname); + } + + List collect = showtablenameList.stream().distinct().collect(Collectors.toList()); + + if(collect.size() >= 2){ + log.info("明细表和主表都有附件上传框"); + + List list = new ArrayList<>(); + if (!mainMap.get(mainParamvalue).equals("")) { + String[] mainUploadSplitArr = mainMap.get(mainParamvalue).split(","); + for (String mainUploadSplitNum : mainUploadSplitArr) { + int i = Integer.parseInt(mainUploadSplitNum); + list.add(i); + } + + for ( Map detailDatum : detailData) { + if(! detailDatum.get(detailParamvalue).equals("")){ + String[] detailUploadSplitArr = detailDatum.get(detailParamvalue).split(","); + for (String detailUploadSplitNum : detailUploadSplitArr) { + int i = Integer.parseInt(detailUploadSplitNum); + list.add(i); + } + }else{ + continue; + } + } + for (Integer uploadNum : list) { + String findFjSQL = "select * from docdetail where id = ?"; + RecordSet recordSet = new RecordSet(); + boolean findFj= recordSet.executeQuery(findFjSQL, uploadNum); + log.info("b1是否执行:" + findFj); + while (recordSet.next()) { + String docsubject = recordSet.getString("docsubject"); + log.info("find docsubject is : " + docsubject); + if (!"".equals(docsubject)) { + String fjName = mainMap.get("sqdh") + " - " + docsubject; + log.info("附件修改后的名称:" + fjName); + String updateFjNameSQL = "update docdetail set docsubject = ? where id = " + uploadNum; + log.info("修改文件名称sql:" + updateFjNameSQL); + //recordset使用重复 + boolean updateFjName = recordSet.executeUpdate(updateFjNameSQL,fjName); + log.info("b2是否执行:" + updateFjName); +// todo:处理逻辑 + String selectImageFileNameSql = "select imagefilename from docimagefile where docid = ?"; + while (recordSet.executeQuery(selectImageFileNameSql,uploadNum)&&recordSet.next()){ + String imageFileName = recordSet.getString("imagefilename"); + log.info("find imagefilename is : "+imageFileName); + if (!"".equals(imageFileName)) { + String fjName1 = mainMap.get("sqdh") + " - "+imageFileName; + log.info("修改文件名称sql:"+fjName1); + String updateImageFileNameSql = "update docimagefile set imagefilename = ? where id = ?"; + } + } + + } + } + } + }else{ + for (Map detailDatum : detailData) { + if(! detailDatum.get(detailParamvalue).equals("")){ + String[] detailUploadSplitArr = detailDatum.get(detailParamvalue).split(","); + for (String detailUploadSplitNum : detailUploadSplitArr) { + int i = Integer.parseInt(detailUploadSplitNum); + list.add(i); + } + }else{ + continue; + } + } + for (Integer uploadNum : list) { + String findFjSQL = "select * from docdetail where id = ?"; + RecordSet recordSet = new RecordSet(); + boolean findFj= recordSet.executeQuery(findFjSQL, uploadNum); + log.info("b1是否执行:" + findFj); + while (recordSet.next()) { + String docsubject = recordSet.getString("docsubject"); + log.info("find docsubject is : " + docsubject); + if (!"".equals(docsubject)) { + String fjName = mainMap.get("sqdh") + " - " + docsubject; + log.info("附件修改后的名称:" + fjName); + String updateFjNameSQL = "update docdetail set docsubject = ? where id = " + uploadNum; + log.info("修改文件名称sql:" + updateFjNameSQL); + //recordset使用重复 + boolean updateFjName = recordSet.executeUpdate(updateFjNameSQL,fjName); + log.info("b2是否执行:" + updateFjName); + } + } + } + } + + }else{ + log.info("主表或者明细表只有一个有附件上传框,或者都没上传框"); + return Action.SUCCESS; + } + return Action.SUCCESS; + } + + /** + *

获取所有明细数据

+ * + * @return 以明细表需要为键,以明细表数据为值的键值对明细数据信息 + */ + protected Map>> getDetailTableValue(RequestInfo requestInfo) { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 0.75)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + /** + *

根据明细表信息获取明细表数据

+ * + * @param detailTable 明细表对象 + * @return 明细表数据 + */ + @NotNull + private List> getDetailValue(DetailTable detailTable) { + Row[] rowArr = detailTable.getRow(); + List> detailData = new ArrayList<>(rowArr.length); + for (Row row : rowArr) { + Cell[] cellArr = row.getCell(); + Map rowData = new HashMap<>((int) Math.ceil(cellArr.length * 0.75)); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } +} diff --git a/src/main/java/weaver/chaoyang/he/shangan/common/util/CommonWFUtil.java b/src/main/java/weaver/chaoyang/he/shangan/common/util/CommonWFUtil.java new file mode 100644 index 0000000..c06a66a --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/shangan/common/util/CommonWFUtil.java @@ -0,0 +1,273 @@ +package weaver.chaoyang.he.shangan.common.util; + +import weaver.conn.RecordSet; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.workflow.webservices.*; +import weaver.workflow.workflow.WorkflowComInfo; +import weaver.zwl.common.ToolUtil; + +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 常用通用工具方法 + * EBU七部 + */ +public class CommonWFUtil { + + private static final ToolUtil tu = new ToolUtil(); + /** + * + * 发起流程 + * @param workflowId 流程id + * @param mainFormData 主表数据 key:数据库字段名称 value:值 + * @param dtlFormData 明细数据 key:明细表num value:每一行明细数据 + * @param defaultValue 是否需要默认值和节点前附加规则的设值,例如人力资源、日期等 + * @param user 当前用户信息 + */ + public static String startWorkflow(String workflowId, Map mainFormData, + Map>> dtlFormData, boolean defaultValue, User user) throws Exception{ + return startWorkflow(workflowId,mainFormData,dtlFormData,defaultValue,user,"0"); + } + + /** + * + * 发起流程 + * @param workflowId 流程id + * @param mainFormData 主表数据 key:数据库字段名称 value:值 + * @param dtlFormData 明细数据 key:明细表num value:每一行明细数据 + * @param defaultValue 是否需要默认值和节点前附加规则的设值,例如人力资源、日期等 + * @param user 当前用户信息 + * @param isNextFlow 是否自动提交至下一个节点 0:否 1:是 + */ + public static String startWorkflow(String workflowId, Map mainFormData, + Map>> dtlFormData, boolean defaultValue, User user,String isNextFlow) { + int formid = 0; + String defaultName = ""; + RecordSet rs = new RecordSet(); + String sql = " select a.formId ,a.isValId,a.defaultName,a.version,a.activeVersionID from workflow_base a where a.id=?"; + rs.executeQuery(sql, workflowId); + if (rs.next()) { + formid = Math.abs(rs.getInt("formId")); + defaultName = Util.null2String(rs.getString("defaultName")).trim(); + String activeVersionID = Util.null2String(rs.getString("activeVersionID")); + + if(!"".equals(activeVersionID)){ + workflowId = activeVersionID; + } + } + + //流程默认标题没有开启 + if("1".equals(defaultName) || "".equals(defaultName)){ + //生成默认标题 + WorkflowComInfo wc = new WorkflowComInfo(); + //流程标题 + defaultName = Util.formatMultiLang(wc.getWorkflowname(workflowId)) + "-" + user.getLastname() + "-" + TimeUtil.getCurrentDateString(); + } + + //设置流程信息 + WorkflowBaseInfo wbi = new WorkflowBaseInfo(); + wbi.setWorkflowId(workflowId); + WorkflowServiceImpl wsi = new WorkflowServiceImpl(); + WorkflowRequestInfo wri = new WorkflowRequestInfo();//流程基本信息 + wri.setCreatorId(user.getUID()+"");//创建人id + wri.setCreatorName(user.getLastname()); + wri.setRequestLevel("0");//0 正常,1重要,2紧急 + wri.setRequestName(defaultName);//流程标题 + wri.setWorkflowBaseInfo(wbi); //流程类型 + wri.setIsnextflow(isNextFlow); + + //主表 + WorkflowRequestTableRecord[] writ = new WorkflowRequestTableRecord[1]; + + if(mainFormData == null){ + mainFormData = new HashMap<>(); + } + + if(defaultValue){ + //查询主表的附加规则设置 + rs.executeQuery("select a.customervalue,b.fieldname from workflow_addinoperate a " + + " join workflow_billfield b on a.fieldid = b.id " + + " join workflow_flownode c on c.nodeid = a.objid " + + " where a.workflowid = ? and a.isnode = 1 and a.ispreadd = 1 and a.type = 0 and c.nodetype = 0 and b.viewtype = 0 ", workflowId); + while(rs.next()){ + String fieldname = Util.null2String(rs.getString("fieldname")); + String customervalue = Util.null2String(rs.getString("customervalue")); + if(!mainFormData.containsKey(fieldname)){ + mainFormData.put(fieldname, customervalue); + } + } + + defaultValueSet(mainFormData,user,workflowId,""); + } + if(mainFormData.size() > 0){ + int filedCount = mainFormData.size();//需要维护的字段数量 + WorkflowRequestTableField[] workflowRequestTableField = new WorkflowRequestTableField[filedCount]; //一行的字段数组 + int i = 0; + for(Map.Entry entry:mainFormData.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + workflowRequestTableField[i] = new WorkflowRequestTableField(); + workflowRequestTableField[i].setFieldName(key);//字段名称 + workflowRequestTableField[i].setFieldValue(value);//字段的值 + workflowRequestTableField[i].setView(true);//字段是否可见 + workflowRequestTableField[i].setEdit(true);//字段是否可编辑 + i++; + } + writ[0] = new WorkflowRequestTableRecord(); + writ[0].setWorkflowRequestTableFields(workflowRequestTableField); + }else{ + WorkflowRequestTableField[] workflowRequestTableField = new WorkflowRequestTableField[0]; //一行的字段数组 + writ[0] = new WorkflowRequestTableRecord(); + writ[0].setWorkflowRequestTableFields(workflowRequestTableField); + } + + WorkflowMainTableInfo wmi = new WorkflowMainTableInfo(); + wmi.setRequestRecords(writ); + wri.setWorkflowMainTableInfo(wmi);//添加主字段数据 + //主表end + + //明细表 + //查询流程共有几个明细表 + int maxDtl = 0; + List dtlTableList = new ArrayList<>(); + rs.executeQuery("select a.tableName,a.billId from workflow_billDetailTable a join workflow_base b on b.formId = a.billId where b.id = ? \n" + + "order by a.orderId asc", workflowId); + while(rs.next()){ + String tableName = Util.null2String(rs.getString("tableName")); + + int dtlId = Util.getIntValue(tableName.substring(tableName.indexOf("_dt") + 3),-1); + + if(dtlId>maxDtl){ + maxDtl = dtlId; + } + dtlTableList.add(""+dtlId); + } + if(dtlFormData != null && dtlFormData.size() > 0){ + WorkflowDetailTableInfo[] workflowDetailTableInfos = new WorkflowDetailTableInfo[maxDtl]; + for(int i = 0;i < dtlTableList.size();i++){ + List> dtlList = dtlFormData.get(dtlTableList.get(i)); //第i个明细表中的数据 + if(dtlList == null || dtlList.size() == 0){ + continue; + } + + WorkflowRequestTableRecord[] WorkflowRequestTableRecord = new WorkflowRequestTableRecord[dtlList.size()]; + Map defaultData = new HashMap<>(); + if(defaultValue){ + //明细默认信息 + rs.executeQuery("select a.customerValue,b.fieldName from workflow_addinoperate a " + + " join workflow_billfield b on a.fieldid = b.id " + + " join workflow_flownode c on c.nodeid = a.objid " + + " where a.workflowid = ? and a.isnode = 1 and a.ispreadd = 1 " + + " and a.type = 0 and c.nodetype = 0 and b.viewtype = 1 and b.detailtable = ?", workflowId,"formtable_main_"+formid+"_dt"+i); + while(rs.next()){ + String fieldname = Util.null2String(rs.getString("fieldName")); + String customervalue = Util.null2String(rs.getString("customerValue")); + if(!defaultData.containsKey(fieldname)){ + defaultData.put(fieldname, customervalue); + } + } + + defaultValueSet(defaultData,user,workflowId,"formtable_main_" + formid + "_dt" + i); + } + int num = 0; + for(Map dtlMap : dtlList){ //添加一行明细表数据 + tu.writeDebuggerLog("","明细表" + i + ",第" + (num + 1) + "行待写入字段信息:[" + dtlMap.toString() + "]!"); + + WorkflowRequestTableField[] workflowRequestTableFields = new WorkflowRequestTableField[dtlMap.size()+defaultData.size()]; + int j = 0; + for(Map.Entry entry:dtlMap.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + workflowRequestTableFields[j] = new WorkflowRequestTableField(); + workflowRequestTableFields[j].setFieldName(key);//字段名称 + workflowRequestTableFields[j].setFieldValue(value);//字段的值 + workflowRequestTableFields[j].setView(true);//字段是否可见 + workflowRequestTableFields[j].setEdit(true);//字段是否可编辑 + j++; + } + if(defaultValue){ + for(Map.Entry entry:defaultData.entrySet()){ + String key = entry.getKey(); + if(dtlMap.containsKey(key)){ + continue; + } + String value = entry.getValue(); + workflowRequestTableFields[j] = new WorkflowRequestTableField(); + workflowRequestTableFields[j].setFieldName(key);//字段名称 + workflowRequestTableFields[j].setFieldValue(value);//字段的值 + workflowRequestTableFields[j].setView(true);//字段是否可见 + workflowRequestTableFields[j].setEdit(true);//字段是否可编辑 + j++; + } + } + + tu.writeDebuggerLog("","明细表" + i + ",第" + (num + 1) + "行总有" + j + "字段!"); + + WorkflowRequestTableRecord[num] = new WorkflowRequestTableRecord(); + WorkflowRequestTableRecord[num].setWorkflowRequestTableFields(workflowRequestTableFields); + num++; + } + + tu.writeDebuggerLog("","明细表" + i + ",共有" + WorkflowRequestTableRecord.length + "行记录!"); + + workflowDetailTableInfos[i] = new WorkflowDetailTableInfo(); + workflowDetailTableInfos[i].setWorkflowRequestTableRecords(WorkflowRequestTableRecord); + } + + tu.writeDebuggerLog("","创建的流程共有" + workflowDetailTableInfos.length + "个明细表!"); + wri.setWorkflowDetailTableInfos(workflowDetailTableInfos);//添加明细字段信息 + } + return wsi.doCreateWorkflowRequest(wri,user.getUID()); + } + + /** + * 设置默认值 + * @param defaultData 默认数据集合 + * @param user 当前用户信息 + * @param workflowId 流程类型ID + * @param tableName 流程表名称 + */ + private static void defaultValueSet(Map defaultData,User user,String workflowId,String tableName){ + RecordSet rs = new RecordSet(); + + String selectSQL = "select a.fieldName,a.type from workflow_billfield a " + + " join workflow_base b on a.billid = b.formid " + + " where b.id = ? and a.fieldhtmltype = 3 " + + " and a.type in(1,2,4,19,178,164)"; + + if(!"".equals(tableName)){ + selectSQL += " and a.detailtable = '" + tableName + "' and a.viewtype = 1"; + }else{ + selectSQL += " and a.viewtype = 0"; + } + + //查询主表的人力资源、部门、分部、日期、年度等浏览按钮填写默认值 + rs.executeQuery(selectSQL, workflowId); + + while(rs.next()){ + String fieldName = Util.null2String(rs.getString("fieldName")); + int type = Util.getIntValue(rs.getString("type"),0); + if(!defaultData.containsKey(fieldName)){ + if(type == 1){//人力资源 + defaultData.put(fieldName, ""+user.getUID()); + }else if(type == 2){//日期 + defaultData.put(fieldName, TimeUtil.getCurrentDateString()); + }else if(type == 4){//部门 + defaultData.put(fieldName, ""+user.getUserDepartment()); + }else if(type == 19){//时间 + String timestrformart = "HH:mm" ; + SimpleDateFormat SDF = new SimpleDateFormat(timestrformart) ; + Calendar calendar = Calendar.getInstance() ; + defaultData.put(fieldName, SDF.format(calendar.getTime())); + }else if(type == 178){ //年 + defaultData.put(fieldName, TimeUtil.getCurrentDateString().split("-")[0]); + }else if(type == 164){//分部 + defaultData.put(fieldName, ""+user.getUserSubCompany1()); + } + } + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailInfoDao.java b/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailInfoDao.java new file mode 100644 index 0000000..7263dee --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailInfoDao.java @@ -0,0 +1,107 @@ +package weaver.chaoyang.he.shangan.cornjob; + + +import org.apache.commons.lang3.StringUtils; + +import java.util.Date; +import java.util.List; + +/** + * 邮件信息 实体类 + */ +public class MailInfoDao { + + /** + * 发件人 + */ + private String from ; + + /** + * 发件日期 + */ + private Date date; + + /** + * 邮件主题 + */ + private String subject; + + /** + * 邮件内容 + */ + private String content; + + /** + * 是否包含附件 + */ + private boolean isContainAttachment; + + /** + * 附件ID(上传至OA系统) + */ + private List attachmentIdList; + + /** + * 对象toString 方法 + * @return 字符串 + */ + public String toString(){ + return "MailInfoDao Information: {" + + "form :" + from + ",\n" + + "date :" + date + ",\n" + + "subject :" + subject + ",\n" + + "content :" + content + ",\n" + + "isContainAttachment :" + isContainAttachment + ",\n" + + "attachmentIdList :" + StringUtils.join(attachmentIdList, ",") + "\n" + + "}"; + } + + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public boolean isContainAttachment() { + return isContainAttachment; + } + + public void setContainAttachment(boolean containAttachment) { + isContainAttachment = containAttachment; + } + + public List getAttachmentIdList() { + return attachmentIdList; + } + + public void setAttachmentIdList(List attachmentIdList) { + this.attachmentIdList = attachmentIdList; + } +} diff --git a/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailTriggerWorkflowCronJob.java b/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailTriggerWorkflowCronJob.java new file mode 100644 index 0000000..5f45f7e --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/shangan/cornjob/MailTriggerWorkflowCronJob.java @@ -0,0 +1,190 @@ +package weaver.chaoyang.he.shangan.cornjob; + +import org.apache.commons.lang3.StringUtils; +import weaver.chaoyang.he.shangan.common.util.CommonWFUtil; +import weaver.chaoyang.he.zwl.common.ThreadPoolConfig; +import weaver.conn.RecordSet; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.interfaces.schedule.BaseCronJob; + +import weaver.zwl.common.ToolUtil; + +import java.util.*; +import java.util.concurrent.ExecutorService; + +/** + * 上海安装工程集团 + * 邮件触发流程 计划任务 + */ +public class MailTriggerWorkflowCronJob extends BaseCronJob { + + private final ToolUtil tool = new ToolUtil(); + + private final ReadMail readMail = new ReadMail(); + + + /** + * 实现父类方法 + * 具体的业务实现 + */ + @Override + public synchronized void execute(){ + tool.writeDebuggerLog("","-------- MailTriggerWorkflowCronJob Begin---------------"); + //拿到一个线程池 + ExecutorService threadPool = ThreadPoolConfig.createThreadPoolInstance(); + List> configList = readMail.getConfiguration(); + + tool.writeDebuggerLog("","configList:[" + configList.size() + "]"); + +// threadPool.execute(() -> { + for(Map configMap : configList){ + try { + getMainInfoAndCreateWorkflow(configMap); + } catch (Exception e) { + tool.writeDebuggerLog("","创建流程信息异常,异常信息:[" + e.getMessage() + "]"); + throw new RuntimeException(e); + } + } +// }); + + tool.writeDebuggerLog("","-------- MailTriggerWorkflowCronJob End---------------"); + } + + /** + * 获取邮箱中的邮件信息,且根据配置创建流程 + * @param dataMap 配置信息 + */ + @SuppressWarnings("unchecked") + private void getMainInfoAndCreateWorkflow(Map dataMap) throws Exception { + try { + //邮箱地址 + String mailAddress = (String) dataMap.get("mailAddress"); + //邮箱密码 + String mailPassword = (String) dataMap.get("mailPassword"); + //白名单列表 + String whiteList = Util.null2String(dataMap.get("whiteList")); + //获取用户ID + int remindUser = (int) dataMap.get("remindUser"); + //文档存储目录 + int secCategory = (int) dataMap.get("secCategory"); + //触发的流程类型ID + String workflowId = (String) dataMap.get("workflowId"); + //邮件文件夹 + String mailFolder = Util.null2String(dataMap.get("mailFolder")); + + //用户信息 + User createUser = new User(remindUser); + + //流程字段与邮件信息匹配集合 + List> fieldList = (List>) dataMap.get("fieldList"); + + List> newFieldList = new ArrayList<>(); + + //先对配置字段进行转换,将字段ID转成对应的字段数据库名 + for(Map fieldMap : fieldList){ + for(int key : fieldMap.keySet()){ + int fieldId = fieldMap.get(key); + //根据字段ID获取其字段名称 + String fieldName = getFieldNameByFieldid(fieldId); + + Map dtMap = new HashMap<>(); + dtMap.put("fieldName",fieldName); + dtMap.put("fieldId",fieldId); + dtMap.put("mailField",key); + + newFieldList.add(dtMap); + } + } + + //获取邮箱中的未读邮件 + List mailInfoDaoList = readMail.getMainInfo(mailAddress,mailPassword,whiteList,secCategory,remindUser,mailFolder); + + tool.writeDebuggerLog("","mailInfoDaoList:[" + mailInfoDaoList.size() + "]"); + if(mailInfoDaoList.size() > 0){ + for(MailInfoDao mailInfoDao : mailInfoDaoList){ + System.out.println(mailInfoDao.toString()); + + createWorkflow(workflowId,createUser,mailInfoDao,newFieldList); + } + } + } catch (Exception e) { + e.printStackTrace(); + tool.writeDebuggerLog("","导出邮箱中的未读邮件报错==="+e); + } + } + + /** + * 根据字段ID获取其对应的字段名称 + * @param fieldId 字段ID + * @return 字段名称 + */ + private String getFieldNameByFieldid(int fieldId){ + if(fieldId > 0){ + String querySQL = "select fieldname from workflow_billfield where id = ?"; + + RecordSet rs = new RecordSet(); + + if(rs.executeQuery(querySQL,fieldId) && rs.next()){ + return Util.null2String(rs.getString(1)); + } + } + return ""; + } + + + /** + * 创建流程信息 + * @param mailInfoDao 邮件信息实体类 + * @param fieldList 流程字段与邮件信息匹配映射 + */ + private void createWorkflow(String workflowId, User createUser, MailInfoDao mailInfoDao, List> fieldList) throws Exception { + Map mainTableMap = new HashMap<>(); + + for(Map fieldMap : fieldList){ + tool.writeDebuggerLog("","fieldMap:[" + fieldMap.toString() + "]"); + //字段数据库名 + String fieldName = Util.null2String(fieldMap.get("fieldName")); + + if(!"".equals(fieldName)){ + + int mailField = Util.getIntValue(Util.null2String(fieldMap.get("mailField")),-1); + + String fieldValue = ""; + + switch (mailField){ + case 0 ://发件人 + fieldValue = mailInfoDao.getFrom(); + break; + case 1 : //发件日期 + Date date = mailInfoDao.getDate(); + fieldValue = TimeUtil.getFormartString(date,"yyyy-MM-dd"); + break; + case 2 : //邮件主题 + fieldValue = mailInfoDao.getSubject(); + break; + case 3 : //邮件内容 + fieldValue = mailInfoDao.getContent(); + break; + case 4 ://是否包含附件 + fieldValue = mailInfoDao.isContainAttachment() ? "1" : "0"; + break; + case 5 : //附件 + List docIds = mailInfoDao.getAttachmentIdList(); + fieldValue = StringUtils.join(docIds,","); + break; + } + mainTableMap.put(fieldName,fieldValue); + } + } + + tool.writeDebuggerLog("","mainTableMap:[" + mainTableMap.toString() + "]"); + + if(!mainTableMap.isEmpty()){ + String requestId = CommonWFUtil.startWorkflow(workflowId,mainTableMap,null,true,createUser,"0"); + + tool.writeDebuggerLog("","创建成功的流程请求ID:[" + requestId + "]"); + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/shangan/cornjob/ReadMail.java b/src/main/java/weaver/chaoyang/he/shangan/cornjob/ReadMail.java new file mode 100644 index 0000000..6e797df --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/shangan/cornjob/ReadMail.java @@ -0,0 +1,520 @@ +package weaver.chaoyang.he.shangan.cornjob; + +import com.sun.mail.imap.IMAPFolder; +import com.sun.mail.imap.IMAPStore; +import org.apache.commons.lang3.StringUtils; +import weaver.conn.RecordSet; +import weaver.docs.docs.DocImageManager; +import weaver.docs.webservices.DocInfo; +import weaver.docs.webservices.DocServiceImpl; +import weaver.file.ImageFileManager; +import weaver.general.IOUtils; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.zwl.common.ToolUtil; + +import javax.mail.*; +import javax.mail.internet.MimeMultipart; +import javax.mail.internet.MimeUtility; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.util.*; + +/** + * 上海安装工程集团 + * 读取邮件信息工具类 + * + */ +public class ReadMail extends ToolUtil { + + /** + * 定义SSL factory + */ + private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; + + /** + * 定义邮箱host (腾讯邮箱)暂不修改 + */ + private static final String host = "imap.exmail.qq.com"; + + /** + * 定义邮箱端口 + */ + private static final String port = "993"; + + /** + * 邮箱连接Session + */ + private static Session session; + + /** + * 配置表名称 + */ + private final static String configTableName = "uf_mail_wf_config"; + + /** + * 获取收件箱中的邮件信息 + * @param mailAddress 邮箱地址 + * @param mailPassword 邮箱密码 + * @param whiteList 发件人白名单 + * @param secCategory 附件目录ID + * @param userId 操作者ID + * @return 返回收件箱中的邮件信息集合 + */ + public List getMainInfo(String mailAddress,String mailPassword,String whiteList,int secCategory,int userId){ + return getMainInfo(mailAddress,mailPassword,whiteList,secCategory,userId,""); + } + /** + * 获取收件箱中的邮件信息 + * @param mailAddress 邮箱地址 + * @param mailPassword 邮箱密码 + * @param whiteList 发件人白名单 + * @param secCategory 附件目录ID + * @param userId 操作者ID + * @param mailFolder 邮箱文件夹 + * @return 返回收件箱中的邮件信息集合 + */ + public List getMainInfo(String mailAddress,String mailPassword,String whiteList,int secCategory,int userId,String mailFolder){ + if(session == null){ + session = createSession(); + } + + List mailInfoDaoList = new ArrayList<>(); + //文件夹信息 + IMAPFolder folder = null; + //邮箱会话信息 + IMAPStore store = null; + try{ + store=(IMAPStore)session.getStore("imap"); // 使用imap会话机制,连接服务器 + store.connect(host,Util.getIntValue(port),mailAddress,mailPassword); + + if(StringUtils.isBlank(mailFolder)){ + mailFolder = "INBOX"; + } + + folder=(IMAPFolder)store.getFolder(mailFolder); //收件箱 + + // 使用只读方式打开收件箱 + folder.open(Folder.READ_WRITE); + + //获取所有的邮件 +// Message[] mess = folder.getMessages(); + //获取未读邮件 + Message[] mess = folder.getMessages(folder.getMessageCount()-folder.getUnreadMessageCount()+1,folder.getMessageCount()); + + for (Message message : mess) { + Flags flags = message.getFlags(); + if (!flags.contains(Flags.Flag.SEEN)) {//未读邮件处理 + String from = MimeUtility.decodeText(message.getFrom()[0].toString()); + + if (StringUtils.isNotBlank(whiteList) && !isBelongToWhite(whiteList, from)) { + continue; + } + //设置已读 + message.setFlag(Flags.Flag.SEEN, true); + + MailInfoDao mailInfoDao = analysisMessage(message, secCategory, userId); + + mailInfoDaoList.add(mailInfoDao); + } + } + }catch (MessagingException e) { + e.printStackTrace(); + this.writeDebuggerLog("","异常信息96:[" + e.getMessage() + "]"); + } catch (Exception e) { + e.printStackTrace(); + this.writeDebuggerLog("","异常信息99:[" + e.getMessage() + "]"); + throw new RuntimeException(e); + } finally { + try { + if (folder != null) { + folder.close(false); + } + if (store != null) { + store.close(); + } + } catch (MessagingException e) { + e.printStackTrace(); + this.writeDebuggerLog("","异常信息110:[" + e.getMessage() + "]"); + } + } + + return mailInfoDaoList; + + } + + /** + * 解析邮件信息 + * @param message 邮件 + * @param secCategory 附件存储目录 + * @param userId 附件所属者 + * @return 返回邮件对象 + * @throws Exception 抛出异常信息 + */ + private MailInfoDao analysisMessage(Message message,int secCategory,int userId) throws Exception { + MailInfoDao dao = new MailInfoDao(); + //邮件发送主题 + String subject = message.getSubject(); + //发送日期 + Date date = message.getSentDate(); + //邮件正文 + String htmlContent = getTextFromMessage(message); + + String from = MimeUtility.decodeText(message.getFrom()[0].toString()); + + + //是否包含附件 + boolean isContainAttachment = isContainAttachment(message); + + dao.setFrom(from); + dao.setSubject(subject); + dao.setDate(date); + dao.setContent(htmlContent); + dao.setContainAttachment(isContainAttachment); + if(isContainAttachment){ + List docList = saveAttachment(message,secCategory,userId); + dao.setAttachmentIdList(docList); + } + + return dao; + } + + + /** + * 判断邮件中是否包含附件 + * @return 邮件中存在附件返回true,不存在返回false + * @throws MessagingException Message异常信息 + * @throws IOException IO异常信息 + */ + private boolean isContainAttachment(Part part) throws MessagingException, IOException { + boolean flag = false; + if (part.isMimeType("multipart/*")) { + MimeMultipart multipart = (MimeMultipart) part.getContent(); + int partCount = multipart.getCount(); + for (int i = 0; i < partCount; i++) { + BodyPart bodyPart = multipart.getBodyPart(i); + String disposition = bodyPart.getDisposition(); + if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) { + flag = true; + } else if (bodyPart.isMimeType("multipart/*")) { + flag = isContainAttachment(bodyPart); + } else { + String contentType = bodyPart.getContentType(); + if (contentType.contains("application") || contentType.contains("name")) { + flag = true; + } + } + + if (flag) break; + } + } else if (part.isMimeType("message/rfc822")) { + flag = isContainAttachment((Part)part.getContent()); + } + return flag; + } + + /** + * 获取邮件附件信息,同时将附件上传至OA系统中返回对应的文档ID + * @param part 邮件中多个组合体中的其中一个组合体 + * @throws Exception 抛出的异常信息 + */ + private List saveAttachment(Part part,int secCategory,int userId) throws Exception { + + List docList = new ArrayList<>(); + + if (part.isMimeType("multipart/*")) { + Multipart multipart = (Multipart) part.getContent(); //复杂体邮件 + //复杂体邮件包含多个邮件体 + int partCount = multipart.getCount(); + for (int i = 0; i < partCount; i++) { + //获得复杂体邮件中其中一个邮件体 + BodyPart bodyPart = multipart.getBodyPart(i); + //某一个邮件体也有可能是由多个邮件体组成的复杂体 + String disposition = bodyPart.getDisposition(); + + if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) { + InputStream is = bodyPart.getInputStream(); + //附件名称 + String fileName = MimeUtility.decodeText(bodyPart.getFileName()); + int imageFileId = createFileByInputSteam(is, fileName); + + if(imageFileId > 0){ + int docId = createDocByImageFileId(fileName,secCategory,imageFileId,userId); + + docList.add(docId); + } + } else if (bodyPart.isMimeType("multipart/*")) { + docList.addAll(saveAttachment(bodyPart,secCategory,userId)); + } else { + + /*String contentType = bodyPart.getContentType(); + if (contentType.contains("name") || contentType.contains("application")) { + //附件名称 + String fileName = MimeUtility.decodeText(bodyPart.getFileName()); + int imageFileId = createFileByInputSteam(bodyPart.getInputStream(), fileName); + + if(imageFileId > 0){ + int docId = createDocByImageFileId(fileName,secCategory,imageFileId,userId); + docList.add(docId); + } + }*/ + + } + } + } else if (part.isMimeType("message/rfc822")) { + docList.addAll(saveAttachment((Part) part.getContent(),secCategory,userId)); + } + + return docList; + } + + /** + * 创建文件信息,文件权限继承文档目录权限 + * + * @param fileName 文件名称 + * @param secCategory 文件目录 + * @param imageFileId 物理文件ID + * @param userId 用户ID + * @return 文档ID + * @throws Exception 可能会出现的异常 + */ + private int createDocByImageFileId(String fileName, int secCategory, int imageFileId, Integer userId) throws Exception { + DocInfo docInfo = new DocInfo(); + docInfo.setImagefileId(imageFileId); + docInfo.setSeccategory(secCategory); + docInfo.setDocSubject(fileName); + docInfo.setDoccontent(""); + DocServiceImpl docService = new DocServiceImpl(); + User user = new User(userId); + user.setLanguage(7); + + int docId = docService.createDocByUser(docInfo, user); + DocImageManager imgManger = new DocImageManager(); + imgManger.resetParameter(); + imgManger.setDocid(docId); + imgManger.setImagefileid(imageFileId); + imgManger.setImagefilename(fileName); + imgManger.setIsextfile("1"); + String ext = fileName.substring(fileName.lastIndexOf(".") + 1); + if ("doc".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("3"); + } else if ("xls".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("4"); + } else if ("ppt".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("5"); + } else if ("wps".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("6"); + } else if ("docx".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("7"); + } else if ("xlsx".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("8"); + } else if ("pptx".equalsIgnoreCase(ext)) { + imgManger.setDocfiletype("9"); + } else { + imgManger.setDocfiletype("2"); + } + imgManger.AddDocImageInfo(); + return docId; + } + + + /** + * 创建物理文件 + * + * @param content 文件流 + * @param fileName 文件名 + * @return 文件id + */ + private int createFileByInputSteam(InputStream content, String fileName) { + ImageFileManager imageFileManager = new ImageFileManager(); + int imgFileId = 0; + try { + Method saveImageFileByInputStream = ImageFileManager.class.getMethod("saveImageFileByInputStream", InputStream.class, String.class); + imgFileId = (int) saveImageFileByInputStream.invoke(imageFileManager, content, fileName); + } catch (NoSuchMethodException e) { + imageFileManager.setImagFileName(fileName); + try { + imageFileManager.setData(IOUtils.toBytes(content)); + imgFileId = imageFileManager.saveImageFile(); + } catch (Exception ex) { + ex.printStackTrace(); + this.writeDebuggerLog("","创建文件失败,文件流转换失败,失败原因:[" + e.getMessage() + "]"); + } + } catch (Exception e) { + e.printStackTrace(); + this.writeDebuggerLog("","创建文件失败,失败原因:[" + e.getMessage() + "]"); + } + return imgFileId; + } + + /** + * 解析邮件正文 + * @param message 邮件消息类 + * @return 返回邮件正文 + * @throws MessagingException 信息异常 + * @throws IOException IO流异常 + */ + private String getTextFromMessage(Message message) throws MessagingException, IOException { + String result = ""; + + if (message.isMimeType("text/plain")) { + result = message.getContent().toString(); + } else if (message.isMimeType("multipart/*")) { + MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); + result = getTextFromMimeMultipart(mimeMultipart); + } + + return result; + } + + /** + * 复杂体 递归获取邮件正文 + * @param mimeMultipart 邮件复杂体类 + * @return 正文 + * @throws MessagingException 信息异常 + * @throws IOException IO流异常 + */ + private String getTextFromMimeMultipart( + MimeMultipart mimeMultipart) throws MessagingException, IOException{ + + StringBuilder result = new StringBuilder(); + + int count = mimeMultipart.getCount(); + + for (int i = 0; i < count; i++) { + BodyPart bodyPart = mimeMultipart.getBodyPart(i); + if (bodyPart.isMimeType("text/plain")) { + result.append(bodyPart.getContent()); + break; // without break same text appears twice in my tests + } else if (bodyPart.isMimeType("text/html")) { + String html = (String) bodyPart.getContent(); + //result.append(org.jsoup.Jsoup.parse(html).text()); + result.append(html); + } else if (bodyPart.getContent() instanceof MimeMultipart){ + result.append(getTextFromMimeMultipart((MimeMultipart) bodyPart.getContent())); + } + + } + + return result.toString(); + + } + + + /** + * 判断发件人 是否属于白名单中 + * @param whiteList 白名单列表 + * @param from 发件人 + * @return 返回判断结果 + */ + private boolean isBelongToWhite(String whiteList,String from){ + boolean isContain = false; + + List list = Util.splitString2List(whiteList,";"); + + for(String mail : list){ + if(from.contains(mail)){ + isContain = true; + break; + } + } + + return isContain; + } + + /** + * 获取登录邮箱的Session信息 + * @return 返回创建的Session + */ + private Session createSession(){ + Properties props = System.getProperties(); + props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY); + props.setProperty("mail.imap.socketFactory.port",port); + props.setProperty("mail.store.protocol","imap"); + props.setProperty("mail.imap.host", host); + props.setProperty("mail.imap.port", port); + props.setProperty("mail.imap.auth.login.disable", "true"); + Session session = Session.getDefaultInstance(props,null); + session.setDebug(false); + return session; + } + + /** + * 获取建模配置信息 + * @return 返回建模配置信息集合 + */ + public List> getConfiguration(){ + //查询配置信息 + String selectData = "select u.*,wb.docCategory from " + configTableName + " u left join workflow_base wb on u.workflowId = wb.id where u.status = 1"; + + String selectDetailData = "select * from " + configTableName + "_dt1 where mainId = ?"; + RecordSet rs = new RecordSet(); + + List> configList = new ArrayList<>(); + + RecordSet rs_d = new RecordSet(); + + int mainId; + + if(rs.executeQuery(selectData)){ + while(rs.next()){ + mainId = Util.getIntValue(rs.getString("id"),-1); + //流程类型ID + String workflowId = Util.null2String(rs.getString("workflowId")); + //收件人邮箱 + String mailAddress = Util.null2String(rs.getString("mailAddress")); + //邮箱密码 + String mailPassword = Util.null2String(rs.getString("mailPassword")); + //邮件内容写入字段ID + //int contentField = Util.getIntValue(rs.getString("contentField"),0); + //提醒人 + int remindUser = Util.getIntValue(rs.getString("remindUser"),0); + //发件人白名单 + String whiteSender = Util.null2String(rs.getString("whiteSender")); + //文件夹目录 + String docCategory = Util.null2String(rs.getString("docCategory")); + //邮箱文件夹 + String mailFolder = Util.null2String(rs.getString("mailFolder")); + + Map detailMap = new HashMap<>(); + + detailMap.put("workflowId",workflowId); + detailMap.put("mailAddress",mailAddress); + detailMap.put("mailPassword",mailPassword); + detailMap.put("mailFolder",mailFolder); + detailMap.put("remindUser",remindUser); + detailMap.put("whiteSender",whiteSender); + + int secCategory = -1; + if(!"".equals(docCategory)){ + secCategory = Util.getIntValue(docCategory.substring(docCategory.lastIndexOf(",")),0); + } + + detailMap.put("secCategory",secCategory); + + List> fieldList = new ArrayList<>(); + if(rs_d.executeQuery(selectDetailData,mainId)){ + while(rs_d.next()){ + //邮件字段 + int mailField = Util.getIntValue(rs_d.getString("mailField"),0); + //流程字段 + int billField = Util.getIntValue(rs_d.getString("billField"),0); + + Map fieldMap = new HashMap<>(); + fieldMap.put(mailField,billField); + + fieldList.add(fieldMap); + } + } + + detailMap.put("fieldList",fieldList); + + configList.add(detailMap); + } + } + + return configList; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/dao/ConfigMappingCMD.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/dao/ConfigMappingCMD.java new file mode 100644 index 0000000..f020e94 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/dao/ConfigMappingCMD.java @@ -0,0 +1,162 @@ +package weaver.chaoyang.he.xiao.commons.config.dao; + +import weaver.conn.RecordSet; +import weaver.general.Util; +import weaver.xiao.commons.config.entity.DocImageFile; +import weaver.xiao.commons.config.entity.FieldMessage; +import weaver.xiao.commons.config.entity.MappingDetail; +import weaver.xiao.commons.config.entity.RequestMappingConfig; +import weaver.xiao.commons.config.enumtype.DataSourceEnum; +import weaver.xiao.commons.exception.ValueDealException; +import weaver.xiao.commons.utils.SqlUtil; +import weaver.zwl.common.ToolUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + + +/** + * @author XiaoBokang + * @create 2021/12/29 9:46 + */ + +public class ConfigMappingCMD { + + private final ToolUtil toolUtil = new ToolUtil(); + private final String configTableName = "uf_request_config"; + private final SqlUtil sqlUtil = new SqlUtil(); + + public RequestMappingConfig selectByUniqueCode(String uniqueCode) { + toolUtil.writeDebuggerLog("=======================查询配置列表======================="); + RequestMappingConfig requestMappingConfig = new RequestMappingConfig(); + RecordSet recordSet = new RecordSet(); + String querySql = "select id,workflow,requestUrl,dataSource,uniqueCode from " + configTableName + " where uniqueCode = ?"; + toolUtil.writeDebuggerLog("执行查询的sql query mainRequestMappingConfig list sql new>>>>" + querySql + " uniqueCode >>" + uniqueCode); + recordSet.executeQuery(querySql, uniqueCode); + if (recordSet.next()) { + int mainId = Util.getIntValue(recordSet.getString("id")); + requestMappingConfig = sqlUtil.recordSetToEntityByEntity(recordSet, RequestMappingConfig.class); + this.setDetailMapping(mainId, requestMappingConfig); + } + return requestMappingConfig; + } + + private void setDetailMapping(int mainId, RequestMappingConfig requestMappingConfig) { + // 查询明细1的信息 + RecordSet detail1RecordSet = new RecordSet(); + String dataSource = requestMappingConfig.getDataSource(); + if (Objects.isNull(dataSource) || "".equals(dataSource)) { + dataSource = "0"; + } + DataSourceEnum anEnum = DataSourceEnum.getEnum(dataSource); + String queryDetail1Sql = ""; + switch (anEnum) { + case CUS_TABLE: + queryDetail1Sql = "select paramName,paramType,getValueType,dataSource,belongTo,workflowField,modelField,fieldName,valueContext," + + " from " + configTableName + "_dt1 config "; + break; + case WORKFLOW: + queryDetail1Sql = "select paramName,paramType,getValueType,dataSource,belongTo,workflowField,modelField,valueContext," + + " fv.id fieldId,fv.fieldname,fv.tablename,fv.indexdesc " + + " from " + configTableName + "_dt1 config " + + " left join workflow_field_table_view fv on config.workflowField = fv.id " + + " where mainid = ? "; + break; + case MODEL: + queryDetail1Sql = "select paramName,paramType,getValueType,dataSource,belongTo,workflowField,modelField,fieldName,valueContext," + + " fv.id fieldId,fv.fieldname,fv.tablename,fv.indexdesc " + + " from " + configTableName + "_dt1 config " + + " left join workflow_field_table_view fv on config.modelField = fv.id " + + " where mainid = ? "; + break; + default: + throw new ValueDealException("不支持的数据来源"); + } + toolUtil.writeDebuggerLog("执行查询的明细1sql query detail1Sql >>>>" + queryDetail1Sql + " mainId:" + mainId); + detail1RecordSet.executeQuery(queryDetail1Sql, mainId); + List mappingDetails = new ArrayList<>(); + while (detail1RecordSet.next()) { + MappingDetail mappingDetail = sqlUtil.recordSetToEntityByEntity(detail1RecordSet, MappingDetail.class); + String getValueType = mappingDetail.getGetValueType(); + // 设置流程字段相关信息 +// if("0".equals(getValueType) || "4".equals(getValueType)){ + FieldMessage fieldMessage = sqlUtil.recordSetToEntityByEntity(detail1RecordSet, FieldMessage.class); + mappingDetail.setFieldMassage(fieldMessage); +// } + mappingDetails.add(mappingDetail); + } + // 查询明细2的信息 + RecordSet detail2RecordSet = new RecordSet(); + String queryDetail2Sql = "select paramName,belongTo,childType,dataSource,detailId from uf_request_config_dt2 where mainid = ?"; + toolUtil.writeDebuggerLog("执行查询的明细sql query detail2Sql >>>>" + queryDetail2Sql + " mainId:" + mainId); + detail2RecordSet.executeQuery(queryDetail2Sql, mainId); + while (detail2RecordSet.next()) { + MappingDetail mappingDetail = sqlUtil.recordSetToEntityByEntity(detail2RecordSet, MappingDetail.class); + mappingDetail.setParamType("6");// 设置参数类型为List + mappingDetails.add(mappingDetail); + } + // 查询明细3的信息 + RecordSet detail3RecordSet = new RecordSet(); + String queryDetail3Sql = "select paramName,belongTo from uf_request_config_dt3 where mainid = ?"; + toolUtil.writeDebuggerLog("执行查询的明细sql query detail3Sql >>>>" + queryDetail3Sql + " mainId:" + mainId); + detail3RecordSet.executeQuery(queryDetail3Sql, mainId); + while (detail3RecordSet.next()) { + MappingDetail mappingDetail = sqlUtil.recordSetToEntityByEntity(detail3RecordSet, MappingDetail.class); + mappingDetail.setParamType("5");// 设置参数类型为Object + mappingDetails.add(mappingDetail); + } + requestMappingConfig.setConfigDetail(mappingDetails); +// //查询明细4的信息 +// RecordSet detail4RecordSet = new RecordSet(); +// List responseMappingList = new ArrayList<>(); +// String queryDetail4Sql = "select responseFieldName,workflowField,mainOrDetail,detailTableId,workflowFieldName from uf_request_config_dt4 where mainid = ?"; +// toolUtil.writeDebuggerLog("执行查询的明细sql query detail4Sql >>>>"+queryDetail4Sql+" mainId:"+mainId); +// detail4RecordSet.executeQuery(queryDetail4Sql,mainId); +// while (detail4RecordSet.next()){ +// ResponseMapping responseMapping = sqlUtil.recordSetToEntityByEntity(detail4RecordSet, ResponseMapping.class); +// responseMappingList.add(responseMapping); +// } +// requestMappingConfig.setResponseMappingList(responseMappingList); + requestMappingConfig.setConfigDetail(mappingDetails); + } + + + /** + *

查询附件信息

+ * + * @param docIds 文档id + * @return 附件信息 + * @author YouHong.ai + */ + public List selectDocImageFileList(String docIds) { + String sql = "select docfile.IMAGEFILEID,docfile.IMAGEFILENAME,docfile.DOCID,docfile.ID, " + + " imf.FILESIZE " + + "from docimagefile docfile " + + "left join imagefile imf on imf.IMAGEFILEID = docfile.IMAGEFILEID " + + "where docid in (" + docIds + ")"; + RecordSet rs = new RecordSet(); + rs.executeQuery(sql); + List docImageFileList = new ArrayList<>(); + while (rs.next()) { + String IMAGEFILEID = rs.getString("IMAGEFILEID"); + String IMAGEFILENAME = rs.getString("IMAGEFILENAME"); + String DOCID = rs.getString("DOCID"); + String ID = rs.getString("ID"); + String fileSize = rs.getString("FILESIZE"); + DocImageFile docImageFile = new DocImageFile(); + docImageFile.setImageFileId(Util.getIntValue(IMAGEFILEID)); + docImageFile.setImageFileName(IMAGEFILENAME); + docImageFile.setDocId(Util.getIntValue(DOCID)); + docImageFile.setId(Util.getIntValue(ID)); + docImageFile.setFileSize(Util.getIntValue(fileSize) / 1024L); + docImageFileList.add(docImageFile); + } + if (docImageFileList.isEmpty()) { + throw new NullPointerException("附件字段不存在值!请检查数据表或配置表数据类型是否正确!"); + } + return docImageFileList; + } + + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/DocImageFile.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/DocImageFile.java new file mode 100644 index 0000000..e78ff99 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/DocImageFile.java @@ -0,0 +1,40 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

附件信息

+ * + *

create: 2022-11-21 10:55

+ * + * @author youHong.ai + */ + +@Getter +@Setter +@ToString +public class DocImageFile { + /** + * 文件id + */ + private Integer imageFileId; + /** + * 文件名称 + */ + private String imageFileName; + /** + * docId + */ + private Integer docId; + /** + * id + */ + private Integer id; + + /** + * 文件大小 + */ + private Long fileSize; +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/FieldMessage.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/FieldMessage.java new file mode 100644 index 0000000..c60a52c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/FieldMessage.java @@ -0,0 +1,26 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Data; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; + +/** + * @author XiaoBokang + * @create 2021/12/31 10:15 + */ + +@Data +public class FieldMessage { + + @SqlFieldMapping("fieldId") + private String fieldId; + + @SqlFieldMapping("fieldName") + private String fieldName; + + @SqlFieldMapping("indexDesc") + private String indexDesc; + + @SqlFieldMapping("tableName") + private String tableName; + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ListMapIndexValue.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ListMapIndexValue.java new file mode 100644 index 0000000..bb694d3 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ListMapIndexValue.java @@ -0,0 +1,17 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Data; + +/** + *

list分割暂存类

+ * + *

create: 2022-08-05 11:25

+ * + * @author aiyh EBU7-dev-1 + */ + +@Data +public class ListMapIndexValue { + private String key; + private Object value; +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MappingDetail.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MappingDetail.java new file mode 100644 index 0000000..97ca74a --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MappingDetail.java @@ -0,0 +1,48 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Data; +import weaver.xiao.commons.config.entity.FieldMessage; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; + +import java.util.List; + +/** + * @author XiaoBokang + * @create 2021/12/28 17:45 + */ + +@Data +public class MappingDetail { + + @SqlFieldMapping("paramName") + private String paramName; + + @SqlFieldMapping("paramType") + private String paramType; + + @SqlFieldMapping("getValueType") + private String getValueType; + + @SqlFieldMapping("childType") + private String childType; + + @SqlFieldMapping("dataSource") + private String dataSource; + + @SqlFieldMapping("detailId") + private String detailId; + + @SqlFieldMapping("belongTo") + private String belongTo; + + @SqlFieldMapping("workflowField") + private String workflowField; + + @SqlFieldMapping("valueContext") + private String valueContext; + + private List childList; + + private FieldMessage fieldMassage; + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MultipartFile.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MultipartFile.java new file mode 100644 index 0000000..1acddba --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/MultipartFile.java @@ -0,0 +1,37 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +import java.io.InputStream; + +/** + *

+ * + *

create: 2022-11-21 11:12

+ * + * @author youHong.ai + */ + +@Setter +@Getter +@ToString +public class MultipartFile { + /** + * 文件名 + */ + String fileName; + /** + * 上传文件的key + */ + String fileKey; + /** + * 文件流信息 + */ + InputStream stream; + /** + * 文件大小 + */ + Long fileSize; +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/RequestMappingConfig.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/RequestMappingConfig.java new file mode 100644 index 0000000..ab7ed80 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/RequestMappingConfig.java @@ -0,0 +1,45 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + + + +import lombok.Data; +import weaver.xiao.commons.config.entity.MappingDetail; +import weaver.xiao.commons.config.entity.ResponseMapping; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; + +import java.util.List; + +/** + * @author XiaoBokang + * @create 2021/12/28 17:43 + */ + +@Data +public class RequestMappingConfig { + + @SqlFieldMapping("workflow") + private String workflow; + + @SqlFieldMapping("requestUrl") + private String requestUrl; + + @SqlFieldMapping("uniqueCode") + private String uniqueCode; + + @SqlFieldMapping("dataSource") + private String dataSource; + + @SqlFieldMapping("modelId") + private String modelId; + + @SqlFieldMapping("tableName") + private String tableName; + + @SqlFieldMapping("urlDesc") + private String urlDesc; + + private List configDetail; + + private List responseMappingList; + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ResponseMapping.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ResponseMapping.java new file mode 100644 index 0000000..3e93cf1 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/entity/ResponseMapping.java @@ -0,0 +1,17 @@ +package weaver.chaoyang.he.xiao.commons.config.entity; + +import lombok.Data; + +/** + * @author XiaoBokang + * @create 2022/4/12 22:28 + */ + +@Data +public class ResponseMapping { + private String responseFieldName; + private String workflowField; + private String mainOrDetail; + private String detailTableId; + private String workflowFieldName; +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/DataSourceEnum.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/DataSourceEnum.java new file mode 100644 index 0000000..52dc902 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/DataSourceEnum.java @@ -0,0 +1,35 @@ +package weaver.chaoyang.he.xiao.commons.config.enumtype; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * @author XiaoBokang + * @create 2022/6/14 12:26 + */ + +public enum DataSourceEnum { + + WORKFLOW("0"), + MODEL("1"), + CUS_TABLE("2"); + + private static final Map LOOK_UP = new HashMap<>(8); + + static { + for (DataSourceEnum dataSource : EnumSet.allOf(DataSourceEnum.class)){ + LOOK_UP.put(dataSource.value,dataSource); + } + } + public final String value; + + DataSourceEnum(String value){ + this.value = value; + } + + public static DataSourceEnum getEnum(String value){ + return LOOK_UP.get(value); + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/GetValueTypeEnum.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/GetValueTypeEnum.java new file mode 100644 index 0000000..868d8bb --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/GetValueTypeEnum.java @@ -0,0 +1,44 @@ +package weaver.chaoyang.he.xiao.commons.config.enumtype; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * @author XiaoBokang + * @create 2022/6/14 13:13 + */ + +public enum GetValueTypeEnum { + + WORKFLOW_FIELD("0"), + DEFAULT_VALUE("1"), + CURRENT_TIME("3"), + CUS_SQL("4"), + REQUEST_ID("5"), + MAIN_DATA_ID("6"), + RANDOM("7"), + ATTACHMENT("8"), + + CUS_INTERFACE("9"), + + CUS_FIELD("10"); + + private static final Map LOOK_UP = new HashMap<>(8); + + static { + for (GetValueTypeEnum getValueTypeEnum : EnumSet.allOf(GetValueTypeEnum.class)) { + LOOK_UP.put(getValueTypeEnum.value, getValueTypeEnum); + } + } + + public final String value; + + GetValueTypeEnum(String value) { + this.value = value; + } + + public static GetValueTypeEnum getEnum(String value) { + return LOOK_UP.get(value); + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/ParamTypeEnum.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/ParamTypeEnum.java new file mode 100644 index 0000000..108d26f --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/enumtype/ParamTypeEnum.java @@ -0,0 +1,43 @@ +package weaver.chaoyang.he.xiao.commons.config.enumtype; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * @author XiaoBokang + * @create 2022/6/14 12:56 + */ + +public enum ParamTypeEnum { + + STRING("0"), + INT("1"), + DOUBLE("2"), + DATE("3"), + DATE_TIME("4"), + OBJECT("5"), + LIST("6"), + CUS_DATE_STR("7"), + TIME_STAMP("8"), + DATE_VAL("9"), + Boolean("10"); + + + private static final Map LOOK_UP = new HashMap<>(8); + + static { + for (ParamTypeEnum paramTypeEnum : EnumSet.allOf(ParamTypeEnum.class)){ + LOOK_UP.put(paramTypeEnum.value,paramTypeEnum); + } + } + public final String value; + + ParamTypeEnum(String value){ + this.value = value; + } + + public static ParamTypeEnum getEnum(String value){ + return LOOK_UP.get(value); + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceGetValue.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceGetValue.java new file mode 100644 index 0000000..345f746 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceGetValue.java @@ -0,0 +1,38 @@ +package weaver.chaoyang.he.xiao.commons.config.interfacies; + +import org.apache.log4j.Logger; +import weaver.xiao.commons.utils.LogUtil; + +import java.util.Map; + +/** + *

自定义获取参数值

+ * + * @author EBU7-dev-1 aiyh + *

create: 2022-07-25 14:18

+ */ + +public interface CusInterfaceGetValue { + + final String START_LEFT = "{"; + final String VAR_START_STR = "#{"; + final String MAIN = "main."; + final String DETAIL = "detail."; + final String END_STR = "}"; + + final String SQL_START = "#sql{"; + + final Logger log = LogUtil.getLogger(); + + /** + * 获取参数值 + * + * @param mainMap 主表数据 + * @param detailMap 明细表数据 + * @param currentValue 当前字段值 + * @param pathParam 路径参数 + * @return 最终返回参数 + */ + Object execute(Map mainMap, Map detailMap, String currentValue, + Map pathParam); +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceListValue.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceListValue.java new file mode 100644 index 0000000..add6dd1 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/interfacies/CusInterfaceListValue.java @@ -0,0 +1,25 @@ +package weaver.chaoyang.he.xiao.commons.config.interfacies; + +import java.util.List; +import java.util.Map; + +/** + *

自定义数组数据来源

+ * + *

create: 2022-08-15 15:38

+ * + * @author aiyh EBU7-dev-1 + */ + +public interface CusInterfaceListValue { + + /** + *

自定义数组数据来源

+ * + * @param pathParam 路径参数 + * @param mainMap 主表数据 + * @param mainTable 主表表明 + * @return 数组 + */ + List execute(Map pathParam, Map mainMap, String mainTable); +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/config/service/DealWithMapping.java b/src/main/java/weaver/chaoyang/he/xiao/commons/config/service/DealWithMapping.java new file mode 100644 index 0000000..d47db40 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/config/service/DealWithMapping.java @@ -0,0 +1,855 @@ +package weaver.chaoyang.he.xiao.commons.config.service; + +import com.alibaba.fastjson.JSON; +import com.google.common.base.Strings; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import weaver.conn.RecordSet; +import weaver.file.ImageFileManager; +import weaver.general.Util; +import weaver.xiao.commons.config.dao.ConfigMappingCMD; +import weaver.xiao.commons.config.entity.*; +import weaver.xiao.commons.config.enumtype.GetValueTypeEnum; +import weaver.xiao.commons.config.enumtype.ParamTypeEnum; +import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; +import weaver.xiao.commons.config.interfacies.CusInterfaceListValue; +import weaver.xiao.commons.exception.ValueDealException; +import weaver.zwl.common.ToolUtil; + +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.security.SecureRandom; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author XiaoBokang & aiyh + * @create 2021/12/29 10:10 + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DealWithMapping extends ToolUtil { + + private final ConfigMappingCMD mappingCMD = new ConfigMappingCMD(); + private String mainTable; + private String forMatString; + public static final char SBC_SPACE = 12288; // 全角空格 12288 + public static final char DBC_SPACE = 32; // 半角空格 32 + // ASCII character 33-126 <-> unicode 65281-65374 + public static final char ASCII_START = 33; + public static final char ASCII_END = 126; + public static final char UNICODE_START = 65281; + public static final char UNICODE_END = 65374; + public static final char DBC_SBC_STEP = 65248; // + + private List fileNames = new ArrayList<>(); + private List fileInputStreams = new ArrayList<>(); + private List multipartFileList = new ArrayList<>(); + + + /** + *

将日期字符串转换为Date对象

+ * + * @param dateStr 日期字符串 + * @return 日期对象 + */ + public static Date parseDate(String dateStr) { + ThreadLocal SIMPLE_DATE_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); + if (dateStr == null || dateStr.length() == 0) { + return null; + } + String regex = "\\/|\\.|年|月|日"; + Date date = null; + try { + date = SIMPLE_DATE_FORMAT.get().parse(dateStr.replaceAll(regex, "-")); + return date; + } catch (ParseException e) { + // TODO Auto-generated catch block + throw new ValueDealException("无法将" + dateStr + "转换为日期对象!", e); + } + } + + private static Map getMapMapping(RecordSet rs) { + Map map = new HashMap<>(); + String[] columnType = rs.getColumnTypeName(); + int colCounts; + colCounts = rs.getColCounts() == 0 ? columnType.length : rs.getColCounts(); + for (int i = 1; i <= colCounts; i++) { + String key; + String type = "varchar"; + if (columnType != null) { + if (columnType.length != colCounts) { + type = "varchar"; + } else { + type = columnType[i - 1]; + } + } + key = rs.getColumnName(i).toLowerCase(); + if ("int".equalsIgnoreCase(type) || "Integer".equalsIgnoreCase(type) + || "Long".equalsIgnoreCase(type) || "BIGINT".equalsIgnoreCase(type) + || "NUMBER".equalsIgnoreCase(type) || "INTEGER".equalsIgnoreCase(type) + || "TINYINT".equalsIgnoreCase(type) || "SMALLINT".equalsIgnoreCase(type)) { + map.put(key, rs.getInt(i) == -1 ? rs.getString(i) : rs.getInt(i)); + continue; + } + if ("FLOAT".equalsIgnoreCase(type)) { + map.put(key, rs.getFloat(i)); + continue; + } + if ("DATE".equalsIgnoreCase(type) || "TIMESTAMP".equalsIgnoreCase(type) + || "DATETIME".equalsIgnoreCase(type)) { + map.put(key, rs.getString(i)); + continue; + } + if ("DOUBLE".equalsIgnoreCase(type)) { + map.put(key, rs.getDouble(i)); + continue; + } + if ("DECIMAL".equalsIgnoreCase(type) || "NUMERIC".equalsIgnoreCase(type)) { + map.put(key, rs.getDouble(i)); + continue; + } + map.put(key, rs.getString(i)); + } + return map; + } + + /** + * 将配置参数通过唯一标识查询处理成树形结构 + * + * @param uniqueCode 唯一标识 + * @return + */ + public RequestMappingConfig treeDealWithUniqueCode(String uniqueCode) { + this.writeDebuggerLog("============== 根据uniqueCode查询请求配置树形列表 treeDealWith begin ================="); + RequestMappingConfig tempConfig = mappingCMD.selectByUniqueCode(uniqueCode); + return this.dealWith(tempConfig); + } + + /** + * 处理成树形结构 + * + * @param tempConfig 配置列表 + * @return + */ + public RequestMappingConfig dealWith(RequestMappingConfig tempConfig) { + this.writeDebuggerLog("查询到的请求配置列表 query RequestMappingConfig list >>>" + JSON.toJSONString(tempConfig)); + List mappingDetails = tempConfig.getConfigDetail(); + List subMappingDetailList = new ArrayList<>(); + // 过滤出指定节点的子节点,并返回除去子节点之外的节点列表 + List collect = this.filterList(mappingDetails, subMappingDetailList, "rootNode"); + // 将数据库查询出来的信息赋值给要返回的配置信息树 + RequestMappingConfig requestMappingConfig = new RequestMappingConfig(); + requestMappingConfig.setRequestUrl(tempConfig.getRequestUrl()); + requestMappingConfig.setWorkflow(tempConfig.getWorkflow()); + requestMappingConfig.setResponseMappingList(tempConfig.getResponseMappingList()); + List mappingDetailList = new ArrayList<>(); + // 循环判断根节点 + for (MappingDetail mappingDetail : collect) { + String paramType = mappingDetail.getParamType(); + ParamTypeEnum anEnum = ParamTypeEnum.getEnum(paramType); + if (ParamTypeEnum.OBJECT == anEnum || ParamTypeEnum.LIST == anEnum) { + List childList = new ArrayList<>(); + mappingDetail.setChildList(childList); + this.getChildList(mappingDetail, mappingDetails, childList); + } + mappingDetailList.add(mappingDetail); + } + requestMappingConfig.setConfigDetail(mappingDetailList); + this.writeDebuggerLog("通过处理后得到的树形参数列表 deal with tree >>>" + JSON.toJSONString(requestMappingConfig)); + return requestMappingConfig; + } + + /** + * 通过递归的方式设置子节点信息 + * + * @param mappingDetail 当前节点 + * @param mappingDetailList 所有节点 + * @param childList 子节点 + */ + private void getChildList(MappingDetail mappingDetail, List mappingDetailList, List childList) { + String paramName = mappingDetail.getParamName(); + String paramType = mappingDetail.getParamType(); + if ("5".equals(paramType) || "6".equals(paramType)) { + List list = new ArrayList<>(); + mappingDetail.setChildList(list); + List subMappingDetailList = new ArrayList<>(); + List collect = this.filterList(mappingDetailList, subMappingDetailList, paramName); + for (MappingDetail detail : collect) { + this.getChildList(detail, subMappingDetailList, list); + } + } + childList.add(mappingDetail); + } + + /** + * 过滤list集合信息 + * + * @param mappingDetailList 原始集合 + * @param subMappingDetailList 过滤后集合 + * @param paramName 过滤信息 + * @return + */ + private List filterList(List mappingDetailList, List subMappingDetailList, String paramName) { + List tempList = new ArrayList<>(); + for (MappingDetail mappingDetail : mappingDetailList) { + String belongTo = mappingDetail.getBelongTo(); + if (paramName.equals(belongTo)) { + tempList.add(mappingDetail); + } else { + subMappingDetailList.add(mappingDetail); + } + } + return tempList; + } + + /** + * 解析请求参数配置树,转换成请求参数 + * + * @param recordSet 主表数据结果集 + * @param requestMappingConfig 配置树 + * @return + */ + public Map getRequestParam(RecordSet recordSet, RequestMappingConfig requestMappingConfig) { + this.multipartFileList.clear(); + this.fileNames.clear(); + Map requestParam = new HashMap<>(); + List configDetail = requestMappingConfig.getConfigDetail(); + Map mainMap = getMapMapping(recordSet); + this.objValueDeal(mainMap, null, configDetail, requestParam); + return requestParam; + } + + /** + * 解析请求参数配置树,转换成请求参数 + * + * @param recordSet 主表数据结果集 + * @param requestMappingConfig 配置树 + * @return + */ + public List getRequestListParam(RecordSet recordSet, RequestMappingConfig requestMappingConfig) { + this.multipartFileList.clear(); + this.fileInputStreams.clear(); + this.fileNames.clear(); + Map requestParam = new HashMap<>(); + List configDetail = requestMappingConfig.getConfigDetail(); + Map mainMap = getMapMapping(recordSet); + this.objValueDeal(mainMap, null, configDetail, requestParam); + List rootList = (List) requestParam.get("rootList"); + return rootList; + } + + /** + * 解析请求参数配置树,转换成请求参数 + * + * @param recordSet 主表数据结果集 + * @param detailRecordSet 明细表数据集 + * @param requestMappingConfig 配置树 + * @return + */ + public List> getRequestParams(RecordSet recordSet, RecordSet detailRecordSet, RequestMappingConfig requestMappingConfig) { + this.multipartFileList.clear(); + this.fileInputStreams.clear(); + this.fileNames.clear(); + List> list = new ArrayList<>(); + while (detailRecordSet.next()) { + Map requestParam = new HashMap<>(); + List configDetail = requestMappingConfig.getConfigDetail(); + Map mainMap = getMapMapping(recordSet); + Map detailMap = getMapMapping(detailRecordSet); + this.objValueDeal(mainMap, detailMap, configDetail, requestParam); + list.add(requestParam); + } + return list; + } + + /** + * 对象类型处理 + * + * @param mainMap 主表数据结果集 + * @param detailMap 明细数据结果集 + * @param configDetail 配置列表集合 + * @param requestParam 节点参数 + */ + private void objValueDeal(Map mainMap, Map detailMap, List configDetail, Map requestParam) { + for (MappingDetail mappingDetail : configDetail) { + String paramType = mappingDetail.getParamType(); + ParamTypeEnum anEnum = ParamTypeEnum.getEnum(paramType); + String paramName = mappingDetail.getParamName(); + // 5为对象类型 + if (ParamTypeEnum.OBJECT == anEnum) { + List childList = mappingDetail.getChildList(); + Map map = new HashMap<>(); + requestParam.put(paramName, map); + this.objValueDeal(mainMap, detailMap, childList, map); + } + // 6为List类型 + else if (ParamTypeEnum.LIST == anEnum) { + String childType = mappingDetail.getChildType(); + List childList = mappingDetail.getChildList(); + List list = new ArrayList<>(); + requestParam.put(paramName, list); + this.listValueDeal(mainMap, childList, list, mappingDetail); + List tempList = new ArrayList(); + for (Object o : list) { + if (o instanceof Map) { +// map处理 key->1的类型 + Map mapItem = (Map) o; + Map> tempMap = new HashMap<>(8); + for (Map.Entry entry : mapItem.entrySet()) { + String key = entry.getKey(); + String pattern = "(?\\S+)->(\\[(?[0-9]+)])"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(key); + Object value = entry.getValue(); + if (matcher.find()) { + String tempKey = matcher.group("key"); + if (key.endsWith("_")) { + tempKey = tempKey + "_"; + } + ListMapIndexValue listMapIndexValue = new ListMapIndexValue(); + listMapIndexValue.setValue(value); + listMapIndexValue.setKey(tempKey); + String index = matcher.group("index"); + List listMapIndexValues = tempMap.get(index); + if (null == listMapIndexValues) { + listMapIndexValues = new ArrayList<>(); + } + listMapIndexValues.add(listMapIndexValue); + tempMap.put(index, listMapIndexValues); + } else { + ListMapIndexValue listMapIndexValue = new ListMapIndexValue(); + listMapIndexValue.setValue(value); + listMapIndexValue.setKey(key); + List listMapIndexValues = tempMap.get("default"); + if (null == listMapIndexValues) { + listMapIndexValues = new ArrayList<>(); + } + listMapIndexValues.add(listMapIndexValue); + tempMap.put("default", listMapIndexValues); + } + } + for (Map.Entry> entrty : tempMap.entrySet()) { + Map map = new HashMap<>(); + List valueList = entrty.getValue(); + for (ListMapIndexValue listMapIndexValue : valueList) { + map.put(listMapIndexValue.getKey(), listMapIndexValue.getValue()); + } + tempList.add(map); + } + } + } +// tempList.addAll(list); + requestParam.put(paramName, tempList); +// if (!tempList.isEmpty()) { +// requestParam.put(paramName, tempList); +// } + } else { + Object value = this.normalValueDeal(mainMap, detailMap, mappingDetail); + if (!Objects.isNull(value)) { + requestParam.put(paramName, value); + } + } + } + } + + /** + * 普通类型处理 + * + * @param mainMap 主表数据结果集 + * @param detailMap 明细数据结果集 + * @param mappingDetail 配置节点信息 + * @return + */ + private Object normalValueDeal(Map mainMap, Map detailMap, MappingDetail mappingDetail) { + + String paramType = mappingDetail.getParamType(); + ParamTypeEnum typeEnum = ParamTypeEnum.getEnum(paramType); + String getValueType = mappingDetail.getGetValueType(); + GetValueTypeEnum getValueTypeEnum = GetValueTypeEnum.getEnum(getValueType); + String valueContext = mappingDetail.getValueContext(); + String childSource = mappingDetail.getDataSource(); + String paramName = mappingDetail.getParamName(); + Object value = ""; + switch (getValueTypeEnum) { + // 流程字段 + case WORKFLOW_FIELD: { + FieldMessage fieldMassage = mappingDetail.getFieldMassage(); + String fieldName = fieldMassage.getFieldName(); + if ("1".equals(childSource)) { + value = Util.null2String(detailMap.get(fieldName)); + } else { + value = Util.null2String(mainMap.get(fieldName)); + } + } + break; + // 默认值 + case DEFAULT_VALUE: { + value = valueContext; + } + break; + // 当前时间 + case CURRENT_TIME: { + value = new Date(); + } + break; + // 自定义sql查询 + case CUS_SQL: { + FieldMessage fieldMassage = mappingDetail.getFieldMassage(); + String tempValue = ""; + if (fieldMassage != null) { + String fieldName = fieldMassage.getFieldName(); + if ("1".equals(childSource)) { + tempValue = Util.null2String(detailMap.get(fieldName)); + } else { + tempValue = Util.null2String(mainMap.get(fieldName)); + } + } + String requestId = Util.null2String(mainMap.get("requestid")); + tempValue = "'" + tempValue + "'"; + value = this.getValueByChangeRule(valueContext, tempValue, requestId); + } + break; + // requestId + case REQUEST_ID: { + value = Util.null2String(mainMap.get("requestid")); + } + break; + // 数据id + case MAIN_DATA_ID: { + if ("1".equals(childSource)) { + value = Util.null2String(detailMap.get("id")); + } else { + value = Util.null2String(mainMap.get("id")); + } +// value = Util.null2String(main.getString("id")); + } + break; + // 随机数 + case RANDOM: { + int bit = Util.getIntValue(valueContext, 10); + value = this.getGUID(bit); + } + break; + // 附件 + case ATTACHMENT: { + /*int imageFileId = Util.getIntValue(String.valueOf(value)); + InputStream inputStream = ImageFileManager.getInputStreamById(imageFileId); + String fileName = this.getFileNameById(imageFileId); + fileInputStreams.add(inputStream); + fileNames.add(fileName);*/ + // TODO 附件重新优化 + FieldMessage fieldMassage = mappingDetail.getFieldMassage(); + String fieldName = fieldMassage.getFieldName(); + if ("1".equals(childSource)) { + value = Util.null2String(detailMap.get(fieldName)); + } else { + value = Util.null2String(mainMap.get(fieldName)); + } + String fileIds = Util.null2String(value); + if ("".equals(fileIds)) { + throw new NullPointerException("附件字段不存在值!请检查数据表或配置表数据类型是否正确!"); + } + List docImageFiles = mappingCMD.selectDocImageFileList(fileIds); + for (DocImageFile docImageFile : docImageFiles) { + MultipartFile multipartFile = new MultipartFile(); + InputStream FileInputStream = ImageFileManager.getInputStreamById(docImageFile.getImageFileId()); + multipartFile.setFileKey(paramName); + multipartFile.setStream(FileInputStream); + multipartFile.setFileName(docImageFile.getImageFileName()); + multipartFile.setFileSize(docImageFile.getFileSize() / 1024); + multipartFileList.add(multipartFile); + } + return null; + + } +// 自定义接口 + case CUS_INTERFACE: { + if (null == valueContext || valueContext.length() == 0) { + } else { + Map pathParamMap = new HashMap<>(8); + CusInterfaceGetValue o = getCusInterfaceObj(valueContext, CusInterfaceGetValue.class, pathParamMap); + FieldMessage fieldMassage = mappingDetail.getFieldMassage(); + if (null != fieldMassage && !StringUtils.isEmpty(fieldMassage.getFieldName())) { + String fieldName = fieldMassage.getFieldName(); + if ("1".equals(childSource)) { + value = Util.null2String(detailMap.get(fieldName)); + } else { + value = Util.null2String(mainMap.get(fieldName)); + } + } + value = o.execute(mainMap, detailMap, String.valueOf(value == null ? "" : value), pathParamMap); + } + } + break; + case CUS_FIELD: { + value = detailMap.get(valueContext.trim()); + } + break; + default: + throw new ValueDealException("不支持的取值方式"); + } + + switch (typeEnum) { + // String类型 + case STRING: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = ""; + break; + } + value = Util.null2String(String.valueOf(value)); + } + break; + // int类型 + case INT: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = -1; + break; + } + value = Util.getIntValue(String.valueOf(value)); + } + break; + // double类型 + case DOUBLE: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = 0.00; + break; + } + value = Util.getDoubleValue(String.valueOf(value)); + } + break; + // 日期类型 + case DATE: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = ""; + break; + } + try { + Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); + value = this.diyDateFortMat(date, "yyyy-MM-dd"); + } catch (Exception e) { + this.writeDebuggerLog("时间处理异常:" + e); + throw new ValueDealException("时间处理异常:参数>>" + paramName); + } + + } + break; + // 时间日期类型 + case DATE_TIME: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = ""; + break; + } + try { + Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); + value = this.diyDateFortMat(date, "yyyy-MM-dd HH:mm:ss"); + } catch (Exception e) { + this.writeDebuggerLog("时间处理异常:" + e); + throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e); + } + } + break; + // 自定义时间格式化类型 + case CUS_DATE_STR: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = ""; + break; + } + try { + forMatString = valueContext; + Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); + value = this.diyDateFortMat(date, forMatString); + } catch (Exception e) { + this.writeDebuggerLog("时间处理异常:" + e); + throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e.getMessage()); + } + } + break; + // 时间戳类型 + case TIME_STAMP: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = ""; + break; + } + try { + Date date = value instanceof Date ? (Date) value : parseDate(String.valueOf(value)); + value = date.getTime(); + } catch (Exception e) { + this.writeDebuggerLog("时间处理异常:" + e); + throw new ValueDealException("时间处理异常:参数>>" + paramName + " 异常信息:" + e.getMessage()); + } + } + break; + case Boolean: { + if (null == value || Strings.isNullOrEmpty(String.valueOf(value))) { + value = false; + break; + } + value = Boolean.valueOf(String.valueOf(value)); + } + break; + default: + return value; + } + + return value; + } + + /** + * list类型处理 + * + * @param mainMap 主表数据集 + * @param childList 子节点配置列表 + * @param list 子节点参数 + * @param detail 当前节点 + */ + private void listValueDeal(Map mainMap, List childList, List list, MappingDetail detail) throws ValueDealException { + String childSource = detail.getDataSource(); + String childType = detail.getChildType(); + if ("1".equals(childSource)) { + int mainId = Util.getIntValue(Util.null2String(mainMap.get("id"))); + int detailId = Util.getIntValue(detail.getDetailId()); + String detailTableName = mainTable + "_dt" + detailId; + String querySql = "select * from " + detailTableName + " where mainid = ?"; + RecordSet recordSetDetail = new RecordSet(); + recordSetDetail.executeQuery(querySql, mainId); + while (recordSetDetail.next()) { + Map detailMap = getMapMapping(recordSetDetail); + if ("0".equals(childType)) { + Map item = new HashMap<>(); + list.add(item); + this.objValueDeal(mainMap, detailMap, childList, item); + } else { + for (MappingDetail mappingDetail : childList) { + Object o = this.normalValueDeal(mainMap, detailMap, mappingDetail); + list.add(o); + } + } + } + } else if ("0".equals(childSource)) { + if ("0".equals(childType)) { + Map item = new HashMap<>(); + list.add(item); + this.objValueDeal(mainMap, null, childList, item); + } else { + for (MappingDetail mappingDetail : childList) { + Object o = this.normalValueDeal(mainMap, null, mappingDetail); + list.add(o); + } + } +// for (MappingDetail mappingDetail : childList) { +// Object o = this.normalValueDeal(recordSet, null, mappingDetail); +// list.add(o); +// } + } else if ("2".equals(childSource)) { + // 自定义接口 + Map pathParamMap = new HashMap<>(8); + CusInterfaceListValue cusInterfaceObj = getCusInterfaceObj(detail.getDetailId(), CusInterfaceListValue.class, pathParamMap); + List resultList = cusInterfaceObj.execute(pathParamMap, mainMap, mainTable); + if (null == resultList || resultList.isEmpty()) { + return; + } + if ("0".equals(childType)) { + + // 对象类型 + for (Object o : resultList) { + Map item = new HashMap<>(); + list.add(item); + this.objValueDeal(mainMap, (Map) o, childList, item); + } + } else { + // 普通数据类型 + for (Object o : resultList) { + for (MappingDetail mappingDetail : childList) { + if (o instanceof Map) { + Object value = this.normalValueDeal(mainMap, (Map) o, mappingDetail); + list.add(value); + } else { + list.add(o); + } + } + } + } + } + } + + /** + * 自定义时间格式化 + * + * @param date 日期 + * @param tempStr 格式化字符串 + * @return + */ + private String diyDateFortMat(Date date, String tempStr) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(tempStr); + return simpleDateFormat.format(date); + } + + private String getGUID(int bit) { + + StringBuilder uid = new StringBuilder(); + + // 产生16位的强随机数 + + Random rd = new SecureRandom(); + + for (int i = 0; i < bit; i++) { + + // 产生0-2的3位随机数 + int type = rd.nextInt(3); + + switch (type) { + case 0: + // 0-9的随机数 + uid.append(rd.nextInt(10)); + break; + case 1: + // ASCII在65-90之间为大写,获取大写随机 + uid.append((char) (rd.nextInt(25) + 65)); + break; + case 2: + // ASCII在97-122之间为小写,获取小写随机 + uid.append((char) (rd.nextInt(25) + 97)); + break; + default: + break; + } + } + return uid.toString(); + } + + /** + * 通过文件id获取文件名 + * + * @param fileId 文件id + * @return + */ + public String getFileNameById(int fileId) { + String fileName = ""; + String querySql = "select filename from docimagefile where imgagefileid = ?"; + RecordSet recordSet = new RecordSet(); + recordSet.executeQuery(querySql, fileId); + if (recordSet.next()) { + fileName = recordSet.getString("filename"); + } + return fileName; + } + + /** + * 全角转半角 + * + * @param src 全角字符 + * @return 半角字符 + */ + public static char sbc2dbc(char src) { + if (src == SBC_SPACE) { + return DBC_SPACE; + } + + if (src >= UNICODE_START && src <= UNICODE_END) { + return (char) (src - DBC_SBC_STEP); + } + + return src; + } + + /** + * 全角转半角 + * + * @param src 全角字符串 + * @return DBC case + */ + public static String sbc2dbcCase(String src) { + if (src == null) { + return null; + } + char[] c = src.toCharArray(); + for (int i = 0; i < c.length; i++) { + c[i] = sbc2dbc(c[i]); + } + return new String(c); + } + + public T getCusInterfaceObj(String path, Class clazz, Map pathParamMap) { + path = sbc2dbcCase(path); + String[] split = path.split("\\?"); + String classPath = split[0]; + String paramStr = ""; + if (split.length > 1) { + paramStr = Arrays.stream(split).skip(1).collect(Collectors.joining("")); + } +/* 获取?后的参数:"weaver.aiyh_jitu.pushdata.service.toones.GetRequestValueCusGetValueImpl?" + + "requestType=get&apiOnlyMark=getAssign&valueKey=data&assign=#{main.zd2}&" + + "#processorClass=weaver.aiyh_jitu.pushdata.service.toones.GetAssignProcessorProcessorImpl" + + "&afterProcessor.hrmId=#{main.zd2}&beforeProcessor.hrmId=#{main.zd2}&高=udh高殿下g" + + "&assignValue=#sql{select workcode from hrmresource where id = #{main.zd1} and test = #{h-hah} and a in (${hrmids})}&hah=haode"; + 最终获取到的map,如下 + key:requestType + value:get + key:apiOnlyMark + value:getAssign + key:valueKey + value:data + key:assign + value:#{main.zd2} + key:#processorClass + value:weaver.aiyh_jitu.pushdata.service.toones.GetAssignProcessorProcessorImpl + key:afterProcessor.hrmId + value:#{main.zd2} + key:beforeProcessor.hrmId + value:#{main.zd2} + key:高 + value:udh高殿下g + key:assignValue + value:#sql{select workcode from hrmresource where id = #{main.zd1} and test = #{h-hah} and a in (${hrmids})} + key:hah + value:haode*/ +// 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类,将参数传递给这个类, 使用``包裹的字符串会被解析为一个字符串 + String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + "(?((`([():/\\-&$#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" + + "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(paramStr); + while (matcher.find()) { + String key = matcher.group("key"); + String paramValue = matcher.group("value"); + if (paramValue != null && paramValue.startsWith("`") && paramValue.endsWith("`")) { + paramValue = paramValue.substring(1, paramValue.length() - 1); + } + pathParamMap.put(key, paramValue); + } + Class aClass; + try { + aClass = Class.forName(classPath); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("未能找到自定义接口:" + classPath); + } + if (!clazz.isAssignableFrom(aClass)) { + throw new IllegalArgumentException("自定义接口:" + classPath + " 不是" + + clazz.getName() + "的子类或实现类!"); + } + Constructor constructor; + try { + constructor = aClass.getConstructor(); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException(classPath + "没有空参构造方法,无法获取构造方法对象!"); + } + T o; + try { + o = (T) constructor.newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("无法构造" + classPath + "对象!"); + } + return o; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/exception/RequestException.java b/src/main/java/weaver/chaoyang/he/xiao/commons/exception/RequestException.java new file mode 100644 index 0000000..3bef02c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/exception/RequestException.java @@ -0,0 +1,21 @@ +package weaver.chaoyang.he.xiao.commons.exception; + +/** + * @author XiaoBokang + * @create 2022/1/12 11:06 + */ + +public class RequestException extends RuntimeException{ + public RequestException(String message){ + super(message); + } + + public RequestException(String message, Throwable cause) { + super(message, cause); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return super.fillInStackTrace(); + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/exception/ValueDealException.java b/src/main/java/weaver/chaoyang/he/xiao/commons/exception/ValueDealException.java new file mode 100644 index 0000000..11d8d52 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/exception/ValueDealException.java @@ -0,0 +1,22 @@ +package weaver.chaoyang.he.xiao.commons.exception; + +/** + * @author XiaoBokang + * @create 2022/1/4 9:50 + */ + +public class ValueDealException extends RuntimeException{ + + public ValueDealException(String message){ + super(message); + } + + public ValueDealException(String message, Throwable cause) { + super(message, cause); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return super.fillInStackTrace(); + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/JsonResult.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/JsonResult.java new file mode 100644 index 0000000..f8c669c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/JsonResult.java @@ -0,0 +1,70 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import com.alibaba.fastjson.JSONObject; + + +/** + * @author XiaoBokang + * @create 2021/9/9 19:33 + */ + +public class JsonResult { + + private Integer code; + private String message; + private Object Data; + + public JsonResult(Integer code, String message, Object data) { + this.code = code; + this.message = message; + Data = data; + } + + public static String success(String message){ + return JSONObject.toJSONString(new JsonResult(200,message,null)); + } + public static String success(){ + return JSONObject.toJSONString(new JsonResult(200,"success",null)); + } + public static String successData(String message,Object data){ + return JSONObject.toJSONString(new JsonResult(200,message,data)); + } + public static String successData(Object data){ + return JSONObject.toJSONString(new JsonResult(200,"success",data)); + } + + public static String error(int code,String message){ + return JSONObject.toJSONString(new JsonResult(code,message,null)); + } + public static String error(String message){ + return JSONObject.toJSONString(new JsonResult(500,message,null)); + } + public static String error(){ + return JSONObject.toJSONString(new JsonResult(500,"fail",null)); + } + + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Object getData() { + return Data; + } + + public void setData(Object data) { + Data = data; + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/LogUtil.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/LogUtil.java new file mode 100644 index 0000000..ae57e78 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/LogUtil.java @@ -0,0 +1,73 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import org.apache.log4j.*; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * @author XiaoBokang + * @create 2022/3/3 14:16 + */ + +public class LogUtil { + + private static volatile Logger log = null; + + public static Logger getLogger(){ + return LogUtil.getLogger(weaver.general.GCONST.getLogPath() + "cus" + File.separator + "util_cus" + File.separator + "cus.log"); + } + + /** + * 获取日志对象 + * @return 日志对象 + */ + public static Logger getLogger(String file) { + if (log == null) { + synchronized (LogUtil.class) { + if (log == null) { + DailyRollingFileAppender appender = new DailyRollingFileAppender(); + log = Logger.getLogger("xbk_cus"); + appender.setName("xbk_cus"); + appender.setEncoding("UTF-8"); + appender.setDatePattern("'_'yyyyMMdd'.log'"); + appender.setFile(file); + appender.setThreshold(Priority.DEBUG); + appender.setLayout(new PatternLayout("[%-5p] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%r] [Thread:%t][%F.%M:%L] ==> : %m %x %n")); + appender.setAppend(true); + appender.activateOptions(); + log.addAppender(appender); + boolean enableDebug = true; + if (!enableDebug) { + log.setLevel(Level.INFO); + } + } + } + } + return log; + } + + public static Logger getSqlLogger(){ + return LogUtil.getLogger(weaver.general.GCONST.getLogPath() + "cus" + File.separator + "sql" + File.separator + "cussql.log"); + } + + + /** + * 获取堆栈中的异常信息 + * @param throwable 异常 + * @return + */ + public static String getExceptionStr(Throwable throwable){ + StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter,true)); + String s = stringWriter.getBuffer().toString(); + try{ + stringWriter.close(); + }catch (Exception ignored){ + ignored.printStackTrace(); + } + return s; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PreMap.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PreMap.java new file mode 100644 index 0000000..8419125 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PreMap.java @@ -0,0 +1,26 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author XiaoBokang + * @create 2021/8/20 14:01 + */ + +public class PreMap extends HashMap implements Map { + + public PreMap(){ + super(); + } + + public static PreMap create(){ + return new PreMap(); + } + + @Override + public PreMap put(String key, Object value){ + super.put(key,value); + return this; + } +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PropUtil.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PropUtil.java new file mode 100644 index 0000000..7395a36 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/PropUtil.java @@ -0,0 +1,57 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import weaver.common.util.string.StringUtil; +import weaver.general.GCONST; + +import java.io.*; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * @author XiaoBokang + * @create 2022/3/10 11:13 + */ + +public class PropUtil { + /** + * 通过文件名获取到对应的配置文件map对象 + * @param fileName prop/文件夹下的文件名(不包含.properties) + * @return 配置文件对应的map对象 + */ + public static Map getProperties2Map(String fileName) { + String propertyPath = GCONST.getPropertyPath(); + if (StringUtil.isNullOrEmpty(fileName)) { + return null; + } + if (fileName.contains(".properties")) { + fileName = fileName.replace(".properties", ""); + } + String path = propertyPath + File.separator + fileName + ".properties"; + Properties prop = new Properties(); + Map map = new HashMap<>(); + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(new FileInputStream(path)); + prop.load(inputStream); + Enumeration enumeration = prop.propertyNames(); + while (enumeration.hasMoreElements()) { + String key = String.valueOf(enumeration.nextElement()); + map.put(key, prop.getProperty(key)); + } + } catch (IOException e) { + throw new RuntimeException("找不到文件:" + path); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return map; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestBaseInfo.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestBaseInfo.java new file mode 100644 index 0000000..d0361c2 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestBaseInfo.java @@ -0,0 +1,59 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import lombok.Data; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * @author XiaoBokang + * @create 2021/8/23 16:34 + */ + +@Data +public class RequestBaseInfo{ + + private String type; + private String url; + private Object params; + private InputStream[] inputStreams; + private String[] fileNames; + private String fileField; + private Map headers; + + private static final Map HEADER_NORMAL = new HashMap<>(); + private static final Map PARAMS_NORMAL = new HashMap<>(); + + + public static RequestBaseInfo create(String type, String url){ + return create(type,url,HEADER_NORMAL,PARAMS_NORMAL); + } + + public static RequestBaseInfo create(String type, String url, Map headers){ + return create(type,url,headers,PARAMS_NORMAL); + } + + public static RequestBaseInfo create(String type, String url, Map headers, Object params){ + RequestBaseInfo requestInfo = new RequestBaseInfo(); + requestInfo.setType(type.toUpperCase()); + requestInfo.setUrl(url); + requestInfo.setParams(params); + requestInfo.setHeaders(headers); + return requestInfo; + } + + public static RequestBaseInfo createByFile(String type, String url, Map headers, Object params, InputStream[] inputStreams, String fileField, String[] fileNames){ + RequestBaseInfo requestInfo = new RequestBaseInfo(); + requestInfo.setType(type.toUpperCase()); + requestInfo.setUrl(url); + requestInfo.setParams(params); + requestInfo.setHeaders(headers); + requestInfo.setInputStreams(inputStreams); + requestInfo.setFileNames(fileNames); + requestInfo.setFileField(fileField); + return requestInfo; + } + + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestUtil.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestUtil.java new file mode 100644 index 0000000..783b0b3 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/RequestUtil.java @@ -0,0 +1,166 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.*; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.util.EntityUtils; +import weaver.xiao.commons.exception.RequestException; +import weaver.xiao.commons.utils.RequestBaseInfo; +import weaver.zwl.common.ToolUtil; +import weaver.wechat.request.HttpManager; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.util.Map; + + +/** + * @author XiaoBokang + * @create 2021/8/9 10:09 + */ + +public class RequestUtil { + + public static T apiRequest(RequestBaseInfo requestInfo, Class tClass){ + + Map headers = requestInfo.getHeaders(); + T result = null; + + switch(requestInfo.getType()){ + case "GET" :{ + String sendUrl = serializableUrl(requestInfo.getUrl(), (Map) requestInfo.getParams()); + HttpGet httpGet = new HttpGet(sendUrl); + headers.forEach(httpGet::setHeader); + result = apiSend(httpGet,tClass); + }break; + case "POST" :{ + HttpPost httpPost = new HttpPost(requestInfo.getUrl()); + headers.forEach(httpPost::setHeader); + httpPost.setEntity(new StringEntity(JSON.toJSONString(requestInfo.getParams()),"UTF-8")); + new ToolUtil().writeErrorLog("请求信息:url:"+requestInfo.getUrl()+" params:"+JSON.toJSONString(requestInfo.getParams())); + result = apiSend(httpPost,tClass);}break; + case "PUT" :{ + HttpPut httpPut = new HttpPut(requestInfo.getUrl()); + headers.forEach(httpPut::setHeader); + httpPut.setEntity(new StringEntity(JSON.toJSONString(requestInfo.getParams()),"UTF-8")); + result = apiSend(httpPut,tClass);}break; + } + + return result; + } + + public static T POSTBySerializableUrl(RequestBaseInfo requestInfo, Class tClass){ + T result = null; + Map headers = requestInfo.getHeaders(); + String url = serializableUrl(requestInfo.getUrl(), (Map) requestInfo.getParams()); + HttpPost httpPost = new HttpPost(url); + headers.forEach(httpPost::setHeader); + new ToolUtil().writeErrorLog("请求信息:url:"+requestInfo.getUrl()+" params:"+JSON.toJSONString(requestInfo.getParams())); + result = apiSend(httpPost,tClass); + return result; + } + + public static T apiUploadFileByInputStream(RequestBaseInfo requestInfo, Class tClass){ + Map params = (Map) requestInfo.getParams(); + HttpPost httpPost = new HttpPost(requestInfo.getUrl()); + requestInfo.getHeaders().forEach(httpPost::setHeader); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setCharset(StandardCharsets.UTF_8); + builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); + InputStream[] inputStreams = requestInfo.getInputStreams(); + String[] fileNames = requestInfo.getFileNames(); + for (int i = 0; i < inputStreams.length; i++) { + builder.addBinaryBody(requestInfo.getFileField(),inputStreams[i],ContentType.MULTIPART_FORM_DATA,fileNames[i]); + } + params.forEach((k,v)->{ + builder.addTextBody(k,JSON.toJSONString(v),ContentType.create(MediaType.TEXT_PLAIN,"UTF-8")); + }); + HttpEntity entity = builder.build(); + httpPost.setEntity(entity); + return apiSend(httpPost,tClass); + } + + public static T apiSend( + HttpUriRequest httpRequest, + Class resClass + ){ + DefaultHttpClient httpClient = HttpManager.getHttpClient(); + CloseableHttpResponse execute = null; + T res = null; + try { + new ToolUtil().writeDebuggerLog("开始发送请求:request start -----------------"); + execute = httpClient.execute(httpRequest); + if(execute.getStatusLine().getStatusCode() == 200){ + new ToolUtil().writeDebuggerLog("请求发送成功:request send success -----------------"); + HttpEntity entity = execute.getEntity(); + String response= EntityUtils.toString(entity,"utf-8"); +// ObjectMapper mapper = new ObjectMapper(); +// CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, Map.class); +// List> list = mapper.readValue(response, listType); +// result.put("res",list); + if(resClass.equals(String.class)){ + return (T) response; + }else { + ObjectMapper objectMapper = new ObjectMapper(); + res = objectMapper.readValue(response, resClass); + } + }else { + HttpEntity entity = execute.getEntity(); + String response = EntityUtils.toString(entity,"utf-8"); + new ToolUtil().writeDebuggerLog("请求状态不为200,返回信息为:"+response); + throw new RequestException("请求状态异常:"+response); + } + } catch (IOException e) { + new ToolUtil().writeDebuggerLog("请求发生异常 request error>>>"+e); + try { + if(execute != null) { + execute.close(); + } + } catch (IOException ioException) { + ioException.printStackTrace(); + } + e.printStackTrace(); + throw new RequestException("请求调用异常:"+e); + } + return res; + } + + public static String serializableUrl(String url,Map params){ + if(params == null || params.isEmpty()){ + return url; + } + url += "?"; + for (Map.Entry entry: params.entrySet()){ + url += entry.getKey() + "=" + entry.getValue() + "&"; + } + return url.substring(0,url.length()-1); + } + + /** + * 获取堆栈中的异常信息 + * @param throwable 异常 + * @return + */ + public static String getExceptionStr(Throwable throwable){ + StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter,true)); + String s = stringWriter.getBuffer().toString(); + try{ + stringWriter.close(); + }catch (Exception ignored){ + ignored.printStackTrace(); + } + return s; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/SqlUtil.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/SqlUtil.java new file mode 100644 index 0000000..d016240 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/SqlUtil.java @@ -0,0 +1,261 @@ +package weaver.chaoyang.he.xiao.commons.utils; + +import org.apache.log4j.Logger; +import weaver.conn.RecordSet; +import weaver.formmode.data.ModeDataIdUpdate; +import weaver.formmode.setup.ModeRightInfo; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.xiao.commons.utils.LogUtil; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; + + +import java.lang.reflect.Field; +import java.util.*; + +/** + * @author XiaoBokang + * @create 2021/12/7 14:19 + */ + +public class SqlUtil { + + private final Logger logger = LogUtil.getSqlLogger(); + ModeDataIdUpdate mdu = ModeDataIdUpdate.getInstance(); + ModeRightInfo mri = new ModeRightInfo(); + + /** + * 通过列名将数据库结果集转换成指定的实体类 + * @param recordSet 数据库结果集 + * @param tClass 实体类文件 + * @param 泛型 + * @return + */ + public T recordSetToEntityByEntity(RecordSet recordSet, Class tClass){ + T res = null; + try{ + String[] columnNames = recordSet.getColumnName(); + if(tClass.equals(Map.class)){ + Map tempRes = new HashMap<>(); + for (String columnName : columnNames) { + tempRes.put(columnName,recordSet.getString(columnName)); + } + res = (T) tempRes; + }else { + Field[] declaredFields = tClass.getDeclaredFields(); + res = tClass.newInstance(); + for (Field field : declaredFields) { + field.setAccessible(true); + SqlFieldMapping annotation = field.getAnnotation(SqlFieldMapping.class); + Class fieldType = field.getType(); + if(annotation != null){ + String value = annotation.value(); + int type = annotation.type(); + Object valueText = null; + switch (type){ + case 1:{ + String tempValue = Util.null2String(recordSet.getString(value)); + valueText = this.getFieldVal(fieldType,tempValue); + }break; + case 2:{ + valueText = this.getFieldVal(fieldType,value); + }break; + } + field.set(res,valueText); + } + } + } + }catch (Exception e){ + logger.info("转换实体类异常:"+e); + } + return res; + } + + /** + * 通过字段类型获取字段的值 + * @param fieldType 字段类型 + * @param tempValue 转换前的字符串值 + * @return + */ + public Object getFieldVal(Class fieldType,String tempValue){ + Object fieldVal = null; + if(fieldType.equals(int.class)){ + fieldVal = Util.getIntValue(tempValue); + }else if(fieldType.equals(String.class)){ + fieldVal = Util.null2String(tempValue); + }else if(fieldType.equals(boolean.class)){ + fieldVal = Boolean.parseBoolean(tempValue); + }else { + fieldVal = ""; + } + return fieldVal; + } + + /** + * 构建更新语句 + * @param tableName 表名 + * @param updateParam 更新参数 + * @param whereParam 条件参数 + * @return + */ + public boolean updateMode(String tableName, Map updateParam, Map whereParam) { + RecordSet recordSet = new RecordSet(); + List paramList = new ArrayList<>(); + String updateSql = buildUpdateSql(tableName, updateParam, whereParam, paramList); + logger.info("向表"+tableName+"更新数据>>>" + updateSql + " param:" + paramList); + boolean updateFlag = recordSet.executeUpdate(updateSql, paramList); + logger.info("更新标识:" + updateFlag); + return updateFlag; + } + + /** + * 构建更新sql语句,收集参数信息 + * @param tableName 表名 + * @param updateParam 更新参数 + * @param whereParam 条件参数 + * @param paramList 参数集合 + * @return + */ + public String buildUpdateSql(String tableName, Map updateParam, Map whereParam,List paramList){ + StringBuilder updateBuilder = new StringBuilder("update "); + updateBuilder.append(tableName).append(" set "); + Set> updateEntries = updateParam.entrySet(); + for (Map.Entry updateEntry : updateEntries) { + updateBuilder.append(updateEntry.getKey()) + .append(" = ?,"); + paramList.add(updateEntry.getValue()); + } + StringBuilder whereBuilder = new StringBuilder(); + Set> whereEntries = whereParam.entrySet(); + for (Map.Entry whereEntry : whereEntries) { + whereBuilder.append(" and ") + .append(whereEntry.getKey()) + .append(" = ? "); + paramList.add(whereEntry.getValue()); + } + String preStr = updateBuilder.substring(0, updateBuilder.length() - 1) + " "; + String fixStr = whereBuilder.toString(); + if(!"".equals(fixStr)){ + fixStr = fixStr.replaceFirst(" and "," where "); + } + return preStr + fixStr; + } + + /** + * 向表插入数据 + * @param tableName 表名 + * @param insertParam 插入参数 + * @return + */ + public boolean insertTable(String tableName, Map insertParam) { + RecordSet recordSet = new RecordSet(); + //构建新建sql语句,收集参数信息 + List paramList = new ArrayList<>(); + String insertSql = buildInsetSql(tableName, insertParam, paramList); + logger.info("向表"+tableName+"插入数据>>>" + insertSql + " param:" + paramList); + boolean flag = recordSet.executeUpdate(insertSql, paramList); + logger.info("插入标识:" + flag); + return flag; + } + + /** + * 构建新建sql语句,收集参数信息 + * @param tableName 表名 + * @param insertParam 插入参数 + * @param paramList 返回数据集合 + * @return + */ + public String buildInsetSql(String tableName, Map insertParam,List paramList){ + StringBuilder suffixBuilder = new StringBuilder(); + StringBuilder prefixBuilder = new StringBuilder(); + prefixBuilder.append("insert into ") + .append(tableName).append("("); + suffixBuilder.append(" values ("); + Set> entries = insertParam.entrySet(); + for (Map.Entry entry : entries) { + String key = entry.getKey(); + Object value = entry.getValue(); + prefixBuilder.append(key).append(","); + suffixBuilder.append("?,"); + paramList.add(value); + } + String suffixString = suffixBuilder.substring(0, suffixBuilder.length() - 1); + String prefixString = prefixBuilder.substring(0, prefixBuilder.length() - 1); + String insertSql = prefixString + ")" + suffixString+")"; + return insertSql; + } + + + /** + * 将接口调用信息插入至建模中 + * @param tableName 表名 + * @param param 插入信息 + * @param modeId 模块id + * @return + */ + public int insertToMode(String tableName,Map param,String modeId){ + logger.info("=====插入建模信息===="); + if(modeId == null || "".equals(modeId)) { + modeId = this.getModeIdByTableName(tableName); + } + logger.info("通过表名获取modeId ==>modeId"+modeId+" tableName==>"+tableName); + Map whereParam = new HashMap<>(); + int dataId = mdu.getModeDataNewId(tableName, Util.getIntValue(modeId,-1), 1, 0, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString()); + whereParam.put("id",dataId); + boolean updateFlag = this.updateMode(tableName, param, whereParam); + if(updateFlag){ + mri.rebuildModeDataShareByEdit(1, Util.getIntValue(modeId,-1),dataId); + }else { + logger.info("更新失败,从表==>"+tableName+" 删除数据:"+dataId); + String deleteSql = "delete from "+tableName+" where id = ?"; + RecordSet deleteRecordSet = new RecordSet(); + deleteRecordSet.executeUpdate(deleteSql,dataId); + } + return dataId; + } + + /** + * 将接口调用信息插入至建模中不做权限重构 + * @param tableName 表名 + * @param param 插入信息 + * @param modeId 模块id + * @return + */ + public int insertToModeNoRight(String tableName,Map param,String modeId){ + logger.info("=====插入建模信息===="); + if(modeId == null || "".equals(modeId)) { + modeId = this.getModeIdByTableName(tableName); + } + logger.info("通过表名获取modeId ==>modeId"+modeId+" tableName==>"+tableName); + Map whereParam = new HashMap<>(); + int dataId = mdu.getModeDataNewId(tableName, Util.getIntValue(modeId,-1), 1, 0, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString()); + whereParam.put("id",dataId); + boolean updateFlag = this.updateMode(tableName, param, whereParam); + if(updateFlag){ + return dataId; + }else { + logger.info("更新失败,从表==>"+tableName+" 删除数据:"+dataId); + String deleteSql = "delete from "+tableName+" where id = ?"; + RecordSet deleteRecordSet = new RecordSet(); + deleteRecordSet.executeUpdate(deleteSql,dataId); + } + return -1; + } + + /** + * 通过表名查询模块id + * @param tableName 表名 + * @return + */ + public String getModeIdByTableName(String tableName){ + String modeId = ""; + String querySql = "select id from modeinfo where formid = (select id from workflow_bill where tablename = ?)"; + RecordSet recordSet = new RecordSet(); + recordSet.executeQuery(querySql,tableName); + if(recordSet.next()){ + modeId = Util.null2String(recordSet.getString("id")); + } + return modeId; + } + +} diff --git a/src/main/java/weaver/chaoyang/he/xiao/commons/utils/annotation/SqlFieldMapping.java b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/annotation/SqlFieldMapping.java new file mode 100644 index 0000000..8f40f62 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/xiao/commons/utils/annotation/SqlFieldMapping.java @@ -0,0 +1,21 @@ +package weaver.chaoyang.he.xiao.commons.utils.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author XiaoBokang + * @create 2022/5/10 18:22 + */ + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SqlFieldMapping { + /** 字段所属 1:数据库值,2:默认值 */ + int type() default 1; + /** 数据库字段名或默认值 */ + String value(); + +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/CusBaseAction.java b/src/main/java/weaver/chaoyang/he/zwl/common/CusBaseAction.java new file mode 100644 index 0000000..3001353 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/CusBaseAction.java @@ -0,0 +1,104 @@ +package weaver.chaoyang.he.zwl.common; + + +import weaver.common.StringUtil; +import weaver.conn.RecordSetTrans; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; +import weaver.workflow.request.RequestManager; +import weaver.zwl.common.ToolUtil; + +/** + * 自定义Action实现类,添加通用参数 + * @author bleach + * @date 2019-10-09 + * @verion 1.0 + */ +public abstract class CusBaseAction extends ToolUtil implements Action { + //当前类名称 + private String className = this.getClass().getName(); + + + protected RequestInfo requestInfo;//流程请求信息实体类 + protected RecordSetTrans rsts = null;//流程操作事务数据集 + protected String tablename;//当前流程表单名称 + protected String requestId;//流程请求ID + protected String workflowId;//流程类型ID + protected User user = null;//当前用户 + protected int creater = -1;//流程创建人ID + protected RequestManager reqManager = null; + protected String[] baseArray = new String[5]; + protected int formid = -1; + protected String cusparam = ""; + + protected abstract String handle();//OrganizationAction 具体操作 + + /** + * 实现父类方法 + * + * @param requestInfo + * @return + */ + @Override + public String execute(RequestInfo requestInfo) { + this.requestInfo = requestInfo; + + this.rsts = requestInfo.getRsTrans(); + if (this.rsts == null) { + rsts = new RecordSetTrans(); + } + this.initParam(); + return handle(); + } + + /** + * 初始化常用参数 + */ + private void initParam() { + this.requestId = StringUtil.vString(requestInfo.getRequestid()); + this.workflowId = StringUtil.vString(requestInfo.getWorkflowid()); + this.reqManager = requestInfo.getRequestManager(); + this.user = reqManager.getUser(); + this.creater = reqManager.getCreater(); + + this.tablename = requestInfo.getRequestManager().getBillTableName(); + + this.formid = reqManager.getFormid(); + //通过系统请求管理类获取表单名称失败,再次查询 + if ("".equals(this.tablename)) { + tablename = getBillTableNameByWorkflowId(this.workflowId); + formid = Util.getIntValue(tablename.replace("formtable_main_", ""),0); + } + + //获取流程基础数据 + String select_base_sql = "select * from workflow_requestbase where requestid = ?"; + try { + if (rsts == null) { + rsts = new RecordSetTrans(); + } + + String request_name = ""; + String request_mark = ""; + + if (rsts.executeQuery(select_base_sql, requestId)) { + while (rsts.next()) { + request_name = Util.null2String(rsts.getString("requestname")); + request_mark = Util.null2String(rsts.getString("requestmark")); + } + } + + baseArray[0] = this.requestId; + baseArray[1] = request_name; + baseArray[2] = request_mark; + baseArray[3] = tablename; + + this.writeNewDebuggerLog(className, "main_requestname:[" + request_name + "],main_requestmark:[" + request_mark + "],workflowid:[" + workflowId + "],requestid:[" + requestId + "],tablename:[" + tablename + "],formid:[" + formid +"]"); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + this.writeNewDebuggerLog(className, "get workflow dataset error:[" + e1.getMessage() + "/" + e1.toString() + "]"); + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/ThreadPoolConfig.java b/src/main/java/weaver/chaoyang/he/zwl/common/ThreadPoolConfig.java new file mode 100644 index 0000000..05848e0 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/ThreadPoolConfig.java @@ -0,0 +1,36 @@ +package weaver.chaoyang.he.zwl.common; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import java.util.concurrent.*; + +/** + * 自定义线程池 + * 异步执行线程池 + */ +public class ThreadPoolConfig { + + private static volatile ExecutorService threadPool; + + /** + * 创建线程池实例 + * @return 返回一个异步执行 + */ + public static ExecutorService createThreadPoolInstance() { + if (threadPool == null) { + synchronized (ThreadPoolConfig.class) { + if (threadPool == null) { + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("thread-pool-cus-%d").build(); + threadPool = new ThreadPoolExecutor(25, + 50, + 60L, + TimeUnit.SECONDS, + new ArrayBlockingQueue<>(100), + threadFactory, + new ThreadPoolExecutor.AbortPolicy()); + } + } + } + return threadPool; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil.java b/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil.java new file mode 100644 index 0000000..9860a63 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil.java @@ -0,0 +1,411 @@ +package weaver.chaoyang.he.zwl.common; + +import weaver.conn.ConnStatementDataSource; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.GCONST; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.zwl.common.logging.Logger; +import weaver.zwl.common.logging.LoggerFactory; + +import java.io.*; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +/** + * 常用工具方法-公用类 + * @author bleach + * @date 2018-01-18 + * @version 2.0 Modify By Weilin.Zhu 添加日志级别 2018-12-05 + * @version 3.0 Modify By Weilin.Zhu 修改日志输出方式,使用log4j 2020-03-10 + * @version 4.0 Modify By Weilin.Zhu 去除根据建模配置来控制日志输出功能 2021-06-29 + */ +public class ToolUtil extends BaseBean { + + Logger logger = LoggerFactory.getLogger("cus"); + + + private RecordSet rs = new RecordSet(); + + + /** + * 构造方法 + */ + public ToolUtil() { + //logger = LoggerFactory.getLogger("cus"); + } + + /** + * 根据流程类型ID获取其对应的表单名称 + * @param workflowid 流程类型ID + * @return 字符串 + */ + public String getBillTableNameByWorkflowId(String workflowid){ + String tablename = ""; + + if(!"".equals(workflowid)){ + String select_data = "select tablename from workflow_bill where id in (select formid from workflow_base where id = ?)"; + + if(rs.executeQuery(select_data, workflowid)){ + if(rs.next()){ + tablename = Util.null2String(rs.getString(1)); + } + } + } + + return tablename; + } + + /** + * 查询满足模糊查询的所有标识集合 + * @param likestr 模糊条件 + * @return + */ + public Map getSystemParamValueMap(String likestr){ + return getSystemParamList(likestr); + } + + /** + * 查询系统中所有参数配置 + * @return + */ + public Map getAllSystemParamValue(){ + return getSystemParamList(""); + } + + + /** + * 获取参数集合 + * @param likestr 模糊查询的条件 + * @return 集合 + */ + private Map getSystemParamList(String likestr){ + Map param_map = new HashMap(); + + String select_sql = "select uuid,paramvalue from uf_systemconfig"; + + RecordSet rs = new RecordSet(); + + if(!"".equals(likestr)){ + select_sql += " where uuid like '%" + likestr + "%'"; + } + + if(rs.execute(select_sql)){ + while(rs.next()){ + String uuid = Util.null2String(rs.getString(1)); + String paramvalue = Util.null2String(rs.getString(2)); + + param_map.put(uuid, paramvalue); + } + } + + return param_map; + + } + + /** + * 获取系统参数设置值 + * @param uuid 参数标识 + * @return 返回配置值 + */ + public String getSystemParamValue(String uuid){ + String paramvalue = ""; + + if(!"".equals(uuid)){ + String select_sql = "select paramvalue from uf_systemconfig where uuid = ?"; + + RecordSet rs = new RecordSet(); + rs.executeQuery(select_sql,uuid); + if(rs.next()){ + paramvalue = Util.null2String(rs.getString(1)); + } + } + + return paramvalue; + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @return 配置值 + */ + public String getValueByChangeRule(String cus_sql,String value){ + + return getValueByChangeRule(cus_sql,value,""); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid){ + + return getValueByChangeRule(cus_sql,value,requestid,0); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @param detailKeyvalue 明细表主键值 + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid,int detailKeyvalue){ + return getValueByChangeRule(cus_sql,value,requestid,detailKeyvalue,null); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @param detailKeyvalue 明细表主键值 + * @pram datasourceid 外部数据源ID + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid,int detailKeyvalue,String datasourceid){ + String endValue = ""; + cus_sql = ToDBC(cus_sql); + + cus_sql = cus_sql.replace(" ", " "); + + cus_sql = cus_sql.replace("{?dt.id}", String.valueOf(detailKeyvalue)); + + //参数进行替换 + String sqlString = cus_sql.replace("{?requestid}", requestid); + + sqlString = sqlString.replace("?", value); + + try { + if(datasourceid != null && !"".equals(datasourceid)){ + ConnStatementDataSource csds = new ConnStatementDataSource(datasourceid); + + csds.setStatementSql(sqlString); + + csds.executeQuery(); + + if(csds.next()){ + endValue = Util.null2String(csds.getString(1)); + } + + csds.close(); + }else{ + + RecordSet rs = new RecordSet(); + if(rs.executeQuery(sqlString)){ + rs.next(); + + endValue = Util.null2String(rs.getString(1)); + } + } + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return endValue; + } + + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @return + */ + public String getValueByChangeRule_SingleParam(String cus_sql,String value){ + String endValue = ""; + + cus_sql = cus_sql.replace(" ", " "); + + RecordSet rs = new RecordSet(); + + if(rs.executeQuery(cus_sql,value)){ + rs.next(); + + endValue = Util.null2String(rs.getString(1)); + } + + return endValue; + } + + /** + * 全角转半角 + * @param input + * @return + */ + private String ToDBC(String input) { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (c[i] == '\u3000') { + c[i] = ' '; + } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + return returnString; + } + + /** + * 根据字段ID获取其对应的字段名称 + * @param fieldid + * @return + */ + public String getFieldNameByFieldid(int fieldid){ + if(fieldid > 0){ + return getFieldNameByFieldid(String.valueOf(fieldid)); + }else{ + return ""; + } + } + + /** + * 根据字段ID获取其对应的字段名称 + * @param fieldid + * @return + */ + public String getFieldNameByFieldid(String fieldid){ + String fieldname = ""; + + if(!"".equals(fieldid)){ + + if(fieldid.startsWith(",")){ + fieldid = fieldid.substring(1); + } + + if(fieldid.endsWith(",")){ + fieldid =fieldid.substring(0,fieldid.length() - 1); + } + + String select_sql = "select fieldname from workflow_billfield where id in (" + fieldid + ")"; + + RecordSet rs = new RecordSet(); + + if(rs.execute(select_sql)){ + while(rs.next()){ + + fieldname += "," + Util.null2String(rs.getString(1)); + } + } + } + + if(fieldname.startsWith(",")){ + fieldname = fieldname.substring(1); + } + + return fieldname; + } + + /** + * 输出调试日志 + * @param logstr 日志信息 + */ + public void writeDebuggerLog(String logstr){ + logger.info(logstr); + } + + /** + * 输出调试日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeDebuggerLog(String className,String logstr){ + logger.info(logstr); + } + + /** + * 输出警告日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeWarningLog(String className,String logstr){ + logger.warn(logstr); + } + + /** + * 输出错误日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeErrorLog(String className,String logstr){ + logger.error(logstr); + } + + + /** + * 日志输出 + * @param logstr + */ + public void writeDebugLog(Object logstr){ + logger.info(logstr); + } + + /** + * 日志输出 + * @param logstr + */ + public void writeErrorLog(Object logstr){ + logger.error(logstr); + } + + /** + * 日志输出 + * @param logstr + */ + public void writeNewDebuggerLog(Object o,Object logstr){ + logger.info(logstr); + } + + /** + * 写入同步的日志文件 + * @param o + * @param s + * @deprecated 该写入文件的日志输出方式删除 + */ + protected void writeNewLog(String o,String s){ + try { + String filename = "cus_" + TimeUtil.getCurrentDateString() + "_ecology.log"; + + + String folder = GCONST.getRootPath() + "log" + File.separatorChar + "cus"; + + //this.writeDebugLog("folder:[" + folder + "]"); + + File f = new File(folder); + + // 创建文件夹 + if (!f.exists()) { + f.mkdirs(); + } + + f = new File(folder + File.separatorChar + filename); + //文件不存在,则直接创建 + if(!f.exists()){ + f.createNewFile(); + } + + BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true))); + + out.write("[" + o + "][" + TimeUtil.getCurrentTimeString() + "]:"+ s + "\r\n"); + + //关闭写入流 + out.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + writeDebugLog("创建日志文件存在异常:[" + e.getMessage() + "/" + e.toString() + "]"); + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil_E9.java b/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil_E9.java new file mode 100644 index 0000000..eb9aeff --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/ToolUtil_E9.java @@ -0,0 +1,396 @@ +package weaver.chaoyang.he.zwl.common; + +import weaver.conn.ConnStatementDataSource; +import weaver.conn.RecordSet; +import weaver.general.BaseBean; +import weaver.general.GCONST; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.zwl.common.logging.Logger; +import weaver.zwl.common.logging.LoggerFactory; + +import java.io.*; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +/** + * 常用工具方法-公用类 + * @author bleach + * @date 2018-01-18 + * @version 2.0 Modify By Weilin.Zhu 添加日志级别 2018-12-05 + * @version 3.0 Modify By Weilin.Zhu 修改日志输出方式,使用log4j 2020-03-10 + * @version 4.0 Modify By Weilin.Zhu 去除根据建模配置来控制日志输出功能 2021-06-29 + * @version 5.0 Modify By Weilin.Zhu 执行SQL转换异常信息抛出,不再进行捕获 + */ +public class ToolUtil_E9 extends BaseBean { + + Logger logger = LoggerFactory.getLogger("cus"); + + + private RecordSet rs = new RecordSet(); + + + /** + * 构造方法 + */ + public ToolUtil_E9() { + //logger = LoggerFactory.getLogger("cus"); + } + + /** + * 根据流程类型ID获取其对应的表单名称 + * @param workflowid 流程类型ID + * @return 字符串 + */ + public String getBillTableNameByWorkflowId(String workflowid){ + String tablename = ""; + + if(!"".equals(workflowid)){ + String select_data = "select tablename from workflow_bill where id in (select formid from workflow_base where id = ?)"; + + if(rs.executeQuery(select_data, workflowid)){ + if(rs.next()){ + tablename = Util.null2String(rs.getString(1)); + } + } + } + + return tablename; + } + + /** + * 查询满足模糊查询的所有标识集合 + * @param likestr 模糊条件 + * @return + */ + public Map getSystemParamValueMap(String likestr){ + return getSystemParamList(likestr); + } + + /** + * 查询系统中所有参数配置 + * @return + */ + public Map getAllSystemParamValue(){ + return getSystemParamList(""); + } + + + /** + * 获取参数集合 + * @param likestr 模糊查询的条件 + * @return 集合 + */ + private Map getSystemParamList(String likestr){ + Map param_map = new HashMap(); + + String select_sql = "select uuid,paramvalue from uf_systemconfig"; + + RecordSet rs = new RecordSet(); + + if(!"".equals(likestr)){ + select_sql += " where uuid like '%" + likestr + "%'"; + } + + if(rs.execute(select_sql)){ + while(rs.next()){ + String uuid = Util.null2String(rs.getString(1)); + String paramvalue = Util.null2String(rs.getString(2)); + + param_map.put(uuid, paramvalue); + } + } + + return param_map; + + } + + /** + * 获取系统参数设置值 + * @param uuid 参数标识 + * @return 返回配置值 + */ + public String getSystemParamValue(String uuid){ + String paramvalue = ""; + + if(!"".equals(uuid)){ + String select_sql = "select paramvalue from uf_systemconfig where uuid = ?"; + + RecordSet rs = new RecordSet(); + rs.executeQuery(select_sql,uuid); + if(rs.next()){ + paramvalue = Util.null2String(rs.getString(1)); + } + } + + return paramvalue; + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @return 配置值 + */ + public String getValueByChangeRule(String cus_sql,String value) throws Exception { + + return getValueByChangeRule(cus_sql,value,""); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid) throws Exception { + + return getValueByChangeRule(cus_sql,value,requestid,0); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @param detailKeyvalue 明细表主键值 + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid,int detailKeyvalue) throws Exception { + return getValueByChangeRule(cus_sql,value,requestid,detailKeyvalue,null); + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @param requestid 流程请求ID + * @param detailKeyvalue 明细表主键值 + * @pram datasourceid 外部数据源ID + * @return + */ + public String getValueByChangeRule(String cus_sql,String value,String requestid,int detailKeyvalue,String datasourceid) throws Exception { + String endValue = ""; + cus_sql = ToDBC(cus_sql); + + cus_sql = cus_sql.replace(" ", " "); + + cus_sql = cus_sql.replace("{?dt.id}", String.valueOf(detailKeyvalue)); + + //参数进行替换 + String sqlString = cus_sql.replace("{?requestid}", requestid); + + sqlString = sqlString.replace("?", value); + + if(datasourceid != null && !"".equals(datasourceid)){ + ConnStatementDataSource csds = new ConnStatementDataSource(datasourceid); + + csds.setStatementSql(sqlString); + + csds.executeQuery(); + + if(csds.next()){ + endValue = Util.null2String(csds.getString(1)); + } + + csds.close(); + }else{ + + RecordSet rs = new RecordSet(); + if(rs.executeQuery(sqlString)){ + rs.next(); + endValue = Util.null2String(rs.getString(1)); + } + } + + + return endValue; + } + + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的SQL + * @param value 参数值 + * @return + */ + public String getValueByChangeRule_SingleParam(String cus_sql,String value){ + String endValue = ""; + + cus_sql = cus_sql.replace(" ", " "); + + RecordSet rs = new RecordSet(); + + if(rs.executeQuery(cus_sql,value)){ + rs.next(); + + endValue = Util.null2String(rs.getString(1)); + } + + return endValue; + } + + /** + * 全角转半角 + * @param input + * @return + */ + public String ToDBC(String input) { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (c[i] == '\u3000') { + c[i] = ' '; + } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + return returnString; + } + + /** + * 根据字段ID获取其对应的字段名称 + * @param fieldid + * @return + */ + public String getFieldNameByFieldid(int fieldid){ + if(fieldid > 0){ + return getFieldNameByFieldid(String.valueOf(fieldid)); + }else{ + return ""; + } + } + + /** + * 根据字段ID获取其对应的字段名称 + * @param fieldid + * @return + */ + public String getFieldNameByFieldid(String fieldid){ + String fieldname = ""; + + if(!"".equals(fieldid)){ + + if(fieldid.startsWith(",")){ + fieldid = fieldid.substring(1); + } + + if(fieldid.endsWith(",")){ + fieldid =fieldid.substring(0,fieldid.length() - 1); + } + + String select_sql = "select fieldname from workflow_billfield where id in (" + fieldid + ")"; + + RecordSet rs = new RecordSet(); + + if(rs.execute(select_sql)){ + while(rs.next()){ + + fieldname += "," + Util.null2String(rs.getString(1)); + } + } + } + + if(fieldname.startsWith(",")){ + fieldname = fieldname.substring(1); + } + + return fieldname; + } + + /** + * 输出调试日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeDebuggerLog(String className,String logstr){ + logger.info(logstr); + } + + /** + * 输出警告日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeWarningLog(String className,String logstr){ + logger.warn(logstr); + } + + /** + * 输出错误日志 + * @param className 类名称 + * @param logstr 日志信息 + */ + public void writeErrorLog(String className,String logstr){ + logger.error(logstr); + } + + + /** + * 日志输出 + * @param logstr + */ + public void writeDebugLog(Object logstr){ + logger.info(logstr); + } + + /** + * 日志输出 + * @param logstr + */ + public void writeErrorLog(Object logstr){ + logger.error(logstr); + } + + /** + * 日志输出 + * @param logstr + */ + public void writeNewDebuggerLog(Object o,Object logstr){ + logger.info(logstr); + } + + /** + * 写入同步的日志文件 + * @param o + * @param s + * @deprecated 该写入文件的日志输出方式删除 + */ + protected void writeNewLog(String o,String s){ + try { + String filename = "cus_" + TimeUtil.getCurrentDateString() + "_ecology.log"; + + + String folder = GCONST.getRootPath() + "log" + File.separatorChar + "cus"; + + //this.writeDebugLog("folder:[" + folder + "]"); + + File f = new File(folder); + + // 创建文件夹 + if (!f.exists()) { + f.mkdirs(); + } + + f = new File(folder + File.separatorChar + filename); + //文件不存在,则直接创建 + if(!f.exists()){ + f.createNewFile(); + } + + BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true))); + + out.write("[" + o + "][" + TimeUtil.getCurrentTimeString() + "]:"+ s + "\r\n"); + + //关闭写入流 + out.close(); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + writeDebugLog("创建日志文件存在异常:[" + e.getMessage() + "/" + e.toString() + "]"); + } + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/WorkflowData_To_Middle_DB_Action.java b/src/main/java/weaver/chaoyang/he/zwl/common/WorkflowData_To_Middle_DB_Action.java new file mode 100644 index 0000000..bea3a7e --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/WorkflowData_To_Middle_DB_Action.java @@ -0,0 +1,429 @@ +package weaver.chaoyang.he.zwl.common; + +import weaver.conn.RecordSet; +import weaver.conn.RecordSetDataSource; +import weaver.conn.RecordSetTrans; +import weaver.general.BaseBean; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.RequestInfo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * OA流程数据写入中间库 + * @author bleach + * @date 2018-09-01 + */ +public class WorkflowData_To_Middle_DB_Action extends BaseBean implements Action { + private String cus_param = "";//自定义参数 + + private String this_requestid = "";//当前流程请求ID + + private String this_requestname = "";//当前流程请求标题 + + private String this_requestmark = "";//当前流程流程编号 + + private String currentday = "";//当前系统日期 + + private String currentdatetime = "";//当前系统日期时间 + + + /** + * 实现父类方法 + * @param requestInfo + * @return + */ + @Override + public String execute(RequestInfo requestInfo) { + this.writeLog("WorkflowData_To_Middle_DB_Action", "------------------------WorkflowData_To_Middle_DB_Action Begin-----------------------------"); + currentday = TimeUtil.getCurrentDateString(); + + currentdatetime = TimeUtil.getOnlyCurrentTimeString(); + + //获取流程类型ID + String workflowid = Util.null2String(requestInfo.getWorkflowid()); + //获取当前请求ID + this_requestid = Util.null2String(requestInfo.getRequestid()); + //获取当前表单ID + int formid = requestInfo.getRequestManager().getFormid(); + //获取当前流程数据所在表名称 + String workflow_main_tablename = requestInfo.getRequestManager().getBillTableName(); + + //获取流程事务 + RecordSetTrans rsts = requestInfo.getRsTrans(); + + //获取流程基础数据 + String select_base_sql = "select * from workflow_requestbase where requestid = ?"; + try { + if (rsts == null) { + rsts = new RecordSetTrans(); + } + + //查询流程基本信息 + if (rsts.executeQuery(select_base_sql, this_requestid)) { + while (rsts.next()) { + this.this_requestname = Util.null2String(rsts.getString("requestname")); + this.this_requestmark = Util.null2String(rsts.getString("requestmark")); + } + } + + //日志输出 + this.writeLog("this_requestname:[" + this_requestname + "],this_requestmark:[" + this_requestmark + "],workflowid:[" + workflowid + "],this_requestid:[" + this_requestid + "],formid:[" + formid + "]"); + } catch (Exception e1) { + e1.printStackTrace(); + this.writeLog("获取该流程事物数据集异常:[" + e1.toString() + "/" + e1.getMessage() + "]"); + + return Action.FAILURE_AND_CONTINUE; + } + + //获取当前流程的字段映射配置(包含其对应的历史版本) + String select_main_config = "select * from workflow_field_config where workflowid in (select id from workflow_base where activeversionid in (select activeVersionID from workflow_base where id = ?) or id = ?)"; + + if(!"".equals(cus_param)){ + select_main_config += " and cus_param = '" + cus_param + "'"; + } + + RecordSet rs = new RecordSet(); + + int main_config_keyid = -1; + //外部主表名称 + String o_maintable = ""; + //外部明细表名称 + String o_detailtable = ""; + //数据条件 + String o_condition = ""; + //数据源标识 + String datasourceid = ""; + + if (rs.executeQuery(select_main_config, workflowid, workflowid)) { + rs.next(); + + main_config_keyid = Util.getIntValue(rs.getString("id"), 0); + + o_maintable = Util.null2String(rs.getString("o_maintable")).toLowerCase(); + + o_detailtable = Util.null2String(rs.getString("o_detailtable")); + + o_condition = Util.null2String(rs.getString("o_condition")); + + datasourceid = Util.null2String(rs.getString("datasourceid")); + } + + //本地明细表与外部明细表的映射关系<本地明细表名,外部明细表名> + Map detail_l_o_map = new HashMap(); + if (main_config_keyid > 0) {//说明该流程对应的配置存在 + //获取当前流程配置对应明细表映射配置 + String select_detailtb_mapping = "select * from workflow_detail_mapping where configid = ?"; + if (rs.executeQuery(select_detailtb_mapping, main_config_keyid)) { + while (rs.next()) { + String l_detail_tablename = Util.null2String(rs.getString("l_detailtablename")).toLowerCase();//本地明细表名称 + String o_detail_tablename = Util.null2String(rs.getString("o_detailtablename")).toLowerCase();//外部明细表名称 + + detail_l_o_map.put(l_detail_tablename, o_detail_tablename); + } + } + + //是否存在明细字段配置 + boolean ishasdetailfield = false; + + List> field_list = new ArrayList>(); + + //获取所有字段映射配置 + String select_detail_config = "select wm.*,wb.fieldname,wb.viewtype,wb.detailtable from workflow_field_mapping wm left join workflow_billfield wb on wm.l_fieldid = wb.id where wm.configid = ?"; + if (rs.executeQuery(select_detail_config, main_config_keyid)) { + while (rs.next()) { + //外部字段名称 + String o_fieldname = Util.null2String(rs.getString("o_fieldname")); + + if ("".equals(o_fieldname) || "requestid".equals(o_fieldname.toLowerCase())) {//若外部字段名称为空,则该条配置直接跳过 + continue; + } + //本地流程字段ID + String l_fieldid = Util.null2String(rs.getString("l_fieldid")); + //本地流程字段所属 + int l_viewtype = Util.getIntValue(rs.getString("viewtype"), 0); + + if (l_viewtype == 1) {//属于明细表字段 + ishasdetailfield = true; + } + //本地流程字段名 + String l_fieldname = Util.null2String(rs.getString("fieldname")); + + //自定义转换规则 + String cussql = Util.null2String(rs.getString("cussql")); + + //本地流程字段存在的明细表名称 + String l_field_table = Util.null2String(rs.getString("detailtable")); + + //外部字段所属表名称 + String o_field_table = Util.null2String(rs.getString("field_table")).toLowerCase(); + + //字段转换规则 + int changerule = Util.getIntValue(rs.getString("changerule"), 0); + + Map detail_map = new HashMap(); + + detail_map.put("o_fieldname", o_fieldname); + detail_map.put("l_fieldid", l_fieldid); + detail_map.put("l_viewtype", l_viewtype); + detail_map.put("l_fieldname", l_fieldname); + detail_map.put("cussql", cussql); + detail_map.put("o_field_table", o_field_table); + detail_map.put("l_field_table", l_field_table); + detail_map.put("changerule", changerule); + + field_list.add(detail_map); + } + } + + Map workflow_detailtable_map = new HashMap(); + //判断当前流程是否存在明细表 + String select_workflow_detailtable = "select * from workflow_billdetailtable where billid = ? order by orderid"; + + if (rs.executeQuery(select_workflow_detailtable, formid)) { + while (rs.next()) { + int orderid = Util.getIntValue(rs.getString("orderid"), 1); + + String tablename = Util.null2String(rs.getString("tablename")); + + workflow_detailtable_map.put(orderid, tablename); + } + } + + RecordSetDataSource rsds = new RecordSetDataSource(datasourceid); + + //查询流程主表数据SQL + String select_workflow_main = "select m.id as mainkeyid,m.* from " + workflow_main_tablename + " m where m.requestid = ? "; + + //若外部明细表与OA明细表对应关系不存在 + if (detail_l_o_map == null || detail_l_o_map.isEmpty() || detail_l_o_map.size() <= 0) { + if (ishasdetailfield) { //字段对应关系中存在明细表映射 + //判断当前流程存在明细表,且明细序列为1的明细存在 + if (workflow_detailtable_map != null && workflow_detailtable_map.size() > 0 && workflow_detailtable_map.containsKey(1)) { + //获取第一个明细表名称 + String first_detail_table = workflow_detailtable_map.get(1); + + if (!"".equals(first_detail_table)) { + select_workflow_main = "select m.id as mainkeyid,dt.id as detailkeyid,m.*,dt.* from " + first_detail_table + " dt left join " + workflow_main_tablename + " m on dt.mainid = m.id where m.requestid = ? "; + } + } + } + } + + this.writeLog("查询流程主表数据信息:[" + select_workflow_main + "]"); + + if (!"".equals(o_condition)) { + select_workflow_main += " " + o_condition; + } + + boolean main_insert_success = false; + + //当前流程主键数据ID + int workflow_main_keyid = 0; + //查询流程主表数据 + if (rs.executeQuery(select_workflow_main, this_requestid)) { + //插入前先删除该流程存在的历史数据 + rsds.execute("delete from " + o_maintable + " where requestid = '" + this_requestid + "'"); + while (rs.next()) { + workflow_main_keyid = Util.getIntValue(rs.getString("mainkeyid"), 0); + + String insert_o_col = "";//插入的列名 + String insert_o_val = "";//插入的列值 + + for (Map detail_map : field_list) { + //获取外部表字段名称 + String o_fieldname = detail_map.get("o_fieldname").toString(); + //获取字段所属的外部表名 + String o_field_table = detail_map.get("o_field_table").toString(); + + if (!o_field_table.equals(o_maintable)) {//说明该字段不属于当前主表 + continue; + } + + String fieldvalue = getFinalfieldvalue(rs,null,detail_map,0); + + insert_o_col += "," + o_fieldname; + insert_o_val += ",'" + fieldvalue + "'"; + } + + //插入外部主表数据SQL + String insert_o_sql = "insert into " + o_maintable + "(requestid" + insert_o_col + ") values (" + this_requestid + insert_o_val + ")"; + + this.writeLog("插入外部主表SQL:[" + insert_o_sql + "]"); + + if (rsds.execute(insert_o_sql)) { + main_insert_success = true; + } else { + requestInfo.getRequestManager().setMessageid("11111" + requestInfo.getRequestManager().getRequestid() + "22222"); + requestInfo.getRequestManager().setMessagecontent("数据写入中间表接口失败,请联系系统管理员!"); + + return Action.FAILURE_AND_CONTINUE; + } + } + } + + boolean detail_insert_success = true;//明细字段插入成功与否的标志位 + + //主表写入成功,明细表映射存在 + if (main_insert_success && detail_l_o_map != null && detail_l_o_map.size() > 0) { + for (String l_detailtablename : detail_l_o_map.keySet()) {//遍历明细表映射集合 + //获取外部明细表名称 + String o_detailtablename = detail_l_o_map.get(l_detailtablename); + + //获取当前流程明细表记录 + String select_workflow_detail = "select * from " + l_detailtablename + " where mainid = ?"; + + RecordSet rs_detail = new RecordSet(); + + if (rs_detail.executeQuery(select_workflow_detail, workflow_main_keyid)) { + int detail_Index_Row = 0; + while (rs_detail.next()) { + String insert_detail_o_col = "";//插入的列名 + String insert_detail_o_val = "";//插入的列值 + + for (Map detail_map : field_list) { + //获取外部表字段名称 + String o_fieldname = detail_map.get("o_fieldname").toString(); + //获取字段所属的外部表名 + String o_field_table = detail_map.get("o_field_table").toString(); + //获取流程表单字段为明细表 + String l_field_table = detail_map.get("o_field_table").toString(); + //获取流程字段所属 + int l_viewtype = (Integer) detail_map.get("l_viewtype"); + + if (!o_field_table.equals(o_detailtablename) || (l_viewtype == 1 && !l_field_table.equals(l_detailtablename))) {//说明该字段不属于当前主表或者取自流程表单明细表字段但字段不属于当前明细表 + continue; + } + + String fieldvalue = getFinalfieldvalue(rs,rs_detail,detail_map,detail_Index_Row++); + + insert_detail_o_col += "," + o_fieldname; + insert_detail_o_val += ",'" + fieldvalue + "'"; + } + + //插入外部明细表数据SQL + String insert_detail_o_sql = "insert into " + o_detailtablename + "(requestid" + insert_detail_o_col + ") values (" + this_requestid + insert_detail_o_val + ")"; + + this.writeLog("插入外部明细表SQL:[" + insert_detail_o_sql + "]"); + + if(!rsds.execute(insert_detail_o_sql)){ + detail_insert_success = false; + break; + } + } + } + } + + } else {//说明该流程对应的配置不存在 + this.writeLog("当前流程映射配置不存在,流程直接跳过Action!"); + } + } + this.writeLog("WorkflowData_To_Middle_DB_Action", "------------------------WorkflowData_To_Middle_DB_Action End-----------------------------"); + return Action.SUCCESS; + } + /** + * 获取转换后的实际值 + * @param rs 主表数据集 + * @param rs_detail 明细表某一行的数据集 + * @param config_map 字段集合 + * @return + */ + private String getFinalfieldvalue(RecordSet rs,RecordSet rs_detail,Map config_map,int detailTable_Index){ + + //获取外部表字段名称 + String o_fieldname = config_map.get("o_fieldname").toString(); + //获取其对应的OA字段名称 + String l_fieldname = config_map.get("l_fieldname").toString(); + //获取其转换规则 + int changerule = (Integer)config_map.get("changerule"); + //流程字段所属 + int l_viewtype = (Integer)config_map.get("l_viewtype"); + //自定义转换规则 + String cussql = config_map.get("cussql").toString(); + + //this.writeLog("---------->o_fieldname:[" + o_fieldname + "],l_fieldname:[" + l_fieldname + "],changerule:[" + changerule + "],cussql:[" + cussql + "]"); + + String field_workflow_value = ""; + if(!"".equals(l_fieldname)){//对应的流程字段不为空 + if(l_viewtype == 1 && rs_detail != null){//字段为明细表字段 + field_workflow_value = Util.null2String(rs_detail.getString(l_fieldname)); + }else { + field_workflow_value = Util.null2String(rs.getString(l_fieldname)); + } + } + + String final_value = ""; + + switch (changerule){ + case 1://流程requestid + final_value = this_requestid; + break; + case 2://流程标题 + final_value = this_requestname; + break; + case 3://流程编号 + final_value = this_requestmark; + break; + case 4://系统日期 + final_value = currentday; + break; + case 5://系统日期时间 + final_value = currentdatetime; + break; + case 6://固定值 + final_value = cussql; + break; + case 7://自定义规则 + final_value = getValueByChangeRule(cussql,field_workflow_value); + break; + case 8://明细行序号 + final_value = String.valueOf(detailTable_Index); + break; + default: + final_value = field_workflow_value; + break; + } + + final_value = final_value.replace("'","''"); + + return final_value; + } + + /** + * 用数据库值,根据规则转换,获取其最终结果 + * @param cus_sql 自定义转换的规则 + * @param value + * @return + */ + private String getValueByChangeRule(String cus_sql,String value){ + String endValue = ""; + + String sqlString = cus_sql.replace("{?requestid}", this_requestid).replace("?", value); + + RecordSet rs = new RecordSet(); + //this.writeLog("转换后的SQL:[" + sqlString + "]"); + if(rs.execute(sqlString)){ + rs.next(); + + endValue = Util.null2String(rs.getString(1)); + } + return endValue; + } + /** + * @return the cus_param + */ + public String getCus_param() { + return cus_param; + } + /** + * @param cus_param the cus_param to set + */ + public void setCus_param(String cus_param) { + this.cus_param = cus_param; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Action.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Action.java new file mode 100644 index 0000000..9f04dce --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Action.java @@ -0,0 +1,45 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.formmode.customjavacode.AbstractModeExpandJavaCode; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; +import weaver.zwl.common.ToolUtil; + +import java.util.Map; + +/** + * 通用工具表单建模 + * 手动执行自定义SQL + */ +public class ExecuteSQL_Action extends AbstractModeExpandJavaCode { + //当前类名称 + private String className = "ExecuteSQL_Action"; + private ToolUtil toolutil = new ToolUtil(); + + /** + * 执行模块扩展动作 + * @param param + * param包含(但不限于)以下数据 + * user 当前用户 + */ + public void doModeExpand(Map param) throws Exception { + toolutil.writeDebuggerLog(className, "---------------" + className + " BEGIN ---------------"); + + //当前用户信息 + User user = (User) param.get("user"); + int billid = -1;//数据id + //int modeid = -1;//模块id + //模块信息 + RequestInfo requestInfo = (RequestInfo) param.get("RequestInfo"); + if (requestInfo != null) { + billid = Util.getIntValue(requestInfo.getRequestid()); + //modeid = Util.getIntValue(requestInfo.getWorkflowid()); + + ExecuteSQL_Util eu = new ExecuteSQL_Util(); + eu.execute_sql_job(billid,1,user.getUID()); + } + + toolutil.writeDebuggerLog(className, "---------------" + className + " End ---------------"); + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Cron.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Cron.java new file mode 100644 index 0000000..44299fe --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Cron.java @@ -0,0 +1,43 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.general.Util; +import weaver.interfaces.schedule.BaseCronJob; +import weaver.zwl.common.ToolUtil; + +/** + * 通用功能 + * ִ执行自定义SQL语句的计划任务 + */ +public class ExecuteSQL_Cron extends BaseCronJob { + private String className = "ExecuteSQL_Cron"; + + private String keyvalue = ""; + + private ToolUtil toolUtil = new ToolUtil(); + + /** + * 实现父类方法 + */ + public void execute(){ + toolUtil.writeNewDebuggerLog(className, "-------------" + className + " BEGIN-----------------"); + + toolUtil.writeDebuggerLog(className,"--->keyvalue:[" + keyvalue + "]"); + + ExecuteSQL_Util eu = new ExecuteSQL_Util(); + + if(!"".equals(keyvalue)){ + eu.execute_sql_job(Util.getIntValue(keyvalue,0),0,1); + }else { + eu.execute_sql_job(); + } + toolUtil.writeNewDebuggerLog(className, "-------------" + className + " End-----------------"); + } + + public String getKeyvalue() { + return keyvalue; + } + + public void setKeyvalue(String keyvalue) { + this.keyvalue = keyvalue; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Util.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Util.java new file mode 100644 index 0000000..409cae8 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/ExecuteSQL_Util.java @@ -0,0 +1,130 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.conn.RecordSet; +import weaver.conn.RecordSetDataSource; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.zwl.common.ToolUtil; + +/** + * 执行自定义SQL的工具类 + */ +public class ExecuteSQL_Util extends ToolUtil { + //当前类名称 + private String className = "ExecuteSQL_Util"; + + /** + * 执行建模中的SQL语句 + */ + public void execute_sql_job(){ + execute_sql_job(0,0,1); + } + + /** + * 执行建模中的SQL语句 + * @param keyvalue 具体记录ID + * @param sourceType 执行方法 0-自动 1-手动 + * @param userid 用户ID + */ + public void execute_sql_job(int keyvalue,int sourceType,int userid) { + this.writeNewDebuggerLog(className, "-------------" + className + " BEGIN-----------------"); + + //获取建模中未执行的SQL + String select_data = "select * from uf_Pending_SQL where 1=1 "; + + if(keyvalue > 0){ + select_data += " and isopen = 0 and id = " + keyvalue; + }else{ + select_data += " and isopen = 0"; + } + + if(sourceType == 0){ + select_data += " and scope in (0,2)"; + }else if(sourceType == 1){ + select_data += " and scope in (1,2)"; + } + + select_data += " order by exe_order"; + + this.writeNewDebuggerLog(className,"查询满足条件的SQL:[" + select_data + "]"); + + RecordSet rs = new RecordSet(); + + RecordSet rs_o = new RecordSet(); + + if(rs.executeQuery(select_data)){ + while(rs.next()){ + //数据ID + int dataid = Util.getIntValue(rs.getString("id"),0); + //配置名称 + String name = Util.null2String(rs.getString("name")); + //数据源标识 + String dbid = Util.null2String(rs.getString("dbid")); + //待执行的SQL + String mainSQL = Util.null2String(rs.getString("mainSQL")); + + mainSQL = mainSQL.replace("^",""); + //对SQL语句字符串特殊字符的处理 + mainSQL = mainSQL.replace(" "," "); + mainSQL = mainSQL.replace("
"," "); + //再次将全角转成半角 + mainSQL = ToDBC(mainSQL); + + this.writeNewDebuggerLog(className,"--->name:[" + name + "],keyid:[" + dataid + "],DBBase:[" + dbid + "],mainSQL:[" + mainSQL + "]"); + + RecordSetDataSource rsds = null; + + if(!"".equals(dbid)){ + rsds = new RecordSetDataSource(dbid); + } + + boolean issuccess = false; + String exception = ""; + try { + + if(!"".equals(dbid)){ + issuccess = rsds.executeSql(mainSQL); + }else{ + issuccess = rs_o.execute(mainSQL); + + if(!issuccess){ + exception = rs_o.getExceptionMsg(); + } + } + + }catch (Exception e){ + e.printStackTrace(); + exception = e.getMessage(); + + this.writeNewDebuggerLog(className,"---->" + e.getMessage() + "/" + e.toString()); + } + + //插入操作日志 + String insert_log = "insert into uf_Pending_SQL_dt1 (mainid,operatetype,exe_result,exe_operator,exe_datetime,failureReason) values (" + + +dataid + "," + sourceType + "," + (issuccess ? 1 : 0) + "," + userid + ",'" + TimeUtil.getCurrentTimeString() + "','" + exception + "')"; + + rs_o.executeUpdate(insert_log); + } + } + + this.writeNewDebuggerLog(className, "-------------" + className + " END-----------------"); + } + + /** + * 全角转半角 + * @param input + * @return + */ + public String ToDBC(String input) { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (c[i] == '\u3000') { + c[i] = ' '; + } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + return returnString; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDao.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDao.java new file mode 100644 index 0000000..c83a221 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDao.java @@ -0,0 +1,134 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import java.util.ArrayList; +import java.util.List; + +/** + * 同步外部数据日志实体类 + * @author bleach + * @date 2021-11-15 + * @version 1.0 + */ +public class SyncLoggerDao { + /** + * 总记录条数 + */ + private int totalNum = 0; + /** + * 成功记录条数 + */ + private int successNum = 0; + /** + * 失败记录条数 + */ + private int failNum = 0; + /** + * 操作人员ID + */ + private int operatorid = 0; + /** + * 操作日期 + */ + private String operateDate = ""; + /** + * 操作时间 + */ + private String operateTime = ""; + /** + * 操作方式 0-手动 1-自动 + */ + private int operateType = -1; + /** + * 对应配置ID + */ + private int configId = -1; + /** + * 描述性文字 + */ + private String message = ""; + + /** + * 详细信息集合 + */ + private List detailDaoList = new ArrayList<>(); + + public int getTotalNum() { + return totalNum; + } + + public void setTotalNum(int totalNum) { + this.totalNum = totalNum; + } + + public int getSuccessNum() { + return successNum; + } + + public void setSuccessNum(int successNum) { + this.successNum = successNum; + } + + public int getFailNum() { + return failNum; + } + + public void setFailNum(int failNum) { + this.failNum = failNum; + } + + public int getOperatorid() { + return operatorid; + } + + public void setOperatorid(int operatorid) { + this.operatorid = operatorid; + } + + public String getOperateDate() { + return operateDate; + } + + public void setOperateDate(String operateDate) { + this.operateDate = operateDate; + } + + public String getOperateTime() { + return operateTime; + } + + public void setOperateTime(String operateTime) { + this.operateTime = operateTime; + } + + public int getOperateType() { + return operateType; + } + + public void setOperateType(int operateType) { + this.operateType = operateType; + } + + public int getConfigId() { + return configId; + } + + public void setConfigId(int configId) { + this.configId = configId; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public List getDetailDaoList() { + return detailDaoList; + } + + public void setDetailDaoList(List detailDaoList) { + this.detailDaoList = detailDaoList; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDetailDao.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDetailDao.java new file mode 100644 index 0000000..0b3f429 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncLoggerDetailDao.java @@ -0,0 +1,70 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +/** + * 同步外部数据详细日志实体类 + * @author bleach + * @date 2021-11-15 + * @version 1.0 + */ +public class SyncLoggerDetailDao { + /** + * 操作的数据ID + */ + private int dataid = -1; + /** + * 数据类型 0-主表 1-明细 + */ + private int datatype = -1; + /** + * 操作类型 0-新增 1-修改 + */ + private int operateType = -1; + /** + * 操作的SQL语句 + */ + private String operateSQL = ""; + /** + * 执行结果 0-失败 1-成功 + */ + private int result = 0; + + public int getDataid() { + return dataid; + } + + public void setDataid(int dataid) { + this.dataid = dataid; + } + + public int getDatatype() { + return datatype; + } + + public void setDatatype(int datatype) { + this.datatype = datatype; + } + + public int getOperateType() { + return operateType; + } + + public void setOperateType(int operateType) { + this.operateType = operateType; + } + + public String getOperateSQL() { + return operateSQL; + } + + public void setOperateSQL(String operateSQL) { + this.operateSQL = operateSQL; + } + + public int getResult() { + return result; + } + + public void setResult(int result) { + this.result = result; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeAction.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeAction.java new file mode 100644 index 0000000..e96bbc3 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeAction.java @@ -0,0 +1,41 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.formmode.customjavacode.AbstractModeExpandJavaCode; +import weaver.general.Util; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; +import weaver.zwl.common.ToolUtil; + +import java.util.Map; + +public class SyncOtherDBToModeAction extends AbstractModeExpandJavaCode { + //当前类名称 + private String className = "SyncOtherDBToModeAction"; + private ToolUtil toolutil = new ToolUtil(); + + /** + * 执行模块扩展动作 + * @param param + * param包含(但不限于)以下数据 + * user 当前用户 + */ + public void doModeExpand(Map param) throws Exception { + toolutil.writeDebuggerLog(className, "---------------" + className + " BEGIN ---------------"); + + //当前用户信息 + User user = (User) param.get("user"); + int billid = -1;//数据id + //int modeid = -1;//模块id + //模块信息 + RequestInfo requestInfo = (RequestInfo) param.get("RequestInfo"); + if (requestInfo != null) { + billid = Util.getIntValue(requestInfo.getRequestid()); + //modeid = Util.getIntValue(requestInfo.getWorkflowid()); + + SyncOtherDBToModeUtil modeUtil = new SyncOtherDBToModeUtil(); + modeUtil.dataSync(billid,1,0); + } + + toolutil.writeDebuggerLog(className, "---------------" + className + " End ---------------"); + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeCron.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeCron.java new file mode 100644 index 0000000..4a68c97 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeCron.java @@ -0,0 +1,32 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.general.Util; +import weaver.interfaces.schedule.BaseCronJob; +import weaver.zwl.common.ToolUtil; + + +public class SyncOtherDBToModeCron extends BaseCronJob { + private String className = "SyncOtherDBToModeCron"; + + private String keyvalue = ""; + + private ToolUtil toolUtil = new ToolUtil(); + + /** + * 实现父类方 + */ + public void execute() { + toolUtil.writeNewDebuggerLog(className, "-------------" + className + " BEGIN-----------------"); + + toolUtil.writeDebuggerLog(className, "--->keyvalue:[" + keyvalue + "]"); + + SyncOtherDBToModeUtil modeUtil = new SyncOtherDBToModeUtil(); + if(!"".equals(keyvalue)){ + modeUtil.dataSync(Util.getIntValue(keyvalue,-1),1,1); + }else{ + modeUtil.allDataSync(1,1); + } + + toolUtil.writeNewDebuggerLog(className, "-------------" + className + " END-----------------"); + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeUtil.java b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeUtil.java new file mode 100644 index 0000000..580c3cc --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/formmode/SyncOtherDBToModeUtil.java @@ -0,0 +1,641 @@ +package weaver.chaoyang.he.zwl.common.formmode; + +import weaver.conn.RecordSet; +import weaver.conn.RecordSetDataSource; +import weaver.formmode.data.ModeDataIdUpdate; +import weaver.formmode.setup.ModeRightInfo; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.zwl.common.ToolUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 同步其他数据库中的数据至表单建模 + * @author zhuweilin + * @date 2021-11-09 + * @version 1.0 新建版本 + */ +public class SyncOtherDBToModeUtil extends ToolUtil { + //当前类名称 + private String className = "SyncOtherDBToModeUtil"; + + /** + * 操作日志对应的建模模块ID + */ + private int OPERATOR_LOGGER_MODEID = -1; + /** + * 操作日志对应的建模表名称 + */ + private String OPERATOR_LOGGER_TABLE = "uf_syncOtherLog"; + + /** + * 构造方法 + */ + public SyncOtherDBToModeUtil(){ + this.OPERATOR_LOGGER_MODEID = Util.getIntValue(this.getSystemParamValue("SYNCOTHERDB_OPERATOR_LOGGER_MODEID"),0); + } + + /** + * 构造方法 + * @param logModeId 日志模块ID + */ + public SyncOtherDBToModeUtil(int logModeId){ + this.OPERATOR_LOGGER_MODEID = logModeId; + } + + /** + * 获取配置信息 + * @param modeid 对应的配置模块 + * @return 配置信息集合 + */ + private Map getConfigurationByModeId(int modeid){ + Map cmap = new HashMap<>(); + + String selectMainSQL = "select u.*,w.tablename from uf_othersysToMode u inner join modeinfo m on u.mid = m.id" + + " inner join workflow_bill w on w.id = m.formid" + + " where u.mid = ?"; + + this.writeDebuggerLog(className,"查询配置信息:[" + selectMainSQL + "]"); + + RecordSet rs = new RecordSet(); + + int mainKeyId = -1; + + if(rs.executeQuery(selectMainSQL,modeid)){ + if(rs.next()){ + mainKeyId = Util.getIntValue(rs.getString("id"),0); + //数据源标识 + String sourceid = Util.null2String(rs.getString("sourceid")); + //外部主表名称 + String outMainTbName = Util.null2String(rs.getString("outMainTbName")); + //外部主键字段名 + String outMainKeyField = Util.null2String(rs.getString("outMainKeyField")); + //数据同步方式 0-追加 1-更新 2-覆盖 + int method = Util.getIntValue(rs.getString("method"),0); + //操作类型 + int operateType = Util.getIntValue(rs.getString("operateType"),0); + //数据条件 + String dataCondition = Util.null2String(rs.getString("dataCondition")); + //内部主表名称 + String innerMainTable = Util.null2String(rs.getString("tablename")); + //内部建模主表外键字段ID + int innerMainKeyField = Util.getIntValue(rs.getString("innerMainKeyField"),0); + + if(!"".equals(dataCondition)){ + dataCondition = dataCondition.replace(" "," "); + dataCondition = dataCondition.replace("
"," "); + } + + cmap.put("configId",mainKeyId); + cmap.put("sourceid",sourceid); + cmap.put("outMainTbName",outMainTbName); + cmap.put("innerMainTable",innerMainTable); + cmap.put("outMainKeyField",outMainKeyField); + cmap.put("innerMainKeyField",innerMainKeyField); + cmap.put("method",method); + cmap.put("operateType",operateType); + cmap.put("dataCondition",dataCondition); + } + } + + if(mainKeyId > 0){ + //获取明细表映射关系 + String selectDetailSQL = "select * from uf_othersysToMode_dt1 where mainid = ?"; + + List> dtList = new ArrayList<>(); + if(rs.executeQuery(selectDetailSQL,mainKeyId)){ + while(rs.next()){ + //外部明细表名称 + String outDtName = Util.null2String(rs.getString("outDtName")); + //外部明细主键字段名 + String outKeyField = Util.null2String(rs.getString("outKeyField")); + //建模明细表序列 + int mDtIndex = Util.getIntValue(rs.getString("mDtIndex"),0); + //数据条件 + String dataCondition = Util.null2String(rs.getString("dataCondition")); + //建模明细表外键字段 + String mKeyField = Util.null2String(rs.getString("mKeyField")); + //是否覆盖更新 0-否 1-是 + int isCover = Util.getIntValue(rs.getString("isCover"),0); + //外部关联字段 + String outLinkField = Util.null2String(rs.getString("outLinkField")); + + if(!"".equals(dataCondition)){ + dataCondition = dataCondition.replace(" "," "); + dataCondition = dataCondition.replace("
"," "); + } + + Map detailmap = new HashMap<>(); + detailmap.put("outDtName",outDtName); + detailmap.put("outKeyField",outKeyField); + detailmap.put("mDtIndex",mDtIndex); + detailmap.put("dataCondition",dataCondition); + detailmap.put("mKeyField",mKeyField); + detailmap.put("isCover",isCover); + detailmap.put("outLinkField",outLinkField); + + dtList.add(detailmap); + } + } + + cmap.put("dtList",dtList); + + List> fieldList = new ArrayList<>(); + //获取详细的字段对应配置 + selectDetailSQL = "select dt.*,wb.fieldname,wb.viewtype,wb.detailtable,wb.fielddbtype from uf_othersysToMode_dt2 dt " + + "left join workflow_billfield wb on dt.mFieldID = wb.id where dt.mainid = ?"; + + if(rs.executeQuery(selectDetailSQL,mainKeyId)){ + while(rs.next()){ + //建模字段名称 + String m_fieldName = Util.null2String(rs.getString("fieldname")); + //建模字段所属 0-主表 1-明细表 + int m_viewtype = Util.getIntValue(rs.getString("viewtype"),0); + //字段所属明细表名 + String detialTableName = Util.null2String(rs.getString("detailtable")); + //字段类型 + String fielddbtype = Util.null2String(rs.getString("fielddbtype")).toLowerCase(); + + //数据库类型 0-文本 1-浮点 2-整型 + int dbType = 0; + + if(fielddbtype.contains("decimal") || fielddbtype.contains("float") || fielddbtype.contains("number")){ + dbType = 1; + }else if(fielddbtype.contains("int") || fielddbtype.contains("integer")){ + dbType = 2; + } + + //字段所在明细表序列 + int dtIndex = 0; + + if(m_viewtype == 1 && !"".equals(detialTableName)){ + dtIndex = Util.getIntValue(detialTableName.substring(detialTableName.indexOf("_dt") + 3),-1); + } + + //外部字段名称 + String o_fieldNmae = Util.null2String(rs.getString("outFieldName")); + + //转换规则 + int changerule = Util.getIntValue(rs.getString("changerule"),0); + //自定义规则 + String cussql = Util.null2String(rs.getString("cussql")); + //规则引用数据源 + int ruleDBSouce = Util.getIntValue(rs.getString("ruleDBSouce"),0); + + Map detailmap = new HashMap<>(); + detailmap.put("m_fieldName",m_fieldName); + detailmap.put("m_viewtype",m_viewtype); + detailmap.put("o_fieldNmae",o_fieldNmae); + detailmap.put("changerule",changerule); + detailmap.put("cussql",cussql); + detailmap.put("ruleDBSouce",ruleDBSouce); + detailmap.put("m_dtIndex",dtIndex); + detailmap.put("dbType",dbType); + + fieldList.add(detailmap); + } + cmap.put("fieldList",fieldList); + } + }else{ + return null; + } + + return cmap; + } + + /** + * 所有配置都进行同步 + * @param userid + * @param operateType + */ + public void allDataSync(int userid,int operateType){ + String selectSQL = "select * from uf_othersysToMode"; + + RecordSet rs = new RecordSet(); + + if(rs.executeQuery(selectSQL)){ + while (rs.next()){ + int mid = Util.getIntValue(rs.getString(1),-1); + + dataSync(mid,userid,operateType); + } + } + } + + /** + * 外部数据同步操作 + * @param modeid 建模模块ID + * @param userid 用户ID + * @param operateType 操作方式 0-手动 1-自动 + */ + public void dataSync(int modeid,int userid,int operateType){ + + SyncLoggerDao loggerDao = new SyncLoggerDao(); + loggerDao.setOperatorid(userid); + loggerDao.setOperateDate(TimeUtil.getCurrentDateString()); + loggerDao.setOperateTime(TimeUtil.getOnlyCurrentTimeString()); + loggerDao.setOperateType(operateType); + + //根据模块ID获取其对应的配置信息 + Map cmap = getConfigurationByModeId(modeid); + + if(cmap != null){ + //获取数据源标识 + String sourceid = Util.null2String(cmap.get("sourceid")); + //获取满足的数据条件 + String dataCondition = Util.null2String(cmap.get("dataCondition")); + + if(!"".equals(dataCondition)){ + dataCondition = ToDBC(dataCondition); + } + RecordSetDataSource rsds = new RecordSetDataSource(sourceid); + //外部主表名称 + String outMainTbName = Util.null2String(cmap.get("outMainTbName")); + + String selectOutMainDataSQL = "select * from " + outMainTbName; + + if(!"".equals(dataCondition)){ + selectOutMainDataSQL += " where " + dataCondition; + } + + RecordSet rs = new RecordSet(); + + RecordSetDataSource dt_rsds = new RecordSetDataSource(sourceid); + + //查询外部数据 + if(rsds.executeSql(selectOutMainDataSQL)){ + //配置ID + int configId = (int) cmap.get("configId"); + loggerDao.setConfigId(configId); + //内部表名称 + String innerMainTable = Util.null2String(cmap.get("innerMainTable")); + //内部主表主键字段ID + int innerMainKeyFieldId = (int) cmap.get("innerMainKeyField"); + //内部主表主键字段名称 + String innerMainKeyFieldName = getFieldNameByFieldid(innerMainKeyFieldId); + + //查询当前OA系统中已存在的数据 + Map oadata = getOAModeData(innerMainTable,innerMainKeyFieldName); + //数据同步方式 0-追加 1-更新 2-覆盖 + int dataMethod = (int) cmap.get("method"); + + //数据字段集合 + List> fieldList = (List>) cmap.get("fieldList"); + + List> dtList = (List>) cmap.get("dtList"); + + //外部主表主键字段名称 + String outMainKeyFieldName = Util.null2String(cmap.get("outMainKeyField")); + + ModeDataIdUpdate mdu = ModeDataIdUpdate.getInstance(); + + //总记录条数(主表) + int totalNum = rsds.getCounts(); + + loggerDao.setTotalNum(totalNum); + + int successNum = 0; + int failNum = 0; + + if(dataMethod == 2){//表示覆盖 + //先删除历史记录 + rs.executeUpdate("delete from " + innerMainTable + " where 1=1 "); + oadata.clear(); + } + + + List detailDaoList = new ArrayList<>(); + while(rsds.next()){ + //外部主表主键字段值 + String outMainKeyFieldValue = Util.null2String(rsds.getString(outMainKeyFieldName)); + + boolean isNewData = false; + int oaDataKeyId = -1; + if(oadata.containsKey(outMainKeyFieldValue)){//该记录已存在 + oaDataKeyId = oadata.get(outMainKeyFieldValue); + + if(dataMethod == 0){//表示追加,已存在的记录不进行处理 + continue; + } + + }else{//该记录不存在 + oaDataKeyId = mdu.getModeDataNewId(innerMainTable, modeid, 1, 1, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString()); + isNewData = true; + } + + //主表数据操作 + String[] sqlArray = genarateOperateSQL(sourceid,rsds,fieldList,0); + + String updateMainSQL = "update " + innerMainTable + " set modedatacreater=1" + sqlArray[0] + " where id = " + oaDataKeyId; + + SyncLoggerDetailDao detailDao = new SyncLoggerDetailDao(); + + detailDao.setDataid(oaDataKeyId); + detailDao.setDatatype(0); + detailDao.setOperateType(isNewData ? 0 : 1); + detailDao.setOperateSQL(updateMainSQL); + + if(rs.executeUpdate(updateMainSQL)){ + detailDao.setResult(1); + successNum++; + //查询对应的明细操作 + if(dtList != null && dtList.size() > 0){ + for(Map detailmap : dtList){ + //是否覆盖 + int isCover = (int) detailmap.get("isCover"); + //外部明细表 + String outDtName = (String) detailmap.get("outDtName"); + //外部关联字段 + String outLinkField = (String) detailmap.get("outLinkField"); + //外部主键字段名称 + String outKeyField = (String) detailmap.get("outKeyField"); + //数据条件 + String dtDataCondition = (String) detailmap.get("dataCondition"); + //建模明细表序列 + int mDtIndex = (int) detailmap.get("mDtIndex"); + //建模明细表外键字段 + String mKeyField = (String) detailmap.get("mKeyField"); + + String mDtTable = innerMainTable + "_dt" + mDtIndex; + if(isCover == 1 && !isNewData){//说明是覆盖更新,则需要将历史记录清空,进行重新写入 + rs.executeUpdate("delete from " + mDtTable + " where mainid = ?",oaDataKeyId); + } + + //查询外部明细表操作 + String selectOutDetail = "select * from " + outDtName + " where " + outLinkField + "='" + outMainKeyFieldValue + "'"; + + if(!"".equals(dtDataCondition)){ + selectOutDetail += dtDataCondition; + } + this.writeDebugLog("执行查询外部明细表记录SQL:[" + selectOutDetail + "]"); + if(dt_rsds.executeSql(selectOutDetail)){ + while(dt_rsds.next()){ + SyncLoggerDetailDao dtDetailDao = new SyncLoggerDetailDao(); + dtDetailDao.setDatatype(1); + //外部主键字段值 + String outKeyFieldValue = Util.null2String(dt_rsds.getString(outKeyField)); + + String[] dtSQLArray = genarateOperateSQL(sourceid,dt_rsds,fieldList,mDtIndex); + + String dtTableOperateSQL = ""; + + if(isNewData){//主表为新记录 + dtDetailDao.setOperateType(0); + //明细表进行写入 + dtTableOperateSQL = "insert into " + mDtTable + "(mainid" + dtSQLArray[1] + ") values (" + oaDataKeyId + dtSQLArray[2] + ")"; + }else { + if (isCover == 1) { + dtDetailDao.setOperateType(0); + dtTableOperateSQL = "insert into " + mDtTable + "(mainid" + dtSQLArray[1] + ") values (" + oaDataKeyId + dtSQLArray[2] + ")"; + } else { + dtDetailDao.setOperateType(1); + //明细表更新SQL + dtTableOperateSQL = "update " + mDtTable + " set id=id" + dtSQLArray[0] + " where " + mKeyField + " = '" + outKeyFieldValue + "'"; + } + } + dtDetailDao.setOperateSQL(dtTableOperateSQL); + if(rs.executeUpdate(dtTableOperateSQL)){ + dtDetailDao.setResult(1); + this.writeDebugLog("建模明细表操作成功,成功SQL:[" + dtTableOperateSQL + "]"); + }else{ + dtDetailDao.setResult(0); + this.writeErrorLog("操作建模明细表失败,失败SQL:[" + updateMainSQL + "]"); + } + + detailDaoList.add(dtDetailDao); + } + }else{ + this.writeErrorLog("查询外部明细表数据失败,失败SQL:[" + updateMainSQL + "]"); + } + } + }else{ + //this.writeDebugLog("无明细操作表需要操作!"); + } + + //新插入的记录,权限重构 + setModeRight(1,modeid,oaDataKeyId); + }else{//数据操作失败 + failNum++; + detailDao.setResult(1); + this.writeErrorLog("外部主表数操作失败,失败SQL:[" + updateMainSQL + "]"); + + if(isNewData){//删除冗余数据 + rs.executeUpdate("delete from " + innerMainTable + " where id = ?",oaDataKeyId); + } + } + + detailDaoList.add(detailDao); + } + + loggerDao.setSuccessNum(successNum); + loggerDao.setFailNum(failNum); + }else{ + loggerDao.setMessage("外部主表数据查询失败,失败SQL:[" + selectOutMainDataSQL + "]"); + this.writeErrorLog("外部主表数据查询失败,失败SQL:[" + selectOutMainDataSQL + "]"); + } + }else{ + loggerDao.setMessage("该模块对应的配置信息不存在,未进行同步操作!"); + this.writeDebugLog("该模块对应的配置信息不存在!"); + } + + //同步日志操作 + operateLogger(loggerDao); + } + + /** + * SQL语句拼接操作 + * @param sourceid 数据源标识 + * @param rsds 外部数据某行数据的数据集 + * @param fieldList 字段详细配置信息集合 + * @param modeDtIndex 模块明细序列 + * @return + */ + private String[] genarateOperateSQL(String sourceid,RecordSetDataSource rsds,List> fieldList,int modeDtIndex){ + String[] operateArray = new String[3]; + + StringBuffer updateSQL = new StringBuffer(); + StringBuffer insertCol = new StringBuffer(); + StringBuffer insertVal = new StringBuffer(); + + for(Map detailmap : fieldList){ + //获取模块字段所属 + int m_dtIndex = (int) detailmap.get("m_dtIndex"); + if(m_dtIndex != modeDtIndex){ + continue; + } + + //获取模块字段名称 + String m_fieldName = (String) detailmap.get("m_fieldName"); + //外部表字段名称 + String o_fieldNmae = (String) detailmap.get("o_fieldNmae"); + //自定义规则 + String cussql = (String) detailmap.get("cussql"); + + String fieldvalue = ""; + if(!"".equals(o_fieldNmae)){ + fieldvalue = Util.null2String(rsds.getString(o_fieldNmae)); + } + + int changerule = (int) detailmap.get("changerule"); + + int ruleDBSouce = (int) detailmap.get("ruleDBSouce"); + + switch (changerule){ + case 0://不转换 + break; + case 1://系统日期 + fieldvalue = TimeUtil.getCurrentDateString(); + break; + case 2://系统日期时间 + fieldvalue = TimeUtil.getCurrentTimeString(); + break; + case 3://固定值 + fieldvalue = cussql; + break; + case 4://自定义SQL + if(ruleDBSouce == 1){//外部数据源 + fieldvalue = getValueByChangeRule(cussql,fieldvalue,"",0,sourceid); + }else{ + fieldvalue = getValueByChangeRule(cussql,fieldvalue); + } + break; + default: + break; + } + + if("".equals(fieldvalue)){//若最终要操作的值为空值 + //int dbType = (int) detailmap.get("dbType"); + insertCol.append(",").append(m_fieldName); + insertVal.append(",NULL"); + updateSQL.append(",").append(m_fieldName).append("=NULL"); + + }else{ + fieldvalue = fieldvalue.replace("'","''"); + + insertCol.append(",").append(m_fieldName); + insertVal.append(",'").append(fieldvalue).append("'"); + + updateSQL.append(",").append(m_fieldName).append("='").append(fieldvalue).append("'"); + } + } + + operateArray[0] = updateSQL.toString(); + operateArray[1] = insertCol.toString(); + operateArray[2] = insertVal.toString(); + + return operateArray; + } + + /** + * 获取某个建模表OA中已存在的数据 + * @param tbName 建模表名 + * @param keyField 外键字段 + * @return 数据集合 + */ + private Map getOAModeData(String tbName,String keyField){ + Map oadata = new HashMap<>(); + + String selectSQL = "select id," + keyField + " from " + tbName; + + RecordSet rs = new RecordSet(); + + if(rs.executeQuery(selectSQL)){ + while(rs.next()){ + oadata.put(Util.null2String(rs.getString(2)),Util.getIntValue(rs.getString(1),0)); + } + } + + return oadata; + } + + /** + * 操作日志 + * @param loggerDao + */ + private void operateLogger(SyncLoggerDao loggerDao){ + + ModeDataIdUpdate mdu = ModeDataIdUpdate.getInstance(); + //获取新的数据ID + int dataid = mdu.getModeDataNewId(OPERATOR_LOGGER_TABLE, OPERATOR_LOGGER_MODEID, 1, 1, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString()); + + if(dataid > 0){ + String message = loggerDao.getMessage(); + + if(!"".equals(message)){ + message = message.replace("'","''"); + } + + //执行更新操作 + String updateLogSQL = "update " + OPERATOR_LOGGER_TABLE + " set configid = " + loggerDao.getConfigId() + ",totalNum = " + loggerDao.getTotalNum() + "," + + "successNum = " + loggerDao.getSuccessNum() + ",failNum = " + loggerDao.getFailNum() + ",operatorid = " + loggerDao.getOperatorid() + "," + + "operateDate = '" + loggerDao.getOperateDate() + "',operateTime = '" + loggerDao.getOperateTime() + "',operateType = '" + loggerDao.getOperateType() + "'," + + "message = '" + message + "' where id = " +dataid; + + RecordSet rs = new RecordSet(); + + if(rs.executeUpdate(updateLogSQL)){ + //获取明细记录 + List detailDaoList = loggerDao.getDetailDaoList(); + + if(detailDaoList.size() > 0){ + for(SyncLoggerDetailDao detailDao : detailDaoList){ + String operateSQL = detailDao.getOperateSQL(); + + if(!"".equals(operateSQL)){ + operateSQL = operateSQL.replace("'","''"); + } + //插入明细操作SQL + String insert_detail = "insert into " + OPERATOR_LOGGER_TABLE + "_dt1 (mainid,dataid,datatype,operateType,operateSQL,result) values (" + + dataid + "," + detailDao.getDataid() + "," + detailDao.getDatatype() + "," + detailDao.getOperateType() + ",'" + operateSQL + "'," + + detailDao.getResult() + ")"; + + rs.executeUpdate(insert_detail); + } + } + + //数据重构 + setModeRight(1,OPERATOR_LOGGER_MODEID,dataid); + }else{ + //删除冗余数据 + rs.executeUpdate("delete from " + OPERATOR_LOGGER_TABLE + " where id = ?",dataid); + } + } + } + + /** + * 给新插入的数据进行赋权操作 + * @param creater + * @param modeid + * @param sourceid + */ + private void setModeRight(int creater,int modeid,int sourceid){ + + ModeRightInfo moderightinfo = new ModeRightInfo(); + + moderightinfo.setNewRight(true); + + moderightinfo.editModeDataShare(creater,modeid,sourceid);//新建的时候添加共享 + } + + /** + * 全角转半角 + * @param input + * @return + */ + public String ToDBC(String input) { + char c[] = input.toCharArray(); + for (int i = 0; i < c.length; i++) { + if (c[i] == '\u3000') { + c[i] = ' '; + } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { + c[i] = (char) (c[i] - 65248); + } + } + String returnString = new String(c); + return returnString; + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/logging/Log4JLogger.java b/src/main/java/weaver/chaoyang/he/zwl/common/logging/Log4JLogger.java new file mode 100644 index 0000000..440ee15 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/logging/Log4JLogger.java @@ -0,0 +1,91 @@ +package weaver.chaoyang.he.zwl.common.logging; + +import weaver.zwl.common.logging.Logger; + +/** + * 写日志(log4j) + * @date 2020-03-10 + * @version 1.0 + */ +public class Log4JLogger implements Logger { + + private org.apache.log4j.Logger log; + //类名 + private String classname; + + @Override + public String getClassname() { + return classname; + } + + @Override + public void setClassname(String classname) { + this.classname = classname; + } + + @Override + public boolean isDebugEnabled() { + return log.isDebugEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return log.isInfoEnabled(); + } + + @Override + public void debug(Object message) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.debug(classname+"."+method+"() - "+message); + } + + @Override + public void debug(Object message, Throwable exception) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.debug(classname+"."+method+"() - "+message, exception); + } + + @Override + public void info(Object message) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.info(classname+"."+method+"() - "+message); + } + + @Override + public void info(Object message, Throwable exception) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.info(classname+"."+method+"() - "+message, exception); + } + + @Override + public void warn(Object message) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.warn(classname+"."+method+"() - "+message); + } + + @Override + public void warn(Object message, Throwable exception) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.warn(classname+"."+method+"() - "+message, exception); + } + + @Override + public void error(Object message) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.error(classname+"."+method+"() - "+message); + } + + @Override + public void error(Object message, Throwable exception) { + String method = Thread.currentThread().getStackTrace()[2].getMethodName(); + log.error(classname+"."+method+"() - "+message, exception); + } + + @Override + public void init(String name) { + if("".equals(name)) { + name = "cuslog"; + } + log = org.apache.log4j.Logger.getLogger(name); + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/logging/Logger.java b/src/main/java/weaver/chaoyang/he/zwl/common/logging/Logger.java new file mode 100644 index 0000000..4582b9c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/logging/Logger.java @@ -0,0 +1,78 @@ +package weaver.chaoyang.he.zwl.common.logging; + +/** + * 日志接口(写) + * + * @author zwl + * @date 2020-03-10 + */ +public interface Logger extends weaver.integration.logging.Logger { + + public boolean isDebugEnabled(); + + /** + * 打印debug日志 + * @param message 消息 + */ + public void debug(Object message); + + /** + * 打印debug日志 + * @param message 消息 + * @param exception 异常 + */ + public void debug(Object message, Throwable exception); + + public boolean isInfoEnabled(); + + /** + * 打印info日志 + * @param message 消息 + */ + public void info(Object message); + + + /** + * 打印info日志 + * @param message 消息 + * @param exception 异常 + */ + public void info(Object message, Throwable exception); + + /** + * 打印warn日志 + * @param message 消息 + */ + public void warn(Object message); + + /** + * 打印warn日志 + * @param message 消息 + * @param exception 异常 + */ + public void warn(Object message, Throwable exception); + + /** + * 打印error日志 + * @param message + */ + public void error(Object message); + + /** + * 打印error日志 + * @param message 消息 + * @param exception 异常 + */ + public void error(Object message, Throwable exception); + + public String getClassname(); + + public void setClassname(String classname); + + /** + * 初始化 + * + * @param name logger名称 + */ + public void init(String name); +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/logging/LoggerFactory.java b/src/main/java/weaver/chaoyang/he/zwl/common/logging/LoggerFactory.java new file mode 100644 index 0000000..62ace9b --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/logging/LoggerFactory.java @@ -0,0 +1,50 @@ +package weaver.chaoyang.he.zwl.common.logging; + + +import weaver.zwl.common.logging.Log4JLogger; +import weaver.zwl.common.logging.Logger; + +/** + * 日志工厂类 + * + * @author zwl + * @date 2020-03-10 + * @version 1.0 + */ +public class LoggerFactory { + private static final String loggerName = "cus"; + public static Logger getLogger(String LogName, String clazz) { + if("".equals(LogName)) { + LogName = loggerName; + } + Logger logger = new Log4JLogger(); + logger.setClassname(clazz); + logger.init(LogName); + return logger; + } + /** + * 获取指定类的logger对象 + * @param clazz + * @return + */ + public static Logger getLogger(Class clazz) { + return getLogger(loggerName,clazz.getCanonicalName()); + } + /** + * 获取指定类的logger对象 + * @param className + * @return + */ + public static Logger getLogger(String className) { + return getLogger(loggerName,className); + } + /** + * 获取未指定指定类的logger对象 + * @param + * @return + */ + public static Logger getLogger() { + String className = Thread.currentThread().getStackTrace()[2].getClassName(); + return getLogger(loggerName, className); + } +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/workflow/JsonType.java b/src/main/java/weaver/chaoyang/he/zwl/common/workflow/JsonType.java new file mode 100644 index 0000000..256d81c --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/workflow/JsonType.java @@ -0,0 +1,24 @@ +package weaver.chaoyang.he.zwl.common.workflow; + +/** + * JSON类型 对应配置值 + */ +public class JsonType { + /** + * 文本 - 字符串 + */ + public static final int JSON_TEXT_STRING = 0; + + /** + * 文本 - 数组 + */ + public static final int JSON_TEXT_ARRAY = 1; + /** + * 对象 + */ + public static final int JSON_OBJECT = 2; + /** + * 数组 + */ + public static final int JSON_ARRAY = 3; +} diff --git a/src/main/java/weaver/chaoyang/he/zwl/common/workflow/WorkflowDataToJson.java b/src/main/java/weaver/chaoyang/he/zwl/common/workflow/WorkflowDataToJson.java new file mode 100644 index 0000000..31d6201 --- /dev/null +++ b/src/main/java/weaver/chaoyang/he/zwl/common/workflow/WorkflowDataToJson.java @@ -0,0 +1,311 @@ +package weaver.chaoyang.he.zwl.common.workflow; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Strings; +import weaver.conn.RecordSet; +import weaver.general.TimeUtil; +import weaver.general.Util; +import weaver.workflow.workflow.WorkflowVersion; +import weaver.zwl.common.ToolUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * OA流程数据根据配置信息转成JSON对象 + * @author bleach + * @version 1.0 + */ +public class WorkflowDataToJson extends ToolUtil { + + + /** + * 根据流程类型ID获取其对应的配置信息 + * @param workflowId 流程类型ID + * @param cusParam 自定义配置参数值 + * @return 配置信息集合 + */ + public Map getConfigurationByWorkflowId(String workflowId,String cusParam){ + Map configMap = new HashMap<>(); + + //获取当前流程类型对应的所有版本ID + String allWfIds = WorkflowVersion.getAllVersionStringByWFIDs(workflowId); + + RecordSet rs = new RecordSet(); + + //查询配置信息SQL(主表) + String selectMainSQL = "select * from uf_wfdataToJson where wfid in (" + allWfIds + ")"; + + if(!"".equals(cusParam)){ + selectMainSQL += " and cusparamValue = '" + cusParam + "'"; + }else{ + selectMainSQL += " and (cusparamValue is null or cusparamValue = '')"; + } + + int mainKeyId = -1; + if(rs.executeQuery(selectMainSQL)){ + if(rs.next()){ + mainKeyId = Util.getIntValue(rs.getString("id"),-1); + + //自定义数据条件 + String dataCondition = Util.null2String(rs.getString("dataCondition")); + + if(!Strings.isNullOrEmpty(dataCondition)){ + dataCondition = dataCondition.replace(" "," "); + dataCondition = dataCondition.replace("
"," "); + } + + //TODO 防止数据条件的中的SQL出现全角字符 + + configMap.put("mainKeyId",mainKeyId); + configMap.put("dataCondition",dataCondition); + } + } + + if(mainKeyId > 0){ + + List> fieldList = new ArrayList<>(); + //查询JSON与流程字段映射(明细表1) + String selectDetailSQL = "select dt.*,wb.fieldName,wb.viewType,wb.detailTable" + + " from uf_wfdataToJson_dt1 dt left join workflow_billfield wb on dt.wfField = wb.id where dt.mainid = ?"; + + if(rs.executeQuery(selectDetailSQL,mainKeyId)){ + while(rs.next()){ + //JSON名称 + String jsonName = Util.null2String(rs.getString("jsonName")); + //JSON类型 + int jsonType = Util.getIntValue(rs.getString("jsonType"),0); + //父节点名称 + String parentNode = Util.null2String(rs.getString("parentNode")); + //流程表单字段名称 + String fieldName = Util.null2String(rs.getString("fieldName")); + //流程表单字段所属 + int viewType = Util.getIntValue(rs.getString("viewType"),0); + //流程表单字段所在明细表名称 + String detailTable = Util.null2String(rs.getString("detailTable")); + //流程表单字段所在明细表序列 + int dtIndex = 0; + //转换规则 + int changeRule = Util.getIntValue(rs.getString("changeRule"),0); + //自定义规则 + String cusSQL = Util.null2String(rs.getString("cusSQL")); + + if(viewType == 1 && !Strings.isNullOrEmpty(detailTable)){ + dtIndex = Util.getIntValue(detailTable.substring(detailTable.indexOf("_dt") + 3),-1); + } + + Map detailMap = new HashMap<>(); + detailMap.put("jsonName",jsonName); + detailMap.put("jsonType",jsonType); + detailMap.put("parentNode",parentNode); + detailMap.put("fieldName",fieldName); + detailMap.put("viewType",viewType); + detailMap.put("detailTable",detailTable); + detailMap.put("dtIndex",dtIndex); + detailMap.put("changeRule",changeRule); + detailMap.put("cusSQL",cusSQL); + fieldList.add(detailMap); + } + } + + configMap.put("fieldList",fieldList); + + List> jsonArrayDtList = new ArrayList<>(); + //查询JSON数组与明细表映射关系(明细表2) + selectDetailSQL = "select * from uf_wfdataToJson_dt2 where mainid = ?"; + + if(rs.executeQuery(selectDetailSQL,mainKeyId)){ + while (rs.next()){ + //JSON数组名称 + String jsonArrayName = Util.null2String(rs.getString("arrayJsonName")); + //对应流程明细表序列 + int dtIndex = Util.getIntValue(rs.getString("dtIndex"),0); + //数据条件 + String dtCondition = Util.null2String(rs.getString("dtCondition")); + + if(!Strings.isNullOrEmpty(dtCondition)){ + dtCondition = dtCondition.replace(" "," "); + dtCondition = dtCondition.replace("
"," "); + } + //TODO 防止数据条件的中的SQL出现全角字符 + + Map detailMap = new HashMap<>(); + detailMap.put("jsonArrayName",jsonArrayName); + detailMap.put("dtIndex",dtIndex); + detailMap.put("dtCondition",dtCondition); + + jsonArrayDtList.add(detailMap); + } + } + + configMap.put("jsonArrayDtList",jsonArrayDtList); + }else{//说明该流程类型该参数对应的配置不存在 + return null; + } + + return configMap; + } + + /** + * 根据配置递归生成JSON对象 + * @param baseArray 流程基础信息数组 [请求ID,请求标题,请求编号,流程表单名称,流程主表主键ID] + * @param parentNode 父节点名称 + * @param rs 流程主表数据集 + * @param rs_detail 流程明细表某行记录数据集 + * @param fieldList 字段配置信息集合 + * @param arrayDtList 明细表与JSONArray映射配置集合 + * @param dtIndex 明细表序列 + * @return + */ + public JSONObject recursionGenerateJSON(String[] baseArray,String parentNode,RecordSet rs,RecordSet rs_detail,List> fieldList,List> arrayDtList,int dtIndex,int sequence){ + JSONObject obj = new JSONObject(); + + if(fieldList != null && fieldList.size() > 0){ + for(Map fieldMap : fieldList){ + //父节点名称 + String _parentNode = (String) fieldMap.get("parentNode"); + + if(!parentNode.equals(_parentNode)){ + continue; + } + + //字段所属 + int _viewType = (int) fieldMap.get("viewType"); + //流程字段所在明细序列 + int _dtIndex = (int) fieldMap.get("dtIndex"); + + if(_viewType == 1 && _dtIndex != dtIndex){ + continue; + } + + String _jsonName = (String) fieldMap.get("jsonName"); + //当前节点类型 + int _jsonType = (int) fieldMap.get("jsonType"); + + if (_jsonType == JsonType.JSON_TEXT_STRING){//文本 - 文本 + obj.put(_jsonName,getFieldValue(baseArray,fieldMap,rs,rs_detail,sequence)); + }else if(_jsonType == JsonType.JSON_TEXT_ARRAY){//文本 - 数组 + JSONArray array = new JSONArray(); + array.add(getFieldValue(baseArray,fieldMap,rs,rs_detail,sequence)); + obj.put(_jsonName,array); + }else if(_jsonType == JsonType.JSON_OBJECT){//对象 + obj.put(_jsonName,recursionGenerateJSON(baseArray,_jsonName,rs,rs_detail,fieldList,arrayDtList,dtIndex,sequence)); + }else if(_jsonType == JsonType.JSON_ARRAY){//数组 + JSONArray array = new JSONArray(); + + if(arrayDtList != null && arrayDtList.size() > 0) { + for (Map dtMap : arrayDtList) { + //JSON数组名称 + String jsonArrayName = (String) dtMap.get("jsonArrayName"); + + if(!_jsonName.equals(jsonArrayName)){ + continue; + } + + //明细序列ID + int _dtx = (int) dtMap.get("dtIndex"); + + String selectDetailSQl = "select * from " + baseArray[3] + "_dt" + _dtx + " where mainid = ?"; + + int rowNum = 0; + if(rs_detail.executeQuery(selectDetailSQl,baseArray[4])){ + while(rs_detail.next()){ + JSONObject detailJson = recursionGenerateJSON(baseArray,_jsonName,rs,rs_detail,fieldList,arrayDtList,_dtx,++rowNum); + + array.add(detailJson); + } + } + } + } + } + + } + } + + return obj; + } + + /** + * 根据配置获取最终需要传输的字段值 + * @param baseArray 流程基础信息数组 + * @param fieldMap 字段配置信息集合 + * @param rs 流程主表数据集 + * @param rs_detail 明细表某行记录数据集 + * @param sequence 明细序列号 + * @return + */ + private String getFieldValue(String[] baseArray,Map fieldMap,RecordSet rs,RecordSet rs_detail,int sequence){ + String fieldValue = ""; + //字段名称 + String _fieldName = (String) fieldMap.get("fieldName"); + //字段所属 + int _viewType = (int) fieldMap.get("viewType"); + + //转换规则 + int _changeRule = (int) fieldMap.get("changeRule"); + //自定义SQL + String _cusSQL = (String) fieldMap.get("cusSQL"); + + if(!Strings.isNullOrEmpty(fieldValue)){ + if(_viewType == 1 && rs_detail != null){ + fieldValue = Util.null2String(rs_detail.getString(_fieldName)); + }else if(_viewType == 0){ + fieldValue = Util.null2String(rs.getString(_fieldName)); + } + } + + switch (_changeRule){ + case 0 ://不转换 + break; + case 1 ://流程请求ID + fieldValue = baseArray[0]; + break; + case 2 ://流程请求标题 + fieldValue = baseArray[1]; + break; + case 3 ://流程请求编号 + fieldValue = baseArray[2]; + break; + case 4 ://系统日期 + fieldValue = TimeUtil.getCurrentDateString(); + break; + case 5 ://系统日期时间 + fieldValue = TimeUtil.getCurrentTimeString(); + break; + case 6 ://固定值 + fieldValue = _cusSQL; + break; + case 7 ://明细序列 + fieldValue = String.valueOf(sequence); + break; + case 8://自定义转换 + int detailKeyId = -1; + if(!Strings.isNullOrEmpty(_cusSQL) && _cusSQL.indexOf("{dt.id}") > 0 && rs_detail != null){ + detailKeyId = Util.getIntValue(rs_detail.getString("id"),-1); + } + fieldValue = getValueByChangeRule(_cusSQL,fieldValue,baseArray[0],detailKeyId); + break; + } + + return fieldValue; + } + + /** + * 调用接口信息,获取接口返回信息 + * @param object 发送的JSON对象 + * @param type 接口类型 0-预算校验 1-预算扣除 2-预算释放 + */ + public void callInterface(int type,JSONObject object){ + String interfaceURL = ""; + if(type == 0){ + interfaceURL = this.getSystemParamValue(""); + }else if(type == 1){ + + }else if(type == 2){ + + } + } +}