diff --git a/.gitignore b/.gitignore index 5621e6a..530ce3c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ log .idea/ #.gitignore !.gitignore +*.iml # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` # should NOT be excluded as they contain compiler settings and other important # information for Eclipse / Flash Builder. @@ -38,6 +39,7 @@ DirectoryV2.xml /lib/weaverLib/ *.groovy *.log +*.iml src/main/resources/WEB-INF/sqllog/ java.io.tempdir/ ecology-9-dev.iml diff --git a/javascript/common/Utils.js b/javascript/common/Utils.js new file mode 100644 index 0000000..6c960d1 --- /dev/null +++ b/javascript/common/Utils.js @@ -0,0 +1,149 @@ +window.Utils = { + /** + * @author youhong.ai + * @desc 发起请求 + */ + request: function (url, type = "GET", data, isAsync = true, success = () => { + }, error = () => { + }, complete = () => { + }, contentType = 'application/json', beforeSend = () => { + }) { + let options = { + url, + type, + dataType: "json", + contentType, + async: isAsync, + data, + beforeSend, + success, + error, + complete, + } + if (contentType == 'application/json') { + options.data = JSON.stringify(data) + } + return $.ajax(options) + }, + + /** + * @author youhong.ai + * @desc 发起请求 + */ + api: function (requestOptions = { + url: "", + type: "GET", + data: "", + isAsync: true, + success: () => { + }, + error: () => { + }, + complete: () => { + }, + contentType: 'application/json', + beforeSend: () => { + } + }) { + let options = Object.assign({ + url: "", + type: "GET", + data: "", + isAsync: true, + success: () => { + }, + error: () => { + }, + complete: () => { + }, + contentType: 'application/json', + beforeSend: () => { + } + }, requestOptions) + return $.ajax(options) + }, + + /** + * @author youhong.ai + * @desc 获取react组件实例 + */ + findReact: function (dom, traverseUp = 0) { + const key = Object.keys(dom).find(key => { + return key.startsWith("__reactFiber$") // react 17+ + || key.startsWith("__reactInternalInstance$") + || key.startsWith("__reactEventHandlers$"); // react <17 + }); + const domFiber = dom[key]; + if (domFiber == null) return null; + // react <16 + if (domFiber._currentElement) { + let compFiber = domFiber._currentElement._owner; + for (let i = 0; i < traverseUp; i++) { + compFiber = compFiber._currentElement._owner; + } + return compFiber._instance; + } + // react 16+ + const GetCompFiber = fiber => { + let parentFiber = fiber.return; + while (typeof parentFiber.type == "string") { + parentFiber = parentFiber.return; + } + return parentFiber; + }; + let compFiber = GetCompFiber(domFiber); + for (let i = 0; i < traverseUp; i++) { + compFiber = GetCompFiber(compFiber); + } + return compFiber.stateNode; + }, + + + /** + * 转换字段名为字段ID + * @param fieldName 字段名称 + * @returns {*|string} + */ + convertNameToIdUtil: function (fieldName) { + let fieldIds = []; + if (fieldName instanceof Array) { + fieldName.forEach(item => { + fieldIds.push(Utils.convertNameObjToId(item)) + }) + return fieldIds.join(',') + } + return Utils.convertNameObjToId(fieldName) + }, + + /** + * 将字段名称转为字段id + * @param fieldObj 字段名称对象 {string|object} + * @returns {*} + */ + convertNameObjToId: function (fieldObj = {fieldName: '', table: 'main'}) { + if (typeof fieldObj === 'object') { + return WfForm.convertFieldNameToId(fieldObj.fieldName, fieldObj.table) + } + return WfForm.convertFieldNameToId(fieldObj) + }, + + /** + * 根据字段名称查询字段值 + * @param fieldName 字段名称 + * @param rowIndex 明细行下表(明细获取才传递) + * @returns {*} 字段值 + */ + getFiledValueByName: function (fieldName, rowIndex) { + return WfForm.getFieldValue(Utils.convertNameObjToId(fieldName) + (rowIndex ? '_' + rowIndex : '')) + }, + + /** + * 通过字段名称修改字段值 + * @param fieldName 字段名称 + * @param value 值 + */ + changeFieldValueByName: function (fieldName, value) { + WfForm.changeFieldValue(Utils.convertNameObjToId(fieldName), {value}) + } + +} diff --git a/javascript/common/dev.js b/javascript/common/dev.js new file mode 100644 index 0000000..0ceb3ed --- /dev/null +++ b/javascript/common/dev.js @@ -0,0 +1,153 @@ +const WfForm = { + isMobile: () => { + // true表示是eMobile、微信、钉钉等移动终端,false代表PC端 + }, +} +WfForm.OPER_SAVE = '保存' +WfForm.OPER_SUBMIT = '提交/批准/提交需反馈/不需反馈等' +WfForm.OPER_SUBMITCONFIRM = '提交至确认页面,如果是确认界面,点确认触发的是SUBMIT' +WfForm.OPER_REJECT = '退回' +WfForm.OPER_REMARK = '批注提交' +WfForm.OPER_INTERVENE = '干预' +WfForm.OPER_FORWARD = '转发' +WfForm.OPER_TAKEBACK = '强制收回' +WfForm.OPER_DELETE = '删除' +WfForm.OPER_ADDROW = '添加明细行,需拼明细表序号' +WfForm.OPER_DELROW = '删除明细行,需拼明细表序号' +WfForm.OPER_PRINTPREVIEW = '打印预览 KB900190501' +WfForm.OPER_EDITDETAILROW = '移动端-编辑明细 KB900191101' +WfForm.OPER_BEFOREVERIFY = '校验必填前触发事件 KB900191201' +WfForm.OPER_TURNHANDLE = '转办 KB900201101' +WfForm.OPER_ASKOPINION = '意见征询 KB900201101' +WfForm.OPER_TAKFROWARD = '征询转办 KB900201101' +WfForm.OPER_TURNREAD = '传阅 KB900201101' +WfForm.OPER_FORCEOVER = '强制归档 KB900201101' +WfForm.OPER_BEFORECLICKBTN = '点右键按钮前 KB900201101' +WfForm.OPER_SAVECOMPLETE = '保存后页面跳转前 KB900210501' +WfForm.OPER_WITHDRAW = '撤回 KB900201101' +WfForm.OPER_CLOSE = '页面关闭' + +WfForm.registerCheckEvent = (type, callback = (callback) = {}) => { + // WfForm.registerCheckEvent(WfForm.OPER_SAVE+","+WfForm.OPER_SUBMIT,function(callback){ + // //... 执行自定义逻辑 + // callback(); + // }); +} + +WfForm.ACTION_ADDROW = '添加明细行,需拼明细表序号 KB900190407' +WfForm.ACTION_DELROW = '删除明细行,需拼明细表序号 KB900190407' +WfForm.ACTION_EDITDETAILROW = '移动端-编辑明细行,需拼明细表序号 KB900190501' +WfForm.ACTION_SWITCHDETAILPAGING = '切换明细分页 KB900191201' +WfForm.ACTION_SWITCHTABLAYOUT = '切换模板布局标签页 KB900191201' + +WfForm.registerAction = (type, callback) => { + // WfForm.registerAction(WfForm.ACTION_ADDROW+"1", function(index){ + // alert("添加行下标是"+index); + // }); //下标从1开始,明细1添加行触发事件,注册函数入参为新添加行下标 + // WfForm.registerAction(WfForm.ACTION_DELROW+"2", function(arg){ + // alert("删除行下标集合是"+arg.join(",")); + // }); //下标从1开始,明细2删除行触发事件 + // WfForm.registerAction(WfForm.ACTION_SWITCHDETAILPAGING, function(groupid){ + // alert("切换明细表"+(groupid+1)+"的页码触发事件"); + // }); + // WfForm.registerAction(WfForm.ACTION_SWITCHTABLAYOUT, function(tabid){ + // alert("切换到标签项"+tabid+"触发事件"); + // }); +} + +WfForm.convertFieldNameToId = (fieldName, table, flag) => { + // var fieldid = WfForm.convertFieldNameToId("zs"); + // var fieldid = WfForm.convertFieldNameToId("zs_mx", "detail_1"); + // var fieldid = WfForm.convertFieldNameToId("zs_mx", "detail_1", false); +} + +WfForm.getFieldValue = function (fieldMark) { + // fieldMark String 是 字段标示,格式field${字段ID}_${明细行号} + // var fieldvalue = WfForm.getFieldValue("field110"); +} + +WfForm.bindFieldChangeEvent = function (fieldMarkStr, funobj = (obj, id, value) => { +}) { +// fieldMarkStr String 是 绑定字段标示,可多个拼接逗号隔开,例如:field110(主字段),field111_2(明细字段)…… +// funobj Function 是 字段值变化触发的自定义函数,函数默认传递以下三个参数,参数1:触发字段的DOM对象,参数2:触发字段的标示(field27555等),参数3:修改后的值 +// WfForm.bindFieldChangeEvent("field27555,field27556", function (obj, id, value) { +// console.log("WfForm.bindFieldChangeEvent--", obj, id, value); +// }); +} + +WfForm.controlBtnDisabled = function (isDisabled) { + // isDisabled boolean 是 true:按钮全部置灰不可操作,false:恢复按钮可操作状态 + // function subimtForm(params){ + // WfForm.controlBtnDisabled(true); //操作按钮置灰 + // ... + // WfForm.controlBtnDisabled(false); + // } +} + + +WfForm.showMessage = function (msg, type, duration) { + // 参数 参数类型 必须 说明 + // msg String true 提示信息内容 + // type int false 提示类型,1(警告)、2(错误)、3(成功)、4(一般),默认为1,不同类型提示信息效果不同 + // duration Float false 多长时间自动消失,单位秒,默认为1.5秒 + // WfForm.showMessage("结束时间需大于开始时间"); //警告信息,1.5s后自动消失 + // WfForm.showMessage("运算错误", 2, 10); //错误信息,10s后消失 + +} + +WfForm.getBaseInfo = function () { +// console.log(WfForm.getBaseInfo()); //返回当前请求基础信息 +// //输出对象说明: + return { + f_weaver_belongto_userid: "5240", //用户信息 + f_weaver_belongto_usertype: "0", + formid: -2010, //表单id + isbill: "1", //新表单/老表单 + nodeid: 19275, //节点id + requestid: 4487931, //请求id + workflowid: 16084, //路径id + } +} + +WfForm.changeFieldValue = function (fieldMark, valueInfo) { + // fieldMark String 是 字段标示,格式field${字段ID}_${明细行号} + // valueInfo JSON 是 字段值信息,非浏览按钮字段格式为{value:”修改的值”};specialobj为浏览按钮信息,数组格式;showhtml属性只在单行文本类型且只读情况下生效; + //修改文本框、多行文本、选择框等字段类型 +// WfForm.changeFieldValue("field123", {value:"1.234"}); +// //修改浏览框字段的值,必须有specialobj数组结构对象 +// WfForm.changeFieldValue("field11_2", { +// value: "2,3", +// specialobj:[ +// {id:"2",name:"张三"}, +// {id:"3",name:"李四"} +// ] +// }); +// //修改check框字段(0不勾选、1勾选) +// WfForm.changeFieldValue("field123", {value:"1"}); +// //针对单行文本框字段类型,只读情况,支持显示值跟入库值不一致 +// WfForm.changeFieldValue("field123", { +// value: "入库真实值", +// specialobj: { +// showhtml: "界面显示值" +// } +// }); +} + + +/* ******************* 建模表开发依赖 ******************* */ + +const ModeList = {} +ModeList.dataLoadAfter = function (data) { + // 描述:在列表数据加载完,对列表的数据进行二次加工,并渲染。 dataLoadAfter传入dataHandle方法,用来接收并处理数据,dataHandle有两个参数。 + // var dataHandle = function(datas,displayType){ + // //Changes to 'datas' do not directly modify the real database data, but modify the data received at the front end. + // var newDatas = datas; + // if(displayType == 'normal'){ + // console.log(newDatas); + // } + // return newDatas; + // } + // ModeList.dataLoadAfter(dataHandle); +}; + + diff --git a/javascript/youhong.ai/fentian/ecode/workflow_controller.js b/javascript/youhong.ai/fentian/ecode/workflow_controller.js new file mode 100644 index 0000000..3205701 --- /dev/null +++ b/javascript/youhong.ai/fentian/ecode/workflow_controller.js @@ -0,0 +1,154 @@ +/* ******************* 丰田纺织流程代码块 可选择流程中的字段配置流程标题生成规则******************* */ + +class ConfigWorkflowTitle { + + constructor(config) { + this.config = config + } + + + /** + * 初始化参数 + */ + init = () => { + let baseInfo = WfForm.getBaseInfo(); + if (baseInfo.workflowid != this.config.workflowId) { + return + } + let filedArr = [] + this.config.rules.filter(item => item.type === RulesType.FIELD_VALUE + || item.type === RulesType.SELECT_VALUE + || item.type === RulesType.RADIO_VALUE).forEach(item => filedArr.push(item.fieldName)) + this.addListenerEvent(filedArr) + } + + /** + * 修改流程标题字段值 + */ + changeWorkflowTitle = () => { + let workflowTitle = [] + this.config.rules.forEach(item => { + workflowTitle.push(item.type.run(item)) + }) + WfForm.changeFieldValue(this.config.titleFieldName === 'field-1' ? 'field-1' : + Utils.convertNameToIdUtil(this.config.titleFieldName), { + value: workflowTitle.join("") + }) + } + + /** + * 添加监听方法 + * @param fileNameArr 需要监听的字段数组 + */ + addListenerEvent = (fileNameArr) => { + console.log(Utils.convertNameToIdUtil(fileNameArr)) + WfForm.bindFieldChangeEvent(Utils.convertNameToIdUtil(fileNameArr), (obj, id, value) => { + this.changeWorkflowTitle() + }) + } + +} + +class RulesType { + // 固定值 + static FIX_STRING = { + value: 0, + run: item => item.value + } + // 字段值 + static FIELD_VALUE = { + value: 1, + run: item => Utils.getFiledValueByName(item.fieldName) + } + // 下拉框显示值 + static SELECT_VALUE = { + value: 2, + run: item => $(`div[data-fieldname='${item.fieldName}'] .ant-select-selection-selected-value`).text() + } + // 单选按钮 + static RADIO_VALUE = { + value: 3, + run: item => $(`div[data-fieldname='${item.fieldName}'] .ant-radio.ant-radio.ant-radio-checked.ant-radio-checked`).next().text() + } + // 当前日期 yyyy-mm-dd + static CURRENT_DATE = { + value: 4, + run: () => { + const date = new Date(); + let year = date.getFullYear(); + let month = date.getMonth() + 1; + let day = date.getDay(); + return year + "-" + month + "-" + day + } + } + // 当前时间 HH:mm:ss + static CURRENT_TIME = { + value: 5, + run: () => { + const date = new Date(); + let hours = date.getHours(); + let minutes = date.getMinutes(); + let seconds = date.getSeconds(); + return hours + ":" + minutes + ":" + seconds + } + } + // 当前年份 + static CURRENT_YEAR = { + value: 6, + run: () => new Date().getFullYear() + + } + // 当前月份 + static CURRENT_MONTH = { + value: 7, + run: () => new Date().getMonth() + 1 + + } + // 当前天数 + static CURRENT_DAY = { + value: 8, + run: () => new Date().getDay() + + } + // 当前小时 + static CURRENT_HOUR = { + value: 9, + run: () => new Date().getHours() + + } + // 当前分钟 + static CURRENT_MINUTE = { + value: 10, + run: () => new Date().getMinutes() + + } + // 当前秒数 + static CURRENT_SECOND = { + value: 11, + run: () => new Date().getSeconds() + } + // 当前时间戳 + static CURRENT_TIME_STAMP = { + value: 12, + run: () => new Date().getTime() + } + // 流水号 + static RANDOM = { + value: 13, + run: item => { + let result = [] + let range = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] + for (let i = 0; i < item.length; i++) { + let index = parseInt(Math.random(0, 10) * 10) + result.push(range[index]) + } + return result.join("") + } + } +} + + +window.RulesType = RulesType +window.ConfigWorkflowTitle = ConfigWorkflowTitle + +/* ******************* 可选择流程中的字段配置流程标题生成规则 end ******************* */ \ No newline at end of file diff --git a/javascript/youhong.ai/fentian/workflow_code_block.js b/javascript/youhong.ai/fentian/workflow_code_block.js new file mode 100644 index 0000000..5bb77b3 --- /dev/null +++ b/javascript/youhong.ai/fentian/workflow_code_block.js @@ -0,0 +1,29 @@ +/* ******************* youhong.ai 丰田纺织流程代码块 可选择流程中的字段配置流程标题生成规则******************* */ + +$(() => { + let workflowTitleConfig = { + workflowId: '44', + titleFieldName: 'field-1', + rules: [{ + type: RulesType.CURRENT_DATE + }, + { + type: RulesType.FIX_STRING, + value: '-' + }, { + type: RulesType.FIELD_VALUE, + fieldName: 'mc' + }, { + type: RulesType.FIELD_VALUE, + fieldName: 'sjid' + }, { + type: RulesType.RANDOM, + length: 5 + }, { + type: RulesType.RANDOM, + length: 5 + }] + } + new ConfigWorkflowTitle(workflowTitleConfig).init() +}) +/* ******************* 可选择流程中的字段配置流程标题生成规则 end ******************* */ diff --git a/javascript/youhong.ai/pcn/workflow_code_block.js b/javascript/youhong.ai/pcn/workflow_code_block.js index 95cbb39..290ce16 100644 --- a/javascript/youhong.ai/pcn/workflow_code_block.js +++ b/javascript/youhong.ai/pcn/workflow_code_block.js @@ -1 +1,234 @@ -// 流程代码块 +/* ******************* 保时捷target setting流程提交控制 start ******************* */ +window.workflowCus = Object.assign(window.workflowCus ? window.workflowCus : {}, { + /** + * @author youhong.ai + * @desc 禁止点击提交按钮 + */ + doNotClickSubmit: function () { + let submitButton = $('.ant-btn.ant-btn-primary[ecid="_Route@vmt0lk_Comp@upn4fo_Button@2oxqe7@0_button@xq1ea3"][title="Submit "]') + if (submitButton.length === 0) { + submitButton = $('.ant-btn.ant-btn-primary[ecid="_Route@vmt0lk_Comp@upn4fo_Button@2oxqe7@0_button@xq1ea3"][title="提交"]') + } + if (submitButton.length === 0) { + submitButton = $("#weareqtop_9v5e5i_1670481049632 div.ant-row.wea-new-top-req div.ant-col-xs-18.ant-col-sm-18.ant-col-md-16.ant-col-lg-14 button[title='提交'],[title='Submit '],[title='Submit']") + } + if (submitButton.length !== 0) { + let buttonReact = window.Utils.findReact(submitButton[0]) + let rightBtn = Utils.findReact($(".ant-menu-item.text-elli[ecid='_Route@vmt0lk_Comp@upn4fo_WeaRightMenu@1ok9r0_Item@eu37n0_li@zyccqn']")[0]) + setTimeout(() => { + buttonReact.props.disabled = true + buttonReact.setState({}) + rightBtn.props.disabled = true + rightBtn.setState({}) + }, 100) + } + }, + + /** + * @author youhong.ai + * @desc 允许点击按钮 + */ + allowClickSubmit: function () { + let submitButton = $('.ant-btn.ant-btn-primary[ecid="_Route@vmt0lk_Comp@upn4fo_Button@2oxqe7@0_button@xq1ea3"][title="Submit "]') + if (submitButton.length === 0) { + submitButton = $('.ant-btn.ant-btn-primary[ecid="_Route@vmt0lk_Comp@upn4fo_Button@2oxqe7@0_button@xq1ea3"][title="提交"]') + } + if (submitButton.length === 0) { + submitButton = $("#weareqtop_9v5e5i_1670481049632 div.ant-row.wea-new-top-req div.ant-col-xs-18.ant-col-sm-18.ant-col-md-16.ant-col-lg-14 button[title='提交'],[title='Submit '],[title='Submit']") + } + if (submitButton.length !== 0) { + WfForm.controlBtnDisabled(false) + let buttonReact = window.Utils.findReact(submitButton[0]) + buttonReact.props.disabled = false + buttonReact.setState({}) + } + }, + + /** + * 监听qzhj字段值改变 + * @author youhong.ai + * @param id 字段id + * @param value 字段值 + * @param obj 字段值对象 + */ + onQzhjFieldChangeValue: function (obj, id, value) { + if (value != '100') { + window.workflowCus.doNotClickSubmit() + } else { + window.workflowCus.allowClickSubmit() + } + }, + + /** + * 检查qzhj字段值 + * @author youhong.ai + * @param fieldId qzhj字段id + */ + checkOnQzhJfiedlChangeValue: function (fieldId) { + let value = WfForm.getFieldValue(fieldId); + window.workflowCus.onQzhjFieldChangeValue(null, null, value) + }, + + + /** + * 检查提交按钮是否符合条件 + * @author youhong.ai + * @param fieldId 字段id + * @returns {(function(function()=): void)|*} + */ + checkClickSubmit: function (fieldId) { + return (callback = () => { + }) => { + let value = WfForm.getFieldValue(fieldId); + if (value != 100) { + WfForm.showMessage("~`~`7 目标设定的总值必须是100%,请检查并修改后提交。 " + "`~`8 The total value of target setting must be 100%,please check to submit after modification! " + "`~`9 目标设定的总值必须是100%,请检查并修改后提交。`~`~", 2, 5); + } else { + callback() + } + } + }, + + /** + * 保存按钮触发流程转数据 + * @author youhong.ai + */ + saveTriggerWorkflowToModel: async function () { + let baseInfo = WfForm.getBaseInfo() + if (baseInfo && baseInfo.requestid != '-1') { + let result = await Utils.api({ + url: "/api/aiyh/workflow/target-setting/save-trigger", + type: "POST", + contentType: "application/json", + data: JSON.stringify({ + requestId: baseInfo.requestid, + nodeId: baseInfo.nodeid, + isBill: baseInfo.isbill, + formId: baseInfo.formid, + workflowId: baseInfo.workflowid + }) + }) + if (result && result.code === 200) { + localStorage.setItem("saveTriggerWorkflowToModel", "false") + } + } + }, + + + saveAfterCallback: function (callback) { + localStorage.setItem("saveTriggerWorkflowToModel", "true") + callback() + } + +}) + +/* ******************* 保时捷target setting流程提交控制 end ******************* */ + +/* ******************* 保时捷target setting流程提交控制 start ******************* */ +$(() => { + let qzhjFieldId = WfForm.convertFieldNameToId("qzhj") + window.workflowCus.checkOnQzhJfiedlChangeValue(qzhjFieldId) + WfForm.registerCheckEvent(WfForm.OPER_SUBMIT, window.workflowCus.checkClickSubmit(qzhjFieldId)) + WfForm.registerCheckEvent(WfForm.OPER_SAVECOMPLETE, window.workflowCus.saveAfterCallback) + WfForm.bindFieldChangeEvent(qzhjFieldId, window.workflowCus.onQzhjFieldChangeValue) + let flag = localStorage.getItem("saveTriggerWorkflowToModel") + if (flag === "true") { + window.workflowCus.saveTriggerWorkflowToModel() + } +}) + +/* ******************* 保时捷target setting流程提交控制 end ******************* */ + + +/* ******************* 保时捷个人目标台账查询target setting按钮默认置灰色 ******************* */ +window.workflowCus = Object.assign(window.workflowCus ? window.workflowCus : {}, { + + notAllowedTargetSetting: function () { + window.workflowCus.changeBtnDisabledValue(true) + }, + + changeBtnDisabledValue: function (disable) { + if ($(".ant-btn.ant-btn-primary[ecid='_Route@9uoqid_Com@knmejd_ButtonNew@813let@0_Button@tegwjx_button@xq1ea3']").length === 0) { + return + } + let button = Utils.findReact($(".ant-btn.ant-btn-primary[ecid='_Route@9uoqid_Com@knmejd_ButtonNew@813let@0_Button@tegwjx_button@xq1ea3']")[0]) + if (button) { + button.props.disabled = disable + button.setState({}) + } + }, + + allowedTargetSettingBtnClick: function () { + window.workflowCus.changeBtnDisabledValue(false) + }, + + queryTotalWeight: function () { + Utils.api({ + url: "/api/ayh/target-setting/btn/can-allowed" + }).then(res => { + if (res && res.code === 200) { + if (res.data) { + window.workflowCus.allowedTargetSettingBtnClick() + } else { + window.workflowCus.notAllowedTargetSetting() + } + } + }).catch(error => { + console.log(err) + }) + }, + + reRender: function () { + const dataHandle = function (datas, displayType) { + window.workflowCus.notAllowedTargetSetting() + //Changes to 'datas' do not directly modify the real database data, but modify the data received at the front end. + $(() => { + window.workflowCus.queryTotalWeight() + }) + return datas + + } + ModeList.dataLoadAfter(dataHandle) + } + +}) + +$(() => { + window.workflowCus.notAllowedTargetSetting() + setTimeout(() => { + window.workflowCus.notAllowedTargetSetting() + }, 10) + window.workflowCus.reRender() +}) +/* ******************* 保时捷个人目标台账查询target setting按钮默认置灰色 END ******************* */ + + +/* ******************* apa流程通过apa分数字段带出level字段 ******************* */ + +window.workflowCus = Object.assign(window.workflowCus ? window.workflowCus : {}, { + getLevelByScore: async function (config) { + let scoreFiled = config.scoreFiled + let score = Utils.getFiledValueByName(scoreFiled); + let result = await Utils.api({ + url: "/api/ayh/workflow/apa/level", + data: { + score + } + }) + if (result && result.code === 200) { + Utils.changeFieldValueByName(config.levelField, result.data) + } + } +}) +/* ******************* apa流程通过apa分数字段带出level字段eng ******************* */ + + +/* ******************* apa流程通过apa分数字段带出level字段 ******************* */ +$(() => { + let config = { + scoreFiled: "", + levelField: "" + } + window.workflowCus.getLevelByScore(config) +}) + +/* ******************* apa流程通过apa分数字段带出level字段eng ******************* */ diff --git a/pom.xml b/pom.xml index 64e83b1..348d3ae 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 @@ -56,8 +56,8 @@ ${lombok.version} provided - - + + junit @@ -65,7 +65,20 @@ 4.12 - + + + + com.alibaba + easyexcel + 2.2.0-beta1 + + + org.slf4j + slf4j-api + + + + diff --git a/src/main/java/aiyh/utils/LabelHtmlUtils.java b/src/main/java/aiyh/utils/LabelHtmlUtils.java index a74186d..ed5759b 100644 --- a/src/main/java/aiyh/utils/LabelHtmlUtils.java +++ b/src/main/java/aiyh/utils/LabelHtmlUtils.java @@ -10,9 +10,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * @author EBU7-dev1-ayh - * create 2021/12/13 0013 10:29 - * 多语言工具类 + *

多语言工具类

