diff --git a/ant-design-vue-jeecg/src/assets/css/huahengUI.css b/ant-design-vue-jeecg/src/assets/css/huahengUI.css index a4fabda..643f0e1 100644 --- a/ant-design-vue-jeecg/src/assets/css/huahengUI.css +++ b/ant-design-vue-jeecg/src/assets/css/huahengUI.css @@ -1019,6 +1019,255 @@ label { font-size: 13px; max-width: unset; } +.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9 { + float: left + } + + .col-sm-12 { + width: 100% + } + + .col-sm-11 { + width: 91.66666667% + } + + .col-sm-10 { + width: 83.33333333% + } + + .col-sm-9 { + width: 75% + } + + .col-sm-8 { + width: 66.66666667% + } + + .col-sm-7 { + width: 58.33333333% + } + + .col-sm-6 { + width: 50% + } + + .col-sm-5 { + width: 41.66666667% + } + + .col-sm-4 { + width: 33.33333333% + } + + .col-sm-3 { + width: 25% + } + + .col-sm-2 { + width: 16.66666667% + } + + .col-sm-1 { + width: 8.33333333% + } + + .col-sm-pull-12 { + right: 100% + } + + .col-sm-pull-11 { + right: 91.66666667% + } + + .col-sm-pull-10 { + right: 83.33333333% + } + + .col-sm-pull-9 { + right: 75% + } + + .col-sm-pull-8 { + right: 66.66666667% + } + + .col-sm-pull-7 { + right: 58.33333333% + } + + .col-sm-pull-6 { + right: 50% + } + + .col-sm-pull-5 { + right: 41.66666667% + } + + .col-sm-pull-4 { + right: 33.33333333% + } + + .col-sm-pull-3 { + right: 25% + } + + .col-sm-pull-2 { + right: 16.66666667% + } + + .col-sm-pull-1 { + right: 8.33333333% + } + + .col-sm-pull-0 { + right: auto + } + + .col-sm-push-12 { + left: 100% + } + + .col-sm-push-11 { + left: 91.66666667% + } + + .col-sm-push-10 { + left: 83.33333333% + } + + .col-sm-push-9 { + left: 75% + } + + .col-sm-push-8 { + left: 66.66666667% + } + + .col-sm-push-7 { + left: 58.33333333% + } + + .col-sm-push-6 { + left: 50% + } + + .col-sm-push-5 { + left: 41.66666667% + } + + .col-sm-push-4 { + left: 33.33333333% + } + + .col-sm-push-3 { + left: 25% + } + + .col-sm-push-2 { + left: 16.66666667% + } + + .col-sm-push-1 { + left: 8.33333333% + } + + .col-sm-push-0 { + left: auto + } + + .col-sm-offset-12 { + margin-left: 100% + } + + .col-sm-offset-11 { + margin-left: 91.66666667% + } + + .col-sm-offset-10 { + margin-left: 83.33333333% + } + + .col-sm-offset-9 { + margin-left: 75% + } + + .col-sm-offset-8 { + margin-left: 66.66666667% + } + + .col-sm-offset-7 { + margin-left: 58.33333333% + } + + .col-sm-offset-6 { + margin-left: 50% + } + + .col-sm-offset-5 { + margin-left: 41.66666667% + } + + .col-sm-offset-4 { + margin-left: 33.33333333% + } + + .col-sm-offset-3 { + margin-left: 25% + } + + .col-sm-offset-2 { + margin-left: 16.66666667% + } + + .col-sm-offset-1 { + margin-left: 8.33333333% + } + + .col-sm-offset-0 { + margin-left: 0 + } +} +#img_list li{ + font-size: 10px; + /*width: 50px;*/ + text-align: left; + margin: 5px 20px 5px 5px; +} +#img_list li img{ + height: 35px; + width: 35px; +} +#info_list{ + width: 100%; + display:inline-block; +} +#info_list li{ + margin:8px 3px 0 5px; +} +#info_list li span{ + font-size: 12px; + display: inline-block; + /*width: 65px;*/ + text-align: center; +} +.grid{ + display: inline-block; + width: 50px; + height: 50px; + /*margin: 12px 6px;*/ + margin-bottom: 6px; + background-size:cover; + background-image: url("~@/assets/icon/空盘空闲.png"); +} + + .popover-title { padding: 8px 14px; diff --git a/ant-design-vue-jeecg/src/components/jeecgbiz/JButtonBizComponent/JSelectBizComponentModal.vue b/ant-design-vue-jeecg/src/components/jeecgbiz/JButtonBizComponent/JSelectBizComponentModal.vue index 1a67800..8941622 100644 --- a/ant-design-vue-jeecg/src/components/jeecgbiz/JButtonBizComponent/JSelectBizComponentModal.vue +++ b/ant-design-vue-jeecg/src/components/jeecgbiz/JButtonBizComponent/JSelectBizComponentModal.vue @@ -49,6 +49,8 @@ <a-card :title="'已选' + name" :bordered="false" :head-style="{padding:0}" :body-style="{padding:0}"> <a-table size="middle" :rowKey="rowKey" bordered v-bind="selectedTable"> + + <span slot="action" slot-scope="text, record, index"> <a @click="handleDeleteSelected(record, index)">删除</a> </span> @@ -57,6 +59,7 @@ </a-card> </a-col> </a-row> + <InventoryDetailList></InventoryDetailList> </j-modal> </template> @@ -69,11 +72,12 @@ import JSelectBizQueryItem from './JSelectBizQueryItem' import {cloneDeep} from 'lodash' import {stockTakeTask} from "../../../api/api"; import Utils from './util.js'; +import InventoryDetailList from "../../../views/system/inventory/InventoryDetailList"; export default { name: 'JSelectBizComponentModal', mixins: [JeecgListMixin], - components: {Ellipsis, JSelectBizQueryItem}, + components: {Ellipsis, JSelectBizQueryItem,InventoryDetailList}, props: { value: { type: Array, @@ -155,7 +159,7 @@ export default { scroll: {y: 240}, columns: [ { - ...this.columns[0], + ...this.columns[3], width: this.columns[0].widthRight || this.columns[0].width, }, {title: '操作', dataIndex: 'action', align: 'center', width: 60, scopedSlots: {customRender: 'action'},} @@ -185,6 +189,7 @@ export default { // 表头 innerColumns() { let columns = cloneDeep(this.columns) + debugger columns.forEach(column => { // 给所有的列加上过长裁剪 if (this.ellipsisLength !== -1) { @@ -331,7 +336,7 @@ export default { this.$message.success(res.message) this.$emit('ok') this.close() - Utils.$emit('methodB',"123"); + Utils.$emit('methodB',res.result); } else { this.$message.warning(res.message); } @@ -343,7 +348,6 @@ export default { { alert("至少选择一项") } - Utils.$emit('methodB',"123"); }, /** 删除已选择的 */ handleDeleteSelected(record, index) { diff --git a/ant-design-vue-jeecg/src/components/jeecgbiz/JSelectMultiCycleCount.vue b/ant-design-vue-jeecg/src/components/jeecgbiz/JSelectMultiCycleCount.vue index b90b633..dc42bf8 100644 --- a/ant-design-vue-jeecg/src/components/jeecgbiz/JSelectMultiCycleCount.vue +++ b/ant-design-vue-jeecg/src/components/jeecgbiz/JSelectMultiCycleCount.vue @@ -31,13 +31,13 @@ export default { return { url: {list: '/inventory/inventoryHeader/list'}, columns: [ - {title: '容器号', align: 'center', width: '25%',widthRight: '70%', dataIndex: 'containerCode'}, + {title: 'ID', align: 'center', width: '20%',widthRight: '70%', dataIndex: 'id'}, + {title: '容器号', align: 'center', width: '25%', dataIndex: 'containerCode'}, {title: '容器状态', align: 'center', width: '20%', dataIndex: 'containerStatus'}, {title: '库位号', align: 'center', width: '20%', dataIndex: 'locationCode'}, {title: '总数量', align: 'center', width: '20%', dataIndex: 'totalQty'}, {title: '库区', align: 'center', width: '20%', widthRight: '70%', dataIndex: 'zoneCode'}, {title: '状态', align: 'center', width: '20%', dataIndex: 'enable'}, - {title: 'ID', align: 'center', width: '20%', dataIndex: 'id'}, ], // 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件 default: { diff --git a/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue b/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue index 3e5e110..5f680af 100644 --- a/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue +++ b/ant-design-vue-jeecg/src/components/layouts/UserLayout.vue @@ -16,7 +16,7 @@ <div class="footer"> <div class="copyright"> - Copyright © 2022 华恒焊接股份有限公司 + Copyright © 2023 华恒焊接股份有限公司 </div> </div> </div> diff --git a/ant-design-vue-jeecg/src/views/dashboard/Analysis.vue b/ant-design-vue-jeecg/src/views/dashboard/Analysis.vue index 7f40960..7187a81 100644 --- a/ant-design-vue-jeecg/src/views/dashboard/Analysis.vue +++ b/ant-design-vue-jeecg/src/views/dashboard/Analysis.vue @@ -57,7 +57,7 @@ <a-row :gutter="24"> <a-col :span="12"> - <a-card :loading="loading" :bordered="false" title="历史每日收发货量" :style="{ marginTop: '24px' }"> + <a-card :bordered="false" title="历史每日收发货量" :style="{ marginTop: '24px' }"> <a-row> <a-col :span="19"> <div id="chart1" class="flot-chart1"> @@ -65,11 +65,10 @@ </div> </a-col> </a-row> - <line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid> </a-card> </a-col> <a-col :span="12"> - <a-card :loading="loading" :bordered="false" title="库位利用率" :style="{ marginTop: '24px' }"> + <a-card :bordered="false" title="库位利用率" :style="{ marginTop: '24px' }"> <a-row> <a-col :span="19"> <div id="chart2" class="flot-chart1"> @@ -77,7 +76,6 @@ </div> </a-col> </a-row> - <line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid> </a-card> </a-col> </a-row> @@ -85,7 +83,7 @@ <a-row :gutter="24"> <a-col :span="12"> - <a-card :loading="loading" :bordered="false" title="在线库存状态" :style="{ marginTop: '24px' }"> + <a-card :bordered="false" title="在线库存状态" :style="{ marginTop: '24px' }"> <a-row> <a-col :span="19"> <div id="chart3" class="flot-chart1"> @@ -93,11 +91,10 @@ </div> </a-col> </a-row> - <line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid> </a-card> </a-col> <a-col :span="12"> - <a-card :loading="loading" :bordered="false" title="库存概况" :style="{ marginTop: '24px' }"> + <a-card :bordered="false" title="库存概况" :style="{ marginTop: '24px' }"> <a-row> <a-col :span="19"> <div id="chart4" class="flot-chart1"> @@ -105,7 +102,6 @@ </div> </a-col> </a-row> - <line-chart-multid :fields="visitFields" :dataSource="visitInfo"></line-chart-multid> </a-card> </a-col> </a-row> diff --git a/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue b/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue index 57d9409..9bd0667 100644 --- a/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue +++ b/ant-design-vue-jeecg/src/views/system/monitor/locationStatus.vue @@ -5,10 +5,20 @@ <form id="container-form"> <div class="select-list"> <ul id="select_info"> + <li> - <select id="zoneCode" name="zoneCode" style="width: 100px"> - <option selected>A</option> - </select> + 货主 + <a-select + show-search + placeholder="请选择库位类型" + option-filter-prop="children" + v-model="zoneCode" + style="width: 200px"> + <a-select-option selected="0" id="zoneCode" v-for="item in locationTypeList" :key="item.name" :value="item.code">{{ + item.name + }} + </a-select-option> + </a-select> </li> <li> 第 @@ -23,7 +33,7 @@ </select> </li> <li> - <a-button type="primary" @click="Search()" icon="search">查询</a-button> + <a-button type="primary" @click="Search()" icon="search">查询</a-button> </li> </ul> </div> @@ -81,15 +91,22 @@ </div> </form> </div> + <div class="col-sm-12 select-info"> - <div id="borderCol" style="overflow-y: scroll;white-space:nowrap"> + <div id="borderCol" style="overflow-y: scroll;white-space:nowrap" v-show="showPrise"> <div class="location" id="location"> </div> </div> + <a-spin tip="库位视图生成中..." :spinning="spinning"> + <a-skeleton active :loading="loading" :paragraph="{ rows: 5 }"/> + </a-spin> </div> + + </div> </div> </template> + <script> var prefix = "/location/locationMonitor"; var grid_row; @@ -114,10 +131,7 @@ var currentMaterialCode=0; import huahengUI from '../../../assets/css/huahengUI.css' - import $ from '../../../assets/js/jquery-1.11.1.min' - - import grid_rest from '@/assets/icon/空柜空闲.png' import grid_empty from '@/assets/icon/空盘空闲.png' import grid_half from '@/assets/icon/半盘空闲.png' @@ -131,23 +145,51 @@ import grid_half_lock from '@/assets/icon/半盘锁定.png' import grid_all_lock from '@/assets/icon/整盘锁定.png' import rel_empty from '@/assets/icon/空.png' + import Vue from 'vue' + import {ACCESS_TOKEN} from "@/store/mutation-types" + import {getLocationTypeList} from '@/api/api' + + + export default { name: "locationStatus", - + zoneCode:"", data() { - return {} + return { + spinning:true, + loading:true, + showPrise:false, + // loading:true, + zoneCode:'', + locationTypeList: [], + model:{}, + locationContent:'' + } }, - mounted() { - let _this=this; - this.resetAjax("L"); - // - // this.initEvent(); - // - // //监听浏览器宽度的改变 + // setup() { + // const spinning = ref<boolean>(false); + // + // const changeSpinning = () => { + // spinning.value = !spinning.value; + // }; + + + created() { + let _this=this + _this.loadFrom() + window.gridMsg=_this.gridMsg + window.Mclose=_this.Mclose + window.lays=_this.lays + }, + + + + mounted() { + //监听浏览器宽度的改变 // window.onresize = function(){ // _this.changeMargin(); // _this.border() @@ -158,6 +200,17 @@ // this.border() }, methods: { + loadFrom() { + getLocationTypeList().then((res) => { + if (res.success) { + this.locationTypeList = res.result + this.zoneCode = this.locationTypeList[0].code; + let _this=this; + this.resetAjax("L"); + } + }) + }, + initEvent(){ @@ -218,11 +271,11 @@ //tips信息 lays(x){ - alert(2) let $j=$(x); let row=$j.attr("data-i"); let line=$j.attr("data-j"); let layers=$j.attr("data-k"); + row=parseInt(row); line=parseInt(line); layers=parseInt(layers); @@ -233,13 +286,13 @@ let container_code=''; let list_qty=0; if (list_info[i].containerCode) { - container_code="<br>容器编码:"+ list_info[i].containerCode+""; + container_code="\n容器编码:"+ list_info[i].containerCode+""; if (list_info[i].materialName) { for (let j = 0; j < list_info[i].materialName.length; j++) { let list_batch=list_info[i].batch[j]===null?"无":list_info[i].batch[j]===""?"无":list_info[i].batch[j]; list_qty +=list_info[i].qty[j]; if(j==list_info[i].materialName.length-1){ - str_info=str_info + "<br>批次:"+ list_batch +",物料名称:"+ list_info[i].materialName[j] +",物料编码:"+ list_info[i].materialCode[j] + + str_info=str_info + "\n批次:"+ list_batch +",物料名称:"+ list_info[i].materialName[j] +",物料编码:"+ list_info[i].materialCode[j] + ",数量:"+ list_qty +"" } @@ -248,8 +301,9 @@ } } let code=list_info[i].code===null?"无":list_info[i].code; - layer.tips("第"+row+"行,第"+line+"列,第"+ layers +"层<br>库位:"+ code + container_code + str_info + "" - ,$j,{tips:[1,"rgb(28,132,198)"],time:0,area:'auto',maxWidth: '1000'}); + $("[data-i='"+row+"']"+"[data-j='"+line+"']"+"[data-k='"+layers+"']").attr({ "title":"第"+row+"行,第"+line+"列,第"+ layers +"层\n库位:"+ code + container_code + str_info}); + // Vue.prototype.$Jnotification.success({message: '系统提示', description: "第"+row+"行,第"+line+"列,第"+ layers +"层<br>库位:"+ code + container_code + str_info, duration: 4}) + } } }else {return ""} @@ -258,8 +312,8 @@ //关闭tips Mclose(x){ - alert(1) //关闭 + // Vue.prototype.$Jnotification.error({message: '系统提示', description: "鼠标拿走了", duration: 4}) }, //库位信息请求和状态显示 @@ -267,10 +321,10 @@ let _this=this // let load=layer.msg('加载中', {icon: 16,shade: 0.4,time: false}); $.ajax({ - url:"http://127.0.0.1:8080/wms"+prefix+"/getLocationInfo", + url:window._CONFIG['domianURL']+prefix+"/getLocationInfo", type:"post", headers:{ - "X-Access-Token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NzU4MjQ4NDgsIndhcmVob3VzZUNvZGUiOiJDUzAwMDEiLCJ1c2VybmFtZSI6InlvdWppZSJ9.iiwKWoVA9AOA_fITphsG-rJibOlUD8EgtN-tthRt_Lg" + "X-Access-Token":Vue.ls.get(ACCESS_TOKEN) }, data:info, success:function (res) { @@ -388,15 +442,18 @@ $(".grid").eq(j).attr({"src": rel_empty,"onmouseover": "","onclick": ""}); } } + this.spinning=false; + this.showPrise=true; + this.loading=false; }, //点击显示当前库位信息 gridMsg(msg) { - debugger let $j=$(msg); let row=$j.attr("data-i"); let line=$j.attr("data-j"); let layers=$j.attr("data-k"); + row=parseInt(row); line=parseInt(line); layers=parseInt(layers); @@ -435,13 +492,13 @@ resetAjax(type){ var _this=this; $.ajax({ - url:"http://127.0.0.1:8080/wms"+prefix+"/getAllLocation", + url:window._CONFIG['domianURL']+prefix+"/getAllLocation", type:"post", data:{ type:type }, headers:{ - "X-Access-Token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NzU4MjQ4NDgsIndhcmVob3VzZUNvZGUiOiJDUzAwMDEiLCJ1c2VybmFtZSI6InlvdWppZSJ9.iiwKWoVA9AOA_fITphsG-rJibOlUD8EgtN-tthRt_Lg" + "X-Access-Token":Vue.ls.get(ACCESS_TOKEN) }, success:function (res) { grid_row=res.result.maxRow; @@ -455,7 +512,7 @@ $(".location").append("<br>"); for (let j = 1; j <= grid_line; j++) { // $(".location").append("<img data-i='1' data-j="+j+" data-k="+ i +" class='grid'>"); - $(".location").append("<img data-i='1' data-j="+j+" data-k="+ i +" class='grid' @mouseove='lays(this)' @mouseout='Mclose(this)' @click='gridMsg(this)'>"); + $(".location").append("<img v-html data-i='1' data-j="+j+" data-k="+ i +" class='grid' onmouseove='lays(this)' onmouseout='Mclose(this)' onclick='gridMsg(this)'>"); } } let num=$("#editable-select").val(); @@ -477,7 +534,7 @@ } _this.changeMargin(); - _this.Search(); + _this.Search(); } }); }, @@ -485,9 +542,23 @@ //搜索平面库位 Search(){ + this.spinning=true; + this.showPrise=false; + this.loading=true; let index=$("#editable-select").val(); let num=$("#editable-num").val(); - let zoneCode=$("#zoneCode").val(); + + let zoneCode=""; + + if ($("#zoneCode").val()==null) + { + zoneCode=this.locationTypeList[0].zoneCode; + }else + { + zoneCode=this.locationTypeList[$("#zoneCode").val()].zoneCode; + } + + $("#code").val(""); $("#containerCode").val(""); $("#material").children().remove(); @@ -498,20 +569,21 @@ data={type:zoneCode, row:num}; $("#location").children().remove(); for (let i = grid_layer; i > 0; i--) { - $(".location").append("<br><span>第"+ i+"层</span>"); + $(".location").append("<br><span style='display: inline-block;text-align: right;width: 50px; margin-right: 10px;'>第"+ i+"层</span>"); for (let j = 1; j <= grid_line; j++) { - $(".location").append("<img data-i="+num+" data-j="+j+" data-k="+i+" class='grid' @mouseover='lays(this)' @mouseout='Mclose(this)' @click='gridMsg(this)'>"); + $(".location").append("<img data-i="+num+" data-j="+j+" data-k="+i+" class='grid' onmouseover='lays(this)' onmouseout='Mclose(this)' onclick='gridMsg(this)'>"); } } + + this.changeMargin(); this.ajaxGrid(index,data); } else if (index === "line") { - debugger data={type:zoneCode, line:num}; $("#location").children().remove(); for (let k = grid_layer; k > 0; k--) { - $(".location").append("<br><span>第"+ k+"层</span>"); + $(".location").append("<br><span style='display: inline-block;text-align: right;width: 50px; margin-right: 10px;'>第"+ k+"层</span>"); for (let l = 1; l <= grid_row; l++) { $(".location").append("<img data-i="+l+" data-j="+num+" data-k="+k+" class='grid' onmouseover='lays(this)' onmouseout='Mclose(this)' onclick='gridMsg(this)'>"); } @@ -523,7 +595,7 @@ data={type:zoneCode, layer:num}; $("#location").children().remove(); for (let m = 1; m <= grid_row; m++) { - $(".location").append("<br><span>第"+ m+"行</span>"); + $(".location").append("<br><span style='display: inline-block;text-align: right;width: 50px; margin-right: 10px;'>第"+ m+"行</span>"); for (let n = 1; n <= grid_line; n++) { $(".location").append("<img data-i="+m+" data-j="+n+" data-k="+num+" class='grid' onmouseover='lays(this)' onmouseout='Mclose(this)' onclick='gridMsg(this)'>"); } @@ -531,38 +603,28 @@ this.changeMargin(); this.ajaxGrid(index,data); } + }, - }, - - - searchLocation(){ - if(!currentLocationCode){ - $.modal.alertError("请选择库位") - }else { - localStorage.setItem("locationCode",currentLocationCode) - createMenuItem("路径" +"config/location","库位管理") - } - }, - - searchInventory() { - if(!currentLocationCode){ - $.modal.alertError("请选择库位") - return - } - localStorage.setItem("locationCode",currentLocationCode) - createMenuItem("路径" +"inventory/inventoryHeader","库存查看") - }, seachZone(){ + let _this=this + let zoneCode=""; + if ($("#zoneCode").val()==null) + { + zoneCode=this.locationTypeList[0].zoneCode; + }else + { + zoneCode=this.locationTypeList[$("#zoneCode").val()].zoneCode; + } $.ajax({ - url:"http://127.0.0.1:8080/wms"+prefix+"/getStatus", + url:window._CONFIG['domianURL']+prefix+"/getStatus", data:{ - zoneCode:$("#zoneCode").val() + zoneCode:zoneCode }, headers:{ - "X-Access-Token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NzU4MjQ4NDgsIndhcmVob3VzZUNvZGUiOiJDUzAwMDEiLCJ1c2VybmFtZSI6InlvdWppZSJ9.iiwKWoVA9AOA_fITphsG-rJibOlUD8EgtN-tthRt_Lg" + "X-Access-Token":Vue.ls.get(ACCESS_TOKEN) }, success:function (response) { if (response.code==200){ @@ -582,257 +644,4 @@ </script> <style scoped> - .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9 { - position: relative; - min-height: 1px; - padding-right: 15px; - padding-left: 15px - } - @media (min-width: 768px) { - .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9 { - float: left - } - - .col-sm-12 { - width: 100% - } - - .col-sm-11 { - width: 91.66666667% - } - - .col-sm-10 { - width: 83.33333333% - } - - .col-sm-9 { - width: 75% - } - - .col-sm-8 { - width: 66.66666667% - } - - .col-sm-7 { - width: 58.33333333% - } - - .col-sm-6 { - width: 50% - } - - .col-sm-5 { - width: 41.66666667% - } - - .col-sm-4 { - width: 33.33333333% - } - - .col-sm-3 { - width: 25% - } - - .col-sm-2 { - width: 16.66666667% - } - - .col-sm-1 { - width: 8.33333333% - } - - .col-sm-pull-12 { - right: 100% - } - - .col-sm-pull-11 { - right: 91.66666667% - } - - .col-sm-pull-10 { - right: 83.33333333% - } - - .col-sm-pull-9 { - right: 75% - } - - .col-sm-pull-8 { - right: 66.66666667% - } - - .col-sm-pull-7 { - right: 58.33333333% - } - - .col-sm-pull-6 { - right: 50% - } - - .col-sm-pull-5 { - right: 41.66666667% - } - - .col-sm-pull-4 { - right: 33.33333333% - } - - .col-sm-pull-3 { - right: 25% - } - - .col-sm-pull-2 { - right: 16.66666667% - } - - .col-sm-pull-1 { - right: 8.33333333% - } - - .col-sm-pull-0 { - right: auto - } - - .col-sm-push-12 { - left: 100% - } - - .col-sm-push-11 { - left: 91.66666667% - } - - .col-sm-push-10 { - left: 83.33333333% - } - - .col-sm-push-9 { - left: 75% - } - - .col-sm-push-8 { - left: 66.66666667% - } - - .col-sm-push-7 { - left: 58.33333333% - } - - .col-sm-push-6 { - left: 50% - } - - .col-sm-push-5 { - left: 41.66666667% - } - - .col-sm-push-4 { - left: 33.33333333% - } - - .col-sm-push-3 { - left: 25% - } - - .col-sm-push-2 { - left: 16.66666667% - } - - .col-sm-push-1 { - left: 8.33333333% - } - - .col-sm-push-0 { - left: auto - } - - .col-sm-offset-12 { - margin-left: 100% - } - - .col-sm-offset-11 { - margin-left: 91.66666667% - } - - .col-sm-offset-10 { - margin-left: 83.33333333% - } - - .col-sm-offset-9 { - margin-left: 75% - } - - .col-sm-offset-8 { - margin-left: 66.66666667% - } - - .col-sm-offset-7 { - margin-left: 58.33333333% - } - - .col-sm-offset-6 { - margin-left: 50% - } - - .col-sm-offset-5 { - margin-left: 41.66666667% - } - - .col-sm-offset-4 { - margin-left: 33.33333333% - } - - .col-sm-offset-3 { - margin-left: 25% - } - - .col-sm-offset-2 { - margin-left: 16.66666667% - } - - .col-sm-offset-1 { - margin-left: 8.33333333% - } - - .col-sm-offset-0 { - margin-left: 0 - } - } - #img_list li{ - font-size: 10px; - /*width: 50px;*/ - text-align: left; - margin: 5px 20px 5px 5px; - } - #img_list li img{ - height: 35px; - width: 35px; - } - #info_list{ - width: 100%; - display:inline-block; - } - #info_list li{ - margin:8px 3px 0 5px; - } - #info_list li span{ - font-size: 12px; - display: inline-block; - /*width: 65px;*/ - text-align: center; - } - .grid{ - display: inline-block; - width: 50px; - height: 50px; - /*margin: 12px 6px;*/ - margin-bottom: 6px; - background-size:cover; - background-image: url("~@/assets/icon/空盘空闲.png"); - } - #location span{ - display: inline-block; - text-align: right; - width: 50px; - margin-right: 10px; - } </style> \ No newline at end of file diff --git a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountDetailList.vue b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountDetailList.vue index 45355b0..9a4fbe4 100644 --- a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountDetailList.vue +++ b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountDetailList.vue @@ -77,12 +77,7 @@ <template slot="action" slot-scope="text, record"> <a v-if="record.enableStatus === 1" @click="generateCount(record.id)">生成盘点任务</a> <a-divider v-if="record.enableStatus === 1" type="vertical"/> - <a @click="loadData()"><a-icon type="sync"/>刷新</a> - <a-divider type="vertical"/> - <a-popconfirm title="确定删除吗?" @confirm="handleDelete(record.id)"> - <a>删除</a> - </a-popconfirm> - + <a @click="loadDatas(record.cycleCountHeadId)"><a-icon type="sync"/>刷新</a> </template> </a-table> @@ -98,6 +93,7 @@ <script> import { JeecgListMixin } from '@/mixins/JeecgListMixin' + import { getAction } from '@api/manage' import CycleCountDetailModal from './modules/CycleCountDetailModal' import CycleCountDetailChildSubTable from './subTables/CycleCountDetailChildSubTable' import '@/assets/less/TableExpand.less' @@ -113,6 +109,10 @@ CycleCountDetailChildSubTable, }, props: { + record: { + type: Object, + default: null, + }, isLoad: { type: Boolean, default: false, @@ -259,7 +259,46 @@ return window._CONFIG['domianURL'] + this.url.importExcelUrl } }, + + watch: { + record: { + immediate: true, + handler() { + if (this.record != null) { + this.loadData(this.record) + } + } + } + }, methods: { + loadData(record) { + this.loading = true + this.dataSource = [] + getAction(this.url.list, { + cycleCountHeadId: record.id + }).then((res) => { + if (res.success) { + this.dataSource = res.result.records + } + }).finally(() => { + this.loading = false + }) + }, + + loadDatas(record) { + this.loading = true + this.dataSource = [] + getAction(this.url.list, { + cycleCountHeadId: record + }).then((res) => { + if (res.success) { + this.dataSource = res.result.records + } + }).finally(() => { + this.loading = false + }) + }, + // testaa(){ // alert("刷新了") // var _this = this; @@ -267,7 +306,7 @@ // }, methodB(data) { var _this = this; - _this.loadDataList(); + _this.loadDatas(data); }, initDictConfig() { }, @@ -278,7 +317,7 @@ this.$message.success(res.message) this.$emit('ok') var _this = this; - _this.loadData(); + _this.loadDatas(res.result); } else { this.$message.warning(res.message); } diff --git a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue index cea3de5..e9f1e65 100644 --- a/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue +++ b/ant-design-vue-jeecg/src/views/system/stocktaking/CycleCountHeaderList.vue @@ -92,15 +92,12 @@ </a-button> </template> <span slot="action" slot-scope="text, record"> - <j-select-multi-cycle-count :query-config="selectUserQueryConfig" :test-config="record.id" :header-code="record.code"/> - <a-divider type="vertical" /> + <j-select-multi-cycle-count v-if="record.statusCyc!=100" :query-config="selectUserQueryConfig" :test-config="record.id" :header-code="record.code"/> + <a-divider type="vertical" v-if="record.statusCyc!=100" /> <a-dropdown> <a class="ant-dropdown-link">更多 <a-icon type="down" /></a> <a-menu slot="overlay"> <a-menu-item> - <a @click="loadDataaa()"><a-icon type="sync"/>刷新</a> - </a-menu-item> - <a-menu-item> <a @click="handleEdit(record)">编辑</a> </a-menu-item> <a-menu-item> diff --git a/ant-design-vue-jeecg/src/views/system/stocktaking/subTables/CycleCountDetailChildSubTable.vue b/ant-design-vue-jeecg/src/views/system/stocktaking/subTables/CycleCountDetailChildSubTable.vue index 9dbfb75..17747fd 100644 --- a/ant-design-vue-jeecg/src/views/system/stocktaking/subTables/CycleCountDetailChildSubTable.vue +++ b/ant-design-vue-jeecg/src/views/system/stocktaking/subTables/CycleCountDetailChildSubTable.vue @@ -23,7 +23,7 @@ <template slot="action" slot-scope="text, record"> <adjustment-doc-modal ref="adjustmentModal" @ok="modalFormOk" :id="record.id"/> - <a @click="createMany(record)"><a-icon />实盘登记</a> + <a v-if="record.childStatus != 1" @click="createMany(record)"><a-icon />实盘登记</a> </template> <template slot="fileSlot" slot-scope="text"> diff --git a/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java b/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java index c6b2cb4..79a828b 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/JeecgSystemApplication.java @@ -18,6 +18,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.Environment; @@ -28,6 +29,7 @@ import net.bytebuddy.asm.Advice.This; * 单体启动类(采用此类启动为单体模式) */ @Slf4j +@EnableCaching @SpringBootApplication @EnableAutoConfiguration(exclude = {MongoAutoConfiguration.class}) public class JeecgSystemApplication extends SpringBootServletInitializer { diff --git a/huaheng-wms-core/src/main/java/org/jeecg/config/init/CodeGenerateDbConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/config/init/CodeGenerateDbConfig.java index 2f3928c..6a41029 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/config/init/CodeGenerateDbConfig.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/config/init/CodeGenerateDbConfig.java @@ -12,7 +12,7 @@ import org.springframework.context.annotation.Configuration; * @Description: 代码生成器,自定义DB配置 * 【加了此类,则online模式DB连接,使用平台的配置,jeecg_database.properties配置无效; * 但是使用GUI模式代码生成,还是走jeecg_database.properties配置】 - * 提醒: 达梦数据库需要修改下面的参数${spring.datasource.dynamic.datasource.master.url:}配置 + * 提醒:达梦数据库需要修改下面的参数 ${spring.datasource.dynamic.datasource.master.url} 配置 * @author: scott * @date: 2021年02月18日 16:30 */ @@ -38,11 +38,11 @@ public class CodeGenerateDbConfig { password = ConfigTools.decrypt(publicKey, password); } catch (Exception e) { e.printStackTrace(); - log.error(" 代码生成器数据库连接,数据库密码解密失败!"); + log.error("代码生成器数据库连接,数据库密码解密失败!"); } } CodegenDatasourceConfig.initDbConfig(driverClassName, url, username, password); - log.info(" 代码生成器数据库连接,使用application.yml的DB配置 ###################"); + log.info("###代码生成器数据库连接,使用application.yml的DB配置 ###"); } return null; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java index 97f1c7b..1f2bdbb 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/cas/controller/CasClientController.java @@ -81,7 +81,7 @@ public class CasClientController { String token = HuahengJwtUtil.sign(sysUser.getUsername(), sysUser.getPassword()); // 设置超时时间 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); - redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, HuahengJwtUtil.EXPIRE_TIME * 2 / 1000); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, HuahengJwtUtil.EXPIRE_TIME / 1000); // 获取用户部门信息 JSONObject obj = new JSONObject(); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java index 1102001..331390b 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java @@ -125,7 +125,7 @@ public class LoginController { LoginUser loginUser = new LoginUser(); BeanUtils.copyProperties(sysUser, loginUser); loginUser.setId(sysUser.getId() + ""); - baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null, loginUser); + baseCommonService.addLog("用户名:" + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null, loginUser); // update-end--Author:wangshuai Date:20200714 for:登录日志没有记录人员 return result; } @@ -172,9 +172,9 @@ public class LoginController { LoginUser sysUser = sysBaseAPI.getUserByName(username); if (sysUser != null) { // update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - baseCommonService.addLog("用户名: " + sysUser.getRealname() + ",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser); + baseCommonService.addLog("用户名:" + sysUser.getRealname() + ",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser); // update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - log.info(" 用户名: " + sysUser.getRealname() + ",退出成功! "); + log.info("用户名:" + sysUser.getRealname() + ",退出成功!"); // 清空用户登录Token缓存 redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); // 清空用户登录Shiro权限缓存 @@ -378,7 +378,7 @@ public class LoginController { // 用户信息 userInfo(sysUser, result, warehouseCode); // 添加日志 - baseCommonService.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null); + baseCommonService.addLog("用户名:" + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null); return result; } @@ -429,34 +429,34 @@ public class LoginController { } } + // 暂时移除唯一登录功能 // 删除相同用户名称对应的key - Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); - for (String key : keys) { - String token = (String)redisUtil.get(key); - LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token)); - if (loginUser != null) { - if (oConvertUtils.isNotEmpty(username) && loginUser.getUsername().contains(username)) { - log.info(" 强制 " + sysUser.getRealname() + "退出成功! "); - // 清空用户登录Token缓存 - redisUtil.del(token); - redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); - // 清空用户登录Shiro权限缓存 - redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); - // 清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username> - redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); - // 调用shiro的logout - SecurityUtils.getSubject().logout(); - // - redisUtil.del(key); - } - } - } +// Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); +// for (String key : keys) { +// String token = (String)redisUtil.get(key); +// LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token)); +// if (loginUser != null) { +// if (oConvertUtils.isNotEmpty(username) && loginUser.getUsername().contains(username)) { +// log.info("强制 " + sysUser.getRealname() + " 退出成功! "); +// // 清空用户登录Token缓存 +// redisUtil.del(token); +// // 清空用户登录Token缓存 +// redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token); +// // 清空用户登录Shiro权限缓存 +// redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); +// // 清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username> +// redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); +// // 调用shiro的logout +// SecurityUtils.getSubject().logout(); +// } +// } +// } // update-end--Author:sunjianlei Date:20210802 for:获取用户租户信息 // 生成token String token = HuahengJwtUtil.sign(username, syspassword, warehouseCode); // 设置token缓存有效时间 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); - redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, HuahengJwtUtil.EXPIRE_TIME / 1000); obj.put("token", token); obj.put("userInfo", sysUser); obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); @@ -562,14 +562,14 @@ public class LoginController { String token = JwtUtil.sign(username, syspassword); // 设置超时时间 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); - redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, HuahengJwtUtil.EXPIRE_TIME / 1000); // token 信息 obj.put("token", token); result.setResult(obj); result.setSuccess(true); result.setCode(200); - baseCommonService.addLog("用户名: " + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null); + baseCommonService.addLog("用户名:" + username + ",登录成功[移动端]!", CommonConstant.LOG_TYPE_1, null); return result; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserController.java index 6d238f6..5900c0f 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserController.java @@ -217,7 +217,7 @@ public class SysUserController { Result<SysUser> result = new Result<SysUser>(); try { SysUser sysUser = sysUserService.getById(jsonObject.getString("id")); - baseCommonService.addLog("编辑用户,id: " + jsonObject.getString("id"), CommonConstant.LOG_TYPE_2, 2); + baseCommonService.addLog("编辑用户,id:" + jsonObject.getString("id"), CommonConstant.LOG_TYPE_2, 2); if (sysUser == null) { result.error500("未找到对应实体"); } else { @@ -249,7 +249,7 @@ public class SysUserController { // @RequiresRoles({"admin"}) @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public Result<?> delete(@RequestParam(name = "id", required = true) String id) { - baseCommonService.addLog("删除用户,id: " + id, CommonConstant.LOG_TYPE_2, 3); + baseCommonService.addLog("删除用户,id:" + id, CommonConstant.LOG_TYPE_2, 3); this.sysUserService.deleteUser(id); return Result.ok("删除用户成功"); } @@ -260,7 +260,7 @@ public class SysUserController { // @RequiresRoles({"admin"}) @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) { - baseCommonService.addLog("批量删除用户, ids: " + ids, CommonConstant.LOG_TYPE_2, 3); + baseCommonService.addLog("批量删除用户,ids:" + ids, CommonConstant.LOG_TYPE_2, 3); this.sysUserService.deleteBatchUsers(ids); return Result.ok("批量删除用户成功"); } @@ -1228,7 +1228,7 @@ public class SysUserController { try { String username = JwtUtil.getUserNameByToken(request); SysUser sysUser = sysUserService.getUserByName(username); - baseCommonService.addLog("移动端编辑用户,id: " + jsonObject.getString("id"), CommonConstant.LOG_TYPE_2, 2); + baseCommonService.addLog("移动端编辑用户,id:" + jsonObject.getString("id"), CommonConstant.LOG_TYPE_2, 2); String realname = jsonObject.getString("realname"); String avatar = jsonObject.getString("avatar"); String sex = jsonObject.getString("sex"); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java index 959ce02..65f0e9f 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysUserOnlineController.java @@ -120,7 +120,6 @@ public class SysUserOnlineController { return Result.error("退出登录失败!"); } Collection<String> keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); - List<SysUserOnlineVO> onlineList = new ArrayList<SysUserOnlineVO>(); for (String key : keys) { if (key.equals(online.getToken())) { String tokenValue = (String)redisUtil.get(online.getToken()); @@ -128,18 +127,13 @@ public class SysUserOnlineController { LoginUser sysUser = sysBaseAPI.getUserByName(username); if (sysUser != null) { // update-begin--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - baseCommonService.addLog("用户名: " + sysUser.getRealname() + ",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser); + baseCommonService.addLog("用户名:" + sysUser.getRealname() + ",退出成功!", CommonConstant.LOG_TYPE_1, null, sysUser); // update-end--Author:wangshuai Date:20200714 for:登出日志没有记录人员 - log.info(" 用户名: " + sysUser.getRealname() + ",退出成功! "); - - // 以下两个清空测试无效 保留在这吧 - // 清空用户登录Token缓存/用户登录Shiro权限缓存 + log.info("用户 " + sysUser.getRealname() + ",退出成功!"); + // 清空用户登录Token缓存 redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + tokenValue); + // 用户登录Shiro权限缓存 redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId()); - - // 真*清空Token - redisUtil.del(key); - // 清空用户的缓存信息 redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername())); // 调用shiro的logout diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java index 631a132..f223036 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java @@ -202,7 +202,6 @@ public class ThirdLoginController { return token; } - @SuppressWarnings("unchecked") @RequestMapping(value = "/getLoginUser/{token}/{thirdType}", method = RequestMethod.GET) @ResponseBody public Result<JSONObject> getThirdLoginUser(@PathVariable("token") String token, @PathVariable("thirdType") String thirdType) throws Exception { @@ -235,7 +234,7 @@ public class ThirdLoginController { result.setResult(obj); result.setSuccess(true); result.setCode(200); - baseCommonService.addLog("用户名: " + username + ",登录成功[第三方用户]!", CommonConstant.LOG_TYPE_1, null); + baseCommonService.addLog("用户名:" + username + ",登录成功[第三方用户]!", CommonConstant.LOG_TYPE_1, null); return result; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java index c71c9ef..2039398 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java @@ -392,13 +392,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl // update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------ if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) { // update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------ - baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); + baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); result.error500("该用户已注销"); return result; } // 情况3:根据用户信息查询,该用户已冻结 if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) { - baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); + baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); result.error500("该用户已冻结"); return result; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java index 96c9b3e..1eb399d 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/controller/AcsController.java @@ -1,28 +1,55 @@ package org.jeecg.modules.wms.api.acs.controller; +import java.util.Map; + import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.wms.api.acs.entity.AcsStatus; import org.jeecg.modules.wms.api.acs.service.IAcsService; +import org.jeecg.modules.wms.config.address.service.IAddressService; import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.framework.controller.HuahengBaseController; import org.jeecg.modules.wms.task.agvTask.service.IAgvTaskService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import com.alibaba.fastjson.JSON; import io.swagger.annotations.ApiOperation; @RestController -@RequestMapping("/API/WMS/acs") +@RequestMapping("/api/wms/acs") public class AcsController extends HuahengBaseController { @Resource private IAcsService acsService; + @Resource private IAgvTaskService agvTaskService; + + @Resource + private IAddressService addressService; + +// @PassApiAuthentication +// @ApiLogger(apiName = "API接口第三方Token校验测试", from = "TEST") + @ResponseBody + @PostMapping(value = "/testTokenCheck") + public Result<?> testTokenCheck(@RequestBody Map<String, String> paramMap, HttpServletRequest request) { + String url = "http://127.0.0.1:8080/wms/api/wms/acs/testTokenCheck"; + String body = OkHttpUtils.sendPostByJsonStr(url, JSON.toJSONString(paramMap)); +// String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN); + return Result.ok(body); + } + @PostMapping("/notifyAGVTask") @ApiOperation("更新AGV状态") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java index c4f5ab7..30ea8f9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/acs/service/impl/AcsServiceImpl.java @@ -10,9 +10,9 @@ import org.jeecg.modules.wms.config.location.entity.Location; import org.jeecg.modules.wms.config.location.service.ILocationService; import org.jeecg.modules.wms.task.agvTask.entity.AgvTask; import org.jeecg.modules.wms.task.agvTask.service.IAgvTaskService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; @@ -57,7 +57,7 @@ public class AcsServiceImpl implements IAcsService { } } } - Location toLocation = locationService.getLocationByCode(toPort, warehouseCode); +// Location toLocation = locationService.getLocationByCode(toPort, warehouseCode); agvTask.setPreTaskNo(preTaskNo); boolean success = agvTaskService.updateById(agvTask); if (!success) { @@ -75,7 +75,7 @@ public class AcsServiceImpl implements IAcsService { String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN); String jsonParam = JSON.toJSONString(agvEntity); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } @@ -92,7 +92,7 @@ public class AcsServiceImpl implements IAcsService { agvEntity.setTaskNo(agvTask.getId()); String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_AGV_TASK_CANCEL); String jsonParam = JSON.toJSONString(agvEntity); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } @@ -110,7 +110,7 @@ public class AcsServiceImpl implements IAcsService { agvEntity.setPriority(agvTask.getPriority()); String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_AGV_TASK_UPDATE); String jsonParam = JSON.toJSONString(agvEntity); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/controller/ErpController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/controller/ErpController.java index 61579b5..7131531 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/controller/ErpController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/controller/ErpController.java @@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.RestController; * @author 游杰 */ @RestController -@RequestMapping("/API/WMS/erp") +@RequestMapping("/api/wms/erp") public class ErpController extends HuahengBaseController { @Resource diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java index 4a3d0f4..bbbe41a 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/erp/service/impl/ErpServiceImpl.java @@ -39,9 +39,9 @@ import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail; import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -430,7 +430,7 @@ public class ErpServiceImpl implements IErpService { erpBackReceipt.setReceiptDetailList(receiptDetailList); String jsonParam = JSON.toJSONString(erpBackReceipt); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } @@ -463,7 +463,7 @@ public class ErpServiceImpl implements IErpService { erpBackShipment.setShipmentDetailList(shipmentDetailList); String jsonParam = JSON.toJSONString(erpBackShipment); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/controller/MesController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/controller/MesController.java index 706df7f..d1f796d 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/controller/MesController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/controller/MesController.java @@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.RestController; * @author 游杰 */ @RestController -@RequestMapping("/API/WMS/mes") +@RequestMapping("/api/wms/mes") public class MesController extends HuahengBaseController { @Resource diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java index f85b42b..909c8c4 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/mes/servuce/impl/MesServiceImpl.java @@ -33,9 +33,9 @@ import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -258,7 +258,7 @@ public class MesServiceImpl implements IMesService { String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_MES_BACK_RECEIPT); String jsonParam = JSON.toJSONString(mesBackReceiptList); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } @@ -327,7 +327,7 @@ public class MesServiceImpl implements IMesService { String url = addressService.getUrlByParam(QuantityConstant.ADDRESS_MES_BACK_SHIPMENT); String jsonParam = JSON.toJSONString(mesBackShipmentList); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/controller/WcsController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/controller/WcsController.java index f6533af..426c6aa 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/controller/WcsController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/controller/WcsController.java @@ -24,7 +24,7 @@ import org.springframework.web.bind.annotation.*; import io.swagger.annotations.ApiOperation; @RestController -@RequestMapping("/API/WMS/v2") +@RequestMapping("/api/wms/v2") public class WcsController extends HuahengBaseController { @Resource diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java index 1ece0dc..28440d9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java @@ -35,9 +35,9 @@ import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; +import org.jeecg.utils.OkHttpUtils; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; -import org.jeecg.utils.http.OkHttpUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -256,7 +256,7 @@ public class WcsServiceImpl implements WcsService { String fromLocationCode = taskHeader.getFromLocationCode(); String toLocationCode = taskHeader.getToLocationCode(); Location fromLocation = locationService.getLocationByCode(fromLocationCode, warehouseCode); - Location toLocation = locationService.getLocationByCode(toLocationCode, warehouseCode); +// Location toLocation = locationService.getLocationByCode(toLocationCode, warehouseCode); boolean direction = true; // true 执行时是入库动作, false 执行时是出库动作 switch (taskType) { case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT: @@ -378,7 +378,7 @@ public class WcsServiceImpl implements WcsService { wcsTask = switchTaskTypeToWcs(wcsTask); String jsonParam = JSON.toJSONString(wcsTask); System.out.println(jsonParam); - String body = OkHttpUtils.bodypost(url, jsonParam); + String body = OkHttpUtils.sendPostByJsonStr(url, jsonParam); if (StringUtils.isEmpty(body)) { throw new ServiceException("接口地址错误或返回为空"); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java index 24817b6..f4689a7 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/address/service/impl/AddressServiceImpl.java @@ -6,6 +6,7 @@ import org.apache.commons.math3.analysis.function.Add; import org.jeecg.modules.wms.config.address.entity.Address; import org.jeecg.modules.wms.config.address.mapper.AddressMapper; import org.jeecg.modules.wms.config.address.service.IAddressService; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -20,6 +21,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> implements IAddressService { @Override + @Cacheable(cacheNames = "getAddressByUrl#300", key = "#root.methodName + '_' + #url + '_' + #warehouseCode") public Address getAddressByUrl(String url, String warehouseCode) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getUrl, url).eq(Address::getWarehouseCode, warehouseCode).last(" limit 1"); @@ -28,6 +30,7 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl } @Override + @Cacheable(cacheNames = "getUrlByParam#300", key = "#root.methodName + '_' + #param + '_' + #warehouseCode + '_' + #zoneCode") public String getUrlByParam(String param, String warehouseCode, String zoneCode) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getParam, param).eq(Address::getWarehouseCode, warehouseCode).eq(Address::getZoneCode, zoneCode); @@ -39,7 +42,9 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl return url; } + /** #300 缓存300秒 */ @Override + @Cacheable(cacheNames = "getUrlByParam#300", key = "#root.methodName + '_' + #param") public String getUrlByParam(String param) { LambdaQueryWrapper<Address> addressLambdaQueryWrapper = Wrappers.lambdaQuery(); addressLambdaQueryWrapper.eq(Address::getParam, param); @@ -47,8 +52,6 @@ public class AddressServiceImpl extends ServiceImpl<AddressMapper, Address> impl if (address == null) { return null; } - String url = address.getUrl(); - return url; + return address.getUrl(); } - } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java index 418ea67..957f0ac 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java @@ -93,10 +93,13 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i if (location == null) { return false; } + boolean success = false; // 如果这个托盘号已经在库位表里,那么不能再写入 - boolean success = havaContainerCodeInLocation(containerCode, warehouseCode); - if (success) { - throw new ServiceException("库位表已经存在这个容器号,不能再写入"); + if (StringUtils.isNotEmpty(containerCode)) { + success = havaContainerCodeInLocation(containerCode, warehouseCode); + if (success) { + throw new ServiceException("库位表已经存在这个容器号,不能再写入"); + } } location.setContainerCode(containerCode); location.setStatus(status); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java new file mode 100644 index 0000000..3086f1e --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiAuthenticationAspect.java @@ -0,0 +1,119 @@ +package org.jeecg.modules.wms.framework.aspectj; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import javax.servlet.http.HttpServletRequest; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.bouncycastle.crypto.RuntimeCryptoException; +import org.jeecg.modules.wms.framework.aspectj.dto.RSA256Key; +import org.jeecg.utils.HuahengJwtUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTVerificationException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.baomidou.mybatisplus.extension.service.IService; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; + +/** + * 第三方系统调用接口身份认证Aspect + * @author TanYibin + * @createDate 2023年2月14日 + */ +@Slf4j +@Aspect +@Component +@EnableAsync +public class ApiAuthenticationAspect { + + @Autowired + private RSA256Key rsa256Key; + + @Pointcut("execution(* org.jeecg.modules.wms.api..*.*(..)) " + "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping) " + + "|| @annotation(org.springframework.web.bind.annotation.GetMapping) " + "|| @annotation(org.springframework.web.bind.annotation.PostMapping))") + public void executeController() {} + + /** + * API Token 验证 + * @author TanYibin + * @createDate 2023年2月14日 + * @param joinPoint + * @throws NoSuchMethodException + * @throws Throwable + */ + @Before("executeController()") + public void doBefore(JoinPoint joinPoint) throws NoSuchMethodException, Throwable { + Method method = this.getTargetMethod(joinPoint); + // 检查是否有passtoken注释,有则跳过认证 + if (method.isAnnotationPresent(PassApiAuthentication.class)) { + PassApiAuthentication passApiAuthentication = method.getAnnotation(PassApiAuthentication.class); + if (passApiAuthentication.required()) { + return; + } + } + // 获取request对象 + ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = attributes.getRequest(); + String token = request.getHeader("token"); + if (token == null) { + log.error("Authentication token is null"); + throw new RuntimeException("Authentication token is null"); + } + try { + Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); + JWTVerifier verifier = JWT.require(algorithm).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); + verifier.verify(token); + } catch (JWTVerificationException e) { + log.error(e.getMessage()); + throw e; + } + } + + /** + * 基于连接点信息获取目标方法对象 + * @author TanYibin + * @createDate 2023年2月14日 + * @param joinPoint + * @return + * @throws NoSuchMethodException + */ + private Method getTargetMethod(JoinPoint joinPoint) throws NoSuchMethodException { + // 获取目标类对象 + Class<?> clazz = joinPoint.getTarget().getClass(); + // 获取方法签名信息,方法名和参数列表 + MethodSignature signature = (MethodSignature)joinPoint.getSignature(); + // 获取目标方法对象 + return clazz.getDeclaredMethod(signature.getName(), signature.getParameterTypes()); + } + + /** + * 获取方法类全名+方法名 + * @author TanYibin + * @createDate 2023年2月14日 + * @param method + * @return + */ + private String getClassAndMethodName(Method method) { + // 获取类全名 + String className = method.getDeclaringClass().getName(); + // 获取方法名 + String methodName = method.getName(); + return new StringBuffer(className).append(".").append(methodName).toString(); + } +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java index b60e935..c00ac66 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/ApiLogAspect.java @@ -1,21 +1,33 @@ package org.jeecg.modules.wms.framework.aspectj; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import okhttp3.Request; -import okhttp3.Response; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import org.apache.commons.lang.exception.ExceptionUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; +import org.jeecg.JeecgSystemApplication; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.wms.config.address.entity.Address; import org.jeecg.modules.wms.config.address.service.IAddressService; import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; import org.jeecg.modules.wms.monitor.apiLog.service.IApiLogService; +import org.jeecg.utils.HuahengJwtUtil; import org.jeecg.utils.ServletUtils; import org.jeecg.utils.SpringUtils; import org.jeecg.utils.StringUtils; @@ -23,21 +35,18 @@ import org.jeecg.utils.constant.QuantityConstant; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.*; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import okhttp3.Request; +import okhttp3.Response; /** - * Api调用日志记录处理 + * API调用日志记录处理 * @author huaheng */ @Aspect @@ -64,280 +73,272 @@ public class ApiLogAspect { @Pointcut("@annotation(org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger)") public void logPointCut() {} - @Around("logPointCut() && @annotation(apiLogger)") + @Around("logPointCut() && @annotation(apiLogger)") public Object around(ProceedingJoinPoint point, ApiLogger apiLogger) throws Throwable { - // 实际上静态方法上的Aop注解无法拦截到 - if ("WMS".equalsIgnoreCase(apiLogger.from())) { - return aroundWms2XXX(point, apiLogger); - } else { - return aroundXXX2Wms(point, apiLogger); - } + return aroundXXX2Wms(point, apiLogger); } - /** 处理xxx调用wms接口的日志 **/ + /** 记录第三方系统调用WMS接口的日志 **/ private Object aroundXXX2Wms(ProceedingJoinPoint point, ApiLogger apiLogger) { Object ret = null; - ApiLog log = initApiLog(apiLogger, point); + ApiLog apiLog = initApiLog(apiLogger, point); try { ret = point.proceed(); } catch (Throwable e) { - setApiLogThrowable(log, e); + setApiLogThrowable(apiLog, e); ret = Result.error(e.getMessage()); return ret; } finally { if (ret != null) { - finishApiLog(log, ret); + finishApiLog(apiLog, ret); } } return ret; } - /** 处理WMS调用xxx接口的日志 **/ - private Object aroundWms2XXX(ProceedingJoinPoint point, ApiLogger apiLogger) { - Object ret = null; - ApiLog log = new ApiLog(); - - HttpURLConnection connection = null; - String body = null; - - try { - HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); - connection = (HttpURLConnection)point.getArgs()[0]; - body = (String)point.getArgs()[1]; - initApiLog(connection, body); - ret = point.proceed(); - } catch (Throwable e) { - setApiLogThrowable(log, e); - ret = Result.error(e.getMessage()); - } finally { - if (ret != null) { - finishApiLog(log, connection, ret.toString()); - } - } - return ret; - } - - /** - * 记录响应头信息 - **/ - public static void finishApiLog(ApiLog log, HttpURLConnection connection, String body) { - try { - log.setResponseBody(body); - log.setResponseTime(new Date()); - Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); - log.setDuration(duration.intValue()); - log.setHttpCode(connection.getResponseCode()); - - // 响应头 - Set<String> keyset = connection.getHeaderFields().keySet(); - ArrayList<String> headerList = new ArrayList<>(); - Iterator<String> it = keyset.iterator(); - while (it.hasNext()) { - String name = it.next(); - String header = connection.getHeaderField(name); - if (name == null || "".equals(name)) { - // 第一行没有name - // HTTP/1.1 200 OK - headerList.add(header); - } else { - headerList.add(name + ": " + header); - } - } - log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); - Result json = JSON.parseObject(body, Result.class); - log.setRetCode(json.getCode()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log); - } - } +// /** 记录WMS调用第三方接口的日志 **/ +// private Object aroundWms2XXX(ProceedingJoinPoint point, ApiLogger apiLogger) { +// Object ret = null; +// ApiLog log = new ApiLog(); +// +// HttpURLConnection connection = null; +// String body = null; +// +// try { +// connection = (HttpURLConnection)point.getArgs()[0]; +// body = (String)point.getArgs()[1]; +// initApiLog(connection, body); +// ret = point.proceed(); +// } catch (Throwable e) { +// setApiLogThrowable(log, e); +// ret = Result.error(e.getMessage()); +// } finally { +// if (ret != null) { +// finishApiLog(log, connection, ret.toString()); +// } +// } +// return ret; +// } + +// /** +// * 记录响应头信息,保存日志到数据库 +// */ +// public static void finishApiLog(ApiLog log, HttpURLConnection connection, String body) { +// try { +// log.setResponseBody(body); +// log.setResponseTime(new Date()); +// Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); +// log.setDuration(duration.intValue()); +// log.setHttpCode(connection.getResponseCode()); +// +// // 响应头 +// Set<String> keyset = connection.getHeaderFields().keySet(); +// ArrayList<String> headerList = new ArrayList<>(); +// Iterator<String> it = keyset.iterator(); +// while (it.hasNext()) { +// String name = it.next(); +// String header = connection.getHeaderField(name); +// if (name == null || "".equals(name)) { +// // 第一行没有name +// // HTTP/1.1 200 OK +// headerList.add(header); +// } else { +// headerList.add(name + ": " + header); +// } +// } +// log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); +// Result json = JSON.parseObject(body, Result.class); +// log.setRetCode(json.getCode()); +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log); +// } +// } + +// /** +// * 根据url,从address表中判断调用的去向 +// */ +// public static void parseUrl(ApiLog log, URL url, String warehouseCode) { +// try { +// String[] spList = url.toString().split("/"); +// String apiName = spList[spList.length - 1]; +// String ip = JeecgSystemApplication.getLocalHostExactAddress().getHostAddress(); +// Address address = addressService.getAddressByUrl(url.toString(), warehouseCode); +// log.setApiName(apiName); +// log.setRequestFrom("WMS"); +// log.setIp(ip); +// log.setResponseBy(address.getParam().toUpperCase()); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + +// /** +// * 记录WMS调用第三方系统接口的请求信息 +// * 在HttpUtils.body POST方法中直接调用本类static方法 +// **/ +// public static ApiLog initApiLog(String Method, String urlStr, String body, HttpHeaders headers, String warehouseCode) { +// ApiLog log = new ApiLog(); +// try { +// URL url = new URL(urlStr); +// log.setApiMethod(Method); +// log.setUrl(urlStr); +// log.setRequestTime(new Date()); +// parseUrl(log, url, warehouseCode); +// +// // 请求头 +// Set<String> keySet = headers.keySet(); +// ArrayList<String> headerList = new ArrayList<>(); +// Iterator<String> it = keySet.iterator(); +// while (it.hasNext()) { +// String name = it.next(); +// String header = String.valueOf(headers.getContentType()); +// headerList.add(name + ": " + header); +// } +// +// log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); +// log.setRequestBody(body); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// return log; +// } + +// /** +// * 记录WMS调用第三方系统接口的请求信息 +// * 在HttpUtils.body POST方法中直接调用本类static方法 +// **/ +// public static ApiLog initApiLog(HttpURLConnection connection, String body) { +// ApiLog log = new ApiLog(); +// try { +// log.setApiMethod(connection.getRequestMethod()); +// log.setUrl(connection.getURL().toString()); +// log.setRequestTime(new Date()); +// parseUrl(log, connection.getURL()); +// +// // 请求头 +// Set<String> keySet = connection.getRequestProperties().keySet(); +// ArrayList<String> headerList = new ArrayList<>(); +// Iterator<String> it = keySet.iterator(); +// while (it.hasNext()) { +// String name = it.next(); +// String header = connection.getRequestProperty(name); +// headerList.add(name + ":" + header); +// } +// +// log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); +// log.setRequestBody(body); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// return log; +// } /** - * 根据url,从address表中判断调用的去向 + * 记录WMS调用第三方系统接口的请求信息 + * 在OKHttpUtils.bodypost方法中直接调用本类static方法 + * @param apiLog **/ - public static void parseUrl(ApiLog log, URL url, String warehouseCode) { + public static void initApiLog(ApiLog apiLog, Request request, String body) { try { - String[] spList = url.toString().split("/"); - String apiName = spList[spList.length - 1]; - int index = url.toString().lastIndexOf(apiName); - String addUrl = url.toString().substring(0, index); - - Address address = addressService.getAddressByUrl(url.toString(), warehouseCode); - log.setApiName(apiName); - log.setRequestFrom("WMS"); - log.setResponseBy(address.getParam().toUpperCase()); + apiLog.setApiMethod(request.method()); + apiLog.setUrl(request.url().toString()); + apiLog.setRequestTime(new Date()); + parseUrl(apiLog, request.url().url()); + apiLog.setRequestHeader(request.headers().toString()); + apiLog.setRequestBody(body); } catch (Exception e) { e.printStackTrace(); } } - /** - * 记录WMS调用外接口的请求信息 - * 在HttpUtils.bodypost方法中直接调用本类static方法 - **/ - public static ApiLog initApiLog(String Method, String url, String body, HttpHeaders headers, String warehouseCode) { - ApiLog log = new ApiLog(); - try { - URL url1 = new URL(url); - log.setApiMethod(Method); - log.setUrl(url); - log.setRequestTime(new Date()); - parseUrl(log, url1, warehouseCode); - - // 请求头 - Set<String> keySet = headers.keySet(); - ArrayList<String> headerList = new ArrayList<>(); - Iterator<String> it = keySet.iterator(); - while (it.hasNext()) { - String name = it.next(); - String header = String.valueOf(headers.getContentType()); - headerList.add(name + ": " + header); - } - - log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); - log.setRequestBody(body); - } catch (Exception e) { - e.printStackTrace(); - } - - return log; - } - - /** - * 记录WMS调用外接口的请求信息 - * 在HttpUtils.bodypost方法中直接调用本类static方法 - **/ - public static ApiLog initApiLog(HttpURLConnection connection, String body) { - ApiLog log = new ApiLog(); - try { - log.setApiMethod(connection.getRequestMethod()); - log.setUrl(connection.getURL().toString()); - log.setRequestTime(new Date()); - parseUrl(log, connection.getURL()); - - // 请求头 - Set<String> keySet = connection.getRequestProperties().keySet(); - ArrayList<String> headerList = new ArrayList<>(); - Iterator<String> it = keySet.iterator(); - while (it.hasNext()) { - String name = it.next(); - String header = connection.getRequestProperty(name); - headerList.add(name + ": " + header); - } - - log.setRequestHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); - log.setRequestBody(body); - } catch (Exception e) { - e.printStackTrace(); - } - - return log; - } - - /** - * 记录WMS调用外接口的请求信息 - * 在HttpUtils.bodypost方法中直接调用本类static方法 - **/ - public static ApiLog initApiLog(Request request, String body) { - ApiLog log = new ApiLog(); - try { - log.setApiMethod(request.method()); - log.setUrl(request.url().toString()); - log.setRequestTime(new Date()); - parseUrl(log, request.url().url()); - log.setRequestHeader(request.headers().toString()); - log.setRequestBody(body); - } catch (Exception e) { - e.printStackTrace(); - } - return log; - } - /** 记录响应头信息 **/ - public static void finishApiLog(ApiLog log, Response response, String body) { + public static void finishApiLog(ApiLog log, Response response, String responseBody) { try { - log.setResponseBody(body); log.setResponseTime(new Date()); Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); log.setDuration(duration.intValue()); + if (response == null) { + return; + } log.setHttpCode(response.code()); - - // 响应头 log.setResponseHeader(response.headers().toString()); - Result ajaxResult = null; + log.setResponseBody(responseBody); + Result result = null; try { - ajaxResult = JSON.parseObject(body, Result.class); + result = JSON.parseObject(responseBody, Result.class); } catch (Exception ex) { - body = JSON.parse(body).toString(); - ajaxResult = JSON.parseObject(body, Result.class); + responseBody = JSON.parse(responseBody).toString(); + result = JSON.parseObject(responseBody, Result.class); } - log.setRetCode(ajaxResult.getCode()); + log.setRetCode(result.getCode()); } catch (Exception e) { e.printStackTrace(); } finally { try { if (StringUtils.isNotEmpty(log.getResponseBody()) && log.getResponseBody().length() > 2001) { - log.setResponseBody(log.getResponseBody().substring(0, 2000) + "\n太长了...后面省略。\n" + log.getResponseBody().length()); + log.setResponseBody(log.getResponseBody().substring(0, 2000) + "...\n"); } } catch (Exception e) { - + e.printStackTrace(); } SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log); } } /** 根据url,从address表中判断调用的去向 **/ - public static void parseUrl(ApiLog log, URL url) { + public static void parseUrl(ApiLog apiLog, URL url) { try { String[] spList = url.toString().split("/"); String apiName = spList[spList.length - 1]; - int index = url.toString().lastIndexOf(apiName); - String addUrl = url.toString().substring(0, index); - - Address address = addressService.getAddressByUrl(url.toString(), QuantityConstant.DEFAULT_WAREHOUSE); - log.setApiName(apiName); - log.setRequestFrom("WMS"); - log.setResponseBy(address.getParam().toUpperCase()); + String ip = JeecgSystemApplication.getLocalHostExactAddress().getHostAddress(); + apiLog.setApiName(apiName); + apiLog.setRequestFrom(HuahengJwtUtil.HUAHENG_SYSTEM_ID); + apiLog.setIp(ip); +// Address address = addressService.getAddressByUrl(url.toString(), QuantityConstant.DEFAULT_WAREHOUSE); +// apiLog.setResponseBy(address.getParam().toUpperCase()); } catch (Exception e) { e.printStackTrace(); } } - /** - * 记录响应头信息 - **/ - public static void finishApiLog(ApiLog log, HttpHeaders headers, String body) { - try { - log.setResponseBody(body); - log.setResponseTime(new Date()); - Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); - log.setDuration(duration.intValue()); - log.setHttpCode(200); - - // 响应头 - Set<String> keyset = headers.keySet(); - ArrayList<String> headerList = new ArrayList<>(); - Iterator<String> it = keyset.iterator(); - while (it.hasNext()) { - String name = it.next(); - String header = String.valueOf(headers.getContentType()); - if (name == null || "".equals(name)) - // 第一行没有name - // HTTP/1.1 200 OK - headerList.add(header); - else - headerList.add(name + ": " + header); - } - log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); - Result json = JSON.parseObject(body, Result.class); - log.setRetCode(json.getCode()); - } catch (Exception e) { - e.printStackTrace(); - } finally { - SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log); - } - } +// /** +// * 记录响应头信息 +// **/ +// public static void finishApiLog(ApiLog log, HttpHeaders headers, String body) { +// try { +// log.setResponseBody(body); +// log.setResponseTime(new Date()); +// Long duration = log.getResponseTime().getTime() - log.getRequestTime().getTime(); +// log.setDuration(duration.intValue()); +// log.setHttpCode(200); +// +// // 响应头 +// Set<String> keyset = headers.keySet(); +// ArrayList<String> headerList = new ArrayList<>(); +// Iterator<String> it = keyset.iterator(); +// while (it.hasNext()) { +// String name = it.next(); +// String header = String.valueOf(headers.getContentType()); +// if (name == null || "".equals(name)) +// // 第一行没有name +// // HTTP/1.1 200 OK +// headerList.add(header); +// else +// headerList.add(name + ": " + header); +// } +// log.setResponseHeader(org.apache.commons.lang3.StringUtils.join(headerList, "\n")); +// Result json = JSON.parseObject(body, Result.class); +// log.setRetCode(json.getCode()); +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// SpringUtils.getBean(ApiLogAspect.class).saveApiLog(log); +// } +// } private ApiLog initApiLog(ApiLogger apiLogger, ProceedingJoinPoint point) { ApiLog log = new ApiLog(); @@ -348,19 +349,16 @@ public class ApiLogAspect { log.setApiName(apiLogger.apiName()); HttpServletRequest request = ServletUtils.getRequest(); - String qryStr = request.getQueryString(); String url = request.getRequestURL().toString(); if (StringUtils.isNotEmpty(qryStr)) { url = url + "?" + qryStr; } log.setUrl(url); - log.setApiMethod(request.getMethod()); - log.setIp(request.getRemoteAddr()); + log.setIp(this.getIpAddr(request)); rebuildRequestHeader(log); - rebuildRequestBody(log, request); // 如果reqeust中取不到post参数,就从接口方法参数中取json对象 @@ -401,17 +399,17 @@ public class ApiLogAspect { public static void setApiLogException(ApiLog log, Exception e) { try { String exception = ExceptionUtils.getFullStackTrace(e); - String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000); + String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000) + "..."; log.setException(shortExpInfo); } catch (Exception ex) { ex.printStackTrace(); } } - + public static void setApiLogThrowable(ApiLog log, Throwable e) { try { String exception = ExceptionUtils.getFullStackTrace(e); - String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000); + String shortExpInfo = e.getMessage() + "\n" + org.apache.commons.lang3.StringUtils.left(exception, 1000) + "..."; log.setException(shortExpInfo); } catch (Exception ex) { ex.printStackTrace(); @@ -426,7 +424,7 @@ public class ApiLogAspect { while (names.hasMoreElements()) { String name = (String)names.nextElement(); String header = req.getHeader(name); - headerList.add(name + ": " + header); + headerList.add(name + ":" + header); } String headers = org.apache.commons.lang3.StringUtils.join(headerList, "\n"); log.setRequestHeader(headers); @@ -524,4 +522,35 @@ public class ApiLogAspect { e.printStackTrace(); } } + + public String getIpAddr(HttpServletRequest request) { + String ipAddress = request.getHeader("x-forwarded-for"); + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("WL-Proxy-Client-IP"); + } + if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) { + // 根据网卡取本机配置的IP + InetAddress inet = null; + try { + inet = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + ipAddress = inet.getHostAddress(); + } + } + // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割 + // "***.***.***.***".length() = 15 + if (ipAddress != null && ipAddress.length() > 15) { + if (ipAddress.indexOf(",") > 0) { + ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); + } + } + return ipAddress; + } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/PassApiAuthentication.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/PassApiAuthentication.java new file mode 100644 index 0000000..604da8a --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/PassApiAuthentication.java @@ -0,0 +1,17 @@ +package org.jeecg.modules.wms.framework.aspectj; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 跳过API身份验证注解 + * @author TanYibin + * @createDate 2023年2月13日 + */ +@Target({ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface PassApiAuthentication { + boolean required() default true; +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/ApiAuthentication.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/ApiAuthentication.java new file mode 100644 index 0000000..f97c017 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/ApiAuthentication.java @@ -0,0 +1,31 @@ +package org.jeecg.modules.wms.framework.aspectj.dto; + +import java.util.Date; + +import org.jeecg.utils.HuahengJwtUtil; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import lombok.Data; + +/** + * 接口认证Token生成对象 + * @author TanYibin + * @createDate 2023年2月14日 + */ +@Data +public class ApiAuthentication { + + /** Token提供方 */ + private String operator; + + /** Token使用方 */ + private String audience; // 观众,相当于接受者 + + /** Token签发方(WMS) */ + private String issuer = HuahengJwtUtil.HUAHENG_SYSTEM_ID; + + /** 失效时间 */ + private Date expireDateTime; + +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/RSA256Key.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/RSA256Key.java new file mode 100644 index 0000000..943a5e2 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/aspectj/dto/RSA256Key.java @@ -0,0 +1,29 @@ +package org.jeecg.modules.wms.framework.aspectj.dto; + +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +import org.jeecg.utils.SecretKeyUtils; +import org.springframework.stereotype.Component; + +import lombok.Data; + +@Data +@Component +public class RSA256Key { + + /** 第三方HTTP访问 公钥 */ + private RSAPublicKey publicKey = + (RSAPublicKey)SecretKeyUtils.getPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmYcmhWzpgLgWVD0j+uTyFvQW0BBktYVJmTRQvLlrKt4CHnkfQ4Dn" + + "SLaRXCcJK/TGgAY0BtnaKUgFBqqmTI9l82tpxEWqYRzp4KGRLnVA6/igidYib0JeBWroI6Bs0wR43fkSXA8XG+n32bVbmMTKNa9IFUJCzICVTEjQzMQrSAwIDAQAB"); + + /** 第三方HTTP访问 私钥 */ + private RSAPrivateKey privateKey = + (RSAPrivateKey)SecretKeyUtils.getPrivateKey("MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKZhyaFbOmAuBZUPSP65PIW9BbQEGS1hUmZNFC8uWsq" + + "3gIeeR9DgOdItpFcJwkr9MaABjQG2dopSAUGqqZMj2Xza2nERaphHOngoZEudUDr+KCJ1iJvQl4FaugjoGzTBHjd+RJcDxcb6ffZtVuYxMo1r0gVQkLMgJVMSNDMxCtID" + + "AgMBAAECgYBhxluIMCVI+iKbqyTZVB/l8+PTGwl0qpmStr8iztnaASZODEzlya8Q/XNzFrAQA2TTQ7YKiKB2vqQwY8tNRab7jpR4t5WPApDVrMvjPfvqVvBsPzTYr2c08" + + "xMfqcj5HNzPLisb7Wvi7URSL4jIY/106lXN+9cJuMV0oDZzcAhaYQJBANdNMlSnzTDF8VQ7ETpzZQrF0UzlqKeKG0Pz/YeTXT4IjyBhzvaSOF3+hi1cWucrSU0xMUAR9F" + + "av+K1BlPTYW/MCQQDF1UqEAY7YGzpUZK311ECO12ysb0oMt2jTYMwmgPnfPZfctD6SlV3u/JtsgE+bN5dXwV0ktyfP/3vl395zGoWxAkEAt/bQMKGIpEoeILivyd/b0E6" + + "ivi/l4fIRxghu8y8plt29Xg/0xZ6+5yGaCJxHWAsWgQytZm9w9bk6pN/KpUNRnQJAbQS72oDNSdO/UhBlOOntZYnbTi7J3LYZoxpdhf5fNCFKFYqSTM7ZA8DamXEf7UY2" + + "NVrOTFROMTX1/dhfSojcEQJBALNxIrEP97uszxIc8oH2r7DfXzmhRMKuIvnBfmNe1TR" + "VLvh1G1SKIyCYUTStaQCFN0FcH//Fab+zPiAgDmXApWs="); +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java index d313b3b..83da530 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/HuahengBaseController.java @@ -5,7 +5,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import org.jeecg.common.api.vo.Result; -import org.jeecg.utils.RedissonDistributedLocker; +import org.jeecg.utils.support.RedissonDistributedLocker; import org.springframework.beans.factory.annotation.Autowired; import cn.hutool.core.date.SystemClock; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java index b9508c7..945c84e 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java @@ -11,6 +11,7 @@ import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.modules.system.entity.SysDataLog; import org.jeecg.modules.system.service.ISysDataLogService; +import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.utils.HuahengRedisUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -33,7 +34,6 @@ import lombok.extern.slf4j.Slf4j; */ @Slf4j @RestController -@RequestMapping("/test") public class TestController extends HuahengBaseController { @Autowired @@ -41,10 +41,21 @@ public class TestController extends HuahengBaseController { @Autowired private ISysDataLogService sysDataLogService; + + +// @ApiLogger(apiName = "API接口第三方Token校验测试", from = "TEST") +// @ResponseBody +// @PostMapping(value = "/api/wms/testTokenCheck") +// public Result<?> testTokenCheck(@RequestBody Map<String, String> paramMap, HttpServletRequest request) { +// +// +// return new Result<>(); +// } + @AutoLog(value = "TestController-testRedis") @ResponseBody - @PostMapping(value = "/testRedis") + @PostMapping(value = "/test/testRedis") public Result<?> testRedis(@RequestBody Map<String, String> paramMap, HttpServletRequest request) { // log.info("testRedis in paramMap:{}", JSON.toJSONString(paramMap)); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/home/service/impl/HomePageViewServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/home/service/impl/HomePageViewServiceImpl.java index dcdf2ee..9e48fd9 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/home/service/impl/HomePageViewServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/home/service/impl/HomePageViewServiceImpl.java @@ -26,6 +26,8 @@ import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryDetail; import org.jeecg.modules.wms.inventory.inventoryHeader.entity.InventoryHeader; import org.jeecg.modules.wms.inventory.inventoryHeader.service.impl.InventoryDetailServiceImpl; import org.jeecg.modules.wms.inventory.inventoryHeader.service.impl.InventoryHeaderServiceImpl; +import org.jeecg.modules.wms.inventory.inventoryTransaction.entity.InventoryTransaction; +import org.jeecg.modules.wms.inventory.inventoryTransaction.service.impl.InventoryTransactionServiceImpl; import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader; import org.jeecg.modules.wms.receipt.receiptHeader.service.impl.ReceiptHeaderServiceImpl; import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader; @@ -72,38 +74,71 @@ public class HomePageViewServiceImpl implements HomePageViewService { TaskHeaderServiceImpl taskHeaderService; @Resource HomePageViewService homePageViewService; + @Resource + InventoryTransactionServiceImpl inventoryTransactionServiceImpl; @Override public Result<String> deliveringAmount() { + //通过库存交易记录来查询 + LambdaQueryWrapper<InventoryTransaction> inventoryTransactionLambdaQueryWrapper = Wrappers.lambdaQuery(); + inventoryTransactionLambdaQueryWrapper.select(InventoryTransaction::getCreateTime, InventoryTransaction::getQty,InventoryTransaction::getType); + List<InventoryTransaction> inventoryTransactions = inventoryTransactionServiceImpl.list(inventoryTransactionLambdaQueryWrapper); + + // 查询出库单的7天出库量 - LambdaQueryWrapper<ShipmentHeader> shipmentHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); - shipmentHeaderLambdaQueryWrapper.select(ShipmentHeader::getCreateTime, ShipmentHeader::getTotalQty); - List<ShipmentHeader> shipmentHeaders = shipmentHeaderServiceImpl.list(shipmentHeaderLambdaQueryWrapper); + List<InventoryTransaction> shipmentHeaders=new ArrayList<>(); + shipmentHeaders.addAll(inventoryTransactions); + shipmentHeaders.removeIf(Inventory->Inventory.getType()!=20); LinkedHashMap<String, String> list = new LinkedHashMap<>(); for (int i = 6; i >= 0; i--) { - List<ShipmentHeader> shipmentHeadersCop = shipmentHeaders; String today = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis() - (1000 * 60 * 60 * 24) * i).toString(); - List<ShipmentHeader> collect = shipmentHeadersCop.stream() + List<InventoryTransaction> collect = shipmentHeaders.stream() .filter(shipmentHeader -> new SimpleDateFormat("yyyy-MM-dd").format(shipmentHeader.getCreateTime()).toString().contains(today)) .collect(Collectors.toList()); - list.put(today, String.valueOf(collect.size())); + if (collect.size()!=0) + { + BigDecimal sum=new BigDecimal(0); + for (InventoryTransaction item : collect) + { + sum=sum.add(item.getQty()); + } + list.put(today,String.valueOf(sum)); + }else + { + list.put(today,"0"); + } + } // 查询入库单的7天入库量 - LambdaQueryWrapper<ReceiptHeader> receiptHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); - receiptHeaderLambdaQueryWrapper.select(ReceiptHeader::getCreateTime, ReceiptHeader::getTotalqty); - List<ReceiptHeader> receiptHeaders = receiptHeaderServiceImpl.list(receiptHeaderLambdaQueryWrapper); + + List<InventoryTransaction> receiptHeaders = new ArrayList<>(); + receiptHeaders.addAll(inventoryTransactions); + receiptHeaders.removeIf(Inventory->Inventory.getType()!=10); LinkedHashMap<String, String> list2 = new LinkedHashMap<>(); for (int i = 6; i >= 0; i--) { - List<ReceiptHeader> receiptHeadersCop = receiptHeaders; + List<InventoryTransaction> receiptHeadersCop = receiptHeaders; String today = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis() - (1000 * 60 * 60 * 24) * i).toString(); - List<ReceiptHeader> collect = receiptHeadersCop.stream() + List<InventoryTransaction> collect = receiptHeadersCop.stream() .filter(ReceiptHeader -> new SimpleDateFormat("yyyy-MM-dd").format(ReceiptHeader.getCreateTime()).toString().contains(today)) .collect(Collectors.toList()); - list2.put(today, String.valueOf(collect.size())); + if (collect.size()!=0) + { + BigDecimal sum=new BigDecimal(0); + for (InventoryTransaction item : collect) + { + sum=sum.add(item.getQty()); + } + list2.put(today,String.valueOf(sum)); + }else + { + list2.put(today,"0"); + } } + + Option option = new Option(); option.tooltip().trigger(Trigger.axis).axisPointer().type(PointerType.cross); option.grid().setLeft("3%"); @@ -148,12 +183,12 @@ public class HomePageViewServiceImpl implements HomePageViewService { public Result<String> inventoryUtilization() { // 先存储总数 Integer allStock = locationServiceImpl.count(); - + // 有货数量 = 总库位删除为空的数量长度 LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); locationLambdaQueryWrapper.isNotNull(Location::getContainerCode).ne(Location::getContainerCode, ""); int locationStock = locationServiceImpl.count(locationLambdaQueryWrapper); - + // 无货数量 = 总数 - 有货数量 Integer inStock = allStock - locationStock; Option option = new Option(); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java index 03596a2..334c2be 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/shipment/shipmentCombination/service/impl/ShipmentCombinationServiceImpl.java @@ -135,9 +135,9 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi } } if (over) { - return Result.OK("出库单已经配盘"); + return Result.OK("出库单已经配盘", null); } - return Result.OK("自动组盘成功"); + return Result.OK("自动组盘成功", null); } @Override @@ -210,7 +210,7 @@ public class ShipmentCombinationServiceImpl implements IShipmentCombinationServi throw new ServiceException(result.getMessage()); } } - return Result.OK("自动组盘成功"); + return Result.OK("自动组盘成功", null); } @Override diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/controller/CycleCountDetailController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/controller/CycleCountDetailController.java index 5843f72..e374266 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/controller/CycleCountDetailController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/controller/CycleCountDetailController.java @@ -14,6 +14,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.jeecg.modules.system.entity.SysAnnouncementSend; import org.jeecg.modules.wms.framework.controller.HuahengBaseController; import javax.servlet.http.HttpServletResponse; @@ -89,7 +90,10 @@ public class CycleCountDetailController extends HuahengBaseController { @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) { - QueryWrapper<CycleCountDetail> queryWrapper = QueryGenerator.initQueryWrapper(cycleCountDetail, req.getParameterMap()); + + + LambdaQueryWrapper<CycleCountDetail> queryWrapper = new LambdaQueryWrapper<CycleCountDetail>(); + queryWrapper.eq(CycleCountDetail::getCycleCountHeadId,cycleCountDetail.getCycleCountHeadId()); Page<CycleCountDetail> page = new Page<CycleCountDetail>(pageNo, pageSize); IPage<CycleCountDetail> pageList = cycleCountDetailService.page(page, queryWrapper); return Result.OK(pageList); @@ -216,6 +220,7 @@ public class CycleCountDetailController extends HuahengBaseController { } }); } + result.setResult(headerId); return result; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetail.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetail.java index 82c113e..41dce0c 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetail.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetail.java @@ -94,7 +94,7 @@ public class CycleCountDetail implements Serializable { /**完成时间*/ @Excel(name = "完成时间", width = 15) @ApiModelProperty(value = "完成时间") - private String completedAt; + private Date completedAt; /**盘点明细状态*/ @Excel(name = "盘点明细状态", width = 15) @ApiModelProperty(value = "盘点明细状态") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetailChild.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetailChild.java index 9c1f649..4f86522 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetailChild.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/entity/CycleCountDetailChild.java @@ -8,6 +8,8 @@ import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; + +import java.math.BigDecimal; import java.util.Date; import org.jeecg.common.aspect.annotation.Dict; import io.swagger.annotations.ApiModel; @@ -69,19 +71,31 @@ public class CycleCountDetailChild implements Serializable { /**系统数量*/ @Excel(name = "系统数量", width = 15) @ApiModelProperty(value = "系统数量") - private Integer systemQty; + private BigDecimal systemQty; /**实盘数量*/ @Excel(name = "实盘数量", width = 15) @ApiModelProperty(value = "实盘数量") - private Integer countedQty; + private BigDecimal countedQty; /**差异数量*/ @Excel(name = "差异数量", width = 15) @ApiModelProperty(value = "差异数量") - private Integer gapQty; + private BigDecimal gapQty; /**库存明细id*/ @Excel(name = "库存明细id", width = 15) @ApiModelProperty(value = "库存明细id") private Integer inventoryDetaiId; + /**批次*/ + @Excel(name = "批次*/", width = 15) + @ApiModelProperty(value = "批次*/") + private String batch; + /**批号*/ + @Excel(name = "批号", width = 15) + @ApiModelProperty(value = "批号") + private String lot; + /**库存状态*/ + @Excel(name = "库存状态", width = 15) + @ApiModelProperty(value = "库存状态") + private String inventoryStatus; /**创建人*/ @ApiModelProperty(value = "创建人") private String createBy; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailChildServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailChildServiceImpl.java index 37871e6..48df846 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailChildServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailChildServiceImpl.java @@ -42,8 +42,8 @@ public class CycleCountDetailChildServiceImpl extends ServiceImpl<CycleCountDeta public Result confirmGapQty(String id, String countedQty) { //接收子单ID和实盘数量 //任务未完成可多次登记。 - int qty=Integer.valueOf(id); - if(qty < 0){ + BigDecimal qty=new BigDecimal(countedQty); + if(qty.compareTo(BigDecimal.ZERO) == -1){ return Result.error("实盘登记数不能小于0"); } //明细子单据 @@ -64,7 +64,7 @@ public class CycleCountDetailChildServiceImpl extends ServiceImpl<CycleCountDeta return Result.error("盘点任务完成后不能再登记数量!"); } //实盘登记后差异数量 - int adjQty = qty-countDetailChild.getSystemQty(); + BigDecimal adjQty = qty.subtract(countDetailChild.getSystemQty()); countDetailChild.setGapQty(adjQty); countDetailChild.setCountedQty(qty); countDetailChild.setChildStatus(QuantityConstant.CYCLECOUNT_STATUS_REGISTERED); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailServiceImpl.java index c55b39f..45aaff3 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountDetail/service/impl/CycleCountDetailServiceImpl.java @@ -119,13 +119,29 @@ public class CycleCountDetailServiceImpl extends ServiceImpl<CycleCountDetailMap inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getInventoryHeaderId,taskId); List<InventoryDetail> inventoryDetails = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper); + LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); + locationLambdaQueryWrapper.eq(Location::getCode, inventoryDetails.get(0).getLocationCode()) + .eq(Location::getWarehouseCode, inventoryDetails.get(0).getWarehouseCode()) + .ne(Location::getStatus, QuantityConstant.STATUS_LOCATION_LOCK); + Location location = locationService.getOne(locationLambdaQueryWrapper); + if (StringUtils.isNull(location)) { + return Result.error("库位已锁定!"); + } + + LambdaQueryWrapper<CycleCountDetail> cycleCountDetailLambdaQueryWrapper = Wrappers.lambdaQuery(); + + CycleCountDetail cycleCountDetail = new CycleCountDetail(); - cycleCountDetail.setInventoryHeaderId(headerId); + cycleCountDetail.setCycleCountHeadId(headerId); + cycleCountDetail.setContainerCode(inventoryDetails.get(0).getContainerCode()); + + + cycleCountDetail.setCycleCountHeadCode(code); cycleCountDetail.setCompanyCode(inventoryDetails.get(0).getCompanyCode()); + cycleCountDetail.setWarehouseCode(inventoryDetails.get(0).getWarehouseCode()); cycleCountDetail.setInventoryHeaderId(inventoryDetails.get(0).getInventoryHeaderId()); cycleCountDetail.setLocationCode(inventoryDetails.get(0).getLocationCode()); - cycleCountDetail.setContainerCode(inventoryDetails.get(0).getContainerCode()); cycleCountDetail.setInventorySts(inventoryDetails.get(0).getInventoryStatus()); cycleCountDetail.setSystemQty(inventoryDetails.size()); cycleCountDetail.setCountedQty(0); @@ -146,9 +162,12 @@ public class CycleCountDetailServiceImpl extends ServiceImpl<CycleCountDetailMap cycleCountDetailChild.setMaterialName(inventoryDetail.getMaterialName()); cycleCountDetailChild.setMaterialSpec(inventoryDetail.getMaterialSpec()); cycleCountDetailChild.setMaterialUnit(inventoryDetail.getMaterialUnit()); - cycleCountDetailChild.setSystemQty(inventoryDetail.getQty().intValue()); - cycleCountDetailChild.setCountedQty(0); - cycleCountDetailChild.setGapQty(0); + cycleCountDetailChild.setInventoryStatus(inventoryDetail.getInventoryStatus()); + cycleCountDetailChild.setBatch(inventoryDetail.getBatch()); + cycleCountDetailChild.setLot(inventoryDetail.getLot()); + cycleCountDetailChild.setSystemQty(inventoryDetail.getQty()); + cycleCountDetailChild.setCountedQty(BigDecimal.ZERO); + cycleCountDetailChild.setGapQty(BigDecimal.ZERO); cycleCountDetailChild.setInventoryDetaiId(inventoryDetail.getId()); cycleCountDetailChildServiceImpl.save(cycleCountDetailChild); } @@ -205,6 +224,7 @@ public class CycleCountDetailServiceImpl extends ServiceImpl<CycleCountDetailMap task.setFromLocationCode(cycleCountDetail.getLocationCode()); task.setToPortCode("P10"); task.setSequenceNumber(1); + task.setShipmentContainerHeaderId(cycleCoutDetailId); task.setSequence(1); task.setShipmentOrder(System.currentTimeMillis()); @@ -231,7 +251,7 @@ public class CycleCountDetailServiceImpl extends ServiceImpl<CycleCountDetailMap taskDetail.setMaterialName(item.getMaterialName()); taskDetail.setMaterialSpec(item.getMaterialSpec()); taskDetail.setMaterialUnit(item.getMaterialUnit()); - taskDetail.setQty(new BigDecimal(item.getSystemQty())); + taskDetail.setQty(item.getSystemQty()); //taskDetail.setBatch(cycleCountDetail.getBatch()); //taskDetail.setFromInventoryId(cycleCountDetail.getInventoryDetailId()); //taskDetail.setLot(cycleCountDetail.getLot()); @@ -263,13 +283,17 @@ public class CycleCountDetailServiceImpl extends ServiceImpl<CycleCountDetailMap - LambdaQueryWrapper<InventoryDetail> lambdaQueryWrapper = Wrappers.lambdaQuery(); - lambdaQueryWrapper.eq(InventoryDetail::getContainerCode,task.getContainerCode()); - List<InventoryDetail> inventoryDetails = inventoryDetailService.list(lambdaQueryWrapper); +// LambdaQueryWrapper<InventoryDetail> lambdaQueryWrapper = Wrappers.lambdaQuery(); +// lambdaQueryWrapper.eq(InventoryDetail::getContainerCode,task.getContainerCode()); +// List<InventoryDetail> inventoryDetails = inventoryDetailService.list(lambdaQueryWrapper); + Result result = new Result(); + result.setResult(cycleCountHeader.getId()); + result.setCode(200); + result.setMessage("盘点任务生成成功"); - return Result.ok("盘点任务生成成功"); + return result; } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/ICycleCountHeaderService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/ICycleCountHeaderService.java index e05e91e..617eccb 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/ICycleCountHeaderService.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/ICycleCountHeaderService.java @@ -13,4 +13,6 @@ import com.baomidou.mybatisplus.extension.service.IService; public interface ICycleCountHeaderService extends IService<CycleCountHeader> { public Result<CycleCountHeader> saveCycleCountHeader(CycleCountHeader cycleCountHeader); + + void updataHeaderStatus(String cycleCountHeadCode); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/impl/CycleCountHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/impl/CycleCountHeaderServiceImpl.java index 9b4c62d..b0388ec 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/impl/CycleCountHeaderServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/stocktaking/cycleCountHeader/service/impl/CycleCountHeaderServiceImpl.java @@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.wms.config.receiptType.entity.ReceiptType; import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.entity.CycleCountDetail; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.service.impl.CycleCountDetailServiceImpl; import org.jeecg.modules.wms.stocktaking.cycleCountHeader.entity.CycleCountHeader; import org.jeecg.modules.wms.stocktaking.cycleCountHeader.mapper.CycleCountHeaderMapper; import org.jeecg.modules.wms.stocktaking.cycleCountHeader.service.ICycleCountHeaderService; @@ -16,8 +18,12 @@ import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; import java.text.SimpleDateFormat; +import java.util.Comparator; import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; /** * @Description: 盘点主表 @@ -28,6 +34,12 @@ import java.util.Date; @Service public class CycleCountHeaderServiceImpl extends ServiceImpl<CycleCountHeaderMapper, CycleCountHeader> implements ICycleCountHeaderService { + + + + @Resource + private CycleCountDetailServiceImpl cycleCountDetailService; + @Override public Result<CycleCountHeader> saveCycleCountHeader(CycleCountHeader cycleCountHeader) { String code = createCode(QuantityConstant.SHIPMENT_BILL_TYPE_PD); @@ -43,6 +55,55 @@ public class CycleCountHeaderServiceImpl extends ServiceImpl<CycleCountHeaderMap return Result.OK("添加成功!", cycleCountHeader); } + @Override + public void updataHeaderStatus(String cycleCountHeaderCode) { + //查询明细单状态,然后更新主单状态 + //执行中时,对比主单状态,比主单数值小的不改变主单,明细单大于主单状态时改变主单状态到和明细单相同 + //完成时在全部单据都完成后才能修改主单状态为完成 + //当其中一条明细有差异时,主单为有差异状态 + CycleCountHeader cyclecountHeader = new CycleCountHeader(); + cyclecountHeader.setCode(cycleCountHeaderCode); +// cyclecountHeader.setWarehouseCode(ShiroUtils.getWarehouseCode()); + LambdaQueryWrapper<CycleCountHeader> lamb = Wrappers.lambdaQuery(cyclecountHeader); + cyclecountHeader = this.getOne(lamb); + if(StringUtils.isNull(cyclecountHeader)){ + throw new ServiceException("没有找到盘点主单!"); + } + CycleCountDetail temp = new CycleCountDetail(); + temp.setCycleCountHeadCode(cyclecountHeader.getCode()); + temp.setWarehouseCode(cyclecountHeader.getWarehouseCode()); + //temp.setCompanyCode(cyclecountHeader.getCompanyCode()); + LambdaQueryWrapper<CycleCountDetail> lam = Wrappers.lambdaQuery(temp); + List<CycleCountDetail> list = cycleCountDetailService.list(lam); + if(list.size() < 1){ + throw new ServiceException("明细为空!"); + } + //当有子单的状态为100时触发主单的完成状态 + //100状态只有全部完成才写入主单 + long count100 = list.stream().filter(t-> t.getEnableStatus().equals(QuantityConstant.CYCLECOUNT_STATUS_COMPLETED)).count(); //明细已完成的条数 + if(count100 == list.size() ){ + cyclecountHeader.setStatusCyc(QuantityConstant.CYCLECOUNT_STATUS_COMPLETED); + this.updateById(cyclecountHeader); + } + //有任何子单没有完成则主单不修改为100 + //有到100的子单时,主单的状态一定是100的前一个状态,所以状态不变 + if(count100 == 0){ + //所有子单状态比较主单状态,只有在明细单大于主单状态时才更改主单状态 + int headerStatus = cyclecountHeader.getStatusCyc(); + long count = list.stream().filter(t->t.getEnableStatus() > headerStatus).count(); + if(count > 0 ){ + //stream流取出明细状态中最大的值,赋给主单状态 + List<CycleCountDetail> cycleCountDetailList = list.stream().sorted( + Comparator.comparing(CycleCountDetail::getEnableStatus).reversed()).collect(Collectors.toList()); + cyclecountHeader.setStatusCyc(cycleCountDetailList.get(0).getEnableStatus()); + this.updateById(cyclecountHeader); + } + + } + + + } + @Transactional public String createCode(String receiptType) { diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java index c23117e..d4b9d78 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/controller/TaskHeaderController.java @@ -25,6 +25,7 @@ import org.jeecg.modules.wms.config.port.entity.Port; import org.jeecg.modules.wms.config.port.service.IPortService; import org.jeecg.modules.wms.config.zone.entity.Zone; import org.jeecg.modules.wms.config.zone.service.IZoneService; +import org.jeecg.modules.wms.framework.aspectj.lang.annotation.ApiLogger; import org.jeecg.modules.wms.framework.controller.HuahengBaseController; import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; @@ -648,4 +649,46 @@ public class TaskHeaderController extends HuahengBaseController { return Result.OK(portList); } + /** + * 修复空出的数据 + * @return + */ + @AutoLog(value = "修复空出的数据") + @PostMapping("/handleEmptyOut") + @ApiOperation("修复空出的数据") + @ResponseBody + @ApiLogger(apiName = "修复空出的数据", from = "WMS") + public Result handleEmptyOut(@RequestBody String taskNo) { + Result result = taskHeaderService.handleEmptyOut(taskNo); + return result; + } + + /** + * 修复重入的数据 + * @return + */ + @AutoLog(value = "修复重入的数据") + @PostMapping("/handleDoubleIn") + @ApiOperation("修复重入的数据") + @ResponseBody + @ApiLogger(apiName = "修复重入的数据", from = "WMS") + public Result handleDoubleIn(@RequestBody String taskNo) { + Result result = taskHeaderService.handleDoubleIn(taskNo); + return result; + } + + /** + * 修复取货错的数据 + * @return + */ + @AutoLog(value = "修复取货错的数据") + @PostMapping("handlePickupError") + @ApiOperation("修复取货错的数据") + @ResponseBody + @ApiLogger(apiName = "修复取货错的数据", from = "WMS") + public Result handlePickupError(@RequestBody String taskNo) { + Result result = taskHeaderService.handlePickupError(taskNo); + return result; + } + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java index dd654e4..7692399 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/service/impl/TaskHeaderServiceImpl.java @@ -6,11 +6,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Collectors; import javax.annotation.Resource; +import org.apache.shiro.SecurityUtils; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.system.vo.LoginUser; +import org.jeecg.modules.system.entity.SysDepartRolePermission; import org.jeecg.modules.wms.api.wcs.service.LocationAllocationService; import org.jeecg.modules.wms.api.wcs.service.WcsService; import org.jeecg.modules.wms.config.container.entity.Container; @@ -36,6 +40,7 @@ import org.jeecg.modules.wms.inventory.inventoryTransaction.service.IInventoryTr import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerHeader; import org.jeecg.modules.wms.receipt.receiptContainerHeader.service.IReceiptContainerHeaderService; import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptDetail; +import org.jeecg.modules.wms.receipt.receiptHeader.entity.ReceiptHeader; import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptDetailService; import org.jeecg.modules.wms.receipt.receiptHeader.service.IReceiptHeaderService; import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentContainerDetail; @@ -43,14 +48,21 @@ import org.jeecg.modules.wms.shipment.shipmentContainerHeader.entity.ShipmentCon import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerDetailService; import org.jeecg.modules.wms.shipment.shipmentContainerHeader.service.IShipmentContainerHeaderService; import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentDetail; +import org.jeecg.modules.wms.shipment.shipmentHeader.entity.ShipmentHeader; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentDetailService; import org.jeecg.modules.wms.shipment.shipmentHeader.service.IShipmentHeaderService; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.entity.CycleCountDetail; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.entity.CycleCountDetailChild; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.service.impl.CycleCountDetailChildServiceImpl; +import org.jeecg.modules.wms.stocktaking.cycleCountDetail.service.impl.CycleCountDetailServiceImpl; +import org.jeecg.modules.wms.stocktaking.cycleCountHeader.service.impl.CycleCountHeaderServiceImpl; import org.jeecg.modules.wms.task.taskHeader.entity.TaskDetail; import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.mapper.TaskDetailMapper; import org.jeecg.modules.wms.task.taskHeader.mapper.TaskHeaderMapper; import org.jeecg.modules.wms.task.taskHeader.service.ITaskDetailService; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; +import org.jeecg.utils.HuahengJwtUtil; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; import org.springframework.beans.factory.annotation.Autowired; @@ -105,7 +117,7 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea @Resource private IShipmentDetailService shipmentDetailService; @Resource - private IMaterialService materialService; + private CycleCountDetailServiceImpl cycleCountDetailService; @Resource private WcsService wcsService; @Resource @@ -120,6 +132,10 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea private ILocationHighService locationHighService; @Resource private LocationAllocationService allocationService; + @Resource + private CycleCountDetailChildServiceImpl cycleCountDetailChildService; + @Resource + private CycleCountHeaderServiceImpl cycleCountHeaderService; @Override @Transactional @@ -853,6 +869,9 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT: result = completeShipmentTask(taskHeader); break; + case QuantityConstant.TASK_TYPE_CYCLECOUNT: + result = completeCycleCountTask(taskHeader); + break; case QuantityConstant.TASK_TYPE_EMPTYRECEIPT: result = completeEmptyInTask(taskHeader); break; @@ -1495,6 +1514,160 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea return Result.OK("完成空托盘入库成功"); } + + + + /** + * 盘点完成 + *盘点有差异完成时状态为105 + * @param taskHeader + * @return + */ + @Transactional(rollbackFor = Exception.class) + public Result completeCycleCountTask(TaskHeader taskHeader) { + /*盘点完成,传入任务主单,查出任务明细,通过任务明细查找盘点的明细单, + 完成任务同时,修改盘点细单和主单的状态,完成后库存锁复位*/ + + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED); + //更新用户 + taskHeader.setUpdateBy(sysUser.getUsername()); + //更新时间 + taskHeader.setUpdateTime(new Date()); + + + //1.先拿到盘点单主单据 + CycleCountDetail cycleCountDetail = cycleCountDetailService.getById(taskHeader.getShipmentContainerHeaderId()); + + //2.盘点单主单据查明细单据list + LambdaQueryWrapper<CycleCountDetailChild> childLambdaQueryWrapper = new LambdaQueryWrapper<CycleCountDetailChild>(); + childLambdaQueryWrapper.eq(CycleCountDetailChild::getCycleCountDetailid,cycleCountDetail.getId()); + List<CycleCountDetailChild> children = cycleCountDetailChildService.list(childLambdaQueryWrapper); + + //3.单据list如果差异数量+生成入库单,差异数-生成出库单进行回传类型其他出库单 + + + int outboundOrderId=0; + String outboundOrderCode=null; + int warehousingOrderId=0; + String warehousingOrderCode=null; + + + for (CycleCountDetailChild child : children) + { + child.setChildStatus(QuantityConstant.CYCLECOUNT_STATUS_COMPLETED); + if (child.getGapQty().compareTo(BigDecimal.ZERO) == 1) + { + if (warehousingOrderId==0) { + ReceiptHeader receiptHeader = new ReceiptHeader(); + receiptHeader.setWarehouseCode(taskHeader.getWarehouseCode()); + receiptHeader.setCompanyCode(taskHeader.getCompanyCode()); + receiptHeader.setType(QuantityConstant.RECEIPT_BILL_TYPE_OR); + receiptHeader.setRemark("盘盈 单号"+cycleCountDetail.getCycleCountHeadCode()); + Result result = receiptHeaderService.saveReceiptHeader(receiptHeader); + if (result.getCode() != 200) + { + return result; + } + receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + receiptHeaderService.updateById(receiptHeader); + //生成入库单并且赋值给warehousingOrderId + warehousingOrderId=receiptHeader.getId(); + warehousingOrderCode=receiptHeader.getCode(); + } + + //生成明细 + ReceiptDetail receiptDetail = new ReceiptDetail(); + receiptDetail.setReceiptId(warehousingOrderId); + receiptDetail.setReceiptCode(warehousingOrderCode); + receiptDetail.setWarehouseCode(taskHeader.getWarehouseCode()); + receiptDetail.setCompanyCode(null); + receiptDetail.setMaterialCode(child.getMaterialCode()); + receiptDetail.setMaterialName(child.getMaterialName()); + receiptDetail.setMaterialSpec(child.getMaterialSpec()); + receiptDetail.setMaterialUnit(child.getMaterialUnit()); + receiptDetail.setQty(child.getGapQty().abs()); + receiptDetail.setTaskQty(child.getGapQty().abs()); + receiptDetail.setInventoryStatus(child.getInventoryStatus()); + receiptDetail.setBatch(child.getBatch()); + receiptDetail.setLot(child.getLot()); + receiptDetail.setStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + receiptDetailService.save(receiptDetail); + + } + + if (child.getGapQty().compareTo(BigDecimal.ZERO) == -1) + { + if (outboundOrderId==0) + { + ShipmentHeader shipmentHeader = new ShipmentHeader(); + shipmentHeader.setWarehouseCode(taskHeader.getWarehouseCode()); + shipmentHeader.setCompanyCode(taskHeader.getCompanyCode()); + shipmentHeader.setType(QuantityConstant.SHIPMENT_BILL_TYPE_OS); + shipmentHeader.setRemark("盘亏 单号"+cycleCountDetail.getCycleCountHeadCode()); + Result result = shipmentHeaderService.saveShipmentHeader(shipmentHeader); + if (result.getCode() != 200) + { + return result; + } + shipmentHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + shipmentHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + shipmentHeaderService.updateById(shipmentHeader); + //生成出库单并且赋值给outboundOrderId + outboundOrderId=shipmentHeader.getId(); + outboundOrderCode=shipmentHeader.getCode(); + + } + //生成明细 + ShipmentDetail shipmentDetail = new ShipmentDetail(); + shipmentDetail.setShipmentId(outboundOrderId); + shipmentDetail.setShipmentCode(outboundOrderCode); + shipmentDetail.setWarehouseCode(taskHeader.getWarehouseCode()); + shipmentDetail.setCompanyCode(null); + shipmentDetail.setMaterialCode(child.getMaterialCode()); + shipmentDetail.setMaterialName(child.getMaterialName()); + shipmentDetail.setMaterialSpec(child.getMaterialSpec()); + shipmentDetail.setMaterialUnit(child.getMaterialUnit()); + shipmentDetail.setQty(child.getGapQty().abs()); + shipmentDetail.setTaskQty(child.getGapQty().abs()); + shipmentDetail.setInventoryStatus(child.getInventoryStatus()); + shipmentDetail.setBatch(child.getBatch()); + shipmentDetail.setLot(child.getLot()); + shipmentDetail.setStatus(QuantityConstant.RECEIPT_HEADER_COMPLETED); + shipmentDetailService.save(shipmentDetail); + } + cycleCountDetailChildService.updateById(child); + } + + + + //4.完成当前任务 + if (!taskHeaderService.saveOrUpdate(taskHeader)) { + throw new ServiceException("盘点任务单据状态更新失败!"); + } + //盘点明细状态 + cycleCountDetail.setEnableStatus(QuantityConstant.CYCLECOUNT_STATUS_COMPLETED); + cycleCountDetail.setCompletedBy(sysUser.getUsername()); + cycleCountDetail.setCompletedAt(new Date()); + cycleCountDetailService.updateById(cycleCountDetail); + //更新主单状态 + cycleCountHeaderService.updataHeaderStatus(cycleCountDetail.getCycleCountHeadCode()); + + + //释放库位 + locationService.updateStatus(cycleCountDetail.getLocationCode(), + QuantityConstant.STATUS_LOCATION_EMPTY, taskHeader.getWarehouseCode()); + return Result.OK("完成盘点任务成功"); + } + + + + + + + + /** * 完成空托盘出库任务 * @param taskHeader 任务 @@ -1953,14 +2126,14 @@ public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHea if (StringUtils.isNotEmpty(lastStatus)) { container.setStatus(lastStatus); // 解决空托盘组移库问题 } - if (StringUtils.isNotEmpty(fromLocationCode)) { - success = containerService.havaLocationCodeByContainer(fromLocationCode, warehouseCode); - if (success) { - throw new ServiceException("库位表已经存在这个容器号,不能再写入"); - } - } +// if (StringUtils.isNotEmpty(fromLocationCode)) { +// success = containerService.havaLocationCodeByContainer(fromLocationCode, warehouseCode); +// if (success) { +// throw new ServiceException("库位表已经存在这个容器号,不能再写入"); +// } +// } container.setLastStatus(QuantityConstant.EMPTY_STRING); - container.setLocationCode(fromLocationCode); +// container.setLocationCode(fromLocationCode); success = containerService.updateById(container); if (!success) { throw new ServiceException("取消任务时, 更新容器失败"); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java index 7b58484..a1b3ec6 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengJwtUtil.java @@ -1,20 +1,34 @@ package org.jeecg.utils; +import java.util.Arrays; import java.util.Date; +import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.wms.framework.aspectj.dto.ApiAuthentication; +import org.jeecg.modules.wms.framework.aspectj.dto.RSA256Key; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.DecodedJWT; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import net.bytebuddy.asm.Advice.This; + public class HuahengJwtUtil { - public static final long EXPIRE_TIME = -1; + /** token失效时间 1天 */ + public static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; + + public static final String HUAHENG_SYSTEM_ID = "HUAHENG-WMS4"; /** * 根据request中的token获取用户账号 @@ -60,7 +74,7 @@ public class HuahengJwtUtil { } /** - * 生成签名,5min后过期 + * 生成签名 * @param username 用户名 * @param secret 用户的密码 * @return 加密的token @@ -73,7 +87,7 @@ public class HuahengJwtUtil { } /** - * 生成签名,5min后过期 + * 生成签名 * @param username 用户名 * @param secret 用户的密码 * @param warehouseCode 登录仓库 @@ -87,6 +101,41 @@ public class HuahengJwtUtil { } /** + * 生成第三方系统HTTP访问TOKEN + * @author TanYibin + * @createDate 2023年2月15日 + * @param apiAuthentication + * @param algorithm + * @return + */ + public static String sign(ApiAuthentication apiAuthentication, Algorithm algorithm) { + return JWT.create().withClaim("operator", apiAuthentication.getOperator()) // 创建Token 操作人 + .withAudience(apiAuthentication.getAudience()) // Token 使用方 + .withIssuer(apiAuthentication.getIssuer()) // Token 发布者 + .withIssuedAt(DateUtil.date()) // 生成签名时间 + .withExpiresAt(apiAuthentication.getExpireDateTime()) // 过期时间 + .withJWTId(UUID.randomUUID().toString()).sign(algorithm); + } + + /** + * 生成第三方系统HTTP访问TOKEN + * @author TanYibin + * @createDate 2023年2月15日 + * @param apiAuthentication + * @return + */ + public static String sign(ApiAuthentication apiAuthentication) { + RSA256Key rsa256Key = new RSA256Key(); // 获取公钥/私钥 + Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); + return JWT.create().withClaim("operator", apiAuthentication.getOperator()) // 创建Token 操作人 + .withAudience(apiAuthentication.getAudience()) // Token 使用方 + .withIssuer(apiAuthentication.getIssuer()) // Token 发布者 + .withIssuedAt(DateUtil.date()) // 生成签名时间 + .withExpiresAt(apiAuthentication.getExpireDateTime()) // 过期时间 + .withJWTId(UUID.randomUUID().toString()).sign(algorithm); + } + + /** * 获得token中的信息无需secret解密也能获得 * @return token中包含的用户名 */ @@ -99,4 +148,34 @@ public class HuahengJwtUtil { } } + /** + * 生成第三方系统HTTP访问TOKEN + * @author TanYibin + * @createDate 2023年2月14日 + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + ApiAuthentication apiAuthentication = new ApiAuthentication(); + // 生成TOKEN必填参数 + apiAuthentication.setOperator("TanYibin"); // Token提供方 + apiAuthentication.setAudience("ACS001"); // Token使用方 + apiAuthentication.setExpireDateTime(DateUtil.parse("2099-12-31 23:59:59", DatePattern.NORM_DATETIME_PATTERN)); // Token失效时间 + + String tokenString = sign(apiAuthentication); + System.out.println("HuahengJwtUtil.sign(apiAuthentication) Token:" + tokenString); + + RSA256Key rsa256Key = new RSA256Key(); // 获取公钥/私钥 + Algorithm algorithm = Algorithm.RSA256(rsa256Key.getPublicKey(), rsa256Key.getPrivateKey()); + // Reusable verifier instance 可复用的验证实例 + JWTVerifier verifier = JWT.require(algorithm).withIssuer(HuahengJwtUtil.HUAHENG_SYSTEM_ID).build(); + DecodedJWT jwt = verifier.verify(tokenString); + System.out.println(); + System.out.println("jwt.getId():" + jwt.getId()); + System.out.println("jwt.getClaim(operator):" + jwt.getClaim("operator").asString()); + System.out.println("jwt.getAudience():" + Arrays.toString(jwt.getAudience().toArray())); + System.out.println("jwt.getIssuer():" + jwt.getIssuer()); + System.out.println("jwt.getIssuedAt():" + DateUtil.format(jwt.getIssuedAt(), DatePattern.NORM_DATETIME_PATTERN)); + System.out.println("jwt.getExpiresAt():" + DateUtil.format(jwt.getExpiresAt(), DatePattern.NORM_DATETIME_PATTERN)); + } } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java new file mode 100644 index 0000000..1879e25 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/OkHttpUtils.java @@ -0,0 +1,279 @@ +package org.jeecg.utils; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; +import com.aliyun.oss.ServiceException; +import com.xkcoding.http.util.StringUtil; + +import antlr.StringUtils; +import cn.hutool.core.util.StrUtil; +import net.bytebuddy.asm.Advice.This; +import okhttp3.*; +import org.jeecg.modules.wms.framework.aspectj.ApiLogAspect; +import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.messaging.support.ErrorMessage; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import javax.validation.constraints.NotNull; + +/** + * OkHttp发送请求 + * @author huaheng + * @Date 2022-5-30 + */ +public class OkHttpUtils { + + private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class); + + /** + * 最多重试次数 + */ + public final static int MAX_RENTRY_COUNT = 3; + + /** + * 最大连接时间(秒) + */ + public final static int CONNECTION_TIMEOUT = 1; + + /** + * 最大读取时间(秒) + */ + public final static int READ_TIMEOUT = 30; + + /** + * 最大写入时间(秒) + */ + public final static int WRITE_TIMEOUT = 30; + + /** + * JSON格式 + */ + public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); + /** + * OkHTTP线程池最大空闲线程数 + */ + public final static int MAX_IDLE_CONNECTIONS = 100; + /** + * OkHTTP线程池空闲线程存活时间(秒) + */ + public final static long KEEP_ALIVE_DURATION = 60; + + private static final String CONTENT_TYPE = "Content-Type"; + + /** 访问接口参数配置 */ + private final static OkHttpClient HTTP_CLIENT = + new OkHttpClient.Builder().connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS).readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) + .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS).addInterceptor(new OkHttpUtils.OkhttpInterceptor(MAX_RENTRY_COUNT)) // 过滤器,设置最大重试次数 + .retryOnConnectionFailure(false).connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.SECONDS)).build(); + + /** + * 向指定 URL 发送GET方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式 + * @return 所代表远程资源的响应结果 + * @throws Exception + */ + public static String sendGet(String url, String param) { + Map<String, String> headers = new HashMap<String, String>(); + return sendGet(url, headers, param); + } + + /** + * 向指定 URL 发送GET方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式 + * @param headers 请求头 + * @return 所代表远程资源的响应结果 + * @throws Exception + */ + public static String sendGet(String url, Map<String, String> headers, String param) { + ApiLog apiLog = new ApiLog(); + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + Request request = builder.url(url + "?" + param).get().build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, param); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = + StrUtil.format("执行GET请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), param, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString, e); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行GET请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), param, result); + } else { + String errorString = StrUtil.format("执行GET请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), param, response.code(), response.message()); + throw new ServiceException(errorString); + } + return result; + } + + /** + * 向指定 URL 发送POST方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数是 name1=value1&name2=value2 的形式 + * @return 远程资源的响应结果 + * @throws IOException + */ + public static String sendPost(String url, String param) throws IOException { + Map<String, String> headers = new HashMap<String, String>(); + return sendPost(url, headers, param); + } + + /** + * 向指定 URL 发送POST方法的请求 + * @param url 发送请求的 URL + * @param param 请求参数,请求参数是 name1=value1&name2=value2 的形式 + * @param headers 请求头 + * @return 远程资源的响应结果 + * @throws IOException + */ + public static String sendPost(String url, Map<String, String> headers, String param) { + ApiLog apiLog = new ApiLog(); + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + FormBody body = new FormBody.Builder().build(); + Request request = builder.url(url + "?" + param).post(body).build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, param); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = + StrUtil.format("执行POST请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), param, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString, e); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行POST请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), param, result); + } else { + String errorString = StrUtil.format("执行POST请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), param, response.code(), response.message()); + throw new RuntimeException(errorString); + } + return result; + } + + public static String sendPostByJsonStr(String url, String jsonString) { + Map<String, String> headers = new HashMap<String, String>(); + return sendPostByJsonStr(url, headers, jsonString); + } + + /** + * JSONString形式发送POST请求 + * @throws Exception + * @throws IOException + */ + public static String sendPostByJsonStr(String url, Map<String, String> headers, String jsonString) { + ApiLog apiLog = new ApiLog(); + headers.put("Accept", "application/json");// 设置接收数据的格式 + headers.put("Content-Type", "application/json");// 设置发送数据的格式 + Request.Builder builder = new Request.Builder(); + buildHeader(builder, headers); + RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, jsonString); + Request request = builder.url(url).post(body).build(); + Response response = null; + String result = null; + try { + ApiLogAspect.initApiLog(apiLog, request, jsonString); + response = HTTP_CLIENT.newCall(request).execute(); + result = response.body().string(); + } catch (Exception e) { + String errorString = StrUtil.format("执行POST请求异常,url:{},header:{},param:{},errorMessage:{}", url, JSON.toJSONString(headers), jsonString, e.getMessage()); + ApiLogAspect.setApiLogException(apiLog, e); + throw new RuntimeException(errorString); + } finally { + ApiLogAspect.finishApiLog(apiLog, response, result); + } + if (response.isSuccessful() && Objects.nonNull(response.body())) {// 调用成功 + log.info("执行POST请求成功,url:{},header:{},param:{},result:{}", url, JSON.toJSONString(headers), jsonString, result); + } else { + String errorString = StrUtil.format("执行POST请求失败,url:{},header:{},param:{},responseCode:{},responseMessage:{}", url, + JSON.toJSONString(headers), jsonString, response.code(), response.message()); + throw new RuntimeException(errorString); + } + return result; + } + + /** + * 设置请求头 + * @param builder . + * @param headers 请求头 + */ + private static void buildHeader(Request.Builder builder, Map<String, String> headers) { + if (Objects.nonNull(headers) && headers.size() > 0) { + headers.forEach((k, v) -> { + if (Objects.nonNull(k) && Objects.nonNull(v)) { + builder.addHeader(k, v); + } + }); + } + } + + /** + * 支持嵌套泛型的POST请求 + * @param url 链接 + * @param json 请求json + * @param type 嵌套泛型 + * @return 响应对象, 可进行强转。 + * @throws Exception + */ + public static <T> T sendPostByJsonStr(String url, String jsonString, TypeReference<T> type) throws Exception { + String result = sendPostByJsonStr(url, jsonString); + if (Objects.nonNull(result) && Objects.nonNull(type)) { + return JSON.parseObject(result, type); + } + return null; + } + + public static class OkhttpInterceptor implements Interceptor { + // 最大重试次数 + private int maxRentry; + + public OkhttpInterceptor(int maxRentry) { + this.maxRentry = maxRentry; + } + + /** 递归 2次下发请求,如果仍然失败 则返回 null 但是 intercept must not return null. 返回 null 会报 IllegalStateException 异常 */ + public Response intercept(@NotNull Chain chain) throws IOException { + return retry(chain, 0); + } + + private Response retry(Chain chain, int retryCent) throws IOException { + Request request = chain.request(); + Response response = null; + try { + response = chain.proceed(request); + } catch (Exception e) { + if (maxRentry > retryCent) { + return retry(chain, retryCent + 1); + } + if (Objects.isNull(response)) { + throw e; + } + } + return response; + } + } +} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java new file mode 100644 index 0000000..5aab3b7 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/SecretKeyUtils.java @@ -0,0 +1,163 @@ +package org.jeecg.utils; + +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import org.jeecg.modules.wms.framework.aspectj.dto.RSA256Key; + +/** + * KeyPairGenerator https://www.jianshu.com/p/4de1ee0e7206 key的生成使用方法 + */ +public class SecretKeyUtils { + + public static final String KEY_ALGORITHM = "RSA"; + private static final String PUBLIC_KEY = "RSAPublicKey"; + private static final String PRIVATE_KEY = "RSAPrivateKey"; + + private static RSA256Key rsa256Key; + + // 获得公钥 + public static String getPublicKey(Map<String, Object> keyMap) throws Exception { + // 获得map中的公钥对象 转为key对象 + Key key = (Key)keyMap.get(PUBLIC_KEY); + // byte[] publicKey = key.getEncoded(); + // 编码返回字符串 + return encryptBASE64(key.getEncoded()); + } + + public static String getPublicKey(RSA256Key rsa256Key) throws Exception { + // 获得map中的公钥对象 转为key对象 + Key key = rsa256Key.getPublicKey(); + // byte[] publicKey = key.getEncoded(); + // 编码返回字符串 + return encryptBASE64(key.getEncoded()); + } + + // 获得私钥 + public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { + // 获得map中的私钥对象 转为key对象 + Key key = (Key)keyMap.get(PRIVATE_KEY); + // byte[] privateKey = key.getEncoded(); + // 编码返回字符串 + return encryptBASE64(key.getEncoded()); + } + + // 获得私钥 + public static String getPrivateKey(RSA256Key rsa256Key) throws Exception { + // 获得map中的私钥对象 转为key对象 + Key key = rsa256Key.getPrivateKey(); + // byte[] privateKey = key.getEncoded(); + // 编码返回字符串 + return encryptBASE64(key.getEncoded()); + } + + // 解码返回byte + public static byte[] decryptBASE64(String key) throws Exception { + return Base64.getDecoder().decode(key); + } + + // 编码返回字符串 + public static String encryptBASE64(byte[] key) throws Exception { + return Base64.getEncoder().encodeToString(key); + } + + // 使用KeyPairGenerator 生成公私钥,存放于map对象中 + public static Map<String, Object> initKey() throws Exception { + /* RSA算法要求有一个可信任的随机数源 */ + // 获得对象 KeyPairGenerator 参数 RSA 1024个字节 + KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); + keyPairGen.initialize(1024); + + // 通过对象 KeyPairGenerator 生成密匙对 KeyPair + KeyPair keyPair = keyPairGen.generateKeyPair(); + + // 通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey + RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic(); + RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate(); + + // 公私钥对象存入map中 + Map<String, Object> keyMap = new HashMap<String, Object>(2); + keyMap.put(PUBLIC_KEY, publicKey); + keyMap.put(PRIVATE_KEY, privateKey); + return keyMap; + } + + /** + * 获取公私钥 + * @return + * @throws Exception + */ + public static synchronized RSA256Key getRSA256Key() throws Exception { + if (rsa256Key == null) { + synchronized (RSA256Key.class) { + if (rsa256Key == null) { + rsa256Key = new RSA256Key(); + Map<String, Object> map = initKey(); + rsa256Key.setPrivateKey((RSAPrivateKey)map.get(SecretKeyUtils.PRIVATE_KEY)); + rsa256Key.setPublicKey((RSAPublicKey)map.get(SecretKeyUtils.PUBLIC_KEY)); + } + } + } + return rsa256Key; + } + + /** + * 解码 PublicKey + * @param key + * @return + */ + public static PublicKey getPublicKey(String key) { + try { + byte[] byteKey = Base64.getDecoder().decode(key); + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePublic(x509EncodedKeySpec); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 解码 PrivateKey + * @param key + * @return + */ + public static PrivateKey getPrivateKey(String key) { + try { + byte[] byteKey = Base64.getDecoder().decode(key); + PKCS8EncodedKeySpec x509EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + return keyFactory.generatePrivate(x509EncodedKeySpec); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static void main(String[] args) { + Map<String, Object> keyMap; + try { + keyMap = initKey(); // 使用 java.security.KeyPairGenerator 生成 公/私钥 + String publicKey = getPublicKey(keyMap); + System.out.println("公钥:\n" + publicKey); + String privateKey = getPrivateKey(keyMap); + System.out.println("私钥:\n" + privateKey); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java index fd6a744..cf3b904 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java @@ -1,12 +1,11 @@ package org.jeecg.utils; -import org.apache.commons.lang.text.StrBuilder; -import org.jeecg.utils.support.StrFormatter; - import java.lang.reflect.Field; import java.util.Collection; import java.util.Map; +import org.apache.commons.lang.text.StrBuilder; + /** * 字符串工具类 * @author huaheng @@ -238,25 +237,6 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { } /** - * 格式化文本, {} 表示占位符<br> - * 此方法只是简单将占位符 {} 按照顺序替换为参数<br> - * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> - * 例:<br> - * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> - * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> - * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> - * @param template 文本模板,被替换的部分用 {} 表示 - * @param params 参数值 - * @return 格式化后的文本 - */ - public static String format(String template, Object... params) { - if (isEmpty(params) || isEmpty(template)) { - return template; - } - return StrFormatter.format(template, params); - } - - /** * 驼峰首字符小写 */ public static String uncapitalize(String str) { diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java new file mode 100644 index 0000000..214b6e6 --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengRedisConfig.java @@ -0,0 +1,49 @@ +package org.jeecg.utils.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; + +import org.jeecg.utils.manager.RedisConfigCacheManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.time.Duration; + +@Slf4j +@Configuration +public class HuahengRedisConfig { + + @Bean + @Primary + public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) { + ObjectMapper om = new ObjectMapper(); + RedisSerializer<String> redisSerializer = new StringRedisSerializer(); + Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); + // 解决查询缓存转换异常的问题 + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + // 配置序列化(解决乱码的问题) + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMillis(-1)) + .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues(); + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory); + + /* + * return RedisConfigCacheManager.builder(factory).withInitialCacheConfigurations().transactionAware().build(); + */ + return new RedisConfigCacheManager(cacheWriter, config); + } +} \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengShiroConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengShiroConfig.java index 8a80708..ed6c1e2 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengShiroConfig.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/HuahengShiroConfig.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.config; import java.util.LinkedHashMap; import java.util.Map; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/HttpUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/http/HttpUtils.java deleted file mode 100644 index 27ff6dc..0000000 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/HttpUtils.java +++ /dev/null @@ -1,346 +0,0 @@ -package org.jeecg.utils.http; - -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.jeecg.modules.wms.framework.aspectj.ApiLogAspect; -import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.net.ssl.*; -import java.io.*; -import java.net.*; -import java.security.cert.X509Certificate; - -/** - * 通用http发送方法 - * @author huaheng - */ -public class HttpUtils { - - private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); - - /** - * 向指定 URL 发送GET方法的请求 - * @param url 发送请求的 URL - * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String sendGet(String url, String param) { - StringBuilder result = new StringBuilder(); - BufferedReader in = null; - try { - String urlNameString = url + "?" + param; - log.info("sendGet - {}", urlNameString); - URL realUrl = new URL(urlNameString); - URLConnection connection = realUrl.openConnection(); - connection.setRequestProperty("accept", "*/*"); - connection.setRequestProperty("connection", "Keep-Alive"); - connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); - connection.connect(); - in = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String line; - while ((line = in.readLine()) != null) { - result.append(line); - } - log.info("recv - {}", result); - } catch (ConnectException e) { - log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e.getMessage()); - } catch (SocketTimeoutException e) { - log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e.getMessage()); - } catch (IOException e) { - log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e.getMessage()); - } catch (Exception e) { - log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e.getMessage()); - } finally { - try { - if (in != null) { - in.close(); - } - } catch (Exception ex) { - log.error("调用in.close Exception, url=" + url + ",param=" + param, ex.getMessage()); - } - } - return result.toString(); - } - - // post请求 为erp回传定制 - public static String erppost(String strURL, String params, String key) { - HttpURLConnection connection = null; - InputStream is = null; - OutputStreamWriter out = null; - String result = null; - ApiLog log = null; - - try { - URL url = new URL(strURL);// 创建连接 -// String ur = "" + url; - connection = (HttpURLConnection)url.openConnection(); - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setUseCaches(false); - connection.setInstanceFollowRedirects(true); - connection.setRequestMethod("POST");// 设置请求方式 - connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式 - connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式 - connection.setRequestProperty("apiKey", key);// 测试环境key - log = ApiLogAspect.initApiLog(connection, params); - connection.connect(); - out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");// utf-8编码 - out.append(params); - out.flush(); - out.close(); // 读取响应 - int length = (int)connection.getContentLength();// 获取长度 - is = connection.getInputStream(); -// BufferedReader br = new BufferedReader(new InputStreamReader(is)); - length = 10000; - if (length > 0) { - byte[] data = new byte[length]; - byte[] temp = new byte[512]; - int readLen = 0; - int destPos = 0; - while ((readLen = is.read(temp)) > 0) { - System.arraycopy(temp, 0, data, destPos, readLen); - destPos += readLen; - } - result = new String(data, "UTF-8"); - System.out.println(result); - } - } catch (Exception e) { - ApiLogAspect.setApiLogException(log, e); - e.printStackTrace(); - } finally { - ApiLogAspect.finishApiLog(log, connection, result); - if (connection != null) - connection.disconnect(); - IOUtils.closeQuietly(out, is); - } - return result; - } - - /** - * 向指定 URL 发送POST方法的请求 - * @param url 发送请求的 URL - * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String sendPost(String url, String param) { - PrintWriter out = null; - BufferedReader in = null; - StringBuilder result = new StringBuilder(); - try { - String urlNameString = url + "?" + param; - log.info("sendPost - {}", urlNameString); - URL realUrl = new URL(urlNameString); - URLConnection conn = realUrl.openConnection(); - conn.setRequestProperty("accept", "*/*"); - conn.setRequestProperty("connection", "Keep-Alive"); - conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); - conn.setRequestProperty("Accept-Charset", "utf-8"); - conn.setRequestProperty("contentType", "utf-8"); - conn.setDoOutput(true); - conn.setDoInput(true); - out = new PrintWriter(conn.getOutputStream()); - out.print(param); - out.flush(); - if (((HttpURLConnection)conn).getResponseCode() >= 390) { - in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream())); - } else { - in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - } -// in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); - String line; - while ((line = in.readLine()) != null) { - result.append(line); - } - log.info("recv - {}", result); - } catch (ConnectException e) { - log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e.getMessage()); - } catch (SocketTimeoutException e) { - log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e.getMessage()); - } catch (IOException e) { - log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e.getMessage()); - } catch (Exception e) { - log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e.getMessage()); - } finally { - try { - if (out != null) { - out.close(); - } - if (in != null) { - in.close(); - } - } catch (IOException ex) { - log.error("调用in.close Exception, url=" + url + ",param=" + param, ex.getMessage()); - } - } - return result.toString(); - } - - public static String sendSSLPost(String url, String param) { - StringBuilder result = new StringBuilder(); - String urlNameString = url + "?" + param; - try { - log.info("sendSSLPost - {}", urlNameString); - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, new TrustManager[] {new TrustAnyTrustManager()}, new java.security.SecureRandom()); - URL console = new URL(urlNameString); - HttpsURLConnection conn = (HttpsURLConnection)console.openConnection(); - conn.setRequestProperty("accept", "*/*"); - conn.setRequestProperty("connection", "Keep-Alive"); - conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); - conn.setRequestProperty("Accept-Charset", "utf-8"); - conn.setRequestProperty("contentType", "utf-8"); - conn.setDoOutput(true); - conn.setDoInput(true); - - conn.setSSLSocketFactory(sc.getSocketFactory()); - conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); - conn.connect(); - InputStream is = conn.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - String ret = ""; - while ((ret = br.readLine()) != null) { - if (ret != null && !"".equals(ret.trim())) { - result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8")); - } - } - log.info("recv - {}", result); - conn.disconnect(); - br.close(); - } catch (ConnectException e) { - log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e.getMessage()); - } catch (SocketTimeoutException e) { - log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e.getMessage()); - } catch (IOException e) { - log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e.getMessage()); - } catch (Exception e) { - log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e.getMessage()); - } - return result.toString(); - } - - // 此方法是将参数以body形式发送post请求 - public static String bodypost(String strURL, String params) { - System.out.println(strURL); - System.out.println(params); - HttpURLConnection connection = null; - InputStream is = null; - OutputStreamWriter out = null; - String result = null; - ApiLog log = null; - - try { - URL url = new URL(strURL);// 创建连接 - String stringUrl = "" + url; - connection = (HttpURLConnection)url.openConnection(); - connection.setDoOutput(true); - connection.setDoInput(true); - connection.setUseCaches(false); - connection.setInstanceFollowRedirects(true); - connection.setRequestMethod("POST");// 设置请求方式 - connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式 - connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式 - if ((stringUrl.contains("10.0.15.19"))) { - connection.setRequestProperty("apiKey", "c687ef505557428595e6a596fba5de6c");// 测试环境key - } - log = ApiLogAspect.initApiLog(connection, params); - connection.connect(); - out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");// utf-8编码 - out.append(params); - out.flush(); - out.close(); // 读取响应 - int length = (int)connection.getContentLength();// 获取长度 - is = connection.getInputStream(); -// BufferedReader br = new BufferedReader(new InputStreamReader(is)); - length = 10000; - if (length > 0) { - byte[] data = new byte[length]; - byte[] temp = new byte[512]; - int readLen = 0; - int destPos = 0; - while ((readLen = is.read(temp)) > 0) { - System.arraycopy(temp, 0, data, destPos, readLen); - destPos += readLen; - } - result = new String(data, "UTF-8"); - System.out.println(result); - } - } catch (Exception e) { - ApiLogAspect.setApiLogException(log, e); - e.printStackTrace(); - } finally { - ApiLogAspect.finishApiLog(log, connection, result); - if (connection != null) - connection.disconnect(); - IOUtils.closeQuietly(out, is); - } - return result; - } - - /** - * 发送以json为参数的POST请求 - * @param json - * @param url - * @return - */ - public static String sendJsonPostToken(String json, String url) { - String result = ""; - HttpPost post = new HttpPost(url); - try { - CloseableHttpClient httpClient = HttpClients.createDefault(); - - post.setHeader("Content-Type", "application/json;charset=utf-8"); - post.addHeader("Authorization", "Basic YWRtaW46"); - StringEntity postingString = new StringEntity(json, "utf-8"); - post.setEntity(postingString); - HttpResponse response = httpClient.execute(post); - - InputStream in = response.getEntity().getContent(); - BufferedReader br = new BufferedReader(new InputStreamReader(in, "utf-8")); - StringBuilder strber = new StringBuilder(); - String line = null; - while ((line = br.readLine()) != null) { - strber.append(line + '\n'); - } - br.close(); - in.close(); - result = strber.toString(); - if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { - result = "服务器异常"; - } - } catch (Exception e) { - System.out.println("请求异常"); - throw new RuntimeException(e); - } finally { - post.abort(); - } - return result; - } - - private static class TrustAnyTrustManager implements X509TrustManager { - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) {} - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) {} - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[] {}; - } - } - - private static class TrustAnyHostnameVerifier implements HostnameVerifier { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - } - -} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java deleted file mode 100644 index f513b49..0000000 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/http/OkHttpUtils.java +++ /dev/null @@ -1,174 +0,0 @@ -package org.jeecg.utils.http; - -import com.alibaba.fastjson.parser.Feature; -import com.google.gson.Gson; -import okhttp3.*; -import org.jeecg.modules.wms.framework.aspectj.ApiLogAspect; -import org.jeecg.modules.wms.monitor.apiLog.entity.ApiLog; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -/** - * OkHttp发送请求 - * @author huaheng - * @Date 2022-5-30 - */ -public class OkHttpUtils { - - private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class); - - /** - * 最大连接时间 - */ - public final static int CONNECTION_TIMEOUT = 30; - /** - * JSON格式 - */ - public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8"); - /** - * OkHTTP线程池最大空闲线程数 - */ - public final static int MAX_IDLE_CONNECTIONS = 100; - /** - * OkHTTP线程池空闲线程存活时间 - */ - public final static long KEEP_ALIVE_DURATION = 30L; - - private static final String CONTENT_TYPE = "Content-Type"; - - /** - * client - * 配置重试 - */ - private final static OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().readTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) - .writeTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS).connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) - .connectionPool(new ConnectionPool(MAX_IDLE_CONNECTIONS, KEEP_ALIVE_DURATION, TimeUnit.MINUTES)).build(); - private static final Gson GSON = new Gson(); - - /** - * 向指定 URL 发送GET方法的请求 - * @param url 发送请求的 URL - * //* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String sendGet(String url, String param) { - // headers 请求头 - Map<String, String> headers = new HashMap<>(); - // 请求URI - String urlNameString = url + "?" + param; - - Request.Builder builder = new Request.Builder(); - buildHeader(builder, headers); - - Request request = builder.url(urlNameString).get().build(); - Response response = null; - try { - response = HTTP_CLIENT.newCall(request).execute(); - if (response.isSuccessful() && Objects.nonNull(response.body())) { - String result = response.body().string(); - log.info("执行get请求, url: {} 成功,返回数据: {}", url, result); - return result; - } - } catch (IOException e) { - log.error("执行get请求,url: {} 失败!", url, e); - } - return ""; - } - - /** - * 向指定 URL 发送POST方法的请求 - * @param url 发送请求的 URL - * // * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String sendPost(String url, String param) { - FormBody.Builder builder = new FormBody.Builder(); - String urlNameString = url + "?" + param; - FormBody body = builder.build(); - Request request = new Request.Builder().url(urlNameString).post(body).build(); - Response response = null; - try { - response = HTTP_CLIENT.newCall(request).execute(); - // 调用成功 - if (response.isSuccessful() && response.body() != null) { - return response.body().string(); - } - } catch (IOException e) { - e.printStackTrace(); - } - return ""; - } - - // 此方法是将参数以body形式发送post请求 - public static String bodypost(String strURL, String json) { - ApiLog apiLog = null; - // using above json body as a input to post API call - RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json); - // headers 请求头 - Map<String, String> headers = new HashMap<>(); - headers.put("Accept", "application/json");// 设置接收数据的格式 - headers.put("Content-Type", "application/json");// 设置发送数据的格式 - Request.Builder builder = new Request.Builder(); - buildHeader(builder, headers); - Request request = builder.url(strURL).post(body).build(); - Response response = null; - String result = null; - try { - apiLog = ApiLogAspect.initApiLog(request, json); - response = HTTP_CLIENT.newCall(request).execute(); - if (response.isSuccessful() && Objects.nonNull(response.body())) { - result = response.body().string(); - log.info("执行post请求,url: {}, header: {} ,参数: {} 成功,返回结果: {}", strURL, headers, json, result); - } - } catch (IOException e) { - ApiLogAspect.setApiLogException(apiLog, e); - log.error("执行post请求,url: {},参数: {} 失败!", strURL, json, e); - } finally { - ApiLogAspect.finishApiLog(apiLog, response, result); - } - return result; - } - - /** - * 设置请求头 - * @param builder . - * @param headers 请求头 - */ - private static void buildHeader(Request.Builder builder, Map<String, String> headers) { - if (Objects.nonNull(headers) && headers.size() > 0) { - headers.forEach((k, v) -> { - if (Objects.nonNull(k) && Objects.nonNull(v)) { - builder.addHeader(k, v); - } - }); - } - } - - /** - * 支持嵌套泛型的post请求。 - * - * <pre> - * Type type = new TypeToken<Results<User>>() {}.getType(); - * - * <pre/> - * @param url 链接 - * @param json 请求json - * @param type 嵌套泛型 - * @return 响应对象, 可进行强转。 - */ - public static <T> T post(String url, String json, Type type) { - String result = bodypost(url, json); - if (Objects.nonNull(result) && Objects.nonNull(type)) { - return GSON.fromJson(result, type); - } - return null; - } - -} diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/CustomLogContextListener.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/listener/CustomLogContextListener.java index 46735d8..dfa74f5 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/CustomLogContextListener.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/listener/CustomLogContextListener.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.listener; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java new file mode 100644 index 0000000..ef1a19c --- /dev/null +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/manager/RedisConfigCacheManager.java @@ -0,0 +1,69 @@ +package org.jeecg.utils.manager; + +import java.time.Duration; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.redis.cache.CacheKeyPrefix; +import org.springframework.data.redis.cache.RedisCache; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; + +import lombok.extern.slf4j.Slf4j; + +/** + * redis 配置类 + */ +@Slf4j +public class RedisConfigCacheManager extends RedisCacheManager { + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { + super(cacheWriter, defaultCacheConfiguration); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) { + super(cacheWriter, defaultCacheConfiguration, initialCacheNames); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation, + String... initialCacheNames) { + super(cacheWriter, defaultCacheConfiguration, allowInFlightCacheCreation, initialCacheNames); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, + Map<String, RedisCacheConfiguration> initialCacheConfigurations) { + super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations); + } + + public RedisConfigCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, + Map<String, RedisCacheConfiguration> initialCacheConfigurations, boolean allowInFlightCacheCreation) { + super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, allowInFlightCacheCreation); + } + + private static final RedisSerializationContext.SerializationPair<Object> DEFAULT_PAIR = + RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()); + + private static final CacheKeyPrefix DEFAULT_CACHE_KEY_PREFIX = cacheName -> cacheName + ":"; + + @Override + protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + final int lastIndexOf = StringUtils.lastIndexOf(name, '#'); + if (lastIndexOf > -1) { + final String ttl = StringUtils.substring(name, lastIndexOf + 1); + final Duration duration = Duration.ofSeconds(Long.parseLong(ttl)); + cacheConfig = cacheConfig.entryTtl(duration); + // 修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX).serializeValuesWith(DEFAULT_PAIR); + final String cacheName = StringUtils.substring(name, 0, lastIndexOf); + return super.createRedisCache(cacheName, cacheConfig); + } else { + // 修改缓存key和value值的序列化方式 + cacheConfig = cacheConfig.computePrefixWith(DEFAULT_CACHE_KEY_PREFIX).serializeValuesWith(DEFAULT_PAIR); + return super.createRedisCache(name, cacheConfig); + } + // throw new RuntimeException("字符串中必须包含#号,#号后为过期时间, -1为永不过期"); + } +} \ No newline at end of file diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/RedissonDistributedLocker.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/RedissonDistributedLocker.java index 82d2210..a564ef5 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/RedissonDistributedLocker.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/RedissonDistributedLocker.java @@ -1,4 +1,4 @@ -package org.jeecg.utils; +package org.jeecg.utils.support; import java.util.concurrent.TimeUnit; diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java deleted file mode 100644 index aa86bae..0000000 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/support/StrFormatter.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.jeecg.utils.support; - -import org.jeecg.utils.StringUtils; - -/** - * 字符串格式化 - * @author huaheng - */ -public class StrFormatter { - - public static final String EMPTY_JSON = "{}"; - public static final char C_BACKSLASH = '\\'; - public static final char C_DELIM_START = '{'; - public static final char C_DELIM_END = '}'; - - /** - * 格式化字符串<br> - * 此方法只是简单将占位符 {} 按照顺序替换为参数<br> - * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> - * 例:<br> - * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> - * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> - * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> - * @param strPattern 字符串模板 - * @param argArray 参数列表 - * @return 结果 - */ - public static String format(final String strPattern, final Object... argArray) { - if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) { - return strPattern; - } - final int strPatternLength = strPattern.length(); - - // 初始化定义好的长度以获得更好的性能 - StringBuilder sbuf = new StringBuilder(strPatternLength + 50); - - int handledPosition = 0; - int delimIndex;// 占位符所在位置 - for (int argIndex = 0; argIndex < argArray.length; argIndex++) { - delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); - if (delimIndex == -1) { - if (handledPosition == 0) { - return strPattern; - } else { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 - sbuf.append(strPattern, handledPosition, strPatternLength); - return sbuf.toString(); - } - } else { - if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) { - if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) { - // 转义符之前还有一个转义符,占位符依旧有效 - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(Convert.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; - } else { - // 占位符被转义 - argIndex--; - sbuf.append(strPattern, handledPosition, delimIndex - 1); - sbuf.append(C_DELIM_START); - handledPosition = delimIndex + 1; - } - } else { - // 正常占位符 - sbuf.append(strPattern, handledPosition, delimIndex); - sbuf.append(Convert.utf8Str(argArray[argIndex])); - handledPosition = delimIndex + 2; - } - } - } - // append the characters following the last {} pair. - // 加入最后一个占位符后所有的字符 - sbuf.append(strPattern, handledPosition, strPattern.length()); - - return sbuf.toString(); - } - -} diff --git a/huaheng-wms-core/src/main/resources/application-dev.yml b/huaheng-wms-core/src/main/resources/application-dev.yml index ff37593..4535301 100644 --- a/huaheng-wms-core/src/main/resources/application-dev.yml +++ b/huaheng-wms-core/src/main/resources/application-dev.yml @@ -191,7 +191,7 @@ jeecg: #webapp文件路径 webapp: /opt/webapp shiro: - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/test/test** + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/test/test**,/api/wms/** #阿里云oss存储和大鱼短信秘钥配置 oss: accessKey: ?? @@ -273,8 +273,10 @@ cas: #Mybatis输出sql日志 logging: level: - org.jeecg.modules.wms: debug - org.springframework: info + org.jeecg.common: WARN + org.jeecg.modules: WARN + org.jeecg.modules.wms: DEBUG + org.jeecg.config.shiro: INFO #swagger knife4j: #开启增强配置 diff --git a/huaheng-wms-core/src/main/resources/application-prod.yml b/huaheng-wms-core/src/main/resources/application-prod.yml index 701a2a6..f396120 100644 --- a/huaheng-wms-core/src/main/resources/application-prod.yml +++ b/huaheng-wms-core/src/main/resources/application-prod.yml @@ -189,7 +189,7 @@ jeecg: #webapp文件路径 webapp: /opt/jeecg-boot/webapp shiro: - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/api/getUserInfo + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/test/test**,/api/wms/** #阿里云oss存储和大鱼短信秘钥配置 oss: accessKey: ?? @@ -262,8 +262,10 @@ cas: #Mybatis输出sql日志 logging: level: - org.jeecg.modules.wms: info - org.springframework: info + org.jeecg.common: WARN + org.jeecg.modules: WARN + org.jeecg.modules.wms: DEBUG + org.jeecg.config.shiro: INFO #swagger knife4j: #开启增强配置 diff --git a/huaheng-wms-core/src/main/resources/application-test.yml b/huaheng-wms-core/src/main/resources/application-test.yml index fe4ff8d..d472f24 100644 --- a/huaheng-wms-core/src/main/resources/application-test.yml +++ b/huaheng-wms-core/src/main/resources/application-test.yml @@ -191,7 +191,7 @@ jeecg: #webapp文件路径 webapp: /opt/webapp shiro: - excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/test/test** + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/sys/getWarehouseByUserCode,/test/test**,/api/wms/** #阿里云oss存储和大鱼短信秘钥配置 oss: accessKey: ?? @@ -274,8 +274,10 @@ cas: #Mybatis输出sql日志 logging: level: - org.jeecg.modules.wms: debug - org.springframework: info + org.jeecg.common: WARN + org.jeecg.modules: WARN + org.jeecg.modules.wms: DEBUG + org.jeecg.config.shiro: DEBUG #swagger knife4j: #开启增强配置 diff --git a/huaheng-wms-core/src/main/resources/application.yml b/huaheng-wms-core/src/main/resources/application.yml index 0875ae2..641bf07 100644 --- a/huaheng-wms-core/src/main/resources/application.yml +++ b/huaheng-wms-core/src/main/resources/application.yml @@ -3,3 +3,7 @@ spring: name: huaheng-wms-core profiles: active: test + +huaheng: + system: + Id: HUAHENG-WMS4 diff --git a/huaheng-wms-core/src/main/resources/banner.txt b/huaheng-wms-core/src/main/resources/banner.txt index fbde3db..2c04f55 100644 --- a/huaheng-wms-core/src/main/resources/banner.txt +++ b/huaheng-wms-core/src/main/resources/banner.txt @@ -9,4 +9,4 @@ 888 888 "Y88888P" d88P 888 888 888 8888888888 888 Y888 "Y8888P88 888P Y888 888 888 "Y8888P" 888 Jeecg Boot Version: 3.1.0 -Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} \ No newline at end of file +Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} diff --git a/huaheng-wms-core/src/main/resources/logback-spring.xml b/huaheng-wms-core/src/main/resources/logback-spring.xml index 1fe1103..6a72ece 100644 --- a/huaheng-wms-core/src/main/resources/logback-spring.xml +++ b/huaheng-wms-core/src/main/resources/logback-spring.xml @@ -2,7 +2,7 @@ <configuration debug="false"> <!-- 监听器,指定日志文件存放目录 --> - <contextListener class="org.jeecg.utils.CustomLogContextListener" /> + <contextListener class="org.jeecg.utils.listener.CustomLogContextListener" /> <!--定义日志文件的存储地址 --> <property name="LOG_HOME" value="${LOG_PATH}/logs" />