+ * + * @author EBU7-dev1-ayh create 2021/12/13 0013 10:29 */ diff --git a/src/main/java/aiyh/utils/MybatisUtil.java b/src/main/java/aiyh/utils/MybatisUtil.java index 69cdbc5..2c3f0d5 100644 --- a/src/main/java/aiyh/utils/MybatisUtil.java +++ b/src/main/java/aiyh/utils/MybatisUtil.java @@ -7,24 +7,26 @@ import java.io.File; import java.io.Reader; /** - * @author EBU7-dev1-ayh - * create 2021/12/14 0014 15:57 + *

mybatis集成工具

+ * + * @author EBU7-dev1-ayh create 2021/12/14 0014 15:57 */ public class MybatisUtil { private static SqlSessionManager sqlSessionManager = null; - private synchronized static void init(String config){ + private synchronized static void init(String config) { try { - Reader resourceAsReader = Resources.getResourceAsReader("WEB-INF" + File.separator +config); + Reader resourceAsReader = Resources.getResourceAsReader("WEB-INF" + File.separator + config); sqlSessionManager = SqlSessionManager.newInstance(resourceAsReader); } catch (Exception e) { e.printStackTrace(); } } - public static SqlSessionManager getSessionManager(String config){ - if(sqlSessionManager == null){ + + public static SqlSessionManager getSessionManager(String config) { + if (sqlSessionManager == null) { synchronized (MybatisUtil.class) { if (sqlSessionManager == null) { init(config); @@ -34,7 +36,7 @@ public class MybatisUtil { return sqlSessionManager; } - public static T getMapper(Class tClass){ + public static T getMapper(Class tClass) { return sqlSessionManager.getMapper(tClass); } } diff --git a/src/main/java/aiyh/utils/Util.java b/src/main/java/aiyh/utils/Util.java index ba2fa40..9e9a5dc 100644 --- a/src/main/java/aiyh/utils/Util.java +++ b/src/main/java/aiyh/utils/Util.java @@ -73,8 +73,7 @@ import java.util.zip.ZipEntry; /** * @author EBU7-dev1-ayh - * @date 2021/8/23 0023 11:42 - * mybatisTest.dao 工具类 + * @date 2021/8/23 0023 11:42 mybatisTest.dao 工具类 */ @@ -91,16 +90,15 @@ public class Util extends weaver.general.Util { public static final char UNICODE_END = 65374; public static final char DBC_SBC_STEP = 65248; // 全角半角转换间隔 public static final ExecutorService threadPool = ThreadPoolConfig.createThreadPoolInstance(); + public static final String UF_CUS_DEV_CONFIG = "uf_cus_dev_config"; private static final UtilService utilService = new UtilService(); private static final RecordsetUtil recordsetUtil = new RecordsetUtil(); private static final UtilMapper mapper = recordsetUtil.getMapper(UtilMapper.class); - public static final String UF_CUS_DEV_CONFIG = "uf_cus_dev_config"; + private static final Map otherLog = new HashMap<>(8); static ToolUtil toolUtil = new ToolUtil(); private static RecordSet rs; private static volatile Logger log = null; - private static final Map otherLog = new HashMap<>(8); - static { try { rs = new RecordSet(); @@ -188,7 +186,7 @@ public class Util extends weaver.general.Util { String str = sqlBuilder.toString().trim(); String removeSeparator = ","; if (str.endsWith(removeSeparator)) { -// 如果以分割号结尾,则去除分割号 + // 如果以分割号结尾,则去除分割号 str = str.substring(0, str.length() - 1); } if (str.trim().startsWith(removeSeparator)) { @@ -207,7 +205,7 @@ public class Util extends weaver.general.Util { public static String removeSeparator(StringBuilder sqlBuilder, String removeSeparator) { String str = sqlBuilder.toString().trim(); if (str.endsWith(removeSeparator)) { -// 如果以分割号结尾,则去除分割号 + // 如果以分割号结尾,则去除分割号 str = str.substring(0, str.length() - 1); } if (str.trim().startsWith(removeSeparator)) { @@ -226,7 +224,7 @@ public class Util extends weaver.general.Util { public static String removeSeparator(String string, String removeSeparator) { String str = string.trim(); if (str.endsWith(removeSeparator)) { -// 如果以分割号结尾,则去除分割号 + // 如果以分割号结尾,则去除分割号 str = str.substring(0, str.length() - 1); } if (str.trim().startsWith(removeSeparator)) { @@ -1214,8 +1212,8 @@ public class Util extends weaver.general.Util { inputStream = new BufferedInputStream(new FileInputStream(path)); is = new InputStreamReader(inputStream, StandardCharsets.UTF_8); prop.load(is); -// Enumeration enumeration = prop.propertyNames(); -// 顺序读取 + // Enumeration enumeration = prop.propertyNames(); + // 顺序读取 Enumeration enumeration = prop.keys(); while (enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); @@ -1258,7 +1256,7 @@ public class Util extends weaver.general.Util { Pattern compile = Pattern.compile(objRegex); Matcher matcher = compile.matcher(key); if (matcher.find()) { -// 只匹配前缀.key=value模式的 + // 只匹配前缀.key=value模式的 String resultKey = matcher.group("key"); preResult.put(resultKey, prop2MapPutValue(value)); } @@ -1266,7 +1264,7 @@ public class Util extends weaver.general.Util { compile = Pattern.compile(moreKey); matcher = compile.matcher(key); if (matcher.find()) { -// 匹配前缀.key1.key2=value模式的 + // 匹配前缀.key1.key2=value模式的 String objKey = matcher.group("objKey"); String prefixStr = prePrefix + "." + objKey; Map valueMap; @@ -1284,11 +1282,11 @@ public class Util extends weaver.general.Util { compile = Pattern.compile(strList); matcher = compile.matcher(key); if (matcher.find()) { -// 匹配前缀.key[0]=value模式的 + // 匹配前缀.key[0]=value模式的 String objKey = matcher.group("key"); int index = Integer.parseInt(matcher.group("index")); if (preResult.containsKey(objKey)) { -// 存在值 + // 存在值 List valueList = (List) preResult.get(objKey); if (index >= valueList.size()) { valueList.add(prop2MapPutValue(value)); @@ -1303,19 +1301,19 @@ public class Util extends weaver.general.Util { return null; } String objArray = "^(" + prePrefix + "\\.)(?(\\w+))(\\[(?([0-9])+)])\\.(?(\\S)+)$"; -// String objArray = "^("+prePrefix+"\\.)(?(\\w+))(\\[(?([0-9])+)])(\\.(?(\\S)+))+"; + // String objArray = "^("+prePrefix+"\\.)(?(\\w+))(\\[(?([0-9])+)])(\\.(?(\\S)+))+"; compile = Pattern.compile(objArray); matcher = compile.matcher(key); if (matcher.find()) { -// 匹配前缀.key[0].name=value的模式 + // 匹配前缀.key[0].name=value的模式 String arrKey = matcher.group("arrKey"); String objKey = matcher.group("objKey"); int index = Integer.parseInt(matcher.group("index")); List> mapList; if (preResult.containsKey(arrKey)) { -// 存在 + // 存在 mapList = (List>) preResult.get(arrKey); -// mapList + // mapList Map valueMap; if (index >= mapList.size()) { valueMap = new HashMap<>(); @@ -1348,7 +1346,7 @@ public class Util extends weaver.general.Util { int arrMoreIndex = Integer.parseInt(arrMoreKeyMatcher.group("index")); List arrMoreListValue; if (valueMap.containsKey(arrMoreArrKey)) { -// 存在值 + // 存在值 arrMoreListValue = (List) valueMap.get(arrMoreArrKey); if (arrMoreIndex >= arrMoreListValue.size()) { arrMoreListValue.add(prop2MapPutValue(value)); @@ -1363,11 +1361,11 @@ public class Util extends weaver.general.Util { return null; } -// 直接添加 + // 直接添加 valueMap.put(objKey, prop2MapPutValue(value)); return null; } -// 不存在 + // 不存在 mapList = new ArrayList<>(); Map valueMap = new HashMap<>(); valueMap.put(objKey, prop2MapPutValue(value)); @@ -1496,7 +1494,7 @@ public class Util extends weaver.general.Util { // private static Predicate distinctByKey(Function keyExtractor) { Map seen = new ConcurrentHashMap<>(); -// putIfAbsent添加不存在的键,返回null,如果为null表示不重复 + // putIfAbsent添加不存在的键,返回null,如果为null表示不重复 return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; } @@ -1587,7 +1585,7 @@ public class Util extends weaver.general.Util { for (int i = 0; i < inputList.size(); i++) { T item = inputList.get(i); if (item instanceof InputStream) { -// 属于单级文件,直接压缩并返回 + // 属于单级文件,直接压缩并返回 try { zipOut.putNextEntry(new ZipEntry(base + i)); } catch (IOException e) { @@ -1620,7 +1618,7 @@ public class Util extends weaver.general.Util { if (item instanceof ListZipEntity) { ListZipEntity listZipEntity = (ListZipEntity) item; if (listZipEntity.isDirectory()) { -// 表示属于文件夹,循环添加处理文件夹 + // 表示属于文件夹,循环添加处理文件夹 handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator); } else { List aInputStreams = listZipEntity.getaInputStreamList(); @@ -1651,7 +1649,7 @@ public class Util extends weaver.general.Util { int catchLen = 10 * 1024; for (ListZipEntity listZipEntity : fileList) { if (listZipEntity.isDirectory()) { -// 如果是文件夹 + // 如果是文件夹 handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator); } else { List aInputStreams = listZipEntity.getaInputStreamList(); @@ -1761,8 +1759,8 @@ public class Util extends weaver.general.Util { @Deprecated public static String getDocCategorysById(String workflowId, String docFieldId) { RecordSet rs = new RecordSet(); -// rs.executeQuery("select formid from workflow_base where id = ?",workflowId); -// String formId = Util.recordeSet2Entity(rs, String.class); + // rs.executeQuery("select formid from workflow_base where id = ?",workflowId); + // String formId = Util.recordeSet2Entity(rs, String.class); String query = "select doccategory from workflow_fileupload where workflowid = ? and fieldid = ?"; rs.executeQuery(query, workflowId, docFieldId); String docCategorys = Util.null2String(Util.recordeSet2Entity(rs, String.class)); @@ -2082,6 +2080,7 @@ public class Util extends weaver.general.Util { appender.setAppend(true); appender.activateOptions(); log.addAppender(appender); + log.setAdditivity(false); log.setLevel(Level.INFO); /* boolean enableDebug = false; @@ -2129,6 +2128,7 @@ public class Util extends weaver.general.Util { appender.setAppend(true); appender.activateOptions(); cusLog.addAppender(appender); + cusLog.setAdditivity(false); /* boolean enableDebug = false; try { @@ -2305,7 +2305,7 @@ public class Util extends weaver.general.Util { continue; } dataMap.put(id, item); -// 判断是否属于根节点,如果是根节点,则将数据添加到树中 + // 判断是否属于根节点,如果是根节点,则将数据添加到树中 if (predicate.test(parentId)) { if (childMap.containsKey(id)) { continue; @@ -2313,29 +2313,29 @@ public class Util extends weaver.general.Util { treeList.add(item); childMap.put(id, item); } else { -// 如果不是根节点,则通过id查找到父级 + // 如果不是根节点,则通过id查找到父级 T parent = dataMap.get(parentId); if (Objects.isNull(parent)) { -// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止 + // 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止 List list = buildTree(dataList, dataMap, childMap, index, getIdFn, getParentId, setChildFn, predicate); parent = dataMap.get(parentId); if (Objects.isNull(parent)) { -// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中 + // 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中 treeList.add(item); } else { -// 如果找到了父节点,则将自己挂到父节点上 + // 如果找到了父节点,则将自己挂到父节点上 if (childMap.containsKey(id)) { continue; } setChildFn.accept(parent, item); childMap.put(id, item); } -// 如果查找的list不为空并且有值,那就说明属于根节点 + // 如果查找的list不为空并且有值,那就说明属于根节点 if (list != null && list.size() > 0) { treeList.addAll(list); } } else { -// 如果找到了父节点,则将自己挂到父节点上 + // 如果找到了父节点,则将自己挂到父节点上 if (childMap.containsKey(id)) { continue; } @@ -2377,7 +2377,7 @@ public class Util extends weaver.general.Util { continue; } dataMap.put(id, item); -// 判断是否属于根节点,如果是根节点,则将数据添加到树中 + // 判断是否属于根节点,如果是根节点,则将数据添加到树中 if (predicate.test(parentId)) { if (childMap.containsKey(id)) { continue; @@ -2385,17 +2385,17 @@ public class Util extends weaver.general.Util { treeList.add(item); childMap.put(id, item); } else { -// 如果不是根节点,则通过id查找到父级 + // 如果不是根节点,则通过id查找到父级 T parent = dataMap.get(parentId); if (Objects.isNull(parent)) { -// 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止 + // 如果父级为空,则说明他的父级还没有遍历到,需要从之后的数据进行遍历,直到找到父级为止 List list = buildTree(dataList, dataMap, childMap, index, getIdFn, getParentId, getChildFn, setChildFn, predicate); parent = dataMap.get(parentId); if (Objects.isNull(parent)) { -// 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中 + // 如果还是没有查询到父节点,则表明是顶层节点,将他添加到顶层节点中 treeList.add(item); } else { -// 如果找到了父节点,则将自己挂到父节点上 + // 如果找到了父节点,则将自己挂到父节点上 if (childMap.containsKey(id)) { continue; } @@ -2404,12 +2404,12 @@ public class Util extends weaver.general.Util { setChildFn.accept(parent, childList); childMap.put(id, item); } -// 如果查找的list不为空并且有值,那就说明属于根节点 + // 如果查找的list不为空并且有值,那就说明属于根节点 if (list != null && list.size() > 0) { treeList.addAll(list); } } else { -// 如果找到了父节点,则将自己挂到父节点上 + // 如果找到了父节点,则将自己挂到父节点上 if (childMap.containsKey(id)) { continue; } @@ -2470,7 +2470,7 @@ public class Util extends weaver.general.Util { throw new RuntimeException("invoke method err, cant not invoke method set" + name.substring(0, 1).toUpperCase() + name.substring(1)); } } -// TODO 复制bean + // TODO 复制bean return target; } @@ -3072,20 +3072,25 @@ public class Util extends weaver.general.Util { Matcher matcher = compile.matcher(logStr); int n = 0; while (matcher.find()) { + if (n + 1 > args.length) { + break; + } logStr = logStr.replaceFirst(pattern, "{" + n++ + "}"); } - Object arg = args[args.length - 1]; - if (arg instanceof Throwable) { - for (int i = 0; i < args.length - 1; i++) { - pattern = "\\{" + i + "}"; - logStr = logStr.replaceFirst(pattern, String.valueOf(args[i].toString())); + try { + Object arg = args[args.length - 1]; + if (arg instanceof Throwable) { + for (int i = 0; i < args.length - 1; i++) { + pattern = "\\{" + i + "}"; + logStr = logStr.replaceFirst(pattern, Matcher.quoteReplacement(String.valueOf(args[i]))); + } + return logStr + "\n" + getErrString((Throwable) arg); } - return logStr + "\n" + getErrString((Throwable) arg); + } catch (Exception ignore) { } - int i = 0; - for (Object o : args) { - pattern = "\\{" + i++ + "}"; - logStr = logStr.replaceFirst(pattern, String.valueOf(o)); + for (int i = 0; i < args.length; i++) { + pattern = "\\{" + i + "}"; + logStr = logStr.replaceFirst(pattern, Matcher.quoteReplacement(String.valueOf(args[i]))); } return logStr; } catch (Exception e) { @@ -3231,7 +3236,7 @@ public class Util extends weaver.general.Util { action = cronJobClass.newInstance(); if (declaredFields.length > 0) { for (Field declaredField : declaredFields) { -// 必填参数验证 + // 必填参数验证 boolean hasRequiredMark = declaredField.isAnnotationPresent(RequiredMark.class); String name = declaredField.getName(); String setMethodName = getSetMethodName(name); @@ -3312,7 +3317,7 @@ public class Util extends weaver.general.Util { action = actionClass.newInstance(); if (declaredFields.length > 0) { for (Field declaredField : declaredFields) { -// 必填参数验证 + // 必填参数验证 boolean hasRequiredMark = declaredField.isAnnotationPresent(RequiredMark.class); String name = declaredField.getName(); String setMethodName = getSetMethodName(name); @@ -3432,7 +3437,7 @@ public class Util extends weaver.general.Util { String classPath = split[0]; String paramStr = ""; if (split.length > 1) { - paramStr = Arrays.stream(split).skip(1).collect(Collectors.joining("")); + 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}&" + @@ -3460,11 +3465,13 @@ public class Util extends weaver.general.Util { 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]+))=(?((#(\\{|sql\\{))?([()\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?))&?"; + // 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类,将参数传递给这个类, + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + // "(?(`([\\s():/\\t\\-&*'?$#={ }.\\w\\u4E00-\\u9FA5]*)`|" + + // "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + - "(?((`([():/\\-&$#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" + - "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + "(?(`([^`]*)`|" + + "((#(\\{|sql\\{))?([():/\\-$_*#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; Pattern compile = Pattern.compile(pattern); Matcher matcher = compile.matcher(paramStr); Map pathParamMap = new HashMap<>(8); @@ -3472,6 +3479,9 @@ public class Util extends weaver.general.Util { while (matcher.find()) { String key = matcher.group("key"); String paramValue = matcher.group("value"); + if (paramValue.startsWith("`") && paramValue.endsWith("`")) { + paramValue = paramValue.substring(1, paramValue.length() - 1); + } pathParamMap.put(key, paramValue); } return pathParamMap; diff --git a/src/main/java/aiyh/utils/action/CusBaseAction.java b/src/main/java/aiyh/utils/action/CusBaseAction.java index a6c836e..91a2f07 100644 --- a/src/main/java/aiyh/utils/action/CusBaseAction.java +++ b/src/main/java/aiyh/utils/action/CusBaseAction.java @@ -19,6 +19,7 @@ import java.util.*; * * @author EBU7-dev-1 aiyh */ +@Deprecated public abstract class CusBaseAction implements Action { /** @@ -30,31 +31,36 @@ public abstract class CusBaseAction implements Action { * 全局requestInfo对象 */ protected RequestInfo globalRequestInfo; + /** + *

线程局部变量

+ **/ + protected static ThreadLocal requestInfoThreadLocal = new ThreadLocal<>(); /** *

初始化流程默认的处理方法

*/ private void initHandleMethod() { -// 提交 + // 提交 actionHandleMethod.put(ActionRunType.SUBMIT, this::doSubmit); -// 退回 + // 退回 actionHandleMethod.put(ActionRunType.REJECT, this::doReject); -// 撤回 + // 撤回 actionHandleMethod.put(ActionRunType.WITHDRAW, this::doWithdraw); -// 强制收回 + // 强制收回 actionHandleMethod.put(ActionRunType.DRAW_BACK, this::doDrawBack); } @Override public final String execute(RequestInfo requestInfo) { + requestInfoThreadLocal.set(requestInfo); this.globalRequestInfo = requestInfo; RequestManager requestManager = requestInfo.getRequestManager(); String billTable = requestManager.getBillTableName(); String requestId = requestInfo.getRequestid(); User user = requestInfo.getRequestManager().getUser(); int workflowId = requestManager.getWorkflowid(); -// 操作类型 submit - 提交 reject - 退回 等 + // 操作类型 submit - 提交 reject - 退回 等 String src = requestManager.getSrc(); if ("".equals(billTable)) { WorkflowComInfo workflowComInfo = new WorkflowComInfo(); @@ -67,13 +73,13 @@ public abstract class CusBaseAction implements Action { if (StringUtils.isEmpty(src)) { src = "submit"; } -// 初始化默认的流程处理方法 + // 初始化默认的流程处理方法 initHandleMethod(); -// 提供自定义注册处理方法 + // 提供自定义注册处理方法 registerHandler(actionHandleMethod); -// 获取流程对应的处理方法 + // 获取流程对应的处理方法 CusBaseActionHandleFunction cusBaseActionHandleFunction = actionHandleMethod.get(src); -// 默认没有直接成功不做拦截 + // 默认没有直接成功不做拦截 if (null == cusBaseActionHandleFunction) { return Action.SUCCESS; } @@ -90,6 +96,9 @@ public abstract class CusBaseAction implements Action { if (this.exceptionCallback(e, requestManager)) { return Action.FAILURE_AND_CONTINUE; } + }finally { + // 无论成功还是失败 都将该线程的requestInfo进行移除 + requestInfoThreadLocal.remove(); } return Action.SUCCESS; } @@ -123,8 +132,7 @@ public abstract class CusBaseAction implements Action { /** *

action 提交流程业务处理方法

*

具体业务逻辑实现 - * 全局存在log成员变量,用于日志的输出 - * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 *

* * @param requestId 流程请求ID @@ -141,8 +149,7 @@ public abstract class CusBaseAction implements Action { /** *

action 退回流程业务处理方法

*

具体业务逻辑实现 - * 全局存在log成员变量,用于日志的输出 - * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 *

* * @param requestId 流程请求ID @@ -158,8 +165,7 @@ public abstract class CusBaseAction implements Action { /** *

action 撤回、撤回流程流程业务处理方法

*

具体业务逻辑实现 - * 全局存在log成员变量,用于日志的输出 - * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 *

* * @param requestId 流程请求ID @@ -176,8 +182,7 @@ public abstract class CusBaseAction implements Action { /** *

action 强制收回流程业务处理方法

*

具体业务逻辑实现 - * 全局存在log成员变量,用于日志的输出 - * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 *

* * @param requestId 流程请求ID @@ -198,7 +203,7 @@ public abstract class CusBaseAction implements Action { */ @Deprecated protected Map getMainTableValue() { -// 获取主表数据 + // 获取主表数据 Property[] propertyArr = globalRequestInfo.getMainTableInfo().getProperty(); return getStringMap(propertyArr); } @@ -209,7 +214,7 @@ public abstract class CusBaseAction implements Action { * @return 流程主表数据 */ protected Map getMainTableValue(RequestInfo requestInfo) { -// 获取主表数据 + // 获取主表数据 Property[] propertyArr = requestInfo.getMainTableInfo().getProperty(); return getStringMap(propertyArr); } diff --git a/src/main/java/aiyh/utils/action/CusBaseActionHandleFunction.java b/src/main/java/aiyh/utils/action/CusBaseActionHandleFunction.java index 1a8b86a..ac80efc 100644 --- a/src/main/java/aiyh/utils/action/CusBaseActionHandleFunction.java +++ b/src/main/java/aiyh/utils/action/CusBaseActionHandleFunction.java @@ -10,6 +10,7 @@ import weaver.workflow.request.RequestManager; *

create: 2022-07-23 18:05

*/ +@Deprecated @FunctionalInterface public interface CusBaseActionHandleFunction { /** diff --git a/src/main/java/aiyh/utils/action/SafeCusBaseAction.java b/src/main/java/aiyh/utils/action/SafeCusBaseAction.java new file mode 100644 index 0000000..c638269 --- /dev/null +++ b/src/main/java/aiyh/utils/action/SafeCusBaseAction.java @@ -0,0 +1,288 @@ +package aiyh.utils.action; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import weaver.hrm.User; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.*; +import weaver.workflow.request.RequestManager; +import weaver.workflow.workflow.WorkflowBillComInfo; +import weaver.workflow.workflow.WorkflowComInfo; + +import java.util.*; + +/** + *

基础的action,实现一些基础的参数

+ * + * @author EBU7-dev-1 aiyh + */ +public abstract class SafeCusBaseAction implements Action { + + + /** + * 全局日志对象 + */ + protected final Logger log = Util.getLogger(); + private final Map actionHandleMethod = new HashMap<>(); + + /** + *

初始化流程默认的处理方法

+ */ + private void initHandleMethod() { + // 提交 + actionHandleMethod.put(ActionRunType.SUBMIT, this::doSubmit); + // 退回 + actionHandleMethod.put(ActionRunType.REJECT, this::doReject); + // 撤回 + actionHandleMethod.put(ActionRunType.WITHDRAW, this::doWithdraw); + // 强制收回 + actionHandleMethod.put(ActionRunType.DRAW_BACK, this::doDrawBack); + } + + + @Override + public final String execute(RequestInfo requestInfo) { + RequestManager requestManager = requestInfo.getRequestManager(); + String billTable = requestManager.getBillTableName(); + String requestId = requestInfo.getRequestid(); + User user = requestInfo.getRequestManager().getUser(); + int workflowId = requestManager.getWorkflowid(); + // 操作类型 submit - 提交 reject - 退回 等 + String src = requestManager.getSrc(); + if ("".equals(billTable)) { + WorkflowComInfo workflowComInfo = new WorkflowComInfo(); + String formId = workflowComInfo.getFormId(String.valueOf(workflowId)); + WorkflowBillComInfo workflowBillComInfo = new WorkflowBillComInfo(); + billTable = workflowBillComInfo.getTablename(formId); + } + try { + Util.verifyRequiredField(this); + if (StringUtils.isEmpty(src)) { + src = "submit"; + } + // 初始化默认的流程处理方法 + initHandleMethod(); + // 提供自定义注册处理方法 + registerHandler(actionHandleMethod); + // 获取流程对应的处理方法 + SafeCusBaseActionHandleFunction cusBaseActionHandleFunction = actionHandleMethod.get(src); + // 默认没有直接成功不做拦截 + if (null == cusBaseActionHandleFunction) { + return Action.SUCCESS; + } + cusBaseActionHandleFunction.handle(requestId, billTable, workflowId, user, requestInfo); + } catch (CustomerException e) { + if (e.getCode() != null && e.getCode() == 500) { + Util.actionFail(requestManager, e.getMessage()); + return Action.FAILURE_AND_CONTINUE; + } + if (this.exceptionCallback(e, requestManager)) { + return Action.FAILURE_AND_CONTINUE; + } + } catch (Exception e) { + if (this.exceptionCallback(e, requestManager)) { + return Action.FAILURE_AND_CONTINUE; + } + } + return Action.SUCCESS; + } + + + /** + *

程序执行异常回调

+ * + * @param e 异常信息 + * @param requestManager requestManager对象 + * @return 是否阻止action往下提交,true- 阻止, false-放行 + */ + public boolean exceptionCallback(Exception e, RequestManager requestManager) { + e.printStackTrace(); + log.error(Util.logStr("getDataId action fail, exception message is [{}], error stack trace msg is: \n{}", + e.getMessage(), Util.getErrString(e))); + Util.actionFail(requestManager, e.getMessage()); + return true; + } + + + /** + *

流程其他流转类型处理方法注册

+ * + * @param actionHandleMethod 处理方法对应map + */ + public void registerHandler(Map actionHandleMethod) { + } + + + /** + *

action 提交流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestInfo 请求管理对象 + */ + + public abstract void doSubmit(String requestId, String billTable, int workflowId, + User user, RequestInfo requestInfo); + + + /** + *

action 退回流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestInfo 请求管理对象 + */ + public void doReject(String requestId, String billTable, int workflowId, + User user, RequestInfo requestInfo) { + } + + /** + *

action 撤回、撤回流程流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestInfo 请求管理对象 + */ + public void doWithdraw(String requestId, String billTable, int workflowId, + User user, RequestInfo requestInfo) { + } + + + /** + *

action 强制收回流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestInfo 请求管理对象 + */ + public void doDrawBack(String requestId, String billTable, int workflowId, + User user, RequestInfo requestInfo) { + } + + /** + *

获取流程主表数据

+ * + * @return 流程主表数据 + */ + protected Map getMainTableValue(RequestInfo requestInfo) { + // 获取主表数据 + Property[] propertyArr = requestInfo.getMainTableInfo().getProperty(); + return getStringMap(propertyArr); + } + + @NotNull + private Map getStringMap(Property[] propertyArr) { + 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(); + return getListMap(detailTableArr); + } + + + @NotNull + private Map>> getListMap(DetailTable[] detailTableArr) { + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 1.4)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + + /** + *

获取指定明细表的表数据

+ * + * @param detailNo 明细表编号 + * @return 明细数据 + */ + protected List> getDetailTableValueByDetailNo(int detailNo, RequestInfo requestInfo) { + DetailTable detailTable = requestInfo.getDetailTableInfo().getDetailTable(detailNo); + return getDetailValue(detailTable); + } + + /** + *

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

+ * + * @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 * (1 + 0.4))); + rowData.put("id", row.getId()); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } + + + public static final class ActionRunType { + /** + * 退回 + */ + public static final String REJECT = "reject"; + /** + * 撤回 + */ + public static final String WITHDRAW = "withdraw"; + /** + * 强制收回 + */ + public static final String DRAW_BACK = "drawBack"; + /** + * 提交 + */ + public static final String SUBMIT = "submit"; + } + +} diff --git a/src/main/java/aiyh/utils/action/SafeCusBaseActionHandleFunction.java b/src/main/java/aiyh/utils/action/SafeCusBaseActionHandleFunction.java new file mode 100644 index 0000000..4785ab1 --- /dev/null +++ b/src/main/java/aiyh/utils/action/SafeCusBaseActionHandleFunction.java @@ -0,0 +1,26 @@ +package aiyh.utils.action; + +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; + +/** + *

流程类型处理方法

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

create: 2022-07-23 18:05

+ */ + +@FunctionalInterface +public interface SafeCusBaseActionHandleFunction { + /** + *

流程处理方法action

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestInfo 请求管理对象 + */ + void handle(String requestId, String billTable, int workflowId, + User user, RequestInfo requestInfo); +} diff --git a/src/main/java/aiyh/utils/httpUtil/ResponeVo.java b/src/main/java/aiyh/utils/httpUtil/ResponeVo.java index 9174466..6f07cbb 100644 --- a/src/main/java/aiyh/utils/httpUtil/ResponeVo.java +++ b/src/main/java/aiyh/utils/httpUtil/ResponeVo.java @@ -2,11 +2,11 @@ package aiyh.utils.httpUtil; import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.http.Header; +import org.apache.http.*; +import org.apache.http.params.HttpParams; import java.io.InputStream; import java.util.List; @@ -15,34 +15,44 @@ import java.util.Map; /** * @author EBU7-dev1-ayh - * @date 2021/8/31 0031 17:16 - * http请求相应 + * @date 2021/8/31 0031 17:16 http请求相应 */ -public class ResponeVo { - /** - * 相应状态码 - */ - private int code; - /** - * 相应内容 - */ - private String entityString; - /** - * 相应头信息 - */ - @JSONField(serialize = false) - private Header[] allHeaders; - private Locale locale; +public class ResponeVo implements HttpResponse { + /** + * 相应状态码 + */ + private int code; + /** + * 相应内容 + */ + private String entityString; + /** + * 相应头信息 + */ + + private Locale locale; private InputStream content; private byte[] contentByteArr; - private Map requestData; - public int getCode() { - return code; - } + private Map requestData; + + + private HttpResponse response; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public void setResponse(HttpResponse response) { + this.response = response; + } public Map getRequestData() { return requestData; @@ -53,30 +63,32 @@ public class ResponeVo { } /** - * 根据相应结果转化为map集合 - * @return 资源皇后的map集合 - * @throws JsonProcessingException JSON转换异常 - */ - public Map getEntityMap() throws JsonProcessingException { - ObjectMapper mapper = new ObjectMapper(); - return mapper.readValue(this.getEntityString(), Map.class); - } + * 根据相应结果转化为map集合 + * + * @return 资源皇后的map集合 + * @throws JsonProcessingException JSON转换异常 + */ + public Map getEntityMap() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(this.getEntityString(), Map.class); + } - /** - * 根据相应结果,转化为实体类 - * @param clazz 需要映射的实体类 - * @param 需要转换实体类的泛型 - * @return 转换后的实体类 - * @throws JsonProcessingException JSON转换异常 - */ - public T getEntity(Class clazz) throws JsonProcessingException { + /** + * 根据相应结果,转化为实体类 + * + * @param clazz 需要映射的实体类 + * @param 需要转换实体类的泛型 + * @return 转换后的实体类 + * @throws JsonProcessingException JSON转换异常 + */ + public T getEntity(Class clazz) throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); return mapper.readValue(this.getEntityString(), clazz); } - /** * 根据相应结果,转化为实体类 + * * @param 需要转换实体类的泛型处理器 * @return 转换后的实体类 * @throws JsonProcessingException JSON转换异常 @@ -86,48 +98,167 @@ public class ResponeVo { return mapper.readValue(this.getEntityString(), typeReference); } - /** - * 根据相应结果转化为实体集合 - * @param clazz 需要映射的实体类 - * @param 需要转换的实体类的泛型 - * @return 转换后的实体类的集合 - */ - public List getEntityArray(Class clazz) { - return JSON.parseArray(this.getEntityString(), clazz); - } + /** + * 根据相应结果转化为实体集合 + * + * @param clazz 需要映射的实体类 + * @param 需要转换的实体类的泛型 + * @return 转换后的实体类的集合 + */ + public List getEntityArray(Class clazz) { + return JSON.parseArray(this.getEntityString(), clazz); + } - public Locale getLocale() { - return locale; - } + @Override + public StatusLine getStatusLine() { + return this.response.getStatusLine(); + } - public void setLocale(Locale locale) { - this.locale = locale; - } + @Override + public void setStatusLine(StatusLine statusLine) { - public void setCode(int code) { - this.code = code; - } + } - public Header[] getAllHeaders() { - return allHeaders; - } + @Override + public void setStatusLine(ProtocolVersion protocolVersion, int i) { - public void setAllHeaders(Header[] allHeaders) { - this.allHeaders = allHeaders; - } + } - public String getEntityString() { - return entityString; - } + @Override + public void setStatusLine(ProtocolVersion protocolVersion, int i, String s) { - public void setEntityString(String entityString) { - this.entityString = entityString; - } + } + + @Override + public void setStatusCode(int i) throws IllegalStateException { + + } + + @Override + public void setReasonPhrase(String s) throws IllegalStateException { + + } + + @Override + public HttpEntity getEntity() { + return null; + } + + @Override + public void setEntity(HttpEntity httpEntity) { + + } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + @Override + public ProtocolVersion getProtocolVersion() { + return this.response.getProtocolVersion(); + } + + @Override + public boolean containsHeader(String s) { + return response.containsHeader(s); + } + + @Override + public Header[] getHeaders(String s) { + return response.getHeaders(s); + } + + @Override + public Header getFirstHeader(String s) { + return response.getFirstHeader(s); + } + + @Override + public Header getLastHeader(String s) { + return response.getLastHeader(s); + } + + public Header[] getAllHeaders() { + return response.getAllHeaders(); + } + + @Override + public void addHeader(Header header) { + + } + + @Override + public void addHeader(String s, String s1) { + + } + + @Override + public void setHeader(Header header) { + + } + + @Override + public void setHeader(String s, String s1) { + + } + + @Override + public void setHeaders(Header[] headers) { + + } + + @Override + public void removeHeader(Header header) { + + } + + @Override + public void removeHeaders(String s) { + + } + + @Override + public HeaderIterator headerIterator() { + return response.headerIterator(); + } + + @Override + public HeaderIterator headerIterator(String s) { + return response.headerIterator(s); + } + + @Override + @Deprecated + public HttpParams getParams() { + return response.getParams(); + } + + @Override + public void setParams(HttpParams httpParams) { + + } + + + public String getEntityString() { + return entityString; + } + + public void setEntityString(String entityString) { + this.entityString = entityString; + } public InputStream getContent() { return content; } + public void setContent(InputStream content) { + this.content = content; + } + public byte[] getContentByteArr() { return contentByteArr; } @@ -136,10 +267,6 @@ public class ResponeVo { this.contentByteArr = contentByteArr; } - public void setContent(InputStream content) { - this.content = content; - } - @Override public String toString() { return "ResponeVo{" + diff --git a/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThread.java b/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThread.java index 1e875c9..2f4a8e3 100644 --- a/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThread.java +++ b/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThread.java @@ -1,54 +1,52 @@ package aiyh.utils.httpUtil.httpAsync; +import aiyh.utils.httpUtil.ExtendedIOUtils; +import aiyh.utils.httpUtil.ResponeVo; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.util.EntityUtils; -import aiyh.utils.httpUtil.ExtendedIOUtils; -import aiyh.utils.httpUtil.ResponeVo; import java.util.Locale; import java.util.concurrent.Callable; /** * @author EBU7-dev1-ayh - * @date 2021/9/2 0002 22:55 - * async + * @date 2021/9/2 0002 22:55 async */ public class HttpAsyncThread implements Callable { - private final CloseableHttpClient httpClient; - private final HttpUriRequest request; - private String DEFAULT_ENCODING = "UTF-8"; + private final CloseableHttpClient httpClient; + private final HttpUriRequest request; + private String DEFAULT_ENCODING = "UTF-8"; - public HttpAsyncThread(CloseableHttpClient httpClient, HttpUriRequest request, String DEFAULT_ENCODING) { - this.httpClient = httpClient; - this.request = request; - this.DEFAULT_ENCODING = DEFAULT_ENCODING; - } + public HttpAsyncThread(CloseableHttpClient httpClient, HttpUriRequest request, String DEFAULT_ENCODING) { + this.httpClient = httpClient; + this.request = request; + this.DEFAULT_ENCODING = DEFAULT_ENCODING; + } - @Override - public ResponeVo call() throws Exception { - ResponeVo responeVo = new ResponeVo(); - CloseableHttpResponse response = null; - try { - response = httpClient.execute(request); - HttpEntity entity = response.getEntity(); - Header[] allHeaders = response.getAllHeaders(); - Locale locale = response.getLocale(); - responeVo.setLocale(locale); - responeVo.setAllHeaders(allHeaders); - responeVo.setEntityString(EntityUtils.toString(entity, DEFAULT_ENCODING)); - responeVo.setCode(response.getStatusLine().getStatusCode()); - } catch (Exception e) { - throw e; - } - ExtendedIOUtils.closeQuietly(httpClient); - ExtendedIOUtils.closeQuietly(response); - return responeVo; - } + @Override + public ResponeVo call() throws Exception { + ResponeVo responeVo = new ResponeVo(); + CloseableHttpResponse response = null; + try { + response = httpClient.execute(request); + HttpEntity entity = response.getEntity(); + Header[] allHeaders = response.getAllHeaders(); + Locale locale = response.getLocale(); + responeVo.setLocale(locale); + responeVo.setEntityString(EntityUtils.toString(entity, DEFAULT_ENCODING)); + responeVo.setCode(response.getStatusLine().getStatusCode()); + } catch (Exception e) { + throw e; + } + ExtendedIOUtils.closeQuietly(httpClient); + ExtendedIOUtils.closeQuietly(response); + return responeVo; + } } diff --git a/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThreadCallBack.java b/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThreadCallBack.java index 4bcf525..bd2af44 100644 --- a/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThreadCallBack.java +++ b/src/main/java/aiyh/utils/httpUtil/httpAsync/HttpAsyncThreadCallBack.java @@ -6,7 +6,6 @@ import aiyh.utils.httpUtil.ResponeVo; import aiyh.utils.httpUtil.util.HttpUtilParamInfo; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; -import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; @@ -20,18 +19,16 @@ import java.util.function.Consumer; /** * @author EBU7-dev1-ayh - * @date 2021/9/2 0002 23:18 - * callback + * @date 2021/9/2 0002 23:18 callback */ public class HttpAsyncThreadCallBack implements Runnable { + private static final Logger log = Util.getLogger("http_util"); private final CloseableHttpClient httpClient; private final HttpUriRequest request; private final Consumer consumer; private String defaultEncoding = "UTF-8"; - private static final Logger log = Util.getLogger("http_util"); - private HttpUtilParamInfo httpUtilParamInfo = new HttpUtilParamInfo(); public HttpAsyncThreadCallBack(CloseableHttpClient httpClient, HttpUriRequest request, Consumer consumer) { @@ -54,11 +51,9 @@ public class HttpAsyncThreadCallBack implements Runnable { response = httpClient.execute(request); HttpEntity entity = response.getEntity(); - Header[] allHeaders = response.getAllHeaders(); ResponeVo responeVo = new ResponeVo(); Locale locale = response.getLocale(); responeVo.setLocale(locale); - responeVo.setAllHeaders(allHeaders); responeVo.setEntityString(EntityUtils.toString(entity, defaultEncoding)); responeVo.setCode(response.getStatusLine().getStatusCode()); httpUtilParamInfo.setResponse(responeVo); diff --git a/src/main/java/aiyh/utils/httpUtil/staticUtil/HttpStaticUtils.java b/src/main/java/aiyh/utils/httpUtil/staticUtil/HttpStaticUtils.java index 8688af4..8172f49 100644 --- a/src/main/java/aiyh/utils/httpUtil/staticUtil/HttpStaticUtils.java +++ b/src/main/java/aiyh/utils/httpUtil/staticUtil/HttpStaticUtils.java @@ -33,19 +33,16 @@ import java.util.function.Consumer; /** * @author EBU7-dev1-ayh - * @date 2021/8/31 0031 17:16 - * http请求工具 + * @date 2021/8/31 0031 17:16 http请求工具 */ public class HttpStaticUtils { - // 默认编码 - public static String DEFAULT_ENCODING = "UTF-8"; - - private static final ToolUtil toolUtil = new ToolUtil(); - // 线程池 public static final ThreadPoolExecutor executorService; + private static final ToolUtil toolUtil = new ToolUtil(); + // 默认编码 + public static String DEFAULT_ENCODING = "UTF-8"; static { // private final ExecutorService executorService = Executors.newFixedThreadPool(3); @@ -423,7 +420,6 @@ public class HttpStaticUtils { Header[] allHeaders = response.getAllHeaders(); Locale locale = response.getLocale(); responeVo.setLocale(locale); - responeVo.setAllHeaders(allHeaders); responeVo.setEntityString(EntityUtils.toString(entity, DEFAULT_ENCODING)); responeVo.setCode(response.getStatusLine().getStatusCode()); } catch (Exception e) { diff --git a/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java b/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java index e858fb6..6ea581f 100644 --- a/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java +++ b/src/main/java/aiyh/utils/httpUtil/util/HttpUtils.java @@ -39,8 +39,7 @@ import java.util.function.Function; /** * @author EBU7-dev1-ayh - * @date 2021/8/31 0031 17:16 - * http请求工具 与HttpStaticUtils使用相同,说明请查看HttpStaticUtils + * @date 2021/8/31 0031 17:16 http请求工具 与HttpStaticUtils使用相同,说明请查看HttpStaticUtils */ @@ -122,11 +121,11 @@ public class HttpUtils { String str = sqlBuilder.toString().trim(); String removeSeparator = "&"; if (str.endsWith(removeSeparator)) { -// 如果以分&号结尾,则去除&号 + // 如果以分&号结尾,则去除&号 str = str.substring(0, str.length() - 1); } if (str.trim().startsWith(removeSeparator)) { -// 如果以&开头,则去除& + // 如果以&开头,则去除& str = str.substring(1); } return str; @@ -700,9 +699,9 @@ public class HttpUtils { Header[] allHeaders = response.getAllHeaders(); Locale locale = response.getLocale(); responeVo.setLocale(locale); - responeVo.setAllHeaders(allHeaders); responeVo.setEntityString(EntityUtils.toString(entity, DEFAULT_ENCODING)); responeVo.setCode(response.getStatusLine().getStatusCode()); + responeVo.setResponse(response); httpUtilParamInfo.setResponse(responeVo); httpUtilParamInfo.setResponseDate(new Date()); try { @@ -992,7 +991,7 @@ public class HttpUtils { nvps.add(new BasicNameValuePair(entry.getKey(), JSON.toJSONString(entry.getValue()))); } httpPost.setEntity(new UrlEncodedFormEntity(nvps)); -// } else if (contentType.toUpperCase().startsWith(HttpArgsType.APPLICATION_JSON.toUpperCase())) { + // } else if (contentType.toUpperCase().startsWith(HttpArgsType.APPLICATION_JSON.toUpperCase())) { } else { StringEntity stringEntity; if (params.containsKey(JSON_PARAM_KEY)) { @@ -1021,8 +1020,12 @@ public class HttpUtils { */ private HttpPost uploadFileByInputStream(String url, List multipartFileList, Map params, Map headers) { - log.info(Util.logStr("start request : url is [{}]" + - "", url)); + log.info(Util.logStr("start request : url is [{}],other param [\n{}\n],heard [\n{}\n]", url, JSONObject.toJSONString(params, + SerializerFeature.PrettyFormat, + SerializerFeature.WriteDateUseDateFormat), + JSONObject.toJSONString(headers, + SerializerFeature.PrettyFormat, + SerializerFeature.WriteDateUseDateFormat))); HttpUtilParamInfo httpUtilParamInfo = new HttpUtilParamInfo(); httpUtilParamInfo.setParams(params); httpUtilParamInfo.setUrl(url); @@ -1070,8 +1073,12 @@ public class HttpUtils { */ private HttpPut uploadFileByInputStreamPut(String url, List multipartFileList, Map params, Map headers) { - log.info(Util.logStr("start request : url is [{}]" + - "", url)); + log.info(Util.logStr("start request : url is [{}],other param [\n{}\n],heard [\n{}\n]", url, JSONObject.toJSONString(params, + SerializerFeature.PrettyFormat, + SerializerFeature.WriteDateUseDateFormat), + JSONObject.toJSONString(headers, + SerializerFeature.PrettyFormat, + SerializerFeature.WriteDateUseDateFormat))); HttpUtilParamInfo httpUtilParamInfo = new HttpUtilParamInfo(); httpUtilParamInfo.setParams(params); httpUtilParamInfo.setUrl(url); diff --git a/src/main/java/aiyh/utils/lock/LockEntity.java b/src/main/java/aiyh/utils/lock/LockEntity.java new file mode 100644 index 0000000..ba8f225 --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockEntity.java @@ -0,0 +1,27 @@ +package aiyh.utils.lock; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

锁参数信息

+ * + *

create: 2022-12-11 02:07

+ * + * @author youHong.ai + */ + +@Getter +@Setter +@ToString +public class LockEntity { + /** 锁住次数 */ + private Integer times; + + /** 锁标识 */ + private Thread lockMark; + + /** 过期时间 */ + private Long expirationTime; +} diff --git a/src/main/java/aiyh/utils/lock/LockPojo.java b/src/main/java/aiyh/utils/lock/LockPojo.java new file mode 100644 index 0000000..d1cc18b --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockPojo.java @@ -0,0 +1,33 @@ +package aiyh.utils.lock; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + *

锁对应数据库的实体类

+ * + *

create: 2022-12-11 00:24

+ * + * @author youHong.ai + */ + +@Setter +@Getter +@ToString +public class LockPojo { + /** + * 数据库id + */ + private Integer id; + + /** 过期时间 */ + private Long expirationTime; + + /** 锁的键 */ + private String lockName; + + /** 锁状态 */ + private Integer lockStatus; + +} diff --git a/src/main/java/aiyh/utils/lock/LockUtilMapper.java b/src/main/java/aiyh/utils/lock/LockUtilMapper.java new file mode 100644 index 0000000..3cd6a86 --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockUtilMapper.java @@ -0,0 +1,129 @@ +package aiyh.utils.lock; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; +import aiyh.utils.annotation.recordset.Update; + +/** + *

分布式锁数据库查询

+ * + *

create: 2022-12-11 00:22

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

根据锁名称获取锁状态

+ * 2022/12/11 00:37 + * ****************************************** + * + * @param lockKey 锁名称 + * @return LockPojo 锁参数对象 + * @author youHong.ai ****************************************** + */ + @Select("select id, lock_name, lock_status, expiration_time " + + "from uf_cus_lock " + + "where lock_name = #{lockKey}") + LockPojo selectLock(@ParamMapper("lockKey") String lockKey); + + + /** + *

根据锁名称释放锁资源

+ * 2022/12/11 00:46 + * ****************************************** + * + * @param id 锁id + * @return boolean 是否更新成功 + * @author youHong.ai ****************************************** + */ + @Update("update uf_cus_lock " + + "set lock_status = 0 " + + "where id = #{id} " + + " and lock_status = 1") + boolean unLock(@ParamMapper("id") Integer id); + + /** + *

根据锁名称释放锁资源

+ * 2022/12/11 00:46 + * ****************************************** + * + * @param lockKey 锁名称 + * @return boolean 是否更新成功 + * @author youHong.ai ****************************************** + */ + @Update("update uf_cus_lock " + + "set lock_status = 0 " + + "where lock_name = #{lockKey} " + + " and lock_status = 1") + boolean unLock(@ParamMapper("lockKey") String lockKey); + + + /** + *

更新锁状态,锁住资源

+ * 2022/12/11 00:49 + * ****************************************** + * + * @param id 数据id + * @param lockKey 锁名称 + * @param time 过期时间 + * @return boolean 是否成功锁住资源 + * @author youHong.ai ****************************************** + */ + @Update("update uf_cus_lock " + + "set lock_name = #{lockKey}," + + " expiration_time = #{time}," + + " lock_status = 1 " + + "where id = #{id} " + + " and (lock_status = 0 or expiration_time < #{time})") + boolean lock(@ParamMapper("id") Integer id, + @ParamMapper("lockKey") String lockKey, + @ParamMapper("time") Long time); + + + /** + *

更新锁过期时间,续期

+ * 2022/12/11 00:52 + * ****************************************** + * + * @param lockKey 锁名称 + * @param time 过期时间 + * @return boolean 是否更新成功 + * @author youHong.ai ****************************************** + */ + @Update("update uf_cus_lock " + + "set expiration_time = #{time} " + + "where lock_name = #{lockKey} " + + " and lock_status = 1") + boolean updateLockTime(@ParamMapper("lockKey") String lockKey, + @ParamMapper("time") Long time); + + + /** + *

对过期锁重新设置锁

+ * 2022/12/11 15:02 + * ****************************************** + * + * @param id 锁id + * @param lockKey 锁名称 + * @param time 锁过期时间 + * @param expirationTime 上一个锁的过期时间 + * @return boolean 是否重新上锁成功 + * @author youHong.ai ****************************************** + */ + @Update("update uf_cus_lock " + + "set lock_name = #{lockKey}, " + + " expiration_time = #{time}, " + + " lock_status = 1 " + + "where id = #{id} " + + " and lock_status = 1 " + + " and expiration_time = #{expirationTime}") + boolean reLock(@ParamMapper("id") Integer id, + @ParamMapper("lockKey") String lockKey, + @ParamMapper("time") Long time, + @ParamMapper("expirationTime") Long expirationTime); +} diff --git a/src/main/java/aiyh/utils/lock/LockUtils.java b/src/main/java/aiyh/utils/lock/LockUtils.java new file mode 100644 index 0000000..7c3fe1e --- /dev/null +++ b/src/main/java/aiyh/utils/lock/LockUtils.java @@ -0,0 +1,350 @@ +package aiyh.utils.lock; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import cn.hutool.core.thread.ThreadUtil; +import ebu7common.youhong.ai.bean.Builder; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +/** + *

分布式锁

+ * + *

create: 2022-12-11 00:21

+ * + * @author youHong.ai + */ + +public class LockUtils { + + private static final LockUtilMapper mapper = Util.getMapper(LockUtilMapper.class); + + private static final Map LOCK_MAP = new ConcurrentHashMap<>(); + + /** 默认过期时间 10s */ + private static final Long DEFAULT_OVERDUE_TIME = 1_000 * 10L; + + private static final String UF_CUS_LOCK = "uf_cus_lock"; + + /** + *

上锁

+ * 2022/12/11 15:40 + * ****************************************** + * + * @param lockName 锁名称 + * @param reentrant 是否可重入 + * @return boolean 是否抢占成功 + * @author youHong.ai ****************************************** + */ + public static boolean lock(String lockName, boolean reentrant) { + return lock(lockName, DEFAULT_OVERDUE_TIME, reentrant); + } + + + /** + *

上锁

+ * 2022/12/11 15:40 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 超时时间 + * @param reentrant 是否可重入 + * @return boolean 是否抢占成功 + * @author youHong.ai ****************************************** + */ + public static boolean lock(String lockName, Long overdueTime, boolean reentrant) { + LockPojo lockPojo = mapper.selectLock(lockName); + if (Objects.isNull(lockPojo) || lockPojo.getId() <= 0) { + return insertLock(lockName, overdueTime); + } else { + // 存在当前的锁的锁名称 + if (lockPojo.getLockStatus() == 1) { + // 锁处于锁定状态 + return onLock(lockName, overdueTime, reentrant, lockPojo); + } else { + // 处于未锁定状态开始对资源上锁 + boolean lock = mapper.lock(lockPojo.getId(), lockName, overdueTime); + if (lock) { + // 锁定成功 + LOCK_MAP.put(lockName, + Builder.builder(LockEntity::new) + .with(LockEntity::setTimes, 1) + .with(LockEntity::setLockMark, Thread.currentThread()) + .with(LockEntity::setExpirationTime, overdueTime) + .build()); + return true; + } else { + // 抢占锁失败 + lockPojo = mapper.selectLock(lockName); + return retryGetLock(lockName, overdueTime, lockPojo); + } + } + } + } + + /** + *

处于锁状态

+ * 2022/12/11 12:23 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 锁超时时间 + * @param reentrant 是否可重入锁 + * @param lockPojo 锁信息对象 + * @return boolean 是否获取锁成功 + * @author youHong.ai ****************************************** + */ + private static boolean onLock(String lockName, Long overdueTime, boolean reentrant, LockPojo lockPojo) { + Long time = lockPojo.getExpirationTime(); + if (time > System.currentTimeMillis()) { + // 锁过期了 如果要使锁生效就将日期加长 + return lockExpiration(lockName, overdueTime, lockPojo); + } else { + //锁没有过期 + return inLockTime(lockName, overdueTime, reentrant); + } + } + + /** + *

锁未过期

+ * 2022/12/11 12:24 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 锁过期时间 + * @param reentrant 是否可重入 + * @return boolean 是否成功获取锁 + * @author youHong.ai ****************************************** + */ + private static boolean inLockTime(String lockName, Long overdueTime, boolean reentrant) { + //判断是否存在本地锁对象中 + LockPojo lockPojo = mapper.selectLock(lockName); + if (!LOCK_MAP.containsKey(lockName)) { + // 不是本地锁,不支持可重入,使线程进入等待状态 + int n = 0; + return retryGetLock(lockName, overdueTime, lockPojo); + } + // 是本地锁 + return getLock(lockName, overdueTime, reentrant); + } + + /** + *

尝试抢占资源锁

+ * 2022/12/11 15:34 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 锁过期时间 + * @param lockPojo 锁参数对象 + * @return boolean 是否抢占锁成功 + * @author youHong.ai ****************************************** + */ + private static boolean retryGetLock(String lockName, Long overdueTime, LockPojo lockPojo) { + while (lockPojo.getExpirationTime() > System.currentTimeMillis()) { + // 锁还没过期,使线程休眠 + long l = lockPojo.getExpirationTime() - System.currentTimeMillis(); + if (l > 10) { + ThreadUtil.safeSleep(l - 10L); + } + // 尝试获取锁 + lockExpiration(lockName, overdueTime + l, lockPojo); + } + return true; + } + + /** + *

获取锁

+ * 2022/12/11 13:57 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 超时时间 + * @param reentrant 是否可重入 + * @return boolean 锁是否获取成功 + * @author youHong.ai ****************************************** + */ + private static boolean getLock(String lockName, Long overdueTime, boolean reentrant) { + if (reentrant) { + LockEntity lockEntity = LOCK_MAP.get(lockName); + lockEntity.setTimes(lockEntity.getTimes() + 1); + } else { + LockPojo lockPojo = mapper.selectLock(lockName); + retryGetLock(lockName, overdueTime, lockPojo); + } + return true; + } + + /** + *

锁过期

+ * 2022/12/11 12:25 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 锁过期时间 + * @return boolean 是否成功获取锁 + * @author youHong.ai ****************************************** + */ + private static boolean lockExpiration(String lockName, Long overdueTime, LockPojo lockPojo) { + boolean lock = mapper.reLock(lockPojo.getId(), lockName, overdueTime, lockPojo.getExpirationTime()); + if (lock) { + //更新锁状态成功 + LockEntity lockEntity = Builder.builder(LockEntity::new) + .with(LockEntity::setTimes, 1) + .with(LockEntity::setLockMark, Thread.currentThread()) + .with(LockEntity::setExpirationTime, overdueTime) + .build(); + LOCK_MAP.put(lockName, lockEntity); + return true; + } else { + // 更新失败,可能是其他服务器抢先获得了锁 + LockPojo newLockPojo = mapper.selectLock(lockName); + if (Objects.isNull(newLockPojo)) { + // 锁被释放了 + boolean isLock = insertLock(lockName, overdueTime); + if (!isLock) { + throw new CustomerException("can not getLock!"); + } + return true; + } + if (newLockPojo.getExpirationTime() > lockPojo.getExpirationTime()) { + // 锁被其他机器抢占 + return retryGetLock(lockName, overdueTime, newLockPojo); + } + } + return false; + } + + /** + *

新增锁记录

+ * 2022/12/11 12:25 + * ****************************************** + * + * @param lockName 锁名称 + * @param overdueTime 锁过期时间 + * @return boolean 是否是可重入锁 + * @author youHong.ai ****************************************** + */ + private static boolean insertLock(String lockName, Long overdueTime) { + // 没有锁需要新增一条锁记录 + String modeId = Util.getModeIdByTableName(UF_CUS_LOCK); + int dataId = Util.getModeDataId(UF_CUS_LOCK, Integer.parseInt(modeId), 1); + long currentTime = System.currentTimeMillis(); + Long expirationTime = currentTime + overdueTime; + boolean lock = mapper.lock(dataId, lockName, expirationTime); + if (lock) { + // 锁成功 + LockEntity lockEntity = Builder.builder(LockEntity::new) + .with(LockEntity::setTimes, 1) + .with(LockEntity::setLockMark, Thread.currentThread()) + .with(LockEntity::setExpirationTime, overdueTime) + .build(); + LOCK_MAP.put(lockName, lockEntity); + } else { + LockPojo lockPojo = mapper.selectLock(lockName); + if (Objects.isNull(lockPojo)) { + // 锁失败 + retryLock(dataId, lockName, expirationTime, 0); + } else { + // 其他服务器抢占了锁资源 + return retryGetLock(lockName, overdueTime, lockPojo); + } + } + return true; + } + + + /** + *

重试锁

+ * 2022/12/11 01:39 + * ************************************************************ + * + * @param dataId 数据id + * @param lockName 锁名称 + * @param expirationTime 过期时间 + * @param n 重试次数 + * @author youHong.ai ****************************************** + */ + private static void retryLock(int dataId, String lockName, Long expirationTime, int n) { + if (n > 5) { + throw new CustomerException("get lock error! 5 failed attempts to update the database!"); + } + ThreadUtil.safeSleep((n + 1) * 500); + boolean lock = mapper.lock(dataId, lockName, expirationTime + (n + 1) * 500L); + if (lock) { + // 锁成功 + LockEntity lockEntity = Builder.builder(LockEntity::new) + .with(LockEntity::setTimes, 1) + .with(LockEntity::setLockMark, Thread.currentThread()) + .with(LockEntity::setExpirationTime, expirationTime + (1 + n) * 500L) + .build(); + LOCK_MAP.put(lockName, lockEntity); + } else { + // 锁失败 + retryLock(dataId, lockName, expirationTime, n + 1); + } + } + + /** + *

释放锁

+ * 2022/12/11 15:56 + * ****************************************** + * + * @param lockName 锁名称 + * @author youHong.ai ****************************************** + */ + public static void unLock(String lockName) { + if (LOCK_MAP.containsKey(lockName)) { + // 存在本地锁 + LockEntity lockEntity = LOCK_MAP.get(lockName); + if (!lockEntity.getLockMark().equals(Thread.currentThread())) { + // 并非当前上锁的线程在释放锁 + return; + } + Integer times = lockEntity.getTimes(); + if (times - 1 == 0) { + boolean unlock = mapper.unLock(lockName); + if (!unlock) { + int n = 0; + do { + if (n++ > 5) { + throw new CustomerException("can not unLock!Failed to release the lock after five attempts!"); + } + } while (!mapper.unLock(lockName)); // 释放锁失败 + } + return; + } + lockEntity.setTimes(lockEntity.getTimes() - 1); + } + } + + /** + *

锁续期

+ * 2022/12/11 15:49 + * ****************************************** + * + * @param lockKey 锁名字 + * @param expirationTime 锁过期时间 + * @return boolean 是否续期成功 + * @author youHong.ai ****************************************** + */ + public boolean updateLockTime(String lockKey, Long expirationTime) { + if (!mapper.updateLockTime(lockKey, expirationTime)) { + // 更新失败 + int n = 0; + do { + if (n++ > 5) { + return false; + } + } while (!mapper.updateLockTime(lockKey, expirationTime)); + } + if (LOCK_MAP.containsKey(lockKey)) { + // 存在本地锁,更新锁信息 + LockEntity lockEntity = LOCK_MAP.get(lockKey); + lockEntity.setExpirationTime(expirationTime); + } + return true; + } +} + diff --git a/src/main/java/com/api/xuanran/wang/ambofo/checkuser/controller/CheckUserController.java b/src/main/java/com/api/xuanran/wang/ambofo/checkuser/controller/CheckUserController.java new file mode 100644 index 0000000..5adc100 --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/ambofo/checkuser/controller/CheckUserController.java @@ -0,0 +1,59 @@ +package com.api.xuanran.wang.ambofo.checkuser.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.xuanran.wang.ambofo.checkuser.service.CheckUserService; +import org.apache.log4j.Logger; + +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; + +/** + *

安波福从AD域中校验用户是否存在

+ * + * @Author xuanran.wang + * @Date 2022/12/12 14:24 + */ +@Path("/wxr/ambofo/") +public class CheckUserController { + + private final Logger log = Util.getLogger(); + + @Path("checkUser") + @POST + @Produces(MediaType.TEXT_PLAIN) + public String checkUser(@Context HttpServletRequest request, @Context HttpServletResponse response) { + String checkContent = request.getParameter("checkContent"); + try { + CheckUserService checkUserService = new CheckUserService(); + return ApiResult.success(checkUserService.checkADHasUser(checkContent),"ok"); + }catch (Exception e){ + String error = Util.logStr("AD查询接口发生异常:{}", e.getMessage()); + log.error(error); + log.error(Util.getErrString(e)); + return ApiResult.error(500, error); + } + } + + @Path("logUser") + @GET + @Produces(MediaType.TEXT_PLAIN) + public String logUser(@Context HttpServletRequest request, @Context HttpServletResponse response) { + try { + CheckUserService checkUserService = new CheckUserService(); + checkUserService.logAllUser(); + return ApiResult.successNoData(); + }catch (Exception e){ + String error = Util.logStr("AD查询接口发生异常:{}", e.getMessage()); + log.error(error); + log.error(Util.getErrString(e)); + return ApiResult.error(500, error); + } + } +} diff --git a/src/main/java/com/api/xuanran/wang/ambofo/checkuser/service/CheckUserService.java b/src/main/java/com/api/xuanran/wang/ambofo/checkuser/service/CheckUserService.java new file mode 100644 index 0000000..4a3c165 --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/ambofo/checkuser/service/CheckUserService.java @@ -0,0 +1,149 @@ +package com.api.xuanran.wang.ambofo.checkuser.service; + + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.collections.MapUtils; +import org.apache.log4j.Logger; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.InitialLdapContext; +import javax.naming.ldap.LdapContext; +import java.util.Hashtable; +import java.util.Map; + +/** + *

安波福从AD校验用户是否存在业务方法

+ * + * @Author xuanran.wang + * @Date 2022/12/12 14:29 + */ +public class CheckUserService { + + private Map ADConfig = null; + private final Logger log = Util.getLogger(); + /** + *

构造方法中初始化配置文件

+ * @author xuanran.wang + * @dateTime 2022/12/12 15:31 + **/ + public CheckUserService(){ + // AD配置文件 + ADConfig = Util.getProperties2Map("AmbofoADConfig"); + if(MapUtils.isEmpty(ADConfig)){ + throw new CustomerException("请检查/filesystem/prop/prop2map 文件夹下是否存在AmbofoADConfig.properties文件!"); + } + + log.info(Util.logStr("AD配置对象 : [{}]", JSONObject.toJSONString(ADConfig))); + } + + /** + *

校验AD是否存在指定用户

+ * @author xuanran.wang + * @dateTime 2022/12/12 15:22 + * @param checkInfo 校验内容 + * @return true/false 有/没有 + **/ + public boolean checkADHasUser(String checkInfo) { + //连接到AD + LdapContext ldapContext = login(); + try { + // 域节点 + String searchBase = Util.null2String(ADConfig.get("searchBase")); + // LDAP搜索过滤器类 cn=*name*模糊查询 cn=name 精确查询 String searchFilter = "(objectClass="+type+")"; + //查询域帐号 + String searchFilter = Util.null2String(ADConfig.get("queryField")) + "=" + checkInfo; + log.info("searchFilter : " + searchFilter); + // 创建搜索控制器 + SearchControls searchControl = new SearchControls(); + // 设置搜索范围 深度 + searchControl.setSearchScope(SearchControls.SUBTREE_SCOPE); + // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果 + NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchControl); + // 初始化搜索结果数为0 + return answer.hasMoreElements(); + } catch (NamingException e) { + throw new CustomerException(Util.logStr("从AD搜索用户异常:[{}]",e.getMessage())); + } finally { + close(ldapContext); + } + } + + public void logAllUser() { + //连接到AD + LdapContext ldapContext = login(); + try { + // 域节点 + String searchBase = Util.null2String(ADConfig.get("searchBase")); + // LDAP搜索过滤器类 cn=*name*模糊查询 cn=name 精确查询 String searchFilter = "(objectClass="+type+")"; + // 创建搜索控制器 + SearchControls searchControl = new SearchControls(); + // 设置搜索范围 深度 + searchControl.setSearchScope(SearchControls.SUBTREE_SCOPE); + // 根据设置的域节点、过滤器类和搜索控制器搜索LDAP得到结果 + NamingEnumeration answer = ldapContext.search(searchBase, "", searchControl); + //4. 获取查询的内容 + while (answer.hasMoreElements()) { + SearchResult sr = (SearchResult) answer.next(); + String dn = sr.getName(); + log.info("dn " + dn); + } + } catch (NamingException e) { + throw new CustomerException(Util.logStr("从AD搜索用户异常:[{}]",e.getMessage())); + } finally { + close(ldapContext); + } + } + + /** + *

创建LDAP连接

+ * @author xuanran.wang + * @dateTime 2022/12/12 15:21 + * @return LDAP连接对象 + **/ + private LdapContext login() { + String userName = Util.null2String(ADConfig.get("userName")); + String password = Util.null2String(ADConfig.get("password")); + String server = Util.null2String(ADConfig.get("server")); + String driver = Util.null2String(ADConfig.get("driver")); + String authentication = Util.null2String(ADConfig.get("authentication")); + try { + Hashtable env = new Hashtable<>(); + //用户名称,cn,ou,dc 分别:用户,组,域 + env.put(Context.SECURITY_PRINCIPAL, userName); + //用户密码 cn 的密码 + env.put(Context.SECURITY_CREDENTIALS, password); + //url 格式:协议://ip:端口/组,域 ,直接连接到域或者组上面 + env.put(Context.PROVIDER_URL, server); + //LDAP 工厂 + env.put(Context.INITIAL_CONTEXT_FACTORY, driver); + //验证的类型 "none", "simple", "strong" + env.put(Context.SECURITY_AUTHENTICATION, authentication); + return new InitialLdapContext(env, null); + } catch (NamingException e) { + throw new CustomerException(Util.logStr("连接AD失败! : {}", e.getMessage())); + } + } + + + /** + *

关闭连接

+ * @author xuanran.wang + * @dateTime 2022/12/12 15:30 + * @param lct AD连接对象 + **/ + private void close(LdapContext lct) { + try { + if (lct != null){ + //关闭连接 + lct.close(); + } + } catch (NamingException e) { + throw new CustomerException(Util.logStr("关闭AD连接失败! : {}", e.getMessage())); + } + } +} diff --git a/src/main/java/com/api/xuanran/wang/saic_travel/model_create_workflow/controller/CusCreateWorkFlowController.java b/src/main/java/com/api/xuanran/wang/saic_travel/model_create_workflow/controller/CusCreateWorkFlowController.java index 30a73c8..626d929 100644 --- a/src/main/java/com/api/xuanran/wang/saic_travel/model_create_workflow/controller/CusCreateWorkFlowController.java +++ b/src/main/java/com/api/xuanran/wang/saic_travel/model_create_workflow/controller/CusCreateWorkFlowController.java @@ -6,7 +6,7 @@ import com.alibaba.fastjson.JSONObject; import org.apache.log4j.Logger; import weaver.hrm.HrmUserVarify; import weaver.hrm.User; -import weaver.xuanran.wang.common.util.CommonUtil; +import weaver.xuanran.wang.common.util.CommonUtil; // 工具类 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -26,12 +26,12 @@ import java.util.stream.Collectors; @Path("/wxr/saicTravel/") public class CusCreateWorkFlowController { - private final Logger logger = Util.getLogger(); + private final Logger logger = Util.getLogger(); // 获取日志对象 @Path("cusCreateWorkFlow") @POST @Produces(MediaType.TEXT_PLAIN) - public String getOrgChartTree(@Context HttpServletRequest request, @Context HttpServletResponse response) { + public String createWorkFlow(@Context HttpServletRequest request, @Context HttpServletResponse response) { User logInUser = HrmUserVarify.getUser(request, response); if(logInUser == null){ return ApiResult.error(403,"请先登录!"); @@ -39,14 +39,15 @@ public class CusCreateWorkFlowController { String choiceData = request.getParameter("choiceData"); int modelId = Util.getIntValue(request.getParameter("modelId"), -1); List dataList = Arrays.stream(choiceData.split(",")).collect(Collectors.toList()); - List requestIds = CommonUtil.doCreateWorkFlow(modelId, dataList); + List requestIds = CommonUtil.doCreateWorkFlow(modelId, dataList); // 通过数据审批生成流程 List errorData = new ArrayList<>(); for (int i = 0; i < requestIds.size(); i++) { if (Util.getIntValue(requestIds.get(i), -1) < 0) { errorData.add(dataList.get(i)); } } - logger.error(Util.logStr("执行创建流程失败集合: {}",JSONObject.toJSONString(errorData))); + logger.error(Util.logStr("执行创建流程失败集合: {}",JSONObject.toJSONString(errorData))); // 构建日志字符串 return ApiResult.success(errorData); } } + diff --git a/src/main/java/com/api/xuanran/wang/schroeder/download_file/controller/DownLoadFileController.java b/src/main/java/com/api/xuanran/wang/schroeder/download_file/controller/DownLoadFileController.java new file mode 100644 index 0000000..1d09cfc --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/schroeder/download_file/controller/DownLoadFileController.java @@ -0,0 +1,61 @@ +package com.api.xuanran.wang.schroeder.download_file.controller; + +import aiyh.utils.Util; +import com.api.xuanran.wang.schroeder.download_file.service.DownLoadFileService; +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import weaver.file.ImageFileManager; + +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.*; +import java.net.URLEncoder; +import java.util.Map; + +/** + *

+ * 施罗德下载文件接口/wxr/schroeder/downLoadFile?docId=1212 + *

+ * + * @Author xuanran.wang + * @Date 2022/12/7 10:18 + */ +@Path("/wxr/schroeder/") +public class DownLoadFileController { + + private final DownLoadFileService downLoadFileService = new DownLoadFileService(); + + private final Logger logger = Util.getLogger(); + + @Path("downLoadFile") + @GET + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response downLoadFile(@Context HttpServletRequest request, @Context HttpServletResponse response) { + String docId = request.getParameter("docId"); + try { + Map fileInfo = downLoadFileService.getFileInfo(docId); + String fileName = Util.null2String(fileInfo.get("fileName")); + int imageFileId = Util.getIntValue(Util.null2DefaultStr(fileInfo.get("imageFileId"),""), -1); + InputStream is = ImageFileManager.getInputStreamById(imageFileId); + byte[] bytes = IOUtils.toByteArray(is); + StreamingOutput output = outputStream ->{ + outputStream.write(bytes); + outputStream.close(); + }; + Response.ResponseBuilder header = Response.ok(output, MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); + return header.build(); + }catch (Exception e){ + String error = Util.logStr("docId:{}, 下载文件异常:{}", docId, e.getMessage()); + logger.error(error); + return Response.ok(error, MediaType.APPLICATION_JSON).build(); + } + } + +} diff --git a/src/main/java/com/api/xuanran/wang/schroeder/download_file/mapper/DownLoadFileMapper.java b/src/main/java/com/api/xuanran/wang/schroeder/download_file/mapper/DownLoadFileMapper.java new file mode 100644 index 0000000..6223c91 --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/schroeder/download_file/mapper/DownLoadFileMapper.java @@ -0,0 +1,33 @@ +package com.api.xuanran.wang.schroeder.download_file.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.Map; + +/** + *

文件下载mapper

+ * + * @Author xuanran.wang + * @Date 2022/12/7 10:58 + */ +@SqlMapper +public interface DownLoadFileMapper { + + /** + *

根据docId查询附件信息

+ * @author xuanran.wang + * @dateTime 2022/12/7 11:01 + * @param docId docId + * @return 文件imageField以及文件名 + **/ + @Select("select t3.imagefileid imageFileId,t3.imagefilename fileName,t3.filerealpath filePath " + + "from DocDetail t1 " + + "left join DocImageFile t2 " + + "on t2.docid = t1.id " + + "left join ImageFile t3 " + + "on t3.imagefileid = t2.imagefileid " + + "where t1.id = #{docId}") + Map selectDocInfoByDocId(@ParamMapper("docId") String docId); +} diff --git a/src/main/java/com/api/xuanran/wang/schroeder/download_file/service/DownLoadFileService.java b/src/main/java/com/api/xuanran/wang/schroeder/download_file/service/DownLoadFileService.java new file mode 100644 index 0000000..49f5ef6 --- /dev/null +++ b/src/main/java/com/api/xuanran/wang/schroeder/download_file/service/DownLoadFileService.java @@ -0,0 +1,56 @@ +package com.api.xuanran.wang.schroeder.download_file.service; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.alibaba.fastjson.JSONObject; +import com.api.xuanran.wang.schroeder.download_file.mapper.DownLoadFileMapper; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import weaver.conn.RecordSet; +import java.util.Map; + +/** + *

下载文件业务方法

+ * + * @Author xuanran.wang + * @Date 2022/12/7 10:51 + */ +public class DownLoadFileService { + /** + *

文件记录表

+ **/ + private static final String DOC_LOG_TABLE_NAME = "uf_doc_log"; + /** + *

查询文件记录sql

+ **/ + private static final String SELECT_DOC_LOG_SQL = "select 1 from " + DOC_LOG_TABLE_NAME + " where docId = ? and enable = 0"; + private final DownLoadFileMapper downLoadFileMapper = Util.getMapper(DownLoadFileMapper.class); + + /** + *

根据docId获取文件信息

+ * @author xuanran.wang + * @dateTime 2022/12/7 11:24 + * @param docId docId + **/ + public Map getFileInfo(String docId) { + if(StringUtils.isBlank(docId)) { + throw new CustomerException(Util.logStr("下载文件失败, 请求路径中不包含指定的docId!当前请求docId:{}", docId)); + } + RecordSet rs = new RecordSet(); + if (!rs.executeQuery(SELECT_DOC_LOG_SQL, docId) || !rs.next()) { + throw new CustomerException("下载文件失败, 请确认文件记录表中是否存在docId = [ " + docId + " ]的文件!"); + } + Map fileInfoMap = downLoadFileMapper.selectDocInfoByDocId(docId); + if(MapUtils.isEmpty(fileInfoMap)){ + throw new CustomerException("执行查询文件信息sql失败!"); + } + String fileName = Util.null2DefaultStr(fileInfoMap.get("fileName"),""); + int imageFileId = Util.getIntValue(Util.null2DefaultStr(fileInfoMap.get("imageFileId"),""), -1); + if(StringUtils.isBlank(fileName) ||imageFileId < 0){ + throw new CustomerException(Util.logStr("文件信息部分字段查询为空!当前查询结果map:[{}]", JSONObject.toJSONString(fileInfoMap))); + } + return fileInfoMap; + } + + +} diff --git a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/dto/HrmResourceDto.java b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/dto/HrmResourceDto.java index f692657..8517cb7 100644 --- a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/dto/HrmResourceDto.java +++ b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/dto/HrmResourceDto.java @@ -61,4 +61,7 @@ public class HrmResourceDto { /** 头像地址 */ private String avatar; + + /** 当前所属分部 */ + private Integer subCompanyId; } diff --git a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/mapper/OrgChartMapper.java b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/mapper/OrgChartMapper.java index 5cc7118..742c417 100644 --- a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/mapper/OrgChartMapper.java +++ b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/mapper/OrgChartMapper.java @@ -1,6 +1,5 @@ package com.api.youhong.ai.pcn.organization.orgchart.mapper; -import aiyh.utils.annotation.recordset.CaseConversion; import aiyh.utils.annotation.recordset.ParamMapper; import aiyh.utils.annotation.recordset.Select; import aiyh.utils.annotation.recordset.SqlMapper; @@ -28,24 +27,28 @@ public interface OrgChartMapper { * * @param typeOfEmploymentField 人员自定义字段 * @return List 返回的人员信息 - * @author youHong.ai - * ****************************************** + * @author youHong.ai ****************************************** */ @Select("select hrm.id, " + + " hrm.subcompanyid1 sub_company_id," + " hrm.messagerurl avatar," + - " cus.$t{lastNameEnField} last_name, " + + " (case when cus.$t{lastNameEnField} is null then hrm.lastname " + + " else cus.$t{lastNameEnField} end) last_name, " + " hrm.managerstr manager_str, " + " hrm.jobtitle job_title_id, " + " hrm.managerid manager_id, " + " hrm.departmentid department_id, " + " dept.DEPARTMENTNAME department_name, " + " job.JOBTITLENAME job_title_name, " + - " cus.$t{typeOfEmploymentFiled} type_of_employment " + + " cus1.$t{typeOfEmploymentFiled} type_of_employment " + "from hrmresource hrm " + " inner join hrmjobtitles job on hrm.JOBTITLE = job.id " + " inner join cus_fielddata cus on cus.ID = hrm.ID " + " and cus.SCOPE = 'HrmCustomFieldByInfoType' " + - " and cus.SCOPEID = -1 " + + " and cus.SCOPEID = 1 " + + " inner join cus_fielddata cus1 on cus1.id = hrm.id" + + " and cus1.scope = 'HrmCustomFieldByInfoType' " + + " and cus1.scopeid = -1" + " inner join hrmdepartment dept on dept.id = hrm.DEPARTMENTID " + "where hrm.status in (0, 1)") List selectAll(@ParamMapper("typeOfEmploymentFiled") String typeOfEmploymentField, @@ -59,8 +62,7 @@ public interface OrgChartMapper { * * @param userId 当前用户id * @return ShowPointOrAll 展示与否的人员信息 - * @author youHong.ai - * ****************************************** + * @author youHong.ai ****************************************** */ @Select("select id,resources,show_all,show_type from uf_show_point_or_all " + "where concat(',',resources,',') like concat('%,',#{userId},',%')") diff --git a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/pojo/HrmResource.java b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/pojo/HrmResource.java index 85a8cd9..ec7eab4 100644 --- a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/pojo/HrmResource.java +++ b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/pojo/HrmResource.java @@ -47,5 +47,8 @@ public class HrmResource { /** 用工类型 */ private Integer typeOfEmployment; + /** 当前所属分部 */ + private Integer subCompanyId; + } diff --git a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/service/OrgChartService.java b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/service/OrgChartService.java index e2745d6..cd235e6 100644 --- a/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/service/OrgChartService.java +++ b/src/main/java/com/api/youhong/ai/pcn/organization/orgchart/service/OrgChartService.java @@ -1,6 +1,7 @@ package com.api.youhong.ai.pcn.organization.orgchart.service; import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; import cn.hutool.core.lang.Assert; import com.api.youhong.ai.pcn.organization.orgchart.dto.HrmResourceDto; import com.api.youhong.ai.pcn.organization.orgchart.mapper.OrgChartMapper; @@ -45,6 +46,9 @@ public class OrgChartService { String lastNameEnField = Util.getCusConfigValue("lastNameEnField"); Assert.notBlank(lastNameEnField, "config [lastNameEnField] is null or blank!"); List hrmResourceList = mapper.selectAll(typeOfEmploymentField, lastNameEnField); + if (Objects.isNull(hrmResourceList) || hrmResourceList.isEmpty()) { + throw new CustomerException("查询不到相关人员!"); + } //List hrmResourceDtoList = new ArrayList(); AtomicReference currentUser = new AtomicReference<>(); /* ******************* 将pojo转换为Dto对象,对节点属性默认值赋值,找出当前用户并设置显示 ******************* */ @@ -57,6 +61,11 @@ public class OrgChartService { .endSet()) .collect(Collectors.toList()); hrmResourceDtoList.stream() + .peek(item -> { + if (item.getManagerId() == userId) { + item.setShow(1); + } + }) .filter(item -> item.getId() == userId) .forEach(item -> { Builder.startSet(item) @@ -67,7 +76,32 @@ public class OrgChartService { .endSet(); currentUser.set(item); }); - Assert.notNull(currentUser, "not find current login user info!"); + /* ******************* 系统管理员默认全部展开哦 ******************* */ + if (userId == 1) { + List collect = hrmResourceDtoList.stream() + .map(struct::hrmResourceDtoToVo) + .peek(item -> Builder.startSet(item) + .with(OrgChartNodeVo::setShow, 1) + .with(OrgChartNodeVo::setShowBrother, 1) + .with(OrgChartNodeVo::setShowChildren, 1) + .with(OrgChartNodeVo::setCurrent, true) + .endSet()) + .collect(Collectors.toList()); + return Util.listToTree(collect, OrgChartNodeVo::getId, OrgChartNodeVo::getManagerId, + OrgChartNodeVo::getChildren, OrgChartNodeVo::setChildren, + parentId -> parentId == null || parentId <= 0) + .stream().peek(item -> Builder.startSet(item) + .with(OrgChartNodeVo::setIsRoot, true) + .with(OrgChartNodeVo::setCurrent, true) + .endSet()) + .peek(item -> recursionChildrenNums(item, 0)) + .collect(Collectors.toList()); + } + Assert.notNull(currentUser.get(), "not find current login user info!"); + /* ******************* 根据当前登陆人的分部来过滤 ******************* */ + hrmResourceDtoList = hrmResourceDtoList.stream() + .filter(item -> logInUser.getUserSubCompany1() == item.getSubCompanyId()) + .collect(Collectors.toList()); /* ******************* 查找当前登陆人员的所有上级 ******************* */ String currentUserManagerStr = currentUser.get().getManagerStr(); if (Objects.isNull(currentUserManagerStr)) { @@ -92,6 +126,7 @@ public class OrgChartService { /* ******************* 转换dto为Vo并且设置根节点标识 ******************* */ orgChartNodeVoList = hrmResourceDtoList.stream() .map(struct::hrmResourceDtoToVo) + .peek(item -> item.setType(-1)) .collect(Collectors.toList()); } else { /* ******************* 转换dto为Vo并且设置根节点标识 ******************* */ @@ -108,8 +143,7 @@ public class OrgChartService { if (!showPointOrAll.isShowType()) { item.setType(-1); } - }) - .collect(Collectors.toList()); + }).collect(Collectors.toList()); } return Util.listToTree(orgChartNodeVoList, OrgChartNodeVo::getId, @@ -130,8 +164,7 @@ public class OrgChartService { * * @param chartNodeVo 节点对象 * @return Integer 对应节点的所有子节点的数量 - * @author youHong.ai - * ****************************************** + * @author youHong.ai ****************************************** */ private Integer recursionChildrenNums(OrgChartNodeVo chartNodeVo, int n) { List children = chartNodeVo.getChildren(); diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/ApaLevelByScoreController.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/ApaLevelByScoreController.java new file mode 100644 index 0000000..5476d7c --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/ApaLevelByScoreController.java @@ -0,0 +1,38 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service.ApaLevelByScoreService; +import org.apache.log4j.Logger; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; + +/** + *

通过apa分数获取apalevel

+ * + *

create: 2022-12-13 10:37

+ * + * @author youHong.ai + */ + +@Path("ayh/workflow/apa") +public class ApaLevelByScoreController { + + private final Logger log = Util.getLogger(); + private final ApaLevelByScoreService service = new ApaLevelByScoreService(); + + @Path("/level") + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String getLevelByScore(@QueryParam("score") Double score) { + try { + Integer level = service.getLevelByScore(score); + return ApiResult.success(level); + } catch (Exception e) { + log.error("get level error \n" + Util.getErrString(e)); + return ApiResult.error("get level error " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/NotAllowedClickTGSController.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/NotAllowedClickTGSController.java new file mode 100644 index 0000000..7445e47 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/NotAllowedClickTGSController.java @@ -0,0 +1,46 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service.NotAllowedClickTGSService; +import weaver.hrm.HrmUserVarify; +import weaver.hrm.User; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; +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; + +/** + *

是否允许当前用户点击targetSetting按钮

+ * + *

create: 2022-12-12 15:36

+ * + * @author youHong.ai + */ + +@Path("/ayh/target-setting/btn") +public class NotAllowedClickTGSController { + + private final NotAllowedClickTGSService service = new NotAllowedClickTGSService(); + + @Path("/can-allowed") + @GET + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public String canAllowedClickTGSBtn(@Context HttpServletRequest request, @Context HttpServletResponse response) { + User user = HrmUserVarify.getUser(request, response); + try { + return ApiResult.success(service.canAllowedClickTGSBtn(user)); + } catch (Exception e) { + Util.getLogger().error("get can allowed click target setting button error!\n" + Util.getErrString(e)); + return ApiResult.error("system error!"); + } + + } + +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/TriggerWorkflowToModelController.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/TriggerWorkflowToModelController.java new file mode 100644 index 0000000..21df1b6 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/controller/TriggerWorkflowToModelController.java @@ -0,0 +1,49 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.controller; + +import aiyh.utils.ApiResult; +import aiyh.utils.Util; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service.TriggerWorkflowToModelService; +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.Consumes; +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.Map; + +/** + *

保存按钮流程转数据接口

+ * + *

create: 2022-12-08 18:09

+ * + * @author youHong.ai + */ + +@Path("/aiyh/workflow/target-setting") +public class TriggerWorkflowToModelController { + + private final TriggerWorkflowToModelService service = new TriggerWorkflowToModelService(); + private final Logger logger = Util.getLogger(); + + @Path("/save-trigger") + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public String saveTriggerWorkflowToModel(@RequestBody Map params, + @Context HttpServletRequest request, @Context HttpServletResponse response) { + try { + User user = HrmUserVarify.getUser(request, response); + return ApiResult.success(service.saveTriggerWorkflowToModel(params, request, user)); + } catch (Exception e) { + logger.error("save trigger workflow to mode data error ! \n" + Util.getErrString(e)); + return ApiResult.error(e.getMessage()); + } + } +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/ApaLevelByScoreMapper.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/ApaLevelByScoreMapper.java new file mode 100644 index 0000000..f011991 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/ApaLevelByScoreMapper.java @@ -0,0 +1,28 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper; + +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +/** + *

+ * + *

create: 2022-12-13 10:42

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

通过apa分数查询对应的分数等级

+ * 2022/12/13 10:47 + * ************************************************************ + * + * @param score 分数 + * @return Integer 当前分数对应的等级 + * @author youHong.ai ****************************************** + */ + @Select("select level1 from uf_APAlevel where #{score} between zdf and zgf") + Integer selectLevelByScore(Double score); +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/NotAllowedClickTGSMapper.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/NotAllowedClickTGSMapper.java new file mode 100644 index 0000000..e5b2594 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/NotAllowedClickTGSMapper.java @@ -0,0 +1,46 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; + +/** + *

+ * + *

create: 2022-12-12 15:56

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

根据用户id和当前年份查询个人目标台账主表id

+ * 2022/12/12 17:27 + * ************************************************************ + * + * @param userId 用户id + * @param currentYear 当前年年份 + * @return List 主表id数组 + * @author youHong.ai ****************************************** + */ + @Select("select id from uf_targetsettingdat where sqr = #{userId} and nf = #{currentYear}") + List selectMainIdsByUserIdAndYear(@ParamMapper("userId") Integer userId, + @ParamMapper("currentYear") String currentYear); + + + /** + *

根据主表id查询明细数据

+ * 2022/12/12 17:28 + * ************************************************************ + * + * @param list 主表id数组 + * @return List 明细权重 + * @author youHong.ai ****************************************** + */ + @Select("select qz from uf_targetsettingdat_dt1 where mainid in (${list})") + List selectWeightByMainIds(List list); +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/TriggerWorkflowToModelMapper.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/TriggerWorkflowToModelMapper.java new file mode 100644 index 0000000..3694ede --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/mapper/TriggerWorkflowToModelMapper.java @@ -0,0 +1,35 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper; + +import aiyh.utils.annotation.recordset.ParamMapper; +import aiyh.utils.annotation.recordset.Select; +import aiyh.utils.annotation.recordset.SqlMapper; + +import java.util.List; + +/** + *

查询数据库

+ * + *

create: 2022-12-09 22:26

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

查询当前节点上的流程转数据acitonId

+ * 2022/12/9 22:29 + * ****************************************** + * + * @param nodeId 当前节点id + * @return List 流程转数据的actionId + * @author youHong.ai ****************************************** + */ + @Select("select ACTIONID from mode_workflowtomodeset where TRIGGERNODEID = #{nodeId} " + + " and isenable = 1 and workflowid = #{workflowId}") + List selectActionId(@ParamMapper("nodeId") String nodeId, + @ParamMapper("workflowId") String workflowId); +} + diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/ApaLevelByScoreService.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/ApaLevelByScoreService.java new file mode 100644 index 0000000..8302ceb --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/ApaLevelByScoreService.java @@ -0,0 +1,34 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service; + +import aiyh.utils.Util; +import aiyh.utils.excention.CustomerException; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper.ApaLevelByScoreMapper; + +/** + *

+ * + *

create: 2022-12-13 10:40

+ * + * @author youHong.ai + */ + +public class ApaLevelByScoreService { + private final ApaLevelByScoreMapper mapper = Util.getMapper(ApaLevelByScoreMapper.class); + + /** + *

根据分数查询等级

+ * 2022/12/13 10:55 + * ************************************************************ + * + * @param score 分数 + * @return Integer 等级 + * @author youHong.ai ****************************************** + */ + public Integer getLevelByScore(Double score) { + Integer level = mapper.selectLevelByScore(score); + if (level < -1) { + throw new CustomerException("query level error, score is [" + score + ""); + } + return level; + } +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/NotAllowedClickTGSService.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/NotAllowedClickTGSService.java new file mode 100644 index 0000000..6a4f7b1 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/NotAllowedClickTGSService.java @@ -0,0 +1,47 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service; + +import aiyh.utils.Util; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper.NotAllowedClickTGSMapper; +import weaver.hrm.User; + +import java.util.List; +import java.util.Objects; + +/** + *

+ * + *

create: 2022-12-12 15:38

+ * + * @author youHong.ai + */ + +public class NotAllowedClickTGSService { + + + private final NotAllowedClickTGSMapper mapper = Util.getMapper(NotAllowedClickTGSMapper.class); + + /** + *

查询是否可以点击创建targetSetting流程

+ * 2022/12/12 17:29 + * ************************************************************ + * + * @param user 当前登陆用户 + * @return boolean 是否可以点击创建按钮 + * @author youHong.ai ****************************************** + */ + public boolean canAllowedClickTGSBtn(User user) { + List mainIdList = mapper.selectMainIdsByUserIdAndYear(user.getUID(), Util.getTime("yyyy")); + if (Objects.isNull(mainIdList) || mainIdList.isEmpty()) { + return true; + } + List qzList = mapper.selectWeightByMainIds(mainIdList); + if (Objects.isNull(qzList) || qzList.isEmpty()) { + return true; + } + Integer sum = qzList.stream() + .filter(item -> !Util.isNullOrEmpty(item)) + .map(Integer::parseInt) + .reduce(0, Integer::sum); + return sum < 100; + } +} diff --git a/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/TriggerWorkflowToModelService.java b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/TriggerWorkflowToModelService.java new file mode 100644 index 0000000..15ec446 --- /dev/null +++ b/src/main/java/com/api/youhong/ai/pcn/workflow/doworkflowtomodel/service/TriggerWorkflowToModelService.java @@ -0,0 +1,84 @@ +package com.api.youhong.ai.pcn.workflow.doworkflowtomodel.service; + +import aiyh.utils.Util; +import com.alibaba.fastjson.JSON; +import com.api.youhong.ai.pcn.workflow.doworkflowtomodel.mapper.TriggerWorkflowToModelMapper; +import org.apache.log4j.Logger; +import weaver.formmode.interfaces.action.WorkflowToMode; +import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; +import weaver.soa.workflow.request.RequestService; +import weaver.workflow.request.RequestManager; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + *

+ * + *

create: 2022-12-09 10:49

+ * + * @author youHong.ai + */ + +public class TriggerWorkflowToModelService { + private final RequestService service = new RequestService(); + + private final TriggerWorkflowToModelMapper mapper = Util.getMapper(TriggerWorkflowToModelMapper.class); + private final Logger log = Util.getLogger(); + + public String saveTriggerWorkflowToModel(Map params, HttpServletRequest request, User user) { + log.info("request param:" + JSON.toJSONString(params)); + String requestId = String.valueOf(params.get("requestId")); + String nodeId = String.valueOf(params.get("nodeId")); + String isBill = String.valueOf(params.get("isBill")); + String formId = String.valueOf(params.get("formId")); + String workflowId = String.valueOf(params.get("workflowId")); + RequestInfo requestInfo = service.getRequest(Integer.parseInt(requestId)); + requestInfo.setIspreadd("1"); + requestInfo.setWorkflowid(workflowId); + RequestManager requestManager = requestInfo.getRequestManager(); + requestManager.setRequest(request); + requestManager.setUser(user); + requestManager.setNodeid(Integer.parseInt(nodeId)); + requestManager.setIsbill(Integer.parseInt(isBill)); + requestManager.setFormid(Integer.parseInt(formId)); + requestManager.setWorkflowid(Integer.parseInt(workflowId)); + WorkflowToMode workflowToMode = new WorkflowToMode(); + workflowToMode.setNodeid(Integer.parseInt(nodeId)); + workflowToMode.setIp(getRemoteHost(request)); + List actionIds = mapper.selectActionId(nodeId, workflowId); + if (Objects.isNull(actionIds) || actionIds.isEmpty()) { + return "can not query actionIds;"; + } + List failAction = new ArrayList<>(); + for (Integer actionId : actionIds) { + workflowToMode.setActionid(actionId); + if ("0".equals(workflowToMode.execute(requestInfo))) { + failAction.add("[" + actionId + "]: " + requestManager.getMessagecontent() + "\t" + requestManager.getMessage()); + } + } + if (failAction.isEmpty()) { + return "success"; + } + log.error(Util.join(failAction, "\n")); + return "action execute finish! execute fail!"; + } + + private String getRemoteHost(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; + } +} diff --git a/src/main/java/weaver/xiao/commons/config/dao/ConfigMappingCMD.java b/src/main/java/weaver/xiao/commons/config/dao/ConfigMappingCMD.java index abd7130..cc32fb7 100644 --- a/src/main/java/weaver/xiao/commons/config/dao/ConfigMappingCMD.java +++ b/src/main/java/weaver/xiao/commons/config/dao/ConfigMappingCMD.java @@ -2,10 +2,7 @@ package weaver.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.entity.*; import weaver.xiao.commons.config.enumtype.DataSourceEnum; import weaver.xiao.commons.exception.ValueDealException; import weaver.xiao.commons.utils.SqlUtil; @@ -108,17 +105,22 @@ public class ConfigMappingCMD { 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); + try { + + //查询明细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); + } catch (Exception ignore) { + + } requestMappingConfig.setConfigDetail(mappingDetails); } diff --git a/src/main/java/weaver/xiao/commons/config/entity/MultipartFile.java b/src/main/java/weaver/xiao/commons/config/entity/MultipartFile.java index 0e8e73f..ae4f4a9 100644 --- a/src/main/java/weaver/xiao/commons/config/entity/MultipartFile.java +++ b/src/main/java/weaver/xiao/commons/config/entity/MultipartFile.java @@ -34,4 +34,14 @@ public class MultipartFile { * 文件大小 */ Long fileSize; + + /** + * 文件id + */ + private Integer imageFileId; + + /** + * docId + */ + private Integer docId; } diff --git a/src/main/java/weaver/xiao/commons/config/entity/ResponseMapping.java b/src/main/java/weaver/xiao/commons/config/entity/ResponseMapping.java index eb74d44..0af8dcc 100644 --- a/src/main/java/weaver/xiao/commons/config/entity/ResponseMapping.java +++ b/src/main/java/weaver/xiao/commons/config/entity/ResponseMapping.java @@ -1,6 +1,7 @@ package weaver.xiao.commons.config.entity; import lombok.Data; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; /** * @author XiaoBokang @@ -9,9 +10,19 @@ import lombok.Data; @Data public class ResponseMapping { + + @SqlFieldMapping("responseFieldName") private String responseFieldName; + + @SqlFieldMapping("workflowField") private String workflowField; - private String mainOrDetail; + + @SqlFieldMapping("mainOrDetail") + private Integer mainOrDetail; + + @SqlFieldMapping("detailTableId") private String detailTableId; + + @SqlFieldMapping("workflowFieldName") private String workflowFieldName; -} +} \ No newline at end of file diff --git a/src/main/java/weaver/xiao/commons/config/entity/WeaverFile.java b/src/main/java/weaver/xiao/commons/config/entity/WeaverFile.java new file mode 100644 index 0000000..471b71e --- /dev/null +++ b/src/main/java/weaver/xiao/commons/config/entity/WeaverFile.java @@ -0,0 +1,28 @@ +package weaver.xiao.commons.config.entity; + +import lombok.Data; +import weaver.xiao.commons.utils.annotation.SqlFieldMapping; + +import java.io.InputStream; + +/** + *

文件信息实体类

+ * + * @author XiaoBokang + * @create 2022/8/8 10:24 + */ + +@Data +public class WeaverFile { + + @SqlFieldMapping("imagefilename") + String fileName; + + @SqlFieldMapping("imagefileid") + String imageFileId; + + @SqlFieldMapping("docid") + String docId; + + InputStream inputStream; +} diff --git a/src/main/java/weaver/xiao/commons/config/enumtype/ParamTypeEnum.java b/src/main/java/weaver/xiao/commons/config/enumtype/ParamTypeEnum.java index 8ae2604..c8c40ba 100644 --- a/src/main/java/weaver/xiao/commons/config/enumtype/ParamTypeEnum.java +++ b/src/main/java/weaver/xiao/commons/config/enumtype/ParamTypeEnum.java @@ -5,10 +5,15 @@ import java.util.HashMap; import java.util.Map; /** + *

参数类型枚举类

* @author XiaoBokang * @create 2022/6/14 12:56 + *

版本改动说明 :

+ *

+ * v2.0 xuanran.wang 2022-12-06 + * 增加Object类型的枚举 字段值来自于自定义接口时可以选此选项 保留自定义接口返回参数类型 + *

*/ - public enum ParamTypeEnum { STRING("0"), @@ -21,7 +26,8 @@ public enum ParamTypeEnum { CUS_DATE_STR("7"), TIME_STAMP("8"), DATE_VAL("9"), - Boolean("10"); + Boolean("10"), + Object("11"); private static final Map LOOK_UP = new HashMap<>(8); 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 df97287..ebc7b22 100644 --- a/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java +++ b/src/main/java/weaver/xiao/commons/config/service/DealWithMapping.java @@ -380,7 +380,7 @@ public class DealWithMapping extends ToolUtil { List tempList = new ArrayList(); for (Object o : list) { if (o instanceof Map) { -// map处理 key->1的类型 + // map处理 key->1的类型 Map mapItem = (Map) o; Map> tempMap = new HashMap<>(8); for (Map.Entry entry : mapItem.entrySet()) { @@ -426,11 +426,11 @@ public class DealWithMapping extends ToolUtil { } } } -// tempList.addAll(list); + // tempList.addAll(list); requestParam.put(paramName, tempList); -// if (!tempList.isEmpty()) { -// requestParam.put(paramName, tempList); -// } + // if (!tempList.isEmpty()) { + // requestParam.put(paramName, tempList); + // } } else { Object value = this.normalValueDeal(mainMap, detailMap, mappingDetail); if (!Objects.isNull(value)) { @@ -471,7 +471,7 @@ public class DealWithMapping extends ToolUtil { List tempList = new ArrayList(); for (Object o : list) { if (o instanceof Map) { -// map处理 + // map处理 Map mapItem = (Map) o; Map> tempMap = new HashMap<>(8); for (Map.Entry entry : mapItem.entrySet()) { @@ -517,11 +517,11 @@ public class DealWithMapping extends ToolUtil { } } } -// tempList.addAll(list); + // tempList.addAll(list); requestParam.put(paramName, tempList); -// if (!tempList.isEmpty()) { -// requestParam.put(paramName, tempList); -// } + // if (!tempList.isEmpty()) { + // requestParam.put(paramName, tempList); + // } } else { Object value = this.normalValueDeal(mainMap, detailMap, relationRs, mappingDetail); if (!Objects.isNull(value)) { @@ -538,11 +538,10 @@ public class DealWithMapping extends ToolUtil { * @param detailMap 明细数据结果集 * @param mappingDetail 配置节点信息 * - *

代码版本改动说明:

- *

- * v2.0 xuanran.wang 转换类型是默认值时增加替换规则 - * 将自定义文本中的{?requestid}替换成requestid 以及将 ? 替换成选择的流程字段对应的值 - *

+ *

代码版本改动说明:

+ *

+ * v2.0 xuanran.wang 转换类型是默认值时增加替换规则 将自定义文本中的{?requestid}替换成requestid 以及将 {?} 替换成选择的流程字段对应的值 + *

*/ private Object normalValueDeal(Map mainMap, Map detailMap, MappingDetail mappingDetail) { @@ -570,7 +569,7 @@ public class DealWithMapping extends ToolUtil { case DEFAULT_VALUE: { FieldMessage fieldMassage = mappingDetail.getFieldMassage(); String workFlowVal = ""; - if(fieldMassage != null){ + if (fieldMassage != null) { String fieldName = fieldMassage.getFieldName().toLowerCase(); if ("1".equals(childSource)) { workFlowVal = Util.null2String(detailMap.get(fieldName)); @@ -580,7 +579,7 @@ public class DealWithMapping extends ToolUtil { } value = Util.null2String(valueContext) .replace("{?requestid}", String.valueOf(mainMap.get("requestid"))) - .replace("?", workFlowVal); + .replace("{?}", workFlowVal); } break; // 当前时间 @@ -619,7 +618,7 @@ public class DealWithMapping extends ToolUtil { } else { value = Util.null2String(mainMap.get("id")); } -// value = Util.null2String(main.getString("id")); + // value = Util.null2String(main.getString("id")); } break; // 随机数 @@ -658,7 +657,7 @@ public class DealWithMapping extends ToolUtil { } return null; } -// 自定义接口 + // 自定义接口 case CUS_INTERFACE: { if (null == valueContext || valueContext.length() == 0) { } else { @@ -781,6 +780,10 @@ public class DealWithMapping extends ToolUtil { value = Boolean.valueOf(String.valueOf(value)); } break; + case Object: { + // 当是object类型时不转换 保留原有格式 + } + break; default: return value; } @@ -796,11 +799,10 @@ public class DealWithMapping extends ToolUtil { * @param mappingDetail 配置节点信息 * @param relationRs 关联流程数据集合 * - *

代码版本改动说明:

- *

- * v2.0 xuanran.wang 转换类型是默认值时增加替换规则 - * 将自定义文本中的{?requestid}替换成requestid 以及将 ? 替换成选择的流程字段对应的值 - *

+ *

代码版本改动说明:

+ *

+ * v2.0 xuanran.wang 转换类型是默认值时增加替换规则 将自定义文本中的{?requestid}替换成requestid 以及将 {?} 替换成选择的流程字段对应的值 + *

*/ private Object normalValueDeal(Map mainMap, Map detailMap, RecordSet relationRs, MappingDetail mappingDetail) { String paramType = mappingDetail.getParamType(); @@ -834,7 +836,7 @@ public class DealWithMapping extends ToolUtil { case DEFAULT_VALUE: { FieldMessage fieldMassage = mappingDetail.getFieldMassage(); String workFlowVal = ""; - if(fieldMassage != null){ + if (fieldMassage != null) { String fieldName = fieldMassage.getFieldName().toLowerCase(); if ("1".equals(childSource)) { workFlowVal = Util.null2String(detailMap.get(fieldName)); @@ -849,7 +851,7 @@ public class DealWithMapping extends ToolUtil { } value = Util.null2String(valueContext) .replace("{?requestid}", String.valueOf(mainMap.get("requestid"))) - .replace("?", workFlowVal); + .replace("{?}", workFlowVal); } break; // 当前时间 @@ -932,6 +934,8 @@ public class DealWithMapping extends ToolUtil { MultipartFile multipartFile = new MultipartFile(); InputStream fileInputStream = ImageFileManager.getInputStreamById(docImageFile.getImageFileId()); multipartFile.setFileKey(paramName); + multipartFile.setImageFileId(docImageFile.getImageFileId()); + multipartFile.setDocId(docImageFile.getDocId()); multipartFile.setStream(fileInputStream); multipartFile.setFileName(docImageFile.getImageFileName()); multipartFile.setFileSize(docImageFile.getFileSize() / 1024); @@ -939,7 +943,7 @@ public class DealWithMapping extends ToolUtil { } return null; } -// 自定义接口 + // 自定义接口 case CUS_INTERFACE: { if (null == valueContext || valueContext.length() == 0) { } else { @@ -1063,6 +1067,10 @@ public class DealWithMapping extends ToolUtil { value = Boolean.valueOf(String.valueOf(value)); } break; + case Object: { + // 当是object类型时不转换 保留原有格式 + } + break; default: return value; } @@ -1116,10 +1124,10 @@ public class DealWithMapping extends ToolUtil { list.add(o); } } -// for (MappingDetail mappingDetail : childList) { -// Object o = this.normalValueDeal(recordSet, 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); @@ -1195,10 +1203,10 @@ public class DealWithMapping extends ToolUtil { list.add(o); } } -// for (MappingDetail mappingDetail : childList) { -// Object o = this.normalValueDeal(recordSet, 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); @@ -1231,6 +1239,46 @@ public class DealWithMapping extends ToolUtil { } } + /** + *

请求结果赋值到配置信息中

+ * + * @param responseMappingList 回写信息配置列表 + * @param requestRes 请求结果 + * @return 要插入的信息 + */ + public Map> dealResponse(List responseMappingList, Map requestRes) { + this.writeDebuggerLog("回写信息转换处理 responseMappingList==>" + responseMappingList + " requestRes==>" + requestRes); + Map> tableUpdateMap = new HashMap<>(); + if (responseMappingList != null && !responseMappingList.isEmpty()) { + Map mainUpdateMap = new HashMap<>(); + List detailResponseList = new ArrayList<>(); + for (ResponseMapping responseMapping : responseMappingList) { + if (responseMapping.getMainOrDetail() == 0) { + String resVal = Util.null2String(requestRes.get(responseMapping.getResponseFieldName())); + mainUpdateMap.put(responseMapping.getWorkflowFieldName(), resVal); + } else { + detailResponseList.add(responseMapping); + } + } + tableUpdateMap.put(mainTable, mainUpdateMap); + Map> groupMap = detailResponseList.stream().collect(Collectors.groupingBy(ResponseMapping::getDetailTableId)); + Set>> entries = groupMap.entrySet(); + for (Map.Entry> entry : entries) { + Map detailUpdateMap = new HashMap<>(); + String detailId = entry.getKey(); + List responseMappings = entry.getValue(); + String detailTableName = mainTable + "_dt" + detailId; + for (ResponseMapping responseMapping : responseMappings) { + String resVal = Util.null2String(requestRes.get(responseMapping.getResponseFieldName())); + detailUpdateMap.put(responseMapping.getWorkflowFieldName(), resVal); + } + tableUpdateMap.put(detailTableName, detailUpdateMap); + } + } + this.writeDebuggerLog("回写信息tableUpdateMap==> " + tableUpdateMap); + return tableUpdateMap; + } + /** * 自定义时间格式化 * @@ -1299,7 +1347,7 @@ public class DealWithMapping extends ToolUtil { String classPath = split[0]; String paramStr = ""; if (split.length > 1) { - paramStr = Arrays.stream(split).skip(1).collect(Collectors.joining("")); + 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}&" + @@ -1327,10 +1375,10 @@ public class DealWithMapping extends ToolUtil { 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类,将参数传递给这个类, 使用``包裹的字符串会被解析为一个字符串 + // 最终通过反射调用weaver.aiyh_jitu.pushdata.service.GetAssignProcessorProcessorImpl类,将参数传递给这个类, 使用``包裹的字符串会被解析为一个字符串 String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + - "(?((`([():/\\-&$#={ }.\\w\\u4E00-\\u9FA5?]*)`)|" + - "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + "(?((`([^`]*)`)|" + + "((#(\\{|sql\\{))?([():/\\-$_#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; Pattern compile = Pattern.compile(pattern); Matcher matcher = compile.matcher(paramStr); while (matcher.find()) { diff --git a/src/main/java/weaver/xiao/commons/core/BaseActionHandleFunction.java b/src/main/java/weaver/xiao/commons/core/BaseActionHandleFunction.java new file mode 100644 index 0000000..6639a1f --- /dev/null +++ b/src/main/java/weaver/xiao/commons/core/BaseActionHandleFunction.java @@ -0,0 +1,25 @@ +package weaver.xiao.commons.core; + +import weaver.hrm.User; +import weaver.workflow.request.RequestManager; + +/** + * @ClassName BaseActionHandleFunction + * @Author 肖博亢 + * @Date 2022/11/25 12:17 + * @Description

流程提交类型处理方法

+ **/ +@FunctionalInterface +public interface BaseActionHandleFunction { + /** + *

流程处理方法action

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestManager 请求管理对象 + */ + void handle(String requestId, String billTable, int workflowId, + User user, RequestManager requestManager) throws Exception; +} diff --git a/src/main/java/weaver/xiao/commons/core/CusBaseAction.java b/src/main/java/weaver/xiao/commons/core/CusBaseAction.java new file mode 100644 index 0000000..51b2775 --- /dev/null +++ b/src/main/java/weaver/xiao/commons/core/CusBaseAction.java @@ -0,0 +1,276 @@ +package weaver.xiao.commons.core; + +import org.apache.log4j.Logger; +import weaver.conn.RecordSetTrans; +import weaver.hrm.User; +import weaver.interfaces.workflow.action.Action; +import weaver.soa.workflow.request.*; +import weaver.workflow.request.RequestManager; +import weaver.workflow.workflow.WorkflowBillComInfo; +import weaver.workflow.workflow.WorkflowComInfo; +import weaver.xiao.commons.utils.LogUtil; +import weaver.xiao.commons.utils.VerifyUtil; + +import java.util.*; + + +/** + * @ClassName BaseAction + * @Author 肖博亢 + * @Date 2022/11/25 12:09 + * @Description

实现Action接口并具备一些基本功能

+ **/ +public abstract class CusBaseAction implements Action { + + /** 全局日志对象 */ + protected final Logger log = LogUtil.getLogger(); + + /** 全局requestInfo对象 */ + protected RequestInfo requestInfo; + + /** 全局数据处理事务类 */ + protected RecordSetTrans recordSetTrans = new RecordSetTrans(); + + /** 流程提交方式处理方法集合 */ + private final Map actionHandleMethod = new HashMap<>(); + + + /** + *

初始化流程默认的处理方法

+ */ + private void initHandleMethod() { + //提交 + actionHandleMethod.put(ActionRunType.SUBMIT, this::doSubmit); + //退回 + actionHandleMethod.put(ActionRunType.REJECT, this::doReject); + //撤回 + actionHandleMethod.put(ActionRunType.WITHDRAW, this::doWithdraw); + //强制收回 + actionHandleMethod.put(ActionRunType.DRAW_BACK, this::doDrawBack); + } + + @Override + public final String execute(RequestInfo requestInfo) { + this.requestInfo = requestInfo; + RequestManager requestManager = requestInfo.getRequestManager(); + String billTable = requestManager.getBillTableName(); + String requestId = requestInfo.getRequestid(); + User user = requestInfo.getRequestManager().getUser(); + int workflowId = requestManager.getWorkflowid(); + //操作类型 submit - 提交 reject - 退回 等 + String src = requestManager.getSrc(); + if ("".equals(billTable)) { + WorkflowComInfo workflowComInfo = new WorkflowComInfo(); + String formId = workflowComInfo.getFormId(String.valueOf(workflowId)); + WorkflowBillComInfo workflowBillComInfo = new WorkflowBillComInfo(); + billTable = workflowBillComInfo.getTablename(formId); + } + try { + VerifyUtil.requireVerify(this); + if (VerifyUtil.isBlank(src)) { + src = "submit"; + } + //初始化默认的流程处理方法 + initHandleMethod(); + //提供自定义注册处理方法 + registerHandler(actionHandleMethod); + //获取流程对应的处理方法 + BaseActionHandleFunction cusBaseActionHandleFunction = actionHandleMethod.get(src); + //默认没有直接成功不做拦截 + if (null == cusBaseActionHandleFunction) { + return Action.SUCCESS; + } + cusBaseActionHandleFunction.handle(requestId, billTable, workflowId, user, requestManager); + }catch (Exception e) { + e.printStackTrace(); + log.info("action执行异常 ==>"+LogUtil.getExceptionStr(e)); + String message = doExceptionDeal(e,requestId,workflowId,user,requestManager); + requestInfo.getRequestManager().setMessageid("11111C " + requestId + " 22222"); + requestInfo.getRequestManager().setMessagecontent(message); + return Action.FAILURE_AND_CONTINUE; + } + return Action.SUCCESS; + } + + /** + *

流程其他流转类型处理方法注册

+ * + * @param actionHandleMethod 处理方法对应map + */ + public void registerHandler(Map actionHandleMethod) { + } + + + /** + *

action 提交流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 + * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestManager 请求管理对象 + */ + + public abstract void doSubmit(String requestId, String billTable, int workflowId, + User user, RequestManager requestManager) throws Exception; + + + /** + *

action 退回流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 + * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestManager 请求管理对象 + */ + public void doReject(String requestId, String billTable, int workflowId, + User user, RequestManager requestManager) throws Exception{ + } + + /** + *

action 撤回、撤回流程流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 + * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestManager 请求管理对象 + */ + public void doWithdraw(String requestId, String billTable, int workflowId, + User user, RequestManager requestManager) throws Exception{ + } + + + /** + *

action 强制收回流程业务处理方法

+ *

具体业务逻辑实现 + * 全局存在log成员变量,用于日志的输出 + * Util.actionFailException(requestManager,"error msg"); 用于提示action执行失败 + *

+ * + * @param requestId 流程请求ID + * @param billTable 流程对应主表名称 + * @param workflowId 流程对应流程ID + * @param user 当前节点操作者用户 + * @param requestManager 请求管理对象 + */ + public void doDrawBack(String requestId, String billTable, int workflowId, + User user, RequestManager requestManager) throws Exception{ + } + + /** + *

action 发生异常处理方法

+ * @param e 异常信息 + * @param requestId 请求id + * @param workflowId 流程id + * @param user 用户信息 + * @param requestManager 请求管理对象 + * @return 提示信息 + */ + public abstract String doExceptionDeal(Exception e,String requestId,int workflowId,User user,RequestManager requestManager); + + /** + *

获取流程主表数据

+ * + * @return 流程主表数据 + */ + protected Map getMainTableValue() { + //获取主表数据 + 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() { + DetailTable[] detailTableArr = requestInfo.getDetailTableInfo().getDetailTable(); + Map>> detailDataList = new HashMap<>((int) Math.ceil(detailTableArr.length * 1.4)); + for (DetailTable detailTable : detailTableArr) { + List> detailData = getDetailValue(detailTable); + detailDataList.put(detailTable.getId(), detailData); + } + return detailDataList; + } + + + /** + *

获取指定明细表的表数据

+ * + * @param detailNo 明细表编号 + * @return 明细数据 + */ + protected List> getDetailTableValueByDetailNo(int detailNo) { + DetailTable detailTable = requestInfo.getDetailTableInfo().getDetailTable(detailNo); + return getDetailValue(detailTable); + } + + /** + *

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

+ * + * @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 * (1 + 0.4))); + rowData.put("id", row.getId()); + for (Cell cell : cellArr) { + String fieldName = cell.getName(); + String value = cell.getValue(); + rowData.put(fieldName, value); + } + detailData.add(rowData); + } + return detailData; + } + + + public static final class ActionRunType { + /** + * 退回 + */ + public static final String REJECT = "reject"; + /** + * 撤回 + */ + public static final String WITHDRAW = "withdraw"; + /** + * 强制收回 + */ + public static final String DRAW_BACK = "drawBack"; + /** + * 提交 + */ + public static final String SUBMIT = "submit"; + } + +} diff --git a/src/main/java/weaver/xiao/commons/exception/VerifyException.java b/src/main/java/weaver/xiao/commons/exception/VerifyException.java new file mode 100644 index 0000000..724b955 --- /dev/null +++ b/src/main/java/weaver/xiao/commons/exception/VerifyException.java @@ -0,0 +1,21 @@ +package weaver.xiao.commons.exception; + +/** + * @author XiaoBokang + * @create 2022/7/28 14:47 + */ + +public class VerifyException extends RuntimeException{ + public VerifyException(String message){ + super(message); + } + + public VerifyException(String message, Throwable cause) { + super(message, cause); + } + + @Override + public synchronized Throwable fillInStackTrace() { + return super.fillInStackTrace(); + } +} diff --git a/src/main/java/weaver/xiao/commons/utils/DocImageFileUtil.java b/src/main/java/weaver/xiao/commons/utils/DocImageFileUtil.java new file mode 100644 index 0000000..9d2b53a --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/DocImageFileUtil.java @@ -0,0 +1,292 @@ +package weaver.xiao.commons.utils; + +import aiyh.utils.excention.CustomerException; +import org.apache.log4j.Logger; +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.hrm.User; +import weaver.xiao.commons.config.entity.WeaverFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + + +/** + * @author XiaoBokang + * @create 2022/7/28 16:05 + */ + +public class DocImageFileUtil { + + private static final Logger logger = LogUtil.getLogger(); + + public static final String DOC = "doc"; + public static final String XLS = "xls"; + public static final String PPTX = "pptx"; + public static final String PPT = "ppt"; + public static final String WPS = "wps"; + public static final String DOCX = "docx"; + public static final String XLSX = "xlsx"; + private static final int BUFFER_SIZE = 2 * 1024; + + /** + *

zip解压

+ * @param srcFile zip源文件 + * @param destDirPath 解压后的目标文件夹 + * @throws RuntimeException 解压失败会抛出运行时异常 + */ + public static void unZip(File srcFile, String destDirPath) throws RuntimeException { + long start = System.currentTimeMillis(); + // 判断源文件是否存在 + if (!srcFile.exists()) { + throw new RuntimeException(srcFile.getPath() + "所指文件不存在"); + } + // 开始解压 + ZipFile zipFile = null; + try { + zipFile = new ZipFile(srcFile, Charset.forName("GBK")); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + System.out.println("解压" + entry.getName()); + // 如果是文件夹,就创建个文件夹 + if (entry.isDirectory()) { + String dirPath = destDirPath + "/" + entry.getName(); + File dir = new File(dirPath); + dir.mkdirs(); + } else { + // 如果是文件,就先创建一个文件,然后用io流把内容copy过去 + File targetFile = new File(destDirPath + "/" + entry.getName()); + // 保证这个文件的父文件夹必须存在 + if(!targetFile.getParentFile().exists()){ + targetFile.getParentFile().mkdirs(); + } + targetFile.createNewFile(); + // 将压缩文件内容写入到这个文件中 + InputStream is = zipFile.getInputStream(entry); + FileOutputStream fos = new FileOutputStream(targetFile); + int len; + byte[] buf = new byte[BUFFER_SIZE]; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + } + // 关流顺序,先打开的后关闭 + fos.close(); + is.close(); + } + } + } catch (Exception e) { + logger.info("解压文件出现异常 ==>"+LogUtil.getExceptionStr(e)); + throw new RuntimeException("unzip error from ZipUtils", e); + } finally { + if(zipFile != null){ + try { + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + *

压缩成ZIP方法

+ * @param srcFiles 需要压缩的文件列表 + * @param out 压缩文件输出流 + * @throws RuntimeException 压缩失败会抛出运行时异常 + */ + public static void toZip(List srcFiles , OutputStream out)throws Exception { + long start = System.currentTimeMillis(); + ZipOutputStream zos = null ; + try { + zos = new ZipOutputStream(out); + for (File srcFile : srcFiles) { + byte[] buf = new byte[BUFFER_SIZE]; + zos.putNextEntry(new ZipEntry(srcFile.getName())); + int len; + FileInputStream in = new FileInputStream(srcFile); + while ((len = in.read(buf)) != -1){ + zos.write(buf, 0, len); + } + zos.closeEntry(); + in.close(); + } + long end = System.currentTimeMillis(); + System.out.println("压缩完成,耗时:" + (end - start) +" ms"); + } catch (Exception e) { + logger.info("压缩文件出现异常 ==>"+LogUtil.getExceptionStr(e)); + throw new RuntimeException("zip error from ZipUtils",e); + }finally{ + if(zos != null){ + try { + zos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + * 在指定目录下生成对应的压缩文件 + * @param fileList 文件集合列表 + * @param dirPath 目录 + * @param fileName 压缩文件名 + */ + public static void toZipFileName(List fileList,String dirPath,String fileName) throws IOException { + String filePath = dirPath + File.separator + fileName; + File file = new File(filePath); + if(!file.exists()){ + file.createNewFile(); + } + OutputStream outputStream = Files.newOutputStream(file.toPath()); + toZipByWeaverFile(fileList,outputStream); + } + + /** + * 将文件集合压缩 + * @param fileList 文件信息集合 + * @param outputStream 压缩文件输出流 + */ + public static void toZipByWeaverFile(List fileList, OutputStream outputStream){ + ZipOutputStream zos = null ; + try { + zos = new ZipOutputStream(outputStream); + for (WeaverFile weaverFile : fileList) { + byte[] buf = new byte[BUFFER_SIZE]; + zos.putNextEntry(new ZipEntry(weaverFile.getFileName())); + int len; + InputStream inputStream = weaverFile.getInputStream(); + while ((len = inputStream.read(buf)) != -1){ + zos.write(buf, 0, len); + } + inputStream.close(); + zos.closeEntry(); + } + zos.flush(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("zip error from ZipUtils",e); + }finally{ + if(zos != null){ + try { + zos.finish(); + zos.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + *

创建物理文件

+ * @param content 文件流 + * @param fileName 文件名 + * @return 文件id + */ + public static int createFileByInputSteam(InputStream content, String fileName) { + ImageFileManager imageFileManager = new ImageFileManager(); + int imgFileId = -1; + try { + ImageFileManager.class.getMethod("saveImageFileByInputStream", InputStream.class, String.class); + imgFileId = imageFileManager.saveImageFileByInputStream(content, fileName); + } catch (NoSuchMethodException e) { + imageFileManager.setImagFileName(fileName); + try { + imageFileManager.setData(IOUtils.toBytes(content)); + } catch (Exception ex) { + throw new CustomerException("创建文件失败,文件流转换失败", e); + } + imgFileId = imageFileManager.saveImageFile(); + } catch (Exception e) { + throw new CustomerException("创建文件失败"); + } + return imgFileId; + } + + /** + *

创建文件信息,文件权限继承文档目录权限

+ * + * @param fileName 文件名称 + * @param secCategory 文件目录 + * @param imageFileId 物理文件ID + * @param userId 用户ID + * @return 文档ID + * @throws Exception 可能会出现的异常 + */ + public static int createDocByImageFileId(String fileName, int secCategory, int imageFileId, int userId) throws Exception { + DocInfo docInfo = new DocInfo(); + docInfo.setImagefileId(imageFileId); + docInfo.setSeccategory(secCategory); + docInfo.setDocSubject(fileName); + docInfo.setDoccontent(""); + DocServiceImpl docService = new DocServiceImpl(); + int docId = docService.createDocByUser(docInfo, new User(userId)); + 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 tempFilePath 临时文件路径 + */ + public static void deleteTempFile(String tempFilePath){ + logger.info("=========删除临时文件:"+tempFilePath+"================"); + boolean deleteFlag = true; + int n = 0; + while (deleteFlag) { + try { + n++; + Files.delete(Paths.get(tempFilePath)); + deleteFlag = false; + } catch (Exception e) { + //设置线程沉睡500毫秒,等待jvm进行垃圾回收,将持有临时文件的流对象回收,确保临时文件能删除 + try { + Thread.sleep(500); + } catch (InterruptedException interruptedException) { + deleteFlag = false; + } + if (n > 5) { + deleteFlag = false; + } + } + } + } + +} diff --git a/src/main/java/weaver/xiao/commons/utils/HttpManager.java b/src/main/java/weaver/xiao/commons/utils/HttpManager.java new file mode 100644 index 0000000..7ffa86c --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/HttpManager.java @@ -0,0 +1,98 @@ +package weaver.xiao.commons.utils; + +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; + + +/** + * @author XiaoBokang + * @create 2021/12/7 14:19 + */ + +public class HttpManager { + + /** + * 创建连接池管理对象 + */ + + + private static final int CONNECT_TIMEOUT = 1000 * 60 * 3; + private static final int CONNECTION_REQUEST_TIMEOUT = 1000 * 60 * 3; + private static final int SOCKET_TIMEOUT = 10000 * 60 * 3; + private static final int MAX_TOTAL = 500; + private static final int MAX_PRE_ROUTE = 500; + + /** + * 设置请求配置 + */ + static RequestConfig requestConfig = RequestConfig.custom() + //网络请求的超时时间 + .setConnectTimeout(CONNECT_TIMEOUT) + //连接池去获取连接的超时时间 + .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT) + //设置socket超时时间 + .setSocketTimeout(SOCKET_TIMEOUT) + .build(); + static PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); + static { + // 配置最大的连接数 + manager.setMaxTotal(MAX_TOTAL); + // 每个路由最大连接数(路由是根据host来管理的,大小不好控制) + manager.setDefaultMaxPerRoute(MAX_PRE_ROUTE); + } + + /** + * 获取连接对象 从连接池里面去获取,根据url创建对应的对象,http / https + * @param url 请求地址 + * @return 连接对象 + */ + public static CloseableHttpClient getHttpConnection(String url, CredentialsProvider credentialsProvider){ + if(url.trim().toUpperCase().startsWith("https".toUpperCase())){ + SSLContext sslContext; + SSLConnectionSocketFactory sslsf = null; + try { + sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> { +// 绕过所有验证 + return true; + }).build(); + HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; + sslsf = new SSLConnectionSocketFactory(sslContext,hostnameVerifier); + } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) { + e.printStackTrace(); + } + HttpClientBuilder httpClientBuilder = HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setConnectionManager(manager) + .setConnectionManagerShared(true) + .setDefaultRequestConfig(requestConfig); + if(credentialsProvider != null){ + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + return httpClientBuilder + .build(); + }else{ + HttpClientBuilder httpClientBuilder = HttpClients.custom() + .setConnectionManager(manager) + .setDefaultRequestConfig(requestConfig) + .setConnectionManagerShared(true); + if(credentialsProvider != null){ + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + return httpClientBuilder + .build(); + } + } +} diff --git a/src/main/java/weaver/xiao/commons/utils/RequestUtil.java b/src/main/java/weaver/xiao/commons/utils/RequestUtil.java index e8073b6..8fc8a73 100644 --- a/src/main/java/weaver/xiao/commons/utils/RequestUtil.java +++ b/src/main/java/weaver/xiao/commons/utils/RequestUtil.java @@ -10,9 +10,9 @@ 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.wechat.request.HttpManager; import weaver.xiao.commons.exception.RequestException; import weaver.zwl.common.ToolUtil; -import weaver.wechat.request.HttpManager; import javax.ws.rs.core.MediaType; import java.io.IOException; diff --git a/src/main/java/weaver/xiao/commons/utils/SFTPClientUtil.java b/src/main/java/weaver/xiao/commons/utils/SFTPClientUtil.java new file mode 100644 index 0000000..ddea61e --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/SFTPClientUtil.java @@ -0,0 +1,221 @@ +package weaver.xiao.commons.utils; + +import com.jcraft.jsch.*; +import org.apache.log4j.Logger; + +import java.io.File; +import java.io.FileOutputStream; +import java.nio.file.Files; +import java.util.Iterator; +import java.util.Properties; +import java.util.Vector; + +/** + * @author XiaoBokang + * @create 2022/8/10 12:07 + */ + +public class SFTPClientUtil { + + private final Logger logger = LogUtil.getLogger(); + + /** + * 连接sftp服务器 + * @param host 主机 + * @param port 端口 + * @param username 用户名 + * @param password 密码 + * @return + */ + public ChannelSftp connect(String host, int port, String username, String password) { + ChannelSftp sftp = null; + Channel channel=null; + Session sshSession=null; + try { + JSch jsch = new JSch(); + jsch.getSession(username, host, port); + sshSession = jsch.getSession(username, host, port); + if(logger.isInfoEnabled()){ + logger.info("***************** Session created. **********************"); + logger.info("***************** stf host is "+host+"port is "+port+" username is "+username+" password is "+password+"**********************"); + } + sshSession.setPassword(password); + Properties sshConfig = new Properties(); + sshConfig.put("StrictHostKeyChecking", "no"); + sshSession.setConfig(sshConfig); + sshSession.connect(); + if(logger.isInfoEnabled()){ + logger.info("***************** Session connected. **********************"); + logger.info("***************** Opening Channel. **********************"); + } + channel = sshSession.openChannel("sftp"); + channel.connect(); + sftp = (ChannelSftp) channel; + if(logger.isInfoEnabled()){ + logger.info("***************** Connected to " + host + ". **********************"); + } + } catch (Throwable e) { + if (channel!=null) { + try { + channel.disconnect(); + }catch(Throwable e1) { + } + } + + if (sshSession!=null) { + try { + sshSession.disconnect(); + }catch(Throwable e1) { + } + } + + logger.error(e.getMessage(), e); + } + return sftp; + } + + /** + * 关闭连接 + * @param sftp + */ + public void disconnect(String host, ChannelSftp sftp){ + // 关闭连接 + try { + if (null != sftp) { + sftp.disconnect(); + if(logger.isInfoEnabled()){ + logger.info("***************** Closing Channel. **********************"); + } + if (null != sftp.getSession()) { + sftp.getSession().disconnect(); + if(logger.isInfoEnabled()){ + logger.info("***************** Session disconnect. **********************"); + } + } + } + if (logger.isInfoEnabled()) { + logger.info("**************** Disconnect to " + host + ". *******************"); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 判断目录下是否存在文件或者文件夹 + * @param directory 目录 + * @param fileName 文件 + * @param sftp 连接 + * @return 是否存在 + */ + public boolean isExist(String directory, String fileName, ChannelSftp sftp) { + try { + Vector v = listFiles(directory, sftp); + Iterator it = v.iterator(); + while (it.hasNext()) { + ChannelSftp.LsEntry entry = it.next(); + String flName = entry.getFilename(); + if (flName.equals(fileName)) { + return true; + } + } + } catch (SftpException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 上传文件 + * @param directory 上传的目录 + * @param uploadFile 要上传的文件 + * @param sftp 连接 + */ + public boolean upload(String directory, String uploadFile, ChannelSftp sftp) { + boolean successFlg = true; + try { + sftp.cd(directory); + File file = new File(uploadFile); + sftp.put(Files.newInputStream(file.toPath()), file.getName()); + if(logger.isInfoEnabled()){ + logger.info("***************** Finished **********************"); + } + } catch (Exception e) { + successFlg = false; + logger.info(LogUtil.getExceptionStr(e)); + } + return successFlg; + } + + /** + * 下载文件 + * @param directory 下载目录 + * @param downloadFile 下载的文件 + * @param saveFile 存在本地的路径 + * @param sftp 连接 + */ + public boolean download(String directory, String downloadFile, String saveFile, ChannelSftp sftp) { + boolean successFlg = true; + try { + sftp.cd(directory); + File file = new File(saveFile); + if(!file.getParentFile().exists()){ + file.getParentFile().mkdirs(); + } + sftp.get(downloadFile, new FileOutputStream(file)); + if(logger.isInfoEnabled()){ + logger.info("***************** Finished **********************"); + } + } catch (Exception e) { + successFlg = false; + logger.info(LogUtil.getExceptionStr(e)); + } + return successFlg; + } + + /** + * 删除文件 + * @param directory 要删除文件所在目录 + * @param deleteFile 要删除的文件 + * @param sftp 连接 + */ + public void delete(String directory, String deleteFile, ChannelSftp sftp) { + try { + sftp.cd(directory); + sftp.rm(deleteFile); + if(logger.isInfoEnabled()){ + logger.info("***************** Finished **********************"); + } + if (null != sftp) { + sftp.disconnect(); + if (null != sftp.getSession()) { + sftp.getSession().disconnect(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 列出目录下的文件 + * @param directory 要列出的目录 + * @param sftp 连接 + * @return + * @throws SftpException + */ + @SuppressWarnings("unchecked") + public Vector listFiles(String directory, ChannelSftp sftp) throws SftpException { + return sftp.ls(directory); + } + + /** + * 判断本地路径是否存在,不存在就创建路径 + */ + public void makeDirs(String localSavePath) { + File localFile = new File(localSavePath); + if (!localFile.exists()) { + localFile.mkdirs(); + } + } +} diff --git a/src/main/java/weaver/xiao/commons/utils/SqlUtil.java b/src/main/java/weaver/xiao/commons/utils/SqlUtil.java index 8d6a386..12e6bf6 100644 --- a/src/main/java/weaver/xiao/commons/utils/SqlUtil.java +++ b/src/main/java/weaver/xiao/commons/utils/SqlUtil.java @@ -8,7 +8,6 @@ import weaver.general.TimeUtil; import weaver.general.Util; import weaver.xiao.commons.utils.annotation.SqlFieldMapping; - import java.lang.reflect.Field; import java.util.*; @@ -59,6 +58,7 @@ public class SqlUtil { case 2:{ valueText = this.getFieldVal(fieldType,value); }break; + default:break; } field.set(res,valueText); } @@ -78,18 +78,51 @@ public class SqlUtil { */ public Object getFieldVal(Class fieldType,String tempValue){ Object fieldVal = null; - if(fieldType.equals(int.class)){ + if(fieldType.equals(Integer.class)){ fieldVal = Util.getIntValue(tempValue); }else if(fieldType.equals(String.class)){ fieldVal = Util.null2String(tempValue); - }else if(fieldType.equals(boolean.class)){ + }else if(fieldType.equals(Boolean.class)){ fieldVal = Boolean.parseBoolean(tempValue); + }else if(fieldType.equals(Double.class)){ + fieldVal = Util.getDoubleValue(tempValue,0.0); }else { fieldVal = ""; } return fieldVal; } + /** + * 根据表名和条件获取结果集 + * @param tableName 表名 + * @param param 参数 + * @return 数据集合 + */ + public RecordSet getTableMessage(String tableName, Map param){ + List paramList = new ArrayList<>(); + RecordSet recordSet = new RecordSet(); + Set> entries = param.entrySet(); + StringBuilder whereBuilder = new StringBuilder(); + whereBuilder.append("select * from ").append(tableName); + for (Map.Entry entry : entries) { + if("cusSql".equals(entry.getKey())){ + whereBuilder.append(" and ").append(entry.getValue()); + continue; + } + whereBuilder.append(" and ") + .append(entry.getKey()) + .append(" = ? "); + paramList.add(entry.getValue()); + } + String whereStr = whereBuilder.toString(); + if(!"".equals(whereStr)){ + whereStr = whereStr.replaceFirst(" and"," where"); + } + logger.info("执行查询的sql>>>" + whereStr + " paramList>>>" + paramList); + recordSet.executeQuery(whereStr,paramList); + return recordSet; + } + /** * 构建更新语句 * @param tableName 表名 @@ -120,6 +153,10 @@ public class SqlUtil { updateBuilder.append(tableName).append(" set "); Set> updateEntries = updateParam.entrySet(); for (Map.Entry updateEntry : updateEntries) { + if("cusSql".equals(updateEntry.getKey())){ + updateBuilder.append(updateEntry.getValue()); + continue; + } updateBuilder.append(updateEntry.getKey()) .append(" = ?,"); paramList.add(updateEntry.getValue()); @@ -127,6 +164,10 @@ public class SqlUtil { StringBuilder whereBuilder = new StringBuilder(); Set> whereEntries = whereParam.entrySet(); for (Map.Entry whereEntry : whereEntries) { + if("cusSql".equals(whereEntry.getKey())){ + whereBuilder.append(" and ").append(whereEntry.getValue()); + continue; + } whereBuilder.append(" and ") .append(whereEntry.getKey()) .append(" = ? "); @@ -257,4 +298,22 @@ public class SqlUtil { return modeId; } + /** + * 全角转半角 + * @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/xiao/commons/utils/VerifyUtil.java b/src/main/java/weaver/xiao/commons/utils/VerifyUtil.java new file mode 100644 index 0000000..b727a0a --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/VerifyUtil.java @@ -0,0 +1,328 @@ +package weaver.xiao.commons.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; +import org.apache.log4j.Logger; +import org.jdom.Document; +import org.jdom.input.SAXBuilder; +import org.xml.sax.InputSource; +import weaver.xiao.commons.exception.ValueDealException; +import weaver.xiao.commons.exception.VerifyException; +import weaver.xiao.commons.utils.annotation.JsonParse; +import weaver.xiao.commons.utils.annotation.RequiredVerify; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.*; + +/** + * @author XiaoBokang + * @create 2022/7/28 12:38 + */ + +public class VerifyUtil { + + private static final Logger logger = LogUtil.getLogger(); + + public static void requireVerify(T t) throws IllegalAccessException { + Class clazz = t.getClass(); + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field declaredField : declaredFields) { + declaredField.setAccessible(true); + boolean annotationPresent = declaredField.isAnnotationPresent(RequiredVerify.class); + if (annotationPresent) { + Object value = declaredField.get(t); + Class type = declaredField.getType(); + boolean valueIsNull = isNull(type, value); + RequiredVerify annotation = declaredField.getAnnotation(RequiredVerify.class); + if (valueIsNull) { + throw new VerifyException(annotation.value()); + } + } + } + } + + public static T xmlStrToObject(Class clazz, String xmlStr) throws Exception { + T t = null; + JAXBContext context = JAXBContext.newInstance(clazz); + // 进行将Xml转成对象的核心接口 + Unmarshaller unmarshaller = context.createUnmarshaller(); + StringReader sr = new StringReader(xmlStr); + t = (T) unmarshaller.unmarshal(sr); + dealJsonStr(clazz, t); + return t; + } + + public static T xmlStrToObject(Class clazz, InputStream inputStream) throws Exception { + T t = null; + JAXBContext context = JAXBContext.newInstance(clazz); + // 进行将Xml转成对象的核心接口 + Unmarshaller unmarshaller = context.createUnmarshaller(); + t = (T) unmarshaller.unmarshal(inputStream); + dealJsonStr(clazz, t); + return t; + } + + private static T dealJsonStr(Class clazz, T t) throws Exception { + Field[] declaredFields = clazz.getDeclaredFields(); + for (Field declaredField : declaredFields) { + declaredField.setAccessible(true); + boolean annotationPresent = declaredField.isAnnotationPresent(JsonParse.class); + if (annotationPresent) { + JsonParse annotation = declaredField.getAnnotation(JsonParse.class); + String sourceFieldName = annotation.value(); + Field sourceField = clazz.getDeclaredField(sourceFieldName); + String sourceMethodName = "get" + sourceFieldName.substring(0, 1).toUpperCase() + sourceFieldName.substring(1); + Method declaredMethod = clazz.getDeclaredMethod(sourceMethodName); + Object sourceValue = declaredMethod.invoke(t); + Class sourceType = sourceField.getType(); + if (isNotNull(sourceType, sourceValue)) { + ObjectMapper objectMapper = new ObjectMapper(); + String targetFieldName = declaredField.getName(); + Class targetType = declaredField.getType(); + String targetMethodName = "set" + targetFieldName.substring(0, 1).toUpperCase() + targetFieldName.substring(1); + Method targetMethod = clazz.getDeclaredMethod(targetMethodName, targetType); + if (targetType.equals(List.class)) { + Type genericType = declaredField.getGenericType(); + ParameterizedType pt = (ParameterizedType) genericType; + //得到泛型里的class类型对象 + Class genericClazz = (Class) pt.getActualTypeArguments()[0]; + CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, genericClazz); + List list = objectMapper.readValue(sourceValue.toString(), listType); + targetMethod.invoke(t, list); + } else { + Object o = objectMapper.readValue(sourceValue.toString(), targetType); + targetMethod.invoke(t, o); + } + } + } + } + return t; + } + + public static String beanToXml(T t, String encoding) { + String xmlStr = ""; + try { + //1、创建上下文 + JAXBContext context = JAXBContext.newInstance(t.getClass()); + StringWriter writer = new StringWriter(); + //2、创建Marshaller 这个是用于转换成xml的 + Marshaller marshaller = context.createMarshaller(); + //3、设置marshaller的属性 + //JAXB_FORMATTED_OUTPUT:格式化 + //JAXB_ENCODING:编码格式 + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); + //4、将实体类读取到writer中 + marshaller.marshal(t, writer); + xmlStr = writer.toString(); + } catch (Exception e) { + logger.info("java bean 转换 xml异常 ==>" + LogUtil.getExceptionStr(e)); + } + return xmlStr; + } + + public static String mapToXml(Map map) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("").append("\n").append("").append("\n"); + String xmlBody = mapDeal(map); + stringBuilder.append(xmlBody).append(""); + return stringBuilder.toString(); + } + + public static String mapDeal(Map map) { + StringBuilder stringBuilder = new StringBuilder(); + Set> entries = map.entrySet(); + for (Map.Entry entry : entries) { + String key = entry.getKey(); + Object value = entry.getValue(); + stringBuilder.append("\t").append("<").append(key).append(">"); + if (value instanceof Map) { + String s = mapDeal((Map) value); + stringBuilder.append(s); + } else if (value instanceof List) { + String nodeName = "node"; + String s = listDeal((List) value, nodeName); + stringBuilder.append(s); + } else { + stringBuilder.append(value); + } + stringBuilder.append("").append("\n"); + } + return stringBuilder.toString(); + } + + public static String listDeal(List list, String nodeName) { + StringBuilder stringBuilder = new StringBuilder(); + for (Object o : list) { + stringBuilder.append("\t").append("<").append(nodeName).append(">"); + if (o instanceof Map) { + String s = mapToXml((Map) o); + stringBuilder.append(s); + } else if (o instanceof List) { + throw new ValueDealException("不支持嵌套list"); + } else { + stringBuilder.append(o); + } + stringBuilder.append("").append("\n"); + } + return stringBuilder.toString(); + } + + + public static Document convertStringToDocument(String xmlStr) { + SAXBuilder sb = new SAXBuilder(); + try { + return sb.build(new InputSource(new StringReader(xmlStr))); + } catch (Exception e) { + logger.info("xml字符串解析异常 ==>" + LogUtil.getExceptionStr(e)); + } + return null; + } + + public static Document convertStringToDocument(InputStream inputStream) { + SAXBuilder sb = new SAXBuilder(); + try { + return sb.build(inputStream); + } catch (Exception e) { + logger.info("xml字符串解析异常 ==>" + LogUtil.getExceptionStr(e)); + } + return null; + } + + + public static boolean isNull(Class type, Object value) { + if (type.equals(String.class)) { + return isBlank(value); + } else { + return value == null; + } + } + + public static boolean isNotNull(Class type, Object value) { + return !isNull(type, value); + } + + + public static boolean isNotBlank(Object value) { + return !isBlank(value); + } + + public static boolean isBlank(Object value) { + if (value == null) { + return true; + } + String cs = String.valueOf(value); + int strLen; + if ((strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; + } + + /** + *

驼峰转下划线

+ * @param sourceMap 原参数 + * @return 转换后的map + */ + public static Map humpToUnderlineMap(Map sourceMap) { + return paramConversion(sourceMap, 2); + } + + /** + *

下划线转驼峰

+ * @param sourceMap 原参数 + * @return 转换后的map + */ + public static Map underlineToHumpMap(Map sourceMap) { + return paramConversion(sourceMap, 1); + } + + /** + *

参数转换

+ * @param sourceMap 原参数信息 + * @param conversionType 转换类型 1:下划线转驼峰;2:驼峰转下划线 + * @return 转换后的map + */ + public static Map paramConversion(Map sourceMap, int conversionType) { + if (sourceMap == null || sourceMap.isEmpty()) { + return sourceMap; + } + Map targetMap = new HashMap<>(); + Set> entries = sourceMap.entrySet(); + for (Map.Entry entry : entries) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (conversionType == 1) { + key = toCamelCase(key); + } else { + key = toUnderlineCase(key); + } + targetMap.put(key, value); + } + return targetMap; + } + + /** + *

驼峰转下划线方法

+ * @param sourceString 原字符串 + * @return 转换后字符串 + */ + public static String toUnderlineCase(String sourceString) { + if (VerifyUtil.isBlank(sourceString)) { + return sourceString; + } + StringBuffer stringBuffer = new StringBuffer(); + char[] chars = sourceString.toCharArray(); + for (char aChar : chars) { + if (aChar >= 65 && aChar <= 90) { + stringBuffer.append("_").append(aChar += 32); + } else { + stringBuffer.append(aChar); + } + } + return stringBuffer.toString(); + } + + /** + *

下划线转驼峰

+ * @param sourceString 原字符串 + * @return 转换后字符串 + */ + public static String toCamelCase(String sourceString) { + if (VerifyUtil.isBlank(sourceString)) { + return sourceString; + } + StringBuffer stringBuffer = new StringBuffer(); + char[] chars = sourceString.toCharArray(); + boolean isConversion = false; + for (char aChar : chars) { + //判断是否为'_' + if (aChar == 95) { + isConversion = true; + continue; + } + if (isConversion) { + stringBuffer.append(aChar -= 32); + isConversion = false; + } else { + stringBuffer.append(aChar); + } + } + return stringBuffer.toString(); + } + +} diff --git a/src/main/java/weaver/xiao/commons/utils/annotation/JsonParse.java b/src/main/java/weaver/xiao/commons/utils/annotation/JsonParse.java new file mode 100644 index 0000000..daaf8c4 --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/annotation/JsonParse.java @@ -0,0 +1,19 @@ +package weaver.xiao.commons.utils.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

标记于字段上用于JSON转换

+ * + * @author XiaoBokang + * @create 2022/8/5 15:13 + */ + +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface JsonParse { + String value(); +} diff --git a/src/main/java/weaver/xiao/commons/utils/annotation/RequiredVerify.java b/src/main/java/weaver/xiao/commons/utils/annotation/RequiredVerify.java new file mode 100644 index 0000000..fbbf43f --- /dev/null +++ b/src/main/java/weaver/xiao/commons/utils/annotation/RequiredVerify.java @@ -0,0 +1,17 @@ +package weaver.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/7/28 12:11 + */ + +@Target({ElementType.FIELD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RequiredVerify { + String value(); +} diff --git a/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java b/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java index dea7401..f1c9c82 100644 --- a/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java +++ b/src/main/java/weaver/xuanran/wang/common/util/CommonUtil.java @@ -3,6 +3,7 @@ package weaver.xuanran.wang.common.util; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; import com.alibaba.fastjson.JSONObject; +import com.weaverboot.tools.logTools.LogTools; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.io.FileUtils; @@ -15,8 +16,11 @@ import weaver.xuanran.wang.common.annocation.CusDateFormat; import weaver.xuanran.wang.common.annocation.ParamNotNull; import weaver.xuanran.wang.common.mapper.CommonMapper; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; import java.io.*; import java.lang.reflect.Field; +import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; @@ -37,7 +41,7 @@ public class CommonUtil { /** *

日志对象

**/ - private static final Logger logger = Util.getLogger(CommonUtil.class.getName()); + private static final Logger logger = Util.getLogger(); /** *

sql用in的时候分割集合大小

**/ @@ -55,6 +59,9 @@ public class CommonUtil { **/ private static final CommonMapper commonMapper = Util.getMapper(CommonMapper.class); + public CommonUtil(){ + } + /** *

将文件解压至指定文件夹中

* @author xuanran.wang diff --git a/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java b/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java index c5431e4..b02e57f 100644 --- a/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java +++ b/src/main/java/weaver/xuanran/wang/common/util/CusInfoToOAUtil.java @@ -90,6 +90,29 @@ public class CusInfoToOAUtil { return executeBatch(modelId, params, "", Collections.emptyList(), true); } + /** + *

将自定义信息写入建模

+ * @author xuanran.wang + * @dateTime 2022/11/23 17:00 + * @param modelId 模块id + * @param params 需要插入的数据map + * @param whereSql 重复数据条件sql + * @param whereParams 重复数据参数集合 + * @return 建模数据id集合 + **/ + public static List executeBatch( int modelId, + List> params, + String whereSql, + List whereParams) { + if(modelId < 0){ + throw new RuntimeException("建模模块id不能小于0!"); + } + String tableName = commonMapper.getModelNameByModelId(String.valueOf(modelId)); + if(StringUtils.isBlank(tableName)){ + throw new CustomerException("模块id为 " + modelId + ", 在系统中暂没查询到对应表单!"); + } + return executeBatch(modelId, tableName, params, whereSql, whereParams, true); + } /** *

将自定义信息写入建模

* @author xuanran.wang @@ -148,10 +171,11 @@ public class CusInfoToOAUtil { if(StringUtils.isNotBlank(whereSql)){ whereSql = Util.sbc2dbcCase(whereSql); whereSql = whereSql.replaceAll(TABLE_NAME_PLACEHOLDER, tableName); - log.info("whereSql : " + whereSql); - log.info("参数 : " + whereParams); if (rs.executeQuery(whereSql, whereParams) && rs.next()) { mainId = Util.getIntValue(rs.getString(1),-1); + }else { + log.info("whereSql : " + whereSql); + log.info("参数 : " + whereParams); } } if(mainId < 0){ diff --git a/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/HrmDataToModelAsync.java b/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/CusDataToModelAsync.java similarity index 92% rename from src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/HrmDataToModelAsync.java rename to src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/CusDataToModelAsync.java index 05b9fff..5145d79 100644 --- a/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/HrmDataToModelAsync.java +++ b/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/job/CusDataToModelAsync.java @@ -10,12 +10,12 @@ import weaver.xuanran.wang.saic_travel.model_data_async.service.DataAsyncConfigS /** - *

员工信息同步至建模

+ *

信息同步至建模

* * @Author xuanran.wang * @Date 2022/12/1 15:20 */ -public class HrmDataToModelAsync extends BaseCronJob { +public class CusDataToModelAsync extends BaseCronJob { private final Logger logger = Util.getLogger(); diff --git a/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/service/DataAsyncConfigService.java b/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/service/DataAsyncConfigService.java index fef8ddf..c2fc8e8 100644 --- a/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/service/DataAsyncConfigService.java +++ b/src/main/java/weaver/xuanran/wang/saic_travel/model_data_async/service/DataAsyncConfigService.java @@ -2,7 +2,6 @@ package weaver.xuanran.wang.saic_travel.model_data_async.service; import aiyh.utils.Util; import aiyh.utils.excention.CustomerException; -import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.springframework.util.Assert; @@ -14,8 +13,6 @@ import weaver.xuanran.wang.saic_travel.model_data_async.config.eneity.DataAsyncD import weaver.xuanran.wang.saic_travel.model_data_async.config.eneity.DataAsyncMain; import weaver.xuanran.wang.saic_travel.model_data_async.config.mapper.DataAsyncConfigMapper; import weaver.xuanran.wang.saic_travel.model_data_async.constant.DataAsyncConstant; -import weaver.xuanran.wang.saic_travel.model_data_async.mapper.DataAsyncMapper; -import weaver.zwl.common.ToolUtil; import java.util.*; import java.util.stream.Collectors; @@ -99,8 +96,7 @@ public class DataAsyncConfigService { linkedHashMapList.add(copyMap); } } - List list = CusInfoToOAUtil.executeBatch(modelId, linkedHashMapList); - return list; + return CusInfoToOAUtil.executeBatch(modelId, linkedHashMapList); } /** *

根据配置将值转换

diff --git a/src/main/java/weaver/xuanran/wang/schroeder/action/PushSealTaskAction.java b/src/main/java/weaver/xuanran/wang/schroeder/action/PushSealTaskAction.java index d559208..f88d2b3 100644 --- a/src/main/java/weaver/xuanran/wang/schroeder/action/PushSealTaskAction.java +++ b/src/main/java/weaver/xuanran/wang/schroeder/action/PushSealTaskAction.java @@ -1,14 +1,21 @@ package weaver.xuanran.wang.schroeder.action; import aiyh.utils.Util; -import aiyh.utils.action.CusBaseAction; +import aiyh.utils.action.CusBaseAction; // 基础的action,实现一些基础的参数 import aiyh.utils.annotation.RequiredMark; -import aiyh.utils.excention.CustomerException; +import aiyh.utils.excention.CustomerException; // 自定义异常类 create 2022/3/9 2:20 PM +import org.apache.commons.lang3.StringUtils; import weaver.conn.RecordSetTrans; import weaver.hrm.User; +import weaver.soa.workflow.request.RequestInfo; import weaver.workflow.request.RequestManager; +import weaver.xuanran.wang.common.util.CusInfoToOAUtil; import weaver.xuanran.wang.schroeder.service.SchroederQRCodeService; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + /** *

施罗德创建二维码action

@@ -16,7 +23,7 @@ import weaver.xuanran.wang.schroeder.service.SchroederQRCodeService; * @Author xuanran.wang * @Date 2022/11/30 16:08 */ -public class PushSealTaskAction extends CusBaseAction { +public class PushSealTaskAction extends CusBaseAction { // 基础的action,实现一些基础的参数 /** *

建模配置唯一标识

@@ -30,24 +37,53 @@ public class PushSealTaskAction extends CusBaseAction { @RequiredMark private String QRCodeField; - private final SchroederQRCodeService schroederQRCodeService = new SchroederQRCodeService(); + /** + *

用印文件字段 会将这个字段所有的值存到用印文件记录表中

+ **/ + @RequiredMark + private String fileField; + + /** + *

文档记录表模块id

+ **/ + @RequiredMark + private String modelId; - @Override + private final SchroederQRCodeService schroederQRCodeService = new SchroederQRCodeService(); // 施罗德业务方法 施罗德业务方法 + + + + @Override // action 提交流程业务处理方法 具体业务逻辑实现 public void doSubmit(String requestId, String billTable, int workflowId, User user, RequestManager requestManager) { log.info("---------- PushSealTaskSealValue Begin " + requestId + "----------"); - String scanNum = schroederQRCodeService.pushSealTask(onlyMark, billTable, requestId); + RequestInfo requestInfo = requestInfoThreadLocal.get(); + String scanNum = schroederQRCodeService.pushSealTask(onlyMark, billTable, requestId); // 推送数据创建任务 建模配置唯一标识 RecordSetTrans trans = requestManager.getRsTrans(); trans.setAutoCommit(false); - String updateSql = "update " + billTable + " set " + QRCodeField + " = ? where requestid = ?"; + String updateSql = "update " + billTable + " set " + QRCodeField + " = ? where requestid = ?"; // 二维码来源字段 try{ if(!trans.executeUpdate(updateSql, scanNum, requestId)){ - throw new CustomerException(Util.logStr("更新表单sql执行失败!sql : {}, 参数 scanNum : {}, requestId : {}", scanNum, requestId)); + throw new CustomerException(Util.logStr("更新表单sql执行失败!sql : {}, 参数 scanNum : {}, requestId : {}", scanNum, requestId)); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } + // 获取明细表数据 + List> detailList = getDetailTableValueByDetailNo(1, requestInfo); + List docIds = detailList.stream() + .map(item -> Util.null2DefaultStr(item.get(fileField), "")) + .filter(StringUtils::isNotBlank).collect(Collectors.toList()); + ArrayList> list = new ArrayList<>(); + for (String docId : docIds) { + LinkedHashMap map = new LinkedHashMap<>(); + map.put("docId", docId); + map.put("enable", 0); + list.add(map); + } + // 将数据写入建模 + CusInfoToOAUtil.executeBatch(Util.getIntValue(modelId, -1), list, "select 1 from #{tableName} where docId = ?", docIds); }catch (Exception e){ trans.rollback(); - throw new CustomerException(Util.logStr("执行提交方法异常:{}", e.getMessage())); + throw new CustomerException(Util.logStr("执行提交方法异常:{}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } trans.commit(); } - } + diff --git a/src/main/java/weaver/xuanran/wang/schroeder/cus_field_value/PushSealTaskSealValue.java b/src/main/java/weaver/xuanran/wang/schroeder/cus_field_value/PushSealTaskSealValue.java index 96a484f..1b9dc5b 100644 --- a/src/main/java/weaver/xuanran/wang/schroeder/cus_field_value/PushSealTaskSealValue.java +++ b/src/main/java/weaver/xuanran/wang/schroeder/cus_field_value/PushSealTaskSealValue.java @@ -1,14 +1,14 @@ package weaver.xuanran.wang.schroeder.cus_field_value; import aiyh.utils.Util; -import aiyh.utils.excention.CustomerException; +import aiyh.utils.excention.CustomerException; // 自定义异常类 create 2022/3/9 2:20 PM import com.alibaba.fastjson.JSONObject; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import weaver.conn.RecordSet; -import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; -import weaver.zwl.common.ToolUtil; +import weaver.xiao.commons.config.interfacies.CusInterfaceGetValue; // 自定义获取参数值 +import weaver.zwl.common.ToolUtil; // 常用工具方法-公用类 import java.util.*; import java.util.stream.Collectors; @@ -19,44 +19,40 @@ import java.util.stream.Collectors; * @Author xuanran.wang * @Date 2022/12/2 16:10 */ -public class PushSealTaskSealValue implements CusInterfaceGetValue { - private final ToolUtil toolUtil = new ToolUtil(); +public class PushSealTaskSealValue implements CusInterfaceGetValue { // 自定义获取参数值 + private final ToolUtil toolUtil = new ToolUtil(); // 常用工具方法-公用类 构造方法 - private final Logger logger = Util.getLogger(); + private final Logger logger = Util.getLogger(); // 获取日志对象 - @Override + @Override // 获取参数值 public Object execute(Map mainMap, Map detailMap, String currentValue, Map pathParam) { logger.info(Util.logStr("路径参数:[{}]", JSONObject.toJSONString(pathParam))); + logger.info("路径参数(字符串拼接) : " + JSONObject.toJSONString(pathParam));// 构建日志字符串 // 接口字段 String sealSnField = pathParam.get("sealSnField"); String sealNumField = pathParam.get("sealNumField"); - // 表单字段 - String workFlowSealNumField = pathParam.get("workFlowSealNumField"); - String workFlowSealSnField = pathParam.get("workFlowSealSnField"); // 自定义sql业务印章类型 String sealSnCusSql = pathParam.get("sealSnCusSql"); // 使用次数 String sealNumCusSql = pathParam.get("sealNumCusSql"); // 非空校验 - if(checkBlank(sealSnField, sealNumField, sealSnCusSql, sealNumCusSql, workFlowSealNumField, workFlowSealSnField)){ - throw new CustomerException(Util.logStr("自定义类路径中必要参数为空,请检查!当前pathParam : {}", JSONObject.toJSONString(pathParam))); + if(checkBlank(sealSnField, sealNumField, sealSnCusSql, sealNumCusSql)){ + throw new CustomerException(Util.logStr("自定义类路径中必要参数为空,请检查!当前pathParam : {}", JSONObject.toJSONString(pathParam))); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } - // 表单印章使用类型值 - String sealSnVal = Util.null2String(String.valueOf(detailMap.get(sealSnField)),""); + logger.info(Util.logStr("当前值 : {}", currentValue)); // 构建日志字符串 // 如果为空返回空集合 - if(StringUtils.isBlank(sealSnVal)){ + if(StringUtils.isBlank(currentValue)){ return Collections.emptyList(); } ArrayList> list = new ArrayList<>(); - logger.info(Util.logStr("当前值 : {}", currentValue)); int detailId = -1; if(MapUtils.isNotEmpty(detailMap)){ detailId = Util.getIntValue(String.valueOf(detailMap.get("id")), -1); } - for (String val : sealSnVal.split(",")) { + for (String val : currentValue.split(",")) { // 印章类型转换执行自定义sql - String inSealVal = Util.null2DefaultStr(toolUtil.getValueByChangeRule(sealSnCusSql, val, String.valueOf(mainMap.get("requestid")), detailId),""); - String inSealNumVal = Util.null2DefaultStr(toolUtil.getValueByChangeRule(sealNumCusSql, val, String.valueOf(mainMap.get("requestid")), detailId),""); + String inSealVal = Util.null2DefaultStr(toolUtil.getValueByChangeRule(sealSnCusSql, val, String.valueOf(mainMap.get("requestid")), detailId),""); // 用数据库值,根据规则转换,获取其最终结果 + String inSealNumVal = Util.null2DefaultStr(toolUtil.getValueByChangeRule(sealNumCusSql, val, String.valueOf(mainMap.get("requestid")), detailId),""); // 用数据库值,根据规则转换,获取其最终结果 HashMap map = new HashMap<>(); map.put(sealSnField, inSealVal); map.put(sealNumField, inSealNumVal); @@ -66,6 +62,8 @@ public class PushSealTaskSealValue implements CusInterfaceGetValue { } public boolean checkBlank(String ... args){ - return Arrays.stream(args).noneMatch(StringUtils::isBlank); + return Arrays.stream(args).anyMatch(StringUtils::isBlank); } } + + diff --git a/src/main/java/weaver/xuanran/wang/schroeder/mapper/SchroederMapper.java b/src/main/java/weaver/xuanran/wang/schroeder/mapper/SchroederMapper.java new file mode 100644 index 0000000..1812c4c --- /dev/null +++ b/src/main/java/weaver/xuanran/wang/schroeder/mapper/SchroederMapper.java @@ -0,0 +1,45 @@ +package weaver.xuanran.wang.schroeder.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; + +/** + *

施罗德查询方法

+ * + * @Author xuanran.wang + * @Date 2022/12/13 13:05 + */ +@SqlMapper +public interface SchroederMapper { + + /** + *

查询明细一数据集

+ * @author xuanran.wang + * @dateTime 2022/12/13 13:10 + * @param tableName 表名 + * @param mainId 主表id + * @return 明细表数据集合 + **/ + @Select("select yywj,qfzzl,qfzcs from $t{tableName} where mainid = #{mainId} and sfjgqfz = 0") + List> selectSealTaskInfoList(@ParamMapper("tableName") String tableName, + @ParamMapper("mainId") String mainId); + + /** + *

查询明细一用印文件docId/h1> + * @author xuanran.wang + * @dateTime 2022/12/13 13:10 + * @param fileField 用印文件字段 + * @param tableName 表名 + * @param mainId 主表id + * @return 明细表数据集合 + **/ + @Select("select $t{fileField} from $t{tableName} where mainid = #{mainId}") + List> selectSealFileList(@ParamMapper("fileField") String fileField, + @ParamMapper("tableName") String tableName, + @ParamMapper("mainId") String mainId); + +} diff --git a/src/main/java/weaver/xuanran/wang/schroeder/service/SchroederQRCodeService.java b/src/main/java/weaver/xuanran/wang/schroeder/service/SchroederQRCodeService.java index d85909f..ad6af3b 100644 --- a/src/main/java/weaver/xuanran/wang/schroeder/service/SchroederQRCodeService.java +++ b/src/main/java/weaver/xuanran/wang/schroeder/service/SchroederQRCodeService.java @@ -1,23 +1,34 @@ package weaver.xuanran.wang.schroeder.service; import aiyh.utils.Util; -import aiyh.utils.excention.CustomerException; +import aiyh.utils.excention.CustomerException; // 自定义异常类 create 2022/3/9 2:20 PM import aiyh.utils.httpUtil.ResponeVo; import aiyh.utils.httpUtil.util.HttpUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.google.zxing.qrcode.encoder.QRCode; +import com.icbc.api.internal.apache.http.M; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; +import org.junit.Test; +import org.springframework.beans.BeanUtils; import weaver.conn.RecordSet; import weaver.mobile.plugin.ecology.QRCodeComInfo; import weaver.xiao.commons.config.entity.RequestMappingConfig; import weaver.xiao.commons.config.service.DealWithMapping; +import weaver.xuanran.wang.schroeder.mapper.SchroederMapper; import javax.ws.rs.core.MediaType; +import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; /** *

施罗德业务方法

@@ -44,11 +55,12 @@ public class SchroederQRCodeService { **/ private static final String STATUS_FIELD = "status"; private final DealWithMapping dealWithMapping = new DealWithMapping(); - private final Logger log = Util.getLogger(); + private final Logger log = Util.getLogger(); // 获取日志对象 private final HttpUtils httpUtils = new HttpUtils(); { - httpUtils.getGlobalCache().header.put("Content-Type", MediaType.APPLICATION_JSON); + httpUtils.getGlobalCache().header.put("Content-Type", MediaType.APPLICATION_JSON); // 全局请求头 } + private final SchroederMapper schroederMapper = Util.getMapper(SchroederMapper.class); /** *

推送数据创建任务

@@ -61,10 +73,10 @@ public class SchroederQRCodeService { **/ public String pushSealTask(String onlyMark, String billTable, String requestId){ String res = ""; - RequestMappingConfig requestMappingConfig = dealWithMapping.treeDealWithUniqueCode(onlyMark); + RequestMappingConfig requestMappingConfig = dealWithMapping.treeDealWithUniqueCode(onlyMark); // 将配置参数通过唯一标识查询处理成树形结构 String cusWhere = Util.null2DefaultStr(requestMappingConfig.getCusWhereSql(),""); if(StringUtils.isNotBlank(cusWhere)){ - cusWhere = DealWithMapping.sbc2dbcCase(cusWhere); + cusWhere = DealWithMapping.sbc2dbcCase(cusWhere); // 全角转半角 } String selectMainSql = "select * from " + billTable + " where requestid = ? " + cusWhere; log.info("查询主表数据sql { " + selectMainSql + " }, requestId { " + requestId + " }"); @@ -73,42 +85,88 @@ public class SchroederQRCodeService { if (recordSet.next()) { dealWithMapping.setMainTable(billTable); Map requestParam = dealWithMapping.getRequestParam(recordSet, requestMappingConfig); - log.info(Util.logStr("请求json : {}", JSONObject.toJSONString(requestParam))); + // 如果明细数据存在骑缝章时候增加一行数据进去 + changeRequestMap(requestParam, billTable + "_dt1", recordSet.getString("id")); + // 解析请求参数配置树,转换成请求参数 + log.info(Util.logStr("请求json : {}", JSONObject.toJSONString(requestParam))); // 构建日志字符串 String url = requestMappingConfig.getRequestUrl(); ResponeVo responeVo = null; try { responeVo = httpUtils.apiPost(url, requestParam); } catch (IOException e) { - throw new CustomerException(Util.logStr("发送印章请求发生异常! : {}", e.getMessage())); + throw new CustomerException(Util.logStr("发送印章请求发生异常! : {}", e.getMessage())); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } - Map headers = httpUtils.getGlobalCache().header; - if (responeVo.getCode() != SUCCESS_CODE) { - log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + + Map headers = httpUtils.getGlobalCache().header; // 全局请求头 + if (responeVo.getCode() != SUCCESS_CODE) { // 相应状态码 + log.error(Util.logStr("can not fetch [{}],this request params is [{}]," + // 构建日志字符串 "this request heard is [{}],but response status code is [{}]," + - "this response is [{}]", url, JSON.toJSON(requestParam), JSON.toJSONString(headers), responeVo.getCode(), - responeVo.getEntityString())); - throw new CustomerException(Util.logStr("can not fetch [{}]", url)); + "this response is [{}]", url, JSON.toJSON(requestParam), JSON.toJSONString(headers), responeVo.getCode(), // 相应状态码 + responeVo.getEntityString())); // 相应内容 + throw new CustomerException(Util.logStr("can not fetch [{}]", url)); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } Map response; - log.info(Util.logStr("this response is [{}]", responeVo.getEntityString())); + log.info(Util.logStr("this response is [{}]", responeVo.getEntityString())); // 构建日志字符串 相应内容 try { - response = responeVo.getEntityMap(); - log.info(Util.logStr("接口响应:{}", JSONObject.toJSONString(response))); + response = responeVo.getEntityMap(); // 根据相应结果转化为map集合 + log.info(Util.logStr("接口响应:{}", JSONObject.toJSONString(response))); // 构建日志字符串 } catch (JsonProcessingException e) { - log.error(Util.logStr("push data error, can not parse response to map," + + log.error(Util.logStr("push data error, can not parse response to map," + // 构建日志字符串 "this response is [{}], url is [{}],request params is [{}], request heard is [{}];", - responeVo.getEntityString(), url, JSON.toJSONString(requestParam), JSON.toJSONString(headers))); - throw new CustomerException(Util.logStr("push data error, can not parse response to map")); + responeVo.getEntityString(), url, JSON.toJSONString(requestParam), JSON.toJSONString(headers))); // 相应内容 + throw new CustomerException(Util.logStr("push data error, can not parse response to map")); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } int status = (int) response.get(STATUS_FIELD); if(SUCCESS_STATUS != status){ - throw new CustomerException(Util.logStr("接口响应码不为0,接口响应信息:{}", Util.null2DefaultStr(response.get(MESSAGE_FIELD),""))); + throw new CustomerException(Util.logStr("接口响应码不为0,接口响应信息:{}", Util.null2DefaultStr(response.get(MESSAGE_FIELD),""))); // 自定义异常类 create 2022/3/9 2:20 PM 构建日志字符串 } res = Util.null2DefaultStr(response.get(SCAN_NUM_FIELD),""); } if(StringUtils.isBlank(res)){ - throw new CustomerException("获取接口中响应任务字段为空, 请检查!"); + throw new CustomerException("获取接口中响应任务字段为空, 请检查!"); // 自定义异常类 create 2022/3/9 2:20 PM } return res; } + + /** + *

骑缝章修改请求参数

+ * @author xuanran.wang + * @dateTime 2022/12/13 14:15 + * @param requestParam 请求参数 + * @param billTable 表名 + * @param mainId 主表id + **/ + public void changeRequestMap(Map requestParam, String billTable, String mainId){ + List> files = (List>) requestParam.get("file"); + List> detail1List = schroederMapper.selectSealTaskInfoList(billTable, mainId); + if(CollectionUtils.isEmpty(detail1List) || CollectionUtils.isEmpty(files)){ + return; + } + // 遍历明细数据 + for (Map detailItem : detail1List) { + // 用印文件 + String sealFile = Util.null2String(detailItem.get("yywj")); + // 从生成的请求参数map中开始匹配 + List> filterFiles = files.stream() + .filter(item -> { + String filePath = Util.null2DefaultStr(item.get("filePath"), ""); + String docId = Util.null2DefaultStr(filePath.substring(filePath.lastIndexOf("=") + 1),""); + return sealFile.equals(docId); + }) + .collect(Collectors.toList()); + if(CollectionUtils.isNotEmpty(filterFiles)){ + // 只有一个能匹配 + Map o = filterFiles.get(0); + HashMap tempMap = o.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, HashMap::new)); + // 印章集合 + HashMap seal = new HashMap<>(); + seal.put("sealSn",Util.null2DefaultStr(detailItem.get("qfzzl"),"")); + seal.put("sealNum",Util.null2DefaultStr(detailItem.get("qfzcs"),"0")); + tempMap.put("seal", seal); + files.add(tempMap); + } + } + } + } + + diff --git a/src/main/resources/WEB-INF/prop/prop2map/AmbofoADConfig.properties b/src/main/resources/WEB-INF/prop/prop2map/AmbofoADConfig.properties new file mode 100644 index 0000000..015bb4b --- /dev/null +++ b/src/main/resources/WEB-INF/prop/prop2map/AmbofoADConfig.properties @@ -0,0 +1,7 @@ +userName = SID_ECOLOGY +password = BDw5FzWQ@ +server = ldap://LDAP_ASIA.Aptiv.com:389 +driver = com.sun.jndi.ldap.LdapCtxFactory +authentication = simple +searchBase=CN=Users,DC=aptiv,DC=com +queryField=uid \ No newline at end of file diff --git a/src/test/java/xuanran/wang/ambofo/checkuser/CheckUserTest.java b/src/test/java/xuanran/wang/ambofo/checkuser/CheckUserTest.java new file mode 100644 index 0000000..ebc2770 --- /dev/null +++ b/src/test/java/xuanran/wang/ambofo/checkuser/CheckUserTest.java @@ -0,0 +1,27 @@ +package xuanran.wang.ambofo.checkuser; + +import aiyh.utils.Util; +import basetest.BaseTest; +import com.api.xuanran.wang.ambofo.checkuser.service.CheckUserService; +import org.junit.Test; + +/** + *

安波福校验用户测试类

+ * + * @Author xuanran.wang + * @Date 2022/12/12 15:35 + */ +public class CheckUserTest extends BaseTest { + + @Test + public void testProperties(){ + try{ + CheckUserService checkUserService = new CheckUserService(); + checkUserService.logAllUser(); + }catch (Exception e){ + String error = Util.logStr("AD查询接口发生异常:{}", e.getMessage()); + log.error(error); + log.error(Util.getErrString(e)); + } + } +} diff --git a/src/test/java/xuanran/wang/saic_travel/model_data_async/AsyncTest.java b/src/test/java/xuanran/wang/saic_travel/model_data_async/AsyncTest.java index e0d18ce..a95e623 100644 --- a/src/test/java/xuanran/wang/saic_travel/model_data_async/AsyncTest.java +++ b/src/test/java/xuanran/wang/saic_travel/model_data_async/AsyncTest.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import weaver.formmode.data.ModeDataApproval; +import weaver.general.Util; import weaver.hrm.User; import weaver.xuanran.wang.common.util.CommonUtil; import weaver.xuanran.wang.saic_travel.model_data_async.config.eneity.DataAsyncMain; @@ -44,11 +45,28 @@ public class AsyncTest extends BaseTest { @Test public void testAsync(){ - DataAsyncMain config = dataAsyncConfigService.getDataAsyncConfigByUniqueCode("hrmAsyncTest"); - List data = dataAsyncConfigService.asyncModelData(config, 109); - List list = CommonUtil.doCreateWorkFlow(109, data); - log.info("触发成功 : " + JSONObject.toJSONString(list)); +// try { +// DataAsyncMain config = dataAsyncConfigService.getDataAsyncConfigByUniqueCode("wacoTest"); +// List data = dataAsyncConfigService.asyncModelData(config, 109); +// log.info("生成的数据id : " + JSONObject.toJSONString(data)); +// }catch (Exception e){ +// log.error("生成建模数据异常 : " + e.getMessage()); +// } +// List list = CommonUtil.doCreateWorkFlow(109, data); +// log.info("触发成功 : " + JSONObject.toJSONString(list)); + log.info("select hr.email from HrmResource hr where status in (0,1,2,3) AND "+ Util.getSubINClause("1,3,323,124,544","id","in") + " and " + Util.getSubINClause("1","id","not in")); + log.info(Util.getSubINClause("1,3,323,124,544","id","in",2)); } + @Test + public void testNotNull(){ + String str = "jssjhgdkjs?docId={?}&{$requestid}"; + System.out.println(str.replace("{?}", "123") + .replace("{$requestid}", "12194283")); + } + + public boolean checkNull(String ... args){ + return Arrays.stream(args).anyMatch(StringUtils::isBlank); + } } diff --git a/src/test/java/xuanran/wang/schroeder/download_file/DownLoadFileTest.java b/src/test/java/xuanran/wang/schroeder/download_file/DownLoadFileTest.java new file mode 100644 index 0000000..cfd995b --- /dev/null +++ b/src/test/java/xuanran/wang/schroeder/download_file/DownLoadFileTest.java @@ -0,0 +1,157 @@ +package xuanran.wang.schroeder.download_file; + +import aiyh.utils.Util; +import basetest.BaseTest; +import com.alibaba.fastjson.JSONObject; +import com.api.xuanran.wang.schroeder.download_file.mapper.DownLoadFileMapper; +import com.icbc.api.internal.apache.http.impl.cookie.S; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import org.springframework.beans.BeanUtils; +import weaver.file.ImageFileManager; +import weaver.general.TimeUtil; +import weaver.xuanran.wang.common.util.CommonUtil; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + *

+ * + * @Author xuanran.wang + * @Date 2022/12/7 11:58 + */ +public class DownLoadFileTest extends BaseTest { + private final DownLoadFileMapper downLoadFileMapper = Util.getMapper(DownLoadFileMapper.class); + + @Test + public void testSelectFileInfo() throws IOException { + Map fileInfo = downLoadFileMapper.selectDocInfoByDocId("95"); + log.info("map " + fileInfo); + String fileName = Util.null2String(fileInfo.get("fileName")); + int imageFileId = Util.getIntValue(Util.null2DefaultStr(fileInfo.get("imageFileId"),""), -1); + log.info("imageFileId " + imageFileId); + InputStream is = ImageFileManager.getInputStreamById(imageFileId); + log.info(null == is); + } + + + @Test + public void testImageFileInputSteam(){ + HashMap header = new HashMap<>(); + header.put("Content-Type", "application/json;charset=utf-8"); + header.put("Authorization", ""); + header.put("reqFrom", "1212"); + header.put("reqId", UUID.randomUUID().toString()); + header.put("reqTime", TimeUtil.getCurrentTimeString()); + log.info("header " + header); + } + + @Test + public void testParseStr(){ + String str = ""; + String pattern = "(?<=\\{).+(?=})"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(str); + while (matcher.find()){ + String group = matcher.group(); + if(StringUtils.isNotBlank(group)){ + if(group.startsWith("main.")){ + String replaceAll = group.replaceAll("#\\{.+}","黄齑淡饭"); + log.info("replaceAll : " + replaceAll); + }else if(group.startsWith("detail.")){ + + }else if(group.startsWith("sql.")){ + + } + } + } + } + + @Test + public void testAddItem(){ + String json = "{\"requestId\":\"189567\",\"super\":\"luchenghong\",\"orgNo\":\"junhe\",\"title\":\"鲁诚鸿\",\"sealPlace\":\"2\",\"useSealType\":\"1\",\"userPassword\":\"672518\",\"useSealEquipment\":\"2\",\"file\":[{\"fileName\":\"拜访函(景德镇).docx\",\"filePath\":\"http://oa.junheland.com/hyu/seal.download?docId=12\",\"waterAndSeal\":\"2\",\"crosssealType\":\"2\",\"printCount\":\"1\",\"printType\":\"0\",\"seal\":[{\"sealType\":\"124\",\"sealNum\":\"1\"}]},{\"fileName\":\"附件6-变更签证办理协议.pdf\",\"filePath\":\"http://erp.junheland.com:9070/view?docId=13\",\"waterAndSeal\":\"2\",\"crosssealType\":\"1\",\"printCount\":\"6\",\"printType\":\"1\",\"seal\":[{\"sealType\":\"164\",\"sealNum\":\"6\"}]}]}"; + Map requestParam = JSONObject.parseObject(json, Map.class); + log.info("requestParam " + requestParam); + ArrayList> detail1List = new ArrayList<>(); + HashMap map = new HashMap<>(); + // yywj,qfzzl,qfzcs + map.put("yywj","12"); + map.put("qfzzl","2"); + map.put("qfzcs","3"); + detail1List.add(map); + // 过滤出集合类型的参数 + List> files = (List>) requestParam.get("file"); + if(CollectionUtils.isNotEmpty(files)){ + // 加盖骑缝章的明细数据 + if(CollectionUtils.isNotEmpty(detail1List)){ + // 遍历明细数据 + for (Map detailItem : detail1List) { + // 用印文件 + String sealFile = Util.null2String(detailItem.get("yywj")); + log.info("sealFile : " + sealFile); + // 从生成的请求参数map中开始匹配 + List> filterFiles = files.stream() + .filter(item -> { + String filePath = Util.null2DefaultStr(item.get("filePath"), ""); + String docId = Util.null2DefaultStr(filePath.substring(filePath.lastIndexOf("=") + 1),""); + log.info("filePath : " + filePath + " , docId : " + docId); + return sealFile.equals(docId); + }) + .collect(Collectors.toList()); + log.info("filterFiles " + JSONObject.toJSONString(filterFiles)); + if(CollectionUtils.isNotEmpty(filterFiles)){ + // 只有一个能匹配 + Map o = filterFiles.get(0); + HashMap tempMap = o.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, HashMap::new)); + // 印章集合 + HashMap seal = new HashMap<>(); + seal.put("sealSn",Util.null2DefaultStr(detailItem.get("qfzzl"),"")); + seal.put("sealNum",Util.null2DefaultStr(detailItem.get("qfzcs"),"0")); + tempMap.put("seal", seal); + log.info("tempMap " + tempMap); + files.add(tempMap); + } + } + } + } + log.info("requestParam : " + JSONObject.toJSONString(requestParam) ); + } + + @Test + public void testParse(){ + String paramStr = "weaver.xuanran.wang.schroeder.cus_field_value.PushSealTaskSealValue?sealSnField=sealSn&sealNumField=sealNum&sealSnCusSql=`select\n" + + " ? from jkfdjsfk where id\n" + + " =1`&sealNumCusSql=`select case ? when 0 then htzyzcs when 1 then gzcs else frzcs end from formtable_main_22_dt1 where id = {?dt.id}`&hah=liuliu&cus=`select? * fr$%&#@!)(<>?/\\{}「」【【】[]~、asfom table where id = '' and teset = #{name}`&niua=卧槽"; + + String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + "(?((`([^`]*)`)|" + + "((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(paramStr); + HashMap pathParamMap = new HashMap<>(); + 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); + } + log.info("pathParamMap : " + JSONObject.toJSONString(pathParamMap)); + + String text ="123456"; + String replacement = "two$two"; + String resultString = text.replaceAll("2", replacement); + log.info("resultString " + resultString); + } +} diff --git a/src/test/java/youhong/ai/pcn/TestOrganization.java b/src/test/java/youhong/ai/pcn/TestOrganization.java index 5bc34c6..c8b4da6 100644 --- a/src/test/java/youhong/ai/pcn/TestOrganization.java +++ b/src/test/java/youhong/ai/pcn/TestOrganization.java @@ -1,9 +1,18 @@ package youhong.ai.pcn; +import aiyh.utils.Util; import aiyh.utils.httpUtil.HttpMultipartFile; import aiyh.utils.httpUtil.ResponeVo; import aiyh.utils.httpUtil.util.HttpUtils; import basetest.BaseTest; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.fastjson.JSON; import com.api.youhong.ai.pcn.organization.orgchart.service.OrgChartService; import com.api.youhong.ai.pcn.organization.orgchart.vo.OrgChartNodeVo; @@ -12,6 +21,7 @@ import ebu7common.youhong.ai.bean.Builder; import ebu7common.youhong.ai.sftp.SftpConnectUtil; import org.junit.Test; import weaver.conn.RecordSet; +import weaver.formmode.interfaces.action.WorkflowToMode; import weaver.general.GCONST; import weaver.hrm.User; import weaver.xiao.commons.config.entity.MultipartFile; @@ -22,10 +32,7 @@ import weaver.youhong.ai.pcn.hrorganization.wesmat.model.Employee; import weaver.youhong.ai.pcn.hrorganization.wesmat.model.Position; import weaver.youhong.ai.pcn.hrorganization.wesmat.result.GetOrganizationResult; -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; +import java.io.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -54,7 +61,6 @@ public class TestOrganization extends BaseTest { System.out.println(hris_positionExport20221120); } - @Test public void testGeOrganizationData() { GetOrganizationResult getOrganizationResult = new GetOrganizationResult(); @@ -67,11 +73,46 @@ public class TestOrganization extends BaseTest { log.info(JSON.toJSONString(positionList)); } - @Test public void testStaticLog() { log.info("哈哈哈好的方式"); + String testStr = "weaver.xuanran.wang.schroeder.cus_field_value.PushSealTaskSealValue?sealSnField=sealSn&sealNumField=sealNum&sealSnCusSql=`select\n" + + " ? from jkfdjsfk where id\n" + + " =1`&sealNumCusSql=`select case ? when 0 then htzyzcs when 1 then gzcs else frzcs end from formtable_main_22_dt1 where id = {?dt.id}`&hah=liuliu&cus=`select? * fr$%&#@!)(<>?/\\{}「」【【】[]~、asfom table where id = '' and teset = #{name}`&niua=卧槽"; + Map stringStringMap = Util.parseCusInterfacePathParam(testStr); + System.out.println(stringStringMap); + System.out.println(JSON.toJSONString(stringStringMap)); + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + // "(?(`([():/\\-&$#='*{ }.\\w\\u4E00-\\u9FA5?]*)`|((#(\\{|sql\\{))?([():/\\-$#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + //String pattern = "=`(?(([\\u4E00-\\u9FA5\\w.'#=?${ }*])*))`"; + //String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=(?(`([():/\\-&?%#\\t\\n='{ }.\\w\\u4E00-\\u9FA5]*)*`))"; + //Pattern compile = Pattern.compile(pattern); + //Matcher matcher = compile.matcher(testStr); + //while (matcher.find()) { + // String key = matcher.group("key"); + // System.out.println(key); + //String paramValue = matcher.group("value"); + //System.out.println(paramValue); + //} + String pattern = "&?(?([#.\\w\\u4E00-\\u9FA5]+))=" + + "(?((`([^`]*)`)|" + + "((#(\\{|sql\\{))?([():/\\-$_#={ }.\\w\\u4E00-\\u9FA5?]+)?}?)))&?"; + Pattern compile = Pattern.compile(pattern); + Matcher matcher = compile.matcher(testStr); + while (matcher.find()) { + String key = matcher.group("key"); + String paramValue = matcher.group("value"); + System.out.println(key); + System.out.println(paramValue); + if (paramValue != null && paramValue.startsWith("`") && paramValue.endsWith("`")) { + } + } + } + @Test + public void testLogStr() { + System.out.println(Util.logStr("ajsdf {} jasjdf {}", "{\"cus\":\"select? * fr$%&#@!)(<>?/\\\\「」【【】[]~、asfom table where id = '' and teset = #{name}\",\"sealSnCusSql\":\"select \\n? from jkfdjsfk where id \\n=1\",\"niua\":\"卧槽\",\"sealSnField\":\"sealSn\",\"sealNumField\":\"sealNum\",\"sealNumCusSql\":\"select case ? when 0 then htzyzcs when 1 then gzcs else frzcs end from formtable_main_22_dt1 where id = {?dt.id}\",\"hah\":\"liuliu\"} ")); + System.out.println("{0} {} ".replaceFirst("\\{0}", Matcher.quoteReplacement("{\"cus\":\"select? * fr$%&#@!)(<>?/\\\\「」【【】[]~、asfom table where id = '' and teset = #{name}\",\"sealSnCusSql\":\"select \\n? from jkfdjsfk where id \\n=1\",\"niua\":\"卧槽\",\"sealSnField\":\"sealSn\",\"sealNumField\":\"sealNum\",\"sealNumCusSql\":\"select case ? when 0 then htzyzcs when 1 then gzcs else frzcs end from formtable_main_22_dt1 where id = {?dt.id}\",\"hah\":\"liuliu\"} "))); } @Test @@ -192,15 +233,225 @@ public class TestOrganization extends BaseTest { } } - @Test public void testOrgChart() { - User user = new User(88); + User user = new User(1); OrgChartService orgChartService = new OrgChartService(); List orgChartTree = orgChartService.getOrgChartTree(user); System.out.println(JSON.toJSONString(orgChartTree)); } + @Test + public void testWorkflowToMode() { + RequestService service = new RequestService(); + RequestInfo requestInfo = service.getRequest(18028); + requestInfo.setIspreadd("1"); + RequestManager requestManager = requestInfo.getRequestManager(); + requestManager.setUser(new User(1)); + requestManager.setNodeid(181); + requestManager.setIsbill(1); + requestManager.setWorkflowid(44); + requestInfo.setWorkflowid("44"); + requestManager.setFormid(-20); + // Util.actionTest(WorkflowToMode.class, 18020); + WorkflowToMode workflowToMode = new WorkflowToMode(); + workflowToMode.setIp("10.0.0.1"); + workflowToMode.setNodeid(181); + // requestManager.setNextNodeid(182); + // workflowToMode.setNodelinkid(199); + workflowToMode.setActionid(8); + String execute = workflowToMode.execute(requestInfo); + System.out.println(requestManager.getMessage()); + System.out.println(requestManager.getMessagecontent()); + System.out.println(execute); + } + + @Test + public void testEasyExcel() throws FileNotFoundException { + String tempPath = "/Users/aoey.oct.22/company/Fan_wei/test_file/muban.xlsx"; + String filePath = "/Users/aoey.oct.22/company/Fan_wei/test_file/muban1.xlsx"; + FileOutputStream outputStream = new FileOutputStream(filePath); + int[] mergeColumeIndex = {0, 1}; + int mergeRowIndex = 1; + ExcelWriter excelWriter = EasyExcel.write(outputStream) + .withTemplate(tempPath) + .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumeIndex)) + .build(); + WriteSheet sheet = EasyExcel.writerSheet().build(); + excelWriter.fill(buildList(), sheet); + + excelWriter.finish(); + try { + outputStream.close(); + } catch (IOException e) { + } + } + + public List> buildList() { + List> list = new ArrayList<>(); + list.add(new HashMap() {{ + put("addr", "北京"); + put("kinds", "生活用品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "北京"); + put("kinds", "生活用品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "北京"); + put("kinds", "电子产品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "北京"); + put("kinds", "电子产品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "上海"); + put("kinds", "生活用品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "上海"); + put("kinds", "生活用品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "上海"); + put("kinds", "电子商品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "云南"); + put("kinds", "生活用品"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "云南"); + put("kinds", "电子铲平"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "云南"); + put("kinds", "蘑菇"); + put("price", 10); + put("num", 80); + }}); + list.add(new HashMap() {{ + put("addr", "云南"); + put("kinds", "蘑菇"); + put("price", 10); + put("num", 80); + }}); + + return list; + } } + +class ExcelFillCellMergeStrategy implements CellWriteHandler { + + /** 需要进行单元格合并的列数组 **/ + private int[] mergeColumnIndex; + /** 单元格合并从第几行开始 **/ + private int mergeRowIndex; + + public ExcelFillCellMergeStrategy() {} + + public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndex = mergeColumnIndex; + } + + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) { + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List list, Cell cell, Head head, Integer integer, Boolean isHead) { + int curRowIndex = cell.getRowIndex(); + int curColIndex = cell.getColumnIndex(); + if (curRowIndex > mergeRowIndex) { + for (int i = 0; i < mergeColumnIndex.length; i++) { + if (curColIndex == mergeColumnIndex[i]) { + mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); + break; + } + } + } + } + + /** + * 当前单元格向上合并 + * + * @param writeSheetHolder 表格数据写入处理对象 + * @param cell 当前单元格 + * @param curRowIndex 当前行 + * @param curColIndex 当前列 + */ + private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) { + // 获取当前单元格的数据 + Object curData = + cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue(); + // 获取当前shert表 + Sheet sheet1 = cell.getSheet(); + // 获取当前的行,有可能获取到空行 + Row row = sheet1.getRow(curRowIndex - 1); + if (row == null) { + row = sheet1.getRow(curRowIndex); + } + Cell preCell = row.getCell(curColIndex); + Object preData = + preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue(); + // 将当前单元格数据与上一个单元格数据比较 + Boolean dataBool = preData.equals(curData); + if (dataBool) { + Sheet sheet = writeSheetHolder.getSheet(); + List mergeRegions = sheet.getMergedRegions(); + boolean isMerged = false; + for (int i = 0; i < mergeRegions.size() && !isMerged; i++) { + CellRangeAddress cellRangeAddr = mergeRegions.get(i); + // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元 + if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) { + sheet.removeMergedRegion(i); + cellRangeAddr.setLastRow(curRowIndex); + sheet.addMergedRegion(cellRangeAddr); + isMerged = true; + } + } + // 若上一个单元格未被合并,则新增合并单元 + if (!isMerged) { + CellRangeAddress cellRangeAddress = + new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex); + sheet.addMergedRegion(cellRangeAddress); + } + } + } +} + diff --git a/src/test/java/youhong/ai/pcn/WorkflowTest.java b/src/test/java/youhong/ai/pcn/WorkflowTest.java new file mode 100644 index 0000000..71f6738 --- /dev/null +++ b/src/test/java/youhong/ai/pcn/WorkflowTest.java @@ -0,0 +1,31 @@ +package youhong.ai.pcn; + +import aiyh.utils.Util; +import basetest.BaseTest; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + *

流程相关测试

+ * + *

create: 2022-12-12 16:13

+ * + * @author youHong.ai + */ + +public class WorkflowTest extends BaseTest { + + @Test + public void test() { + List qzList = new ArrayList<>(); + Collections.addAll(qzList, null, "", "1", "2", "3", "4"); + Integer sum = qzList.stream() + .filter(item -> !Util.isNullOrEmpty(item)) + .map(Integer::parseInt) + .reduce(0, Integer::sum); + System.out.println(sum); + } +} diff --git a/常用信息.md b/常用信息.md index d34e1dd..e9d0518 100644 --- a/常用信息.md +++ b/常用信息.md @@ -119,7 +119,7 @@ myComp.setState({test1: test2}); ```css /*修改url,字体文件上传到cloudstore/iconfont/xx/下,没有目录自己创建*/ -/*修改font-family,命名为其他名称,防止与系统自带的或与其他iconfont冲突*/ +/*修改font-family,命名为其他名称,防止与系统自带的或与其他iconfont冲突,并将修改后的css文件内容copy到ecode中,将文件夹发布,并且将css样式文件前置加载*/ @font-face { font-family: "cus_iconfont"; /* Project id 3789451 */ src: url('/cloudstore/iconfont/pcn/iconfont.woff2?t=1669223019749') format('woff2'), @@ -137,13 +137,97 @@ myComp.setState({test1: test2}); } ``` +**7.ecode组件样式引入(非前值加载)** +> 维护人员 youhong.ai + +在ecode开发时,需要编写css样式文件,但是偶尔会出现className与其他组件的className一样,导致样式发生覆盖或影响原来的组件的样式(前置加载会将css文件合并到init。css中,并且会全局引入,所以可能会造成样式污染) +在ecode中,找到config文件夹,找到config.js文件,可以看到的是js文件属于前置加载,我们只需要在这个js文件中将css文件动态添加到页面中就可以了 + +```js + +$(() => { + if (window.location.hash.indexOf("${appId}_organization-chart") !== -1) { + loadCssArr(['index.css']) + /* ******************** 下面两个文件为开发新页面时候,如果用户登陆超时,用于集成系统登陆弹窗的依赖和css样式文件 ******************* */ + // loadJs('/spa/portal/public/index.js') + // loadCss('/spa/portal/public/index.css') + // 使用方法,当请求结果返回的errorCode === '002',然后调用下面的方法 + // doLoginPop() + } +}) + +/** + * 加载当前appId下的css资源文件 + * @param cssArr css文件名称数组 (所有的css会被合并为index.css) + */ +function loadCssArr(cssArr) { + cssArr.forEach(item => { + let href = '/cloudstore/release/${appId}/' + item; + loadCss(href) + }) +} + + +/** + * 加载自定义的css样式文件,可以用于加载上传到resources文件加下的css文件,需要自己拼接路径 + * @param url 样式文件的路径 + */ +function loadCss(url) { + const head = document.getElementsByTagName('head')[0]; + const link = document.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = url; + head.appendChild(link); +} + +/** + * 加载当前ecode文件夹下的js文件,一般js文件会被打包成index.js文件 + * @param jsArr js文件名数组 + */ +function loadJsArr(jsArr) { + jsArr.forEach(item => { + let src = href = '/cloudstore/release/${appId}/' + item; + loadJs(src) + }) +} + +/** + * 加载自定义js文件,可用于加载第三方js库 + * @param url js文件路径 + * @param callback 加载完成后回调方法 + */ +function loadJs(url, callback) { + let script = document.createElement('script'), + fn = callback || function () { + }; + script.type = 'text/javascript'; + //IE + if (script.readyState) { + script.onreadystatechange = function () { + if (script.readyState == 'loaded' || script.readyState == 'complete') { + script.onreadystatechange = null; + fn(); + } + }; + } else { + //其他浏览器 + script.onload = function () { + fn(); + }; + } + script.src = url; + document.getElementsByTagName('head')[0].appendChild(script); +} +``` + ### 数据库 **备份mysql数据库** > 维护人员: youHong.ai ```shell -mysqldump -uroot -p'passowrd' --single-transaction -R -E --databases ecology_dev> /tmp/ecology_dev_back.sql +mysqldump -uroot -p'passowrd' --single-transaction -ApiResult -E --databases ecology_dev> /tmp/ecology_dev_back.sql ``` **mysql常用视图** @@ -418,9 +502,9 @@ from workflow_nodebase nb ```java //@Context HttpServletRequest request, @Context HttpServletResponse response User logInUser=HrmUserVarify.getUser(request,response); -// 传入id会将此人员信息带出 + // 传入id会将此人员信息带出 User user=new User(id); -// 获取人员id + // 获取人员id user.getUID(); ``` @@ -489,7 +573,7 @@ public class SendSms implements SmsService { DocImagefileToPdfUseWps toPdfUseWps=new DocImagefileToPdfUseWps(); newimagefileid=toPdfUseWps.officeDocumetnToPdfByImagefileid(docimagefileid); -//永中转PDF: + //永中转PDF: DocImagefileToPdf yozoToPdf=new DocImagefileToPdf(); newimagefileid=yozoToPdf.officeDocumetnToPdfByImagefileid(docimagefileid); ``` \ No newline at end of